Archive for the 'article' Category

How to use the TileMap editor for cocos2d

Since v0.5 cocos2d for iPhone supports TileMaps. Instead of using the original cocos2d tilemap format (cocos2d for PC) it is using a new format based on the PGU tilemap editor.

This editor lets you edit tiles, tile maps and tile codes.

How do you install the PGU tilemap editor ?

To run the PGU level editor do:

home:~ $ cd src/pgu_level_editorhome:~/src/pgu_level_editor $ python leveledit.py level.tga

The left panel is the map.
The upper-right panel are the tiles.
The bottom-right panel are the codes.

The map is loaded from the file: level.tga
The tiles are loaded from the file: tiles.tga
The codes are loaded from the file: codes.tga

For more info see the leveledit.ini file. eg: you can change the tiles’ size.

Features and limitations:

  • cocos2d v0.6.1 (an earlier) doesn’t support codes, so ignore this feature for the moment.
  • PGU tile editor uses the TGA RGB channels to identify the codes, tiles’ positions and (mmm… what else? I’m not sure). So, you can only have 256 different tiles per TileMap.

IMPORTANT: You need to convert the tiles.tga file to PNG (eg: tiles.png). To convert a TGA file to PNG you can use the GIMP editor.

How to use these files from cocos2d for iPhone:

  • Include the tiles.png and level.tga to your XCode project
  • See the AtlasDemo example: TestAtlas.m. In particular see the Atlas3 demo.

-(id) init{if( ![super init] )return nil;

TileMapAtlas *tilemap = [TileMapAtlas tileMapAtlasWithTileFile:@"tiles.png" mapFile:@"level.tga" tileWidth:16 tileHeight:16];[self add:tilemap];

return self;}

Update: Added missing pyobjc-1.4 package

Compile for Thumb

From the iPhone OS Programming Guide:

“iPhones and iPod touches support two instruction sets, ARM and Thumb. Xcode uses Thumb instructions by default because using Thumb typically reduces code size by about 35 percent relative to ARM.
Applications that have extensive floating point code might perform better if they use ARM instructions rather than Thumb. You can turn off Thumb for your application by turning off the Compile for Thumb build setting.”

So, are you using cocos2d + chipmunk ? Probably you will need to disable “compile for thumb”.
How to:

  1. Open your XCode project
  2. Select ‘Device – iPhone 2.x‘ as Active SDK
  3. For each Target do these:
  4. Go to: Project -> Edit Active Target
  5. Search for ‘thumb’
  6. Disable ‘Compile for Thumb

That’s all. Your game will perform much much much faster.
On the other hand, if you’re not using Chipmunk, you might want to leave ‘compile for thumb’ enabled.

Chipmunk example Thumb disabled Thumb enabled
Example 1 60 FPS 60 FPS
Example 2 30 FPS 12~15 FPS
Example 3 15~20 FPS 8~12 FPS
Example 4 60 FPS 30 FPS
Example 5 12 FPS 4 FPS
Example 6 60 FPS 60 FPS
Example 7 60 FPS 60 FPS

update: Added FPS comparisons

cocos2d for iPhone v0.6.1 released

Hey, I’ve just released cocos2d for iPhone v0.6.1

Download: http://cocos2d-iphone.googlecode.com/files/cocos2d-iphone-0.6.1.tar.gz

Changelog:

  • Documentation: Generation of doc fixes (issue #105)
  • Primitives: drawLine prototype fixed (issue #103)
  • XCode: all projects have “thumb compilation” turned off (issue #104)

As you can see a the changelog is pretty small. But I decided to release a new release because of the “compile for thumb” thing. An article regarding “compilation for thumb” coming soon.

cocos2d: propagating touch events

cocos2d v0.6 has a new way to propagate and most importantly, to stop the propagation of touch events.

The old interface was using the UIKit interface:

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event;- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event;- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event;- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event;

The new interface is very similar, but instead of returning void, it now returns a BOOL, and since the return value can’t be used as part of the selector’s identity, the selector was renamed. The prefix ‘cc’ (short of cocos2d) was prepended. Example:

- (BOOL)ccTouchesBegan:(NSSet *)touches withEvent:(UIEvent *)event;- (BOOL)ccTouchesEnded:(NSSet *)touches withEvent:(UIEvent *)event;- (BOOL)ccTouchesMoved:(NSSet *)touches withEvent:(UIEvent *)event;- (BOOL)ccTouchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event;

If a certain layer handles the event then it should return kEventHandled, else it should return kEventIgnored.

Example taken from Menu.c:

- (BOOL)ccTouchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{ UITouch *touch = [touches anyObject]; CGPoint point = [touch locationInView: [touch view]]; int idx;

 MenuItem *item = [self itemInPoint: point idx:&idx];

 if( item ) {     [item selected];     selectedItem = idx;

     // Event handled. It won't be propagated     return kEventHandled; }

 // event not handled. It will be propagated to the next // Layer on the stack return kEventIgnored;}

Which Layer is the first one to receive the event ?
The last Layer to be added. If this layer doesn’t return kEventHandled, then the event will be propagated to the next Layer on the stack.

cocos2d: Parallax scrolling


cocos2d v0.6 introduces Parallax Scrolling. For those who don’t know the meaning of Parallax Scrolling, it is a way to simulate a 3D environment scrolling layers in a 2D environment.

(When I think of Parallax Scroller I think of Shadow of the Beast.)

As you can see from the screenshot, the image is composed of a Parallax Scrolling of 3 layers:

  • A) A ‘powered by cocos2d’ image
  • B) A tilemap
  • C) A background image

When you move the image, the layers start to scroll at different speeds simulating a 3D environment.

How do you code a parallax scrolling in cocos2d ?

// You need a parent node// It can be an empty node, or a node with images. Your choiceCocosNode *voidNode = [CocosNode node];

// Then you add the children, using the 'add' selector.// But with the additional parallaxRatio

// example:// a child that will move at 0.4 ratio horizontally//                       and 0.5 ratio vertically[voidNode add:background z:-1 parallaxRatio:cpv(0.4,0.5)];

// another child with a ratio of 2.2x, 1.0y[voidNode add:tilemap z:1 parallaxRatio:cpv(2.2,1.0)];

// and another child (top one) that is moved at a ratio of 3.0x, 2.5y[voidNode add:cocosImage z:2 parallaxRatio:cpv(3.0,2.5)];

That’s all.

If you want to alter the Parallax Ratio, you can modify the parallaxRatio property. Eg:

background.parallaxRatio = cpv(1.5, 0.5);tilemap.parallaxRatioX = 2;tilemap.parallaxRatioY = 0.9;

Working Example: ParallaxDemo example. See TestParallax.m file.

cocos2d: Menu alignment in v0.6

cocos2d v0.6 introduces a manual way to align the items. You can align them both vertically and horizontally.
Prior to v0.6 the items were vertically aligned automatically. In v0.6 the automatic alignment feature was removed. If you want to align them you need to do this:

menu = [Menu menuWithItems:item1, item2, item3, nil];[menu alignItemsHorizontally];

or:

menu = [Menu menuWithItems:item1, item2, item3, nil];[menu alignItemsVertically];


Also, the previous vertical alignment algorithm had a bug, and wasn’t aligning the items in the center of the screen. If you want to use the old and buggy alignment algorithm you can do this:

menu = [Menu menuWithItems:item1, item2, item3, nil];[menu alignItemsVerticallyOld];


The alignItemsVerticallyOld is deprecated and will be removed in v0.7.

Tip: you can place your MenuItem as well as the Menu manually like any other CocosNode:

menu = [Menu menuWithItems:item1, item2, item3, nil];menu.position = cpv(0,0);item1.position = cpv(50,50);item2.position = cpv(200,200);

Working Example: MenuTest example. See MenuTest.m file.

cocos2d: Repeat vs. RepeatForever vs. IntervalActions

cocos2d v0.6.0 introduces a new action: RepeatForever. As you can imagine, this action will repeat forever the inner action.

Example:

id jump = [JumpBy actionWithDuration:3 position:cpv(400,0)           height:50 jumps:4];[node do: [RepeatForever actionWithAction:           [Sequence actions: jump, [jump reverse], nil]       ]];

The old action Repeat is still present in v0.6. In fact, it includes some fixes. Now it is possible to Repeat a Sequence of Repeat of Sequences of Repeat… but you can’t use it to repeat an action forever.

Repeat as well as Sequence are IntervalAction actions. This means that they occur during a certain period of time: they start and they stop. You can accelerate, or change the speed of any any IntervalAction using the Accelerate, AccelDeccel and Speed actions, but if an action is executed forever, then it is not an IntervalAction.

This means that:

  • You can Repeat a Sequence of Repeat of Accelerate of Sequence of Repeat of Speed of Sequence…
  • You can’t Sequence a RepeatForever action since Sequence only works with IntervalActions. Again: RepeatForever is not an IntervalAction since it hasn’t an stopping time.
  • But you can RepeatForever a Sequence of Repeat of Sequence of… Note that the RepeatForever is executed first.

Working Example: SpriteDemo example. See SpritesDemo.m file.