CCZSprite and HudLevelSprite, Two Cocos2D Extensions You Need to Know About

Solving a Z-Ordering Issue

CCZSprite Issue Screenshot #1

The square containing our hero sprite covers the rock above…

CCZSprite Issue Screenshot #3

…A possible solution causes the background to bleed through…

CCZSprite Issue Screenshot #4

…Ahhh. Fixed!

Cocos2D is quite a complete 2D game engine and it is always growing. However, what do you do when it just can’t do something you are intending? Well, thankfully it is written in a fairly high-level language like Objective C. You can expand the Cocos2D engine as you see fit.

In this article we will be talking about two expansions to the Cocos2D engine that were necessary to get main characters, enemies, and special effects to draw correctly in the game QuexlorLite. These two extensions are called CCZSprite and HudLevelSprite.

CCZSprite: A Cocos2D Extension Included in the iPhone Game Kit

Getting our barbarian (his name is Quexlor) to draw correctly in the multiple layers of ground, rocks, and trees of the QuexlorLite world was a tad tricky. The challenge was that our hero sprite unnaturally appeared on top of trees. Thanks to Ricardo and the Cocos2D community, a solution was developed. For your reference, here’s the 2nd and 3rd pages of the forum topic that led to the eventual solution.

The original challenge was one of hierarchy. All the layers of the map (a subclass of CCTMXTiledMap) were drawn with successive z orders. However, the main character and enemy sprites were drawn as children of one of the layers. No matter what was done to change the z order of the hero, it didn’t matter because the z order was only relative to other children of that particular layer, not all the layers.

The solution started with using a 2D OpenGL projection with a decent depth buffer. This allowed all the nodes of our game to be given a more accurate z order using CCNode‘s vertexZ property. A range of -1000 to 0 was chosen, -1000 being the lowest vertexZ in the stack. Entire background layers, like the ground, were given successive, automatic vertexZ values (-999, -998, etc…). Foreground layers, like the trees, were given more detailed vertexZ values, assigned to individual tiles of the map (trees, in this case) based on the y position in the tile map (-997.4 for a tree to the north, -997.2 for a tree to the south). These were automatically assigned detailed vertexZ values by setting the layer property cc_vertexz to automatic for that particular foreground layer. Finally, all the player, enemy, and item sprites (essentially, any sprite that could possibly move) were assigned dynamic vertexZ values based on their current y position on the map (for example, -997.3 if the hero was standing in the middle of the two previously mentioned trees). This solution finally enabled Quexlor to look right! Trees were drawn on top of him when appropriate.

The last thing that was necessary to cement this vertexZ solution was to make our hero, enemy, and item sprites use a bit of different drawing code. Hence, the creation of CCZSprite, a subclass of CCSprite that simply overrides the draw method with the vertexZ-friendly drawing code. Here’s that draw method:


@implementation CCZSprite

  -(void) draw
  {
    glEnable(GL_ALPHA_TEST);
    glAlphaFunc(GL_GREATER, 0.0f);

    [super draw];

    glDisable(GL_ALPHA_TEST);
  }

@end

Pretty simple, eh?

HudLevelSprite: Another Cocos2D Addition

HudLevelSprite used in Cocos2DThe aura effect is a HudLevelSprite in action

Born out of the same challenge of accurate z ordering, the HudLevelSprite is a solution for drawing sprites that must appear on top of everything else (like fog, auras, etc…). Because of the way we slide the camera around to view the level map from different points, we also needed these HUD sprites to be attached to certain level objects, hence the name “HUD Level Sprite.” (By the way, HUD stands for Heads Up Display.)

A good example of a HudLevelSprite is the lifebar attached to the top of our hero and all the enemies. It is always drawn on top and always follows the sprite that it is attached to.

Coding a HudLevelSprite is as simple as a method to attach to a level-based object, and another method to move when the camera has changed.


// a subclass for sprites attached to level objects
@interface HudLevelSprite : CCSprite
  {
    CGPoint offset;
    LevelObject* attachee;
  }

  @property CGPoint offset;

  -(void) attach:(LevelObject*)newAttachee;
  -(void) move:(CGPoint)cameraPos;
@end

@implementation HudLevelSprite

  @synthesize offset;

  -(void) attach:(LevelObject*)newAttachee
  {
    // check so that we only add child once
    if(attachee != newAttachee)
    {
      // save attachee
      attachee = newAttachee;

      // add to hud
      [[attachee getHud] addChild:self];
    }

  }

  -(void) move:(CGPoint)cameraPos
  {
    // self pos = attachee pos - camera pos + offset
    CGPoint newPos = ccpSub(attachee.position, cameraPos);
    newPos = ccpAdd(newPos, offset);
    self.position = newPos;
  }

@end

When the camera is moved, the HUD must update all the HudLevelSprite objects. It does this using fast enumeration (the for..in loop) in the moveSprites method. Note the use of the isKindOf method which is a handy extension to Cocoa’s NSObject, part of Extensions.h/.m in the iPhone Game Kit’s source code:


// in our HUD class...
-(void) moveSprites:(CGPoint)cameraPos
{
  // move all hud level sprites
  for(HudLevelSprite* s in self.children)
    if([s isKindOf:@"HudLevelSprite"])
      [s move:cameraPos];
}

Keeping track of sprites like this can be handy in other ways. For example, what if you want to make a type of sprite that is “touchable?” You could code something similar to a HudLevelSprite and use a for..in loop like the one above to query your list of sprites when your game receives a touch event. That’s just one idea…

Remember, you can extend Cocos2D and even Cocoa to your liking. Objective C is a really nice language to extend because of its easy to use class categories and lack of multiple inheritance. So, when you find yourself challenged with something that goes beyond the game engine, just create a way! Make it happen.

Enjoy creating.

    • Nat Weiss

      Yes, it definitely is possible to solve those z ordering issues. Please read through this article and check out the Cocos2d iPhone forum posts it links to.

    • Nat Weiss

      It looks like the z ordering is working. The challenge now looks like the z order for the walls needs to be a little higher than the ninja. Try making the z order for tiles to be consistent with the bottom of the tile, instead of the middle of the tile.

    • Nat Weiss

      Wrote you back on Stack Overflow.

  • -->

    Featured Posts


    Hero Bash: the party moba!

    iOS 7 + Cocos2d 2.1 Update

    Making Cross-Platform iPhone & Android Games – Don’t Get Left Behind! (Part 3)

    Recent Posts


    Tuning the Mind

    From Programmer To Artist 10 of 10 – The Beginning

    From Programmer To Artist 9 of 10 – Animation

    The Ultimate Cocos2d-x Platformer Engine

    A cross-platform, parallaxing game engine based on cocos2dx. Includes procedural level generation, scripting, dynamic texturing, realtime multiplayer, virtual economy (in-app purchase) and all the basics like moving platforms, boxes, slopes, water, ladders and artificial intelligence. Write your game code in C++ and level scripts in Javascript. Games built with this kit can be deployed to iOS, Mac, Windows, Android and any of the other platforms supported by cocos2d-x.
    More Info...


    Action-RPG Engine Code & Tutorial

    Create your own RPG, RTS, action or adventure game with this source kit. Learn how to manage tilemaps, characters, AI and more. This kit includes a flexible RPG engine built on cocos2d iphone (now called cocos2d swift), along with a sample RPG project called Quexlor Lite. Also included is a PDF ebook tutorial and bonus royalty-free art package. Written in Objective C, games built with this kit can be deployed to iPhone, iPad and iPod Touch.
    More Info...


    iPhone Game Creation for Beginners

    This game source kit is a hands-on introduction to making games for the absolute beginner. No programming experience is required. The included PDF book walks you through all the basics of how to code with Objective C and will familiarize you with the tools you need to develop an iPhone game. It includes source code and Xcode project files to a simple checkers game built with cocos2d iphone (now cocos2d swift). Also included is documentation, a game template project, support and a bonus artwork package to start your own creation. Games built with this kit can be deployed to iPhone, iPad and iPod Touch.
    More Info...