Showing posts with label cocos2d. Show all posts
Showing posts with label cocos2d. Show all posts

Wednesday, October 30, 2013

Cocos2D Draw Order

In summary:

  • If within same parent and same Z order, then nodes that are added first will be drawn first, followed by the ones added later in sequence.
  • If within the same parent and different Z order, then it's according to Z order. The higher the Z order, the later it will be drawn. Note: negative Z order will be drawn before the parent, and positive Z order will be drawn after the parent.
  • If different parents, then the Z order of the parent decides first, then Z order within each parent.
  • The only way for nodes with different parents to be ordered with each other independently of parent is using VertexZ. (However, I could not get it to work with Cocos2D-X Isometric tile maps across map layers. I ended up removing all the objects (e.g. buildings) on the other layers in runtime and re-inserting them in the same layer as the other sprites as sprites, and then ordering via Z order.

Wednesday, October 23, 2013

Cocos2D-X: Tile Map Layer Empty Gotcha

With Cocos2D-X, if you leave a layer with no tiles, there will be a crash that look like this:


bool CCTexture2D::hasPremultipliedAlpha()
{
   return m_bHasPremultipliedAlpha; <-------- EXC_BAD_ACCESS HERE
}

This is due to the CCTexture2D object being undefined when initialising the layer. This can occur when the layer does not have a tile defined.

It is sometimes necessary to have a layer with no tiles defined initially and then define them in code during runtime. However, due to this crash, it is necessary to define those tiles and remove them in code prior to the game starting. Same problem might happen in Cocos2D also.

Tuesday, October 22, 2013

Cocos2D: Checking if Animation Currently Running

Check that "bear->numberOfRunningActions()" returns 0.

Reference: http://stackoverflow.com/questions/12582481/check-if-animation-is-running-in-cocos2d-x

Cocos2D Sprite Sheets: To Use CCSpriteBatchNode Or Not

Examples such as the one here use CCSpriteBatchNode as it is apparently some form of "best practice" to do so due to apparent performance benefits by batching draw operations.

However, the benefits of doing this is debatable, with the following articles claiming only marginal benefits in most use cases, and with significant benefits only in certain situations:

Obviously if using CCSpriteBatchNode is easy then it's a no brainer to use it. But unfortunately it gets pretty complicated when you have a sprite that requires multiple sprite sheets. Rather than to have to figure out how it all has to work, or if it can even work in the first place, it's a pretty straightforward decision instead to not use it.

So from the sprite sheet tutorial, instead of using CCSpriteBatchNode:
  1. Load all the various sprite sheets into the sharedSpriteFrameCache
  2. Create one CCAction for every animation sequence using the frame names
  3. Create a Sprite directly using 1 of the frames
  4. Call runAction on the sprite whenever a new animation sequence needs to be run
Other References:

Thursday, October 17, 2013

Tiled / Cocos2D: Using Objects


  1. Go to Tiled, create an object layer
  2. On the object layer, add objects by using the drawing shapes
  3. If you are using rectangular shapes to represent tiles, you can open the object properties sub-menu after selecting the object and adjust the position and size to fit perfectly the tile
  4. Load the map in Cocos2D and read it with the following code (Example is C++ using Cocos2D-X):

   CCTMXObjectGroup* objectGroup = map->objectGroupNamed(objGroupName);
   CCArray* objects = objectGroup->getObjects();
   
   CCDictionary* objectAsDict;
   CCObject* obj;
   CCARRAY_FOREACH(objects, obj)
   {
       objectAsDict = (CCDictionary*)obj;
       if(!objectAsDict)
       {
           break;
       }
       const char* key = "x";
       int x = ((CCString*)objectAsDict->objectForKey(key))->intValue();
       key = "y";
       int y = ((CCString*)objectAsDict->objectForKey(key))->intValue();
       key = "width";
       int width = ((CCString*)objectAsDict->objectForKey(key))->intValue();
       key = "height";
       int height = ((CCString*)objectAsDict->objectForKey(key))->intValue();


       // figure out which tiles are covered the rectangle here
   }

Note that the coordinates for the rectangle are based on the coordinate system of an ortho tile map (with origin at bottom left). If you are using an iso tile map in Cocos2D, the origin is at the top of the diamond. You'll have to do the necessary conversion.

Cocos2D: Creating a HUD Layer

Here's a guide: http://www.raywenderlich.com/4666/how-to-create-a-hud-layer-with-cocos2d

Cocos2D Sprite Sheets

Guide: http://www.raywenderlich.com/32045/how-to-use-animations-and-sprite-sheets-in-cocos2d-2-x

This is based on sprite sheets generated by Texture Packer, which will also generate plist files for each frame, and also uses offset to minimize white space.

I had to change the following before I could get this to work in Cocos2D-X 2.2.0


   [walkAnimFrames addObject:
       [[CCSpriteFrameCache sharedSpriteFrameCache] spriteFrameByName:
           [NSString stringWithFormat:@"bear%d.png",i]]];

Cocos2D-X didn't accept the "CCSpriteFrame" entered here. It was expected "CCAnimationFrame" objects. As such, I had to do this:


CCSpriteFrame* spriteFrame = CCSpriteFrameCache::sharedSpriteFrameCache()->spriteFrameByName(frameName);

CCAnimationFrame* animationFrame = new CCAnimationFrame();
animationFrame->initWithSpriteFrame(spriteFrame, 1.0f, CCDictionary::create());

walkAnimFrames->addObject(animationFrame);

Large Objects in Tiled Map Editor

This article includes a section describing how to include a large object e.g. a large tree or a building in a Tiled map. Basically this involves having a tileset with large tiles and placing them on the map as a separate layer, and then using object layer to specific collision boxes.

Link: http://gamedev.tutsplus.com/tutorials/level-design/introduction-to-tiled-map-editor/

Tuesday, October 8, 2013

Cocos2D Managing Touch Input

In a subclass of CCLayer, just set "isTouchEnabled" to true and implement the callback functions.

Otherwise, add a touch delegate class to the touch dispatcher. There are 2 types, as explained here: http://www.cocos2d-iphone.org/wiki/doku.php/tips:touchdelegates