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.

Comments

10 Responses to “CCZSprite and HudLevelSprite, Two Cocos2D Extensions You Need to Know About”

  1. yuewah

    vertexz will leave a outline for semi-transparent sprite, is that really no method to overcome this? or use z-order ?

    Reply
    • Nat Weiss

      You could change the alpha blending factor or change the bottom-most layer of your TMX to change the outline a little. However, that’s not a real answer to your question.

      The challenge here is the way Cocos2D does z ordering. It’s all relative to the parent node. This makes it impossible to z-order correctly when you have objects that are children of different layers.

      You could get around all this by creating a single layer for all your objects and then implementing your own z-ordering. The trick here is that when an object moves, it needs to be re-ordered, and in Cocos2D this causes the object to be removed and then re-inserted. An expensive operation.

      If you find a better solution, please let me know.

    • 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.

Leave a Reply


+ 6 = thirteen

Subscribe via email

Subscribe in a reader


iPhone Game Creation for Beginners

A hands-on introduction to all the tools you need to develop an iPhone game. It includes source code to a simple board game built with Cocos2d and a comprehensive book that will teach you Xcode, Objective C and the Cocos2d framework. Plus, you get documentation, support and a ton of artwork to start your own creation.
More info…


Action-RPG Engine Code & Tutorial

Create your own action, RPG, adventure or RTS game with this starter kit. Learn how to manage tilemaps, characters, AI and more. This Starter Kit includes a flexible RPG engine built on Cocos2d, along with a sample RPG project that will teach you everything you need to know. Also included is a helpful ebook tutorial and a gigantic royalty-free art package!
More info…

Featured Posts

Cocos2d 2.0, iOS 6 & iPhone 5 Updates - 9/24/12

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

5 Cocos2D iPhone Game Source Code Kits to Revolutionize Your Game Development - 4/5/12

How to Make Games With the iPhone Game Kit 5.0 - 2/19/12

Learn to Make iPhone Games with the iPhone Game Kit 4.0 - 12/10/11

The Cocos2D Family of Game Engines, Their Platforms & Languages - 11/2/11

Game Design Lessons: Introducing Flow - 9/23/11

What is Cocos2D and Why is it One of the Best iPhone Game Engines? - 6/3/11

Community RPG Developer’s Diary, Part One - 1/20/11

CCZSprite and HudLevelSprite, Two Cocos2D Extensions You Need to Know About - 8/10/10

How to Program Dpad Joystick Touch Controls for iPhone Games - 6/7/10

Other Posts

Awesome Heroes Arena! - 3/13/13

Making Cross-Platform iPhone & Android Games – Don’t Get Left Behind! (Part 2) - 5/26/12

An Awesome Review of our RPG Engine from a Customer - 4/26/12

Making Cross-Platform iPhone & Android Games – Don’t Get Left Behind! - 4/16/12

ShakeMidi: A Wireless MIDI Controller That You Can Shake - 12/1/11

Download Monster Checkers Updated Source Code Soon - 7/29/11

iPhone Game Kit Discussed on the Cocos2D Podcast - 7/8/11

New iPhone Game Kit 3.4 Update - 4/28/11

Quexlor LoF Hits the App Store - 4/8/11

The iPhone Game Kit Community Project – A Newcomer’s Perspective - 3/29/11

AI: What Cocos2D Cannot Do - 2/9/11

Cocos2D Community Game, Developer’s Diary, Part Two - 1/28/11

3.2 Kit is Out, Cocos2D 0.99.5 Compatible - 1/13/11

3.1 Kit is Out! Let’s Start the Community RPG - 12/9/10

Develop the Game Kit’s Community RPG and be a part of gaming history! - 11/23/10

iPhone Game Kit 3.0 Released - 10/14/10

New Game Added to the iPhone Game Kit! - 9/21/10

New Tiled Map Editor 0.5.1 Works Like a Charm! - 9/10/10

Four Interesting Things We Are Working To Improve The iPhone Game Kit - 8/25/10

iOS4 Compatible iPhone or iPad Game Source Code - 8/2/10

Making High Resolution Graphics For iPad and iPhone4 Games - 7/16/10

Game Source Code & Tutorials



iPhone Game Creation for Beginners

A hands-on introduction to all the tools you need to develop an iPhone game. It includes source code to a simple board game built with Cocos2d and a comprehensive book that will teach you Xcode, Objective C and the Cocos2d framework. Plus, you get documentation, support and a ton of artwork to start your own creation.
More Info...


Action-RPG Engine Code & Tutorial

Create your own action, RPG, adventure or RTS game with this starter kit. Learn how to manage tilemaps, characters, AI and more. This Starter Kit includes a flexible RPG engine built on Cocos2d, along with a sample RPG project that will teach you everything you need to know. Also included is a helpful ebook tutorial and a gigantic royalty-free art package!
More Info...