The Slippy Flippy Challenge: Make Active Boundaries in Sprite Kit.

icon2_120In Flappy Bird,  hitting the top or bottom boundaries ends the game. They also convey a sense of motion. The boundaries make for a better playing experience. Last time, we set up collision detection, but we need boundaries that are sprites. Sprite node boundaries would be able to tell us what we hit, and run handlers for those cases. We animate them to give a sense of motion.

The boundaries are two sprites that don’t move.  We have one on the top of the screen and one on the bottom of it. Most properties of the top and bottom sprites are the same. Make one method to make both:

-(SKSpriteNode *)makeWorldBoundaryWithName:(NSString*)name{
    CGSize size = CGSizeMake(self.frame.size.width, self.frame.size.height * 0.10);         //10% of height
    SKSpriteNode *boundary = [SKSpriteNode spriteNodeWithColor:[UIColor blueColor] size:size];
    boundary.name = [NSString stringWithFormat:@"%@Boundary",name];                         //all boundaries suffixed with Boundary
    boundary.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:size];                    //physics on, no gravity or motion
    boundary.physicsBody.dynamic = NO;
    boundary.physicsBody.categoryBitMask = obstacleCategory;
    boundary.physicsBody.collisionBitMask = penguinCategory;
    boundary.physicsBody.contactTestBitMask = penguinCategory;

    return boundary;
 }

This code should be familiar by now. It has been covered in other posts. We  make the boundary  size proportional to self.frame. With two boundaries, take a fifth of the frame height for the boundary, and the width of the screen. Make the boundary a solid blue, and set up physics. Like the obstacles, this is a non dynamic physics body. Set the collision bit masks to find this as a boundary. If there is a penguin collision, the physics engine executes didBeginContact: as we discussed last time.

Orient the boundary to the edge of the frame. Some quick calculations can find it, but there is a better way. Each node has a property AnchorPoint which is a CGPoint with x and y values between 0.0 and 1.0.   Sprite Kit uses AnchorPoint to figure position. By default, it is the center of the node.

anchor points
Anchor Points

As indicated in blue, we can use points at (0.5,1.0) and (0.5,0.0) as anchor points for aligning the top and bottom directly to the edge. We can add the following code to initWithSize:.

//make boundaries
SKSpriteNode *topBoundary= [self makeWorldBoundaryWithName:@"top"];
topBoundary.anchorPoint = CGPointMake(0.5, 1.0); //top center anchor
topBoundary.position = CGPointMake(CGRectGetMidX(self.frame), CGRectGetMaxY(self.frame));
[self addChild:topBoundary];

SKSpriteNode *bottomBoundary = [self makeWorldBoundaryWithName:@"bottom"];
bottomBoundary.anchorPoint = CGPointMake(0.5, 0.0); //bottom center anchor
bottomBoundary.position = CGPointMake(CGRectGetMidX(self.frame), CGRectGetMinX(self.frame));
[self addChild:bottomBoundary];

The new method makeWorldBoundaryWithName:makes a sprite.  Change the anchor point, then place our boundary easily on the edge of self.frame.

Build and run:
iOS Simulator Screen shot May 12, 2014, 6.09.00 AM

We now have top and bottom boundaries. The penguin bounces off them. As we move forward, there are several thing we need to do:

  • Add animation on the boundaries to convey a sense of movement
  • Handle a Game Over situation
  • Correct the obstacle code so the gap must show up in playable space
  • Add a scoring and high score mechanism

We will address each of these. Next time, we will add animation on the boundaries through marquee animation.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s