Build a Caterpillar Game with Cocos2D: Movement and Missiles

This is the fifth installment of our Cocos2D tutorial series on cloning Centipede for iOS. Make sure you have completed the previous parts before beginning.


Last Time...

In the last tutorial, we discussed the AI of the caterpillar. You learned how to move the caterpillar through the sprout field as well as the bounds of the level.

In today's tutorial, we will be jumping all over the place as we discuss the player movement/interaction and firing missiles.


Step 1: Controlling The Player

Controlling the player is actually quite simple. The first thing we need to do is tell our game layer to swallow touches in order to interact with it. Add the following code to your init method in GameLayer.m:

As you saw in the first tutorial, this line of code will simply allow GameLayer to be a touch delegate allowing it to receive notifications of touches. Now, there are two methods that we need to implement. Add the following methods to GameLayer.m

  1. We first need to implement the ccTouchesBegan method to let the caller know that we are responding to touches. If you omit this, your game will crash.
  2. Next, is the ccTouchesMoved method which gets called when the player drags their finger on the device.
  3. Get a reference to the coordinates of the current touch location and the coordinates of the previous touch location.
  4. Get the change from the old location to the new one. We will use this change to determine how far the player should move.
  5. Here we have a series of checks to ensure that the player stays within the "player area" or the virtual bounding box that we set up for them. If not, we don't execute the code in #7 that actually moves the player.
  6. Update the player's position.
  7. Here we are checking to see if the player collides with any of the sprouts. Sprouts pose as obstacles for the player and we want to restrict the player's movement if they are in his way.
  8. Finally, if there is a collision, revert the player's position to their last good position.

Now if you run the game, you should be able to drag anywhere on your game area and move the player within the confined space.


Step 2: The Missile Object

The missile object is what allows the player and the other game objects to interact. The player will fire a constant stream of missiles with the speed and frequency varying on the current level.

Before we begin creating the Missile, we need to establish a few constants that will be used. Open GameConfig.h and add the following lines:

I will explain each of these as they come up in the code that follows. Now, create a new GameObject subclass called Missile. Add the following code to Missile.h:

The dirty property will be used in the future to denote that this missile is no longer in play. This could be because of it going off screen or colliding with another game object. Since the missiles are constantly moving, they will need an update method to animate them.

Now, open up Missile.m and add the following code:

  1. Our init method looks very familiar and is only responsible for creating the Missile's sprite.
  2. This is how fast the missile will be moving. It starts with a base value and speeds up based on the current level.
  3. At some point, the speed of our missile might get out of control. We prevent this by adding a max speed.
  4. These two lines are what actually move the missile forward. We calculate a new y for the missile and update the position.
  5. Finally, if the missile collides with the top, set it's _dirty property to true. We will garbage collect the dirty missiles inside of GameLayer.

Step 3: Firing The Missiles

Now that we have some missiles to fire, we need to fire them off from the player. Generally, when you have a large amount of objects such as missiles, you want to reuse as many as possible and not allocate new ones while the main loop is running. To solve this issue, we will create two arrays. One array will hold all of the missiles that are currently in play (ie fired by the player) and the other will hold the pool of missiles that have yet to be fired. At the end of the update method, we will clean up all of the dirty missiles and move them from the "in play" array to the "pool" array.

Add the following properties to your GameLayer.h file:

Now open GameLayer.m, import Missile.h, and add the following lines in to your init method:

  1. Initialize each of the missile arrays
  2. Loop kMissilesTotal times and create that many Missile objects. Once they are created, we add them to the missilesWaiting array.

Next, jump down to the update method and add the following code:

  1. We need to create a static counter to help facilitate the frequency at which the missiles are fired.
  2. Calculates the missile fire frequency. As the level increases, so does the frequency.
  3. We only want to release a new missile if the current frequency is greater than or equal to the specified frequency for the level
  4. Pulls a missile out of the waiting array (if there are any in there) and adds it to the firing array. It's also at this stage that we add the missile's sprite to the batch node to be drawn.
  5. Enumerates all of the missiles checking for dirty one's. If we find one, remember which one it is so we can move it back to the waiting array.
  6. If there was a dirty missile, move it from the waiting to the firing array and remove it's sprite from the batch node.

This is all of the code needed to animate the missiles. Go ahead and run the game at this point and watch the missiles fire from the player as you move around.

Missiles


Conclusion

Now that we have enabled some player and missile animations, it's really starting to feel like a game. We also did some basic collision detection between the player object and the sprout object. In the next tutorial in the series, we will dig deeper into collision detection as we establish collisions between the missiles and the sprouts, missiles and the centipede, and player and the centipede.

Happy coding!

Tags:

Comments

Related Articles