Create Flappy Bird Game in 3 Days – Day 2, Part 2

Why are some of the images in this post went missing?

This is a final part of Day 2 of the 3 Days of the series. Check out the previous post here.

Hour 5 : Obstacle, Point

We will create the obstacle block in this hour. Create a new class Obstacle like the following.

Put the following in buildObstacle method.

Before we continue, you need to understand a little about anchor point in SpriteKit.

This is an excerpt from SpriteKit Programming Guide: A sprite node’s anchorPoint property determines which point in the frame is positioned at the sprite’s position. Anchor points are specified in the unit coordinate system, shown in below figure. The unit coordinate system places the origin at the bottom left corner of the frame and (1,1) at the top right corner of the frame. A sprite’s anchor point defaults to (0.5,0.5), which corresponds to the center of the frame.

You see, by default the anchor point is in the center of the node. That’s OK as long as you know your node length, the position where you want to be and you can try and guess by executing your code on device to get the best position.

But in our case, the block has to be position randomly in vertical and have to take into account of the node height (different for iPhone and iPad) to get the half point and minus the screen offset (different for 3.5 inch, 4 inch and iPad) etc etc. The calculation is getting complicated.

So to make it easier and maintainable, we are going to set the anchor point for lower block to be middle top (0.5, 1), and upper block to be middle bottom (0.5, 0). I’ll show you how easy the calculation later if we going this way.

We add an invisible node in the middle of the gap of the upper block and lower block, as the point block. This will help to detect if the bird have fly in the gap and will notify the system that it should collecting the point.

Next, we add the following in the randomHeight method.

Remember that the coordinate position is originated in bottom left? We set the minimum lower block Y-coordinate to be 70, and the maximum block Y-coordinate to be 360 (140 point from above the screen for 3.5 inch device). Each time we invoke the randomHeight method, it will give the new position for the lower block height.

You see how easy the calculation of the position of the block now that we use anchor point?

Right now, your code will have error on this piece of code.

That’s because this method does not exist in the SDK. Normally, we would use the below to define the body of the block.

But, this method will create a body that is position at the default anchor point, which is at the center. The physics body will still remain the same place if we change our anchor point to other value.

When we change the anchor point and set the position, we only change the position of the display element of the node, not the physics body!

So to address this problem, we need to create physics body that will take into consideration of the anchor point adjustment.

Create a new category class like below and import it in the Obstacle.m later.

In next hour, we are going to putting all the code together to make the bird fly and crash the bird onto the block!

Hour 6 : Putting Bird and Obstacle Together

Add the following in the MyScene.m

This will create four block, with each block separated about 3 block width, and put them 13 block away from the screen to the right.

We need to animate the block to move in sync with the land animation. Overwrite the moveBG method of the MyScene to the following.

The code is about the same as the land animation in the parent class, except that it will only move when the game is still on.

Since we are reusing the block object, we need to call the randomHeight method to re-position the block gap so that it will appear like a new block each time we swap the block to the back.

Next, add the following code to initiate the game.

What this method do is when the first tap occurred,

  • Init the obstacle block
  • Hide the instruction node

For subsequent tap, it will set the body of the bird to dynamic so that it will response to the gravity, and apply the impulse to the bird to make it jump.

Next, we will handle the collission of the bird. Add the following in the MyScene.m

We check if one of the contact body is of point category, it’s actually touching the  gap inside and we increment the totalpoint value, otherwise, it should end the game. We’ve added the shake screen animation and set the gameover flag to true.

Now try to run your game. You should be able to start playing the game for the first time!

In next hour, we are going to display current score and store your best score.

Hour 7 : Score

SpriteKit has the SKLabelNode that can handle displaying of text in game scene. However, it will only handle flat text and can’t do much to do a fancy text.

Hence I’ve build a simple class to display the score using image.

Add the following in your project.

Now, add the following in MyScene.m.

Update the score whenever the bird collect the point in didBeginContact method.

We need to store the top score whenever the current score is higher than the previous top. Add the following in the GameUtil.

In next hour, we are going to retrieve the score and save the score whenever the game is over, and display the scoreboard and coin.

Hour 8 : Game Over, Scoreboard, Coin, Button

Create a new class GameStat that will hold the score, top score and coin information.

In the setup method, we init 2 TexturedFont object that will display the top score and current game score.

In populateScore method, we did the following:

  • Get the previous top score
  • Save the current game score (which will check if the score is more than the previous top score)
  • Run the score from 0 to the current score, and upon completion, check if it’s new top score and display the “NEW” word beside it
  • Display gold, silver, bronze or no coin based on the score

Next, we are going to build game over logo, scoreboard, and some button when the game is over. Add the following method in MyScene.m.

Nothing new here, except that there’s a series of animation that tie together to display each element right after another. You should probably have a detail look into various animation available and customize your own.

Sofar, we’ve added menu button and replay button, that goes back to main menu scene, and reload the game scene again to replay.

Add the below code to handle touches of the button in touchesBegan method in MyScene.m.

Below are the two method that will handle the button action.

Finally, add this in didBeginContact method whenever the game is over.

Go ahead and run your game on your device. By right, the game is quite complete with all the basic function implemented.

Tomorrow we are going to polish up the game and add some final detail like sound, advertisement, rating etc. You can check the post here.

Let me know your thought about this tutorial.

4 thoughts on “Create Flappy Bird Game in 3 Days – Day 2, Part 2

  1. giraff-y says:

    Hi, thanks a lot for the tutorial! I’m pretty new to Xcode and am a creating a game that shares a lot of similarities to Flappy Bird so I was able to use your advice in different places!
    I looked over different of these tutorials and yours is definetely the most detailed one from start to finish!
    I had to change the iAd code and use NSNotifications to call the show/hide methods.
    There was an update of your app on 05.03. where some iAd code was changed. Is this featured in the tutorial?
    Thanks a lot again! J

    1. Yoke Harn says:

      Hi Giraff,
      I’m glad this tutorial helps you.
      The last update of the game is to remove the ads when the iAd is not available in the player country, so player can get away with the blank white space at the bottom of the screen.

  2. giraff-y says:

    Thanks for the quick reply!
    Again, your tutorial has been most helpful and it is very much appreciated!

  3. My WordPress Was Hacked And How To Survive It - Yoke Harn | Yoke Harn says:

    […] to recover the files but to no avail. I lost part of my site forever. Here you can see some post that are missing the […]

Leave a Reply

Your email address will not be published. Required fields are marked *