How To Make a Tile-Based Game with Cocos2D 2.X

Charlie Fulton Charlie Fulton

This post is also available in: Japanese

Update 1/17/2013 Fully updated for Cocos2D 2.1 rc0, Tiled 0.9.0 (released Feb 2013), Xcode 4.6, and ARC. (original post by Ray Wenderlich, update by Charlie Fulton).

Mmm, tasty melons!

Mmm, tasty melons!

In this 2-part tutorial, we’re going to cover how to make a tile-based game with Cocos2D and the Tiled map editor. We will do so by creating a simple tile-based game where a ninja explores a desert in search of tasty watermelon things!

In this part of the tutorial, we’ll cover how to create a map with Tiled, how to add the map to the game, how to scroll the map to follow the player, and how to use object layers.

In the second part of the tutorial, we’ll cover how to make collidable areas in the map, how to use tile properties, how to make collectable items and modify the map dynamically, and how to make sure your ninja doesn’t overeat.

If you haven’t already, you may wish to start with the How To Make A Simple iPhone Game with Cocos2D 2.X Tutorial, since that covers most of the basics that we’ll build upon here.

Ok, so let’s have some fun with tile maps!

Creating a Project Skeleton

We’re going to start by creating a skeleton project to make sure we have all of the files we need for the rest of the project in the right spot.

Note: If you haven’t installed cocos2d 2.1 rc0 yet, download it here and then from a terminal run these commands:

cd ~/Downloads/cocos2d-iphone-2.1-rc0
./install-templates.sh -f -u

Create a new project in Xcode with the iOS / cocos2d v2.x / cocos2d iOS template, and name it TileGame. Select the options to make the project Universal and include git repository setup.

We are going to use ARC in this project, but by default the template isn’t set up to use ARC. Luckily, fixing it is really easy. Just go to Edit\Refactor\Convert to Objective-C ARC. Expand the dropdown and select only the last four files (main.m, AppDelegate.m, HelloWorldLayer.m, and IntroLayer.m), then click Check and finish the steps of the wizard.

Choose files to convert to ARC

And that’s it! Build and run and make sure everything still works OK – you should see the normal Hello World screen.

Next, download this zip file of resources for the game. The zip file contains the following:

  • A sprite we’ll use for our player object. This may look familiar from the How to Make A Simple iPhone Game with Cocos2D Tutorial!
  • Some sound effects we’ll be using that I made with the excellent cxfr utility.
  • Some background music I made with Garage Band (see this post for more info).
  • The tile set we’ll be using – it actually comes with the map editor we’ll be using, but I thought it would be easier to include it with everything else.
  • Some additional “special” tiles we’ll explain a bit later.

Once you have the resources downloaded, unzip it and drag the TileGameResources folder to the “Resources” group in your project. Verify “Copy items into destination group’s folder (if needed)” is checked, “Create groups for any added folders” is selected, and click Finish.

If all works well, all of the files should be listed in your project.

Your project should look like this:

Project screenshot after resources and arc

That’s it for now – time to have some fun and make our map!

Making a Map with Tiled

Cocos2D supports maps created with the open source Tiled Map Editor and saved in TMX format.

If you visit the above link, you’ll see there are two versions of Tiled – one written with the Qt application framework, and one written with Java. There are two versions because Tiled was written first in Java, and they are porting it over to Qt.

Which version you use is largely up to you. In this tutorial we will cover using the Qt version because that is the development mainline for Tiled from now on, but some people like to use the Java version because not all of the old features have been completely ported over yet.

So anyway – if you would like to follow along, download the Qt version and install and run the app. Go to File\New, and fill in the dialog as follows:

New Map Dialog in Tile Map Editor

In the orientation section, you can choose between Orthogonal (think: the Legend of Zelda) or Isometric (think: Disgaea). We’re going to pick Orthogonal here.

Next you get to set up the map size. Keep in mind that this is in tiles, not pixels. We are going to make a smallish sized map, so choose 50×50 here. Tiled will show you the total map size in pixels, at the bottom of the new map dialog. This is calculated by multiplying the map size (50 tiles) by the tile size (32 px) in both height and width.

Finally you specify the tile width and height. What you choose here depends on the tile set that your artist will be making. For this tutorial, we are going to use some sample tiles that come with the Tiled editor which are 32×32, so choose that.

Next, we have to add the tile set that we’ll be using to draw our map. Click on “Map” in the menu bar, “New Tileset…”, and fill in the dialog as follows:

New Tileset Dialog in Tile Map Editor

To get the image, just click Browse and navigate to your TileGame/TileGameResources folder, and pick the tmw_desert_spacing.png file that you downloaded from the resource zip and added to your project. It will automatically fill out the name based on the filename.

You can leave the width and height as 32×32 since that is the size of the tiles. As for margin and spacing, I couldn’t find any good documentation on the exact meaning of these, but this is what I think they mean:

  • Margin is how many pixels Tiled should skip (for both width and height) for the current tile before it starts looking for actual tile pixels.
  • Spacing is how many pixels Tiled should advance (for both width and height) after it reads the actual tile pixels to get to the next tile data.

If you take a look at tmw_desert_spacing.png, you’ll see that each tile has a 1px black border around it, which is would explain the settings of margin and spacing as 1.

Zoomed screenshot of desert tiles

Once you click OK, you will see the tiles show up in the Tilesets window. Now you can start drawing away! Simply click the “Stamp” icon in the toolbar, then click a tile, then click anywhere on the map you’d like to place a tile.

Using the Stamp Tool in Tiled

So go ahead and draw yourself a map – be as creative as you’d like! Make sure to add at least a couple buildings on the map, because we’ll need something to collide into later!

Drawing Our Map in Tiled

Some handy shortcuts to keep in mind:

  • You can drag a box around a series of tiles in the Tileset picker, to put down multiple adjacent tiles at the same time.
  • You can use the paint button in the toolbar to paint the entire background with a base tile.
  • You can zoom in and out with “View\Zoom In…” and “View\Zoom Out…”.
  • The “z” key will now rotate the tile when editing a map with the stamp tool

There is a new feature you might have noticed “Mini-map”. This is an awesome feature, it let’s you see a (you guessed it) Mini-map! Take a look at my poor attempt at a maze in the bottom of the mini-map below. The red box indicates the area you see in the main editing window.

New feature mini-map

Keep this mini-map view in mind when we talk about scrolling in the next section.

Once you’re done drawing the map, double click on the Layer in Layers (which probably says “Tile Layer 1″ right now), and change the name to “Background”. Then click “File\Save” and save the file to TileGame\TileGameResources in the TileGame project, and name the file “TileMap.tmx”.

We’re going to do some more stuff with Tiled later, but for now let’s get this map into our game!

Adding the Tiled Map to our Cocos2D Scene

First thing first, right click on the TileGameResources group, click “Add\Existing Files…” and add the new TileMap.tmx file you just created to your project.

Next let’s turn off Retina Display support because we don’t have any retina sized art.

Make the following changes to AppDelegate.m:

 
// comment out these lines in the -application:didFinishLaunchingWithOptions: method
// this should be lines 93-94
 
//	if( ! [director_ enableRetinaDisplay:YES] )
//		CCLOG(@"Retina Display Not supported");

Open up HelloWorldLayer.h, and replace the contents with the following:

#import <GameKit/GameKit.h>
 
// When you import this file, you import all the cocos2d classes
#import "cocos2d.h"
 
// HelloWorldLayer
@interface HelloWorldLayer : CCLayer
{
}
 
// returns a CCScene that contains the HelloWorldLayer as the only child
+(CCScene *) scene;
 
@end

Replace the contents of HelloWorldLayer.m with the following:

#import "HelloWorldLayer.h"
#import "AppDelegate.h"
 
@interface HelloWorldLayer()
 
@property (strong) CCTMXTiledMap *tileMap;
@property (strong) CCTMXLayer *background;
 
@end
 
@implementation HelloWorldLayer
 
// Helper class method that creates a Scene with the HelloWorldLayer as the only child.
+(CCScene *) scene
{
	// 'scene' is an autorelease object.
	CCScene *scene = [CCScene node];
 
	// 'layer' is an autorelease object.
	HelloWorldLayer *layer = [HelloWorldLayer node];
 
	// add layer as a child to scene
	[scene addChild: layer];
 
	// return the scene
	return scene;
}
 
-(id) init
{
	if( (self=[super init]) ) {
 
        self.tileMap = [CCTMXTiledMap tiledMapWithTMXFile:@"TileMap.tmx"];
        self.background = [_tileMap layerNamed:@"Background"];
 
        [self addChild:_tileMap z:-1];
    }
    return self;
}
@end

Here we make a call to the CCTMXTiledMap file, instructing it to create a map from the map file we created with Tiled.

Some quick background on CCTMXTiledMap. It’s a CCNode, so you can set its position, scale, etc. The children of the node are the layers of the map, and there’s a helper function where you can look the up by name – which we do here to get the background. Each layer is a subclass of CCSpriteSheet for performance reasons – but this also means that you can only have one tileset per layer.

So all we do here is save a reference to the tile map and the background layer, then add the tile map to the HelloWorld layer.

And that’s it! Compile and run the code, and you should see the bottom left corner of your map:

Screenshot of the Tile Map Edge on our iPhone

Not bad! But for this to be a game, we need three things: a) a player, b) a starting point to put the player, and c) to move our view so that we are looking at the player.

And this is where it gets tricky. So let’s tackle this next!

Tiled Object Layers and Setting Tile Map Position

Tiled supports two kinds of layers – tile layers (which is what we’ve been working with so far), and object layers.

Object layers allow you to draw boxes around portions of the maps to specify areas where things might happen. For example, you might make an area where monsters spawn, or an area that is deadly to enter. In our case, we’re going to create an area for our “spawn point” for our player.

So go to the menu bar in Tiled and pick “Layer\Add Object Layer…”, name the layer “Objects”, and click OK. To insert an Object, select the Insert Rectangle(R) item from the toolbar. Your current layer is shown in the bottom left corner.

If you draw on the map, you’ll notice it doesn’t draw a tile, instead it draws a rectangle, which you can expand to cover multiple tiles or move around. In the latest version of tiled you can also draw other types of object shapes.

We just want to select one tile for the player to start in. So choose somewhere on your map and click the tile. The size of the box doesn’t really matter, since we’ll just be using the x, y coordinates.

Tile Map with Object

Then right click the gray object you just added, and click “Object Properties”. Give it a name of “SpawnPoint” and click OK:

Tiled Object Properties

Supposedly, you can get fancy here and set the Type of the object to a Cocos2D class name and it will create an object of that type for you (such as CCSprite), but I couldn’t find where it was doing that in the source code. Update: Tyler from GeekAndDad.com pointed out that the code used to be in a previous version of Cocos2D, but was removed due to issues with it a while back.

Anyway – we’re just going to leave the type blank, which will create an NSMutableDictionary for us where we can access the various aspects of the object, including the x, y coordinates.

Save the map and go back to Xcode. Make the following changes to HelloWorldLayer.m:

// After the interface declaration, with the other private properties
@property (strong) CCSprite *player;
 
// Inside the init method, after setting self.background
CCTMXObjectGroup *objectGroup = [_tileMap objectGroupNamed:@"Objects"];
NSAssert(objectGroup != nil, @"tile map has no objects object layer");
 
NSDictionary *spawnPoint = [objectGroup objectNamed:@"SpawnPoint"];
int x = [spawnPoint[@"x"] integerValue];
int y = [spawnPoint[@"y"] integerValue];
 
_player = [CCSprite spriteWithFile:@"Player.png"];
_player.position = ccp(x,y);
 
[self addChild:_player];
[self setViewPointCenter:_player.position];

Ok let’s stop for a second and explain the bit about the object layer and object groups. First note that you retrieve object layers via the objectGroupNamed method on the CCTMXTiledMap object (rather than layerNamed). It returns a special CCTMXObjectGroup object.

We then call the objectNamed method on the CCTMXObjectGroup to get a NSMutableDictionary containing a bunch of useful info about the object, including x and y coordinates, width, and height. In this case all we care about is the x,y coordinates, so we pull those out and set that as the position of our player sprite.

At the end we want to set the view to focus on where the player is. So now add the following new method to HelloWorldLayer.m (anywhere in the file is fine now in Objective-C):

- (void)setViewPointCenter:(CGPoint) position {
 
    CGSize winSize = [CCDirector sharedDirector].winSize;
 
    int x = MAX(position.x, winSize.width/2);
    int y = MAX(position.y, winSize.height/2);
    x = MIN(x, (_tileMap.mapSize.width * _tileMap.tileSize.width) - winSize.width / 2);
    y = MIN(y, (_tileMap.mapSize.height * _tileMap.tileSize.height) - winSize.height/2);    
    CGPoint actualPosition = ccp(x, y);
 
    CGPoint centerOfView = ccp(winSize.width/2, winSize.height/2);    
    CGPoint viewPoint = ccpSub(centerOfView, actualPosition);
    self.position = viewPoint;
}

Ok, let’s explain this a bit too. Imagine this function is setting the center of a camera. We allow the user to pass in any x,y coordinate in the map here – but if you think about it there are some points that we don’t want to be able to show – for example we don’t want the screen to extend beyond the edges of the map (where it would just be blank space!)

For example, take a look at this diagram:

Diagram of tile map vs. viewport in Cocos2D

See how if the center of the camera is less than winSize.width/2 or winSize.height/2, part of the view would be off the screen? Similarly, we need to check the upper bounds as well, and that’s exactly waht we do here.

Now so far we’ve been treating this function as if it was setting the center of where a camera was looking. However… that isn’t exactly what we’re doing. There is a way in Cocos2D to manipulate the camera of a CCNode, but using that can make things more difficult than the solution we’re going to use: moving the entire layer instead.

Take a look at this diagram:

Diagram of how to move layer to fit within view in Cocos2D

Imagine a big world, and we’re looking at the coordinates from 0 to winSize.height/width. The center of our view is centerOfView, and we know where we want the center to be (actualPosition). So to get the actual position to match up to the center of view, all we do is slide the map down to match!

This is accomplished by subtracting the actual position from the center of view, and then setting the HelloWorld layer to that position.

Phew! Enough theory – let’s see it in action! Compile and run the project, and if all goes well you should see your ninja in the scene, with the view moved to show him strutting his stuff!

Screenshot of our scene centered on our Ninja

Making the Ninja Move

We’re off to a good start, but our ninja is just sitting there! And that’s not very ninja-like.

Let’s make the ninja move simply by moving him in the direction the user taps. Add the following code to HelloWorldLayer.m:

// Inside init method
self.touchEnabled = YES;
 
#pragma mark - handle touches
-(void)registerWithTouchDispatcher
{
    [[[CCDirector sharedDirector] touchDispatcher] addTargetedDelegate:self
                                                              priority:0
                                                       swallowsTouches:YES];
}
 
-(BOOL) ccTouchBegan:(UITouch *)touch withEvent:(UIEvent *)event
{
	return YES;
}
 
-(void)setPlayerPosition:(CGPoint)position {
	_player.position = position;
}
 
-(void)ccTouchEnded:(UITouch *)touch withEvent:(UIEvent *)event
{
    CGPoint touchLocation = [touch locationInView:touch.view];
    touchLocation = [[CCDirector sharedDirector] convertToGL:touchLocation];
    touchLocation = [self convertToNodeSpace:touchLocation];
 
    CGPoint playerPos = _player.position;
    CGPoint diff = ccpSub(touchLocation, playerPos);
 
    if ( abs(diff.x) > abs(diff.y) ) {
        if (diff.x > 0) {
            playerPos.x += _tileMap.tileSize.width;
        } else {
            playerPos.x -= _tileMap.tileSize.width;
        }        
    } else {        
        if (diff.y > 0) {
            playerPos.y += _tileMap.tileSize.height;
        } else {
            playerPos.y -= _tileMap.tileSize.height;
        }        
    }
 
    CCLOG(@"playerPos %@",CGPointCreateDictionaryRepresentation(playerPos));
 
    // safety check on the bounds of the map
    if (playerPos.x <= (_tileMap.mapSize.width * _tileMap.tileSize.width) &&
        playerPos.y <= (_tileMap.mapSize.height * _tileMap.tileSize.height) &&
        playerPos.y >= 0 &&
        playerPos.x >= 0 )
    {
        [self setPlayerPosition:playerPos];
    }
 
    [self setViewPointCenter:_player.position];
}

First, we set our layer as touch enabled in the init method. Then we override the registerWithTouchDispatcher method to register ourselves to handle targed touch events. This will result in ccTouchBegan/ccTouchEnded methods being called (singular case), instead of ccTouchesBegan/ccTouchesEnded methods (plural case).

You may wonder why even bother with this, since we used the ccTouchesBegan/ccTouchesEnded method just fine in the How To Make A Simple iPhone Game with Cocos2D 2.X Tutorial. It’s true, in this case it doesn’t matter either way. However, I wanted to introduce everyone to this method in case you hadn’t seen it already, because it has two significant advantages (these are listed verbatim from the cocos2D source):

  • “You don’t need to deal with NSSets, the dispatcher does the job of splitting them. You get exactly one UITouch per call.”
  • “You can *claim* a UITouch by returning YES in ccTouchBegan. Updates of claimed touches are sent only to the delegate(s) that claimed them. So if you get a move/ended/cancelled update you’re sure it’s your touch. This frees you from doing a lot of checks when doing multi-touch.”

Anyway, inside our ccTouchEnded location, we convert the location to view coordinates and then to GL coordinates as usual. What is new is we call [self convertToNodeSpace:touchLocation].

This is because the touch location will give us coordinates for where the user tapped inside the viewport (for example 100,100). But we might have scrolled the map a good bit so that it actually matches up to (800,800) for example. So calling this method offsets the touch based on how we have moved the layer.

Next, we figure out the difference between the touch and the player position. We have to choose a direction based on the touch, so first we decide whether to move up/down or side to side based on whichever is the greatest distance away. Then we just see if it’s positive or negative to move up or down.

We adjust the player position accordingly, and then set the viewpoint center to be the player position, which we already wrote in the last section!

Update: Note we have to add a safety check to make sure we’re not moving our player off the map as well! This was pointed out by Geek & Dad from the comments section – thanks!

So compile and run the project and try it out! You should now be able to tap the screen to move the ninja around.

Our Ninja can now move around the map!

Where To Go From Here?

That’s all for this part of the tutorial. At this point you should know the basics about creating maps and importing them into your game.

Here’s a sample project with the code we’ve developed so far.

Next check out part 2 of the tutorial, where we show how to add collision detection into the map, to prevent our ninja from happily walking through the walls!

Charlie Fulton
Charlie Fulton

Charlie Fulton is a full time iOS developer. He has worked with many languages and technologies in the past 16 years, and is currently specializing in iOS and Cocos2D development. In his spare time, Charlie enjoys hunting, fishing, and hanging out with his family.

You can follow Charlie on Twitter.

User Comments

28 Comments

[ 1 , 2 ]
  • Hello everyone! Great Tutorial...

    I've encountered a small detail tho...I run this on my simulator and everything works amazing..
    I run this on a device and the map isn't appearing...? I can click & move the ninja(it does appear) around and for some reason it looks like the bounds are there but no images of the map whatsoever...

    I tried deleting the file and uploading it again to the device but it ain't working....What could be the problem??!


    Cheers!
    GumbiRo
  • monkeyboy wrote:Just thought I'd save anyone trying to work this out. I re-did the tutorial from scratch (to the same point so far) and this time it worked. I think the error I made was not browsing to the image required as instructed. Initially I simply typed in the file name instead. I think that xcode needed me to browse. If anyone has a theory I'd love to know. Either way I'm off defcon 1 for now.. I'm a happy noob.. for now..


    Just as a follow up to this, sorry that I missed this earlier. The reason you had the original error was due to how the tilemap was loading the image with a relative path e.g. ../tmw_desert_spacing.png

    Take a look at the tmw file in a text editor and it will probably make more sense :D
    Charlie Fultoncharlie
  • Zace66 wrote:Well perseverance works.....

    Try this for a clean compile


    Code: Select all
    -(void) registerWithTouchDispatcher
    {
       [[CCTouchDispatcher sharedDispatcher] addTargetedDelegate:self priority:thePriority swallowsTouches:YES];
    }


    I was able to run the final project upgraded against cocos2d 2.1 rc1 and everything built correctly. Whenever you upgrade to a new version of cocos2d make sure to updated the search path in the build settings.
    Charlie Fultoncharlie
  • monkeyboy wrote:Hi Again..

    I'm currently stuck with the debugger stating that it can't find tmw_desert_spacing.png and then says that it cant add it when I go to run the simulator. It even says that the build was successful. I can clearly see it in my resources folder inside the tile game project. I've triple checked the steps in the tutorial and am as sure as I can be that I haven't missed anything. Does anyone know why this might be? Below is the entire debugger output.

    2013-03-16 20:28:41.523 TileGame[6115:c07] cocos2d: OS version: 5.1 (0x05010000)
    2013-03-16 20:28:41.527 TileGame[6115:c07] cocos2d: GL_VENDOR: Apple Computer, Inc.
    2013-03-16 20:28:41.529 TileGame[6115:c07] cocos2d: GL_RENDERER: Apple Software Renderer
    2013-03-16 20:28:41.530 TileGame[6115:c07] cocos2d: GL_VERSION: OpenGL ES 2.0 APPLE
    2013-03-16 20:28:41.532 TileGame[6115:c07] cocos2d: GL_MAX_TEXTURE_SIZE: 4096
    2013-03-16 20:28:41.533 TileGame[6115:c07] cocos2d: GL_MAX_TEXTURE_UNITS: 8
    2013-03-16 20:28:41.534 TileGame[6115:c07] cocos2d: GL_MAX_SAMPLES: 4
    2013-03-16 20:28:41.535 TileGame[6115:c07] cocos2d: GL supports PVRTC: YES
    2013-03-16 20:28:41.536 TileGame[6115:c07] cocos2d: GL supports BGRA8888 textures: YES
    2013-03-16 20:28:41.537 TileGame[6115:c07] cocos2d: GL supports NPOT textures: YES
    2013-03-16 20:28:41.538 TileGame[6115:c07] cocos2d: GL supports discard_framebuffer: YES
    2013-03-16 20:28:41.540 TileGame[6115:c07] cocos2d: GL supports shareable VAO: NO
    2013-03-16 20:28:41.541 TileGame[6115:c07] cocos2d: compiled with Profiling Support: NO

    2013-03-16 20:28:41.542 TileGame[6115:c07] cocos2d: **** WARNING **** CC_ENABLE_GL_STATE_CACHE is disabled. To improve performance, enable it by editing ccConfig.h

    2013-03-16 20:28:41.552 TileGame[6115:c07] cocos2d: cocos2d v2.0.0
    2013-03-16 20:28:41.553 TileGame[6115:c07] cocos2d: Using Director Type:CCDirectorDisplayLink
    2013-03-16 20:28:41.624 TileGame[6115:c07] cocos2d: animation started with frame interval: 60.00
    2013-03-16 20:28:41.629 TileGame[6115:c07] cocos2d: surface size: 1024x768
    2013-03-16 20:28:43.045 TileGame[6115:c07] -[CCFileUtils fullPathFromRelativePath:resolutionType:] : cocos2d: Warning: File not found: ../tmw_desert_spacing.png
    2013-03-16 20:28:43.045 TileGame[6115:c07] cocos2d: CCTexture2D. Can't create Texture. cgImage is nil
    2013-03-16 20:28:43.048 TileGame[6115:c07] cocos2d: Couldn't add image:../tmw_desert_spacing.png in CCTextureCache


    I got the same problem. But I fixed it.

    What I did is I opened the TileMap.tmx file in the project navigator, it will look lie this :

    Code: Select all
    <?xml version="1.0" encoding="UTF-8"?>
    <map version="1.0" orientation="orthogonal" width="50" height="50" tilewidth="32" tileheight="32">
    <tileset firstgid="1" name="tmw_desert_spacing" tilewidth="32" tileheight="32" spacing="1" margin="1">
      <image source="../Documents/somefolder/projectfolder/projectfolder/resourcefolder/tmw_desert_spacing.png" width="265" height="199"/>
    </tileset>
    <layer name="Background" width="50" height="50">
      <data encoding="base64" compression="zlib">
       eJztlesKgkAQRqeCrmBWdC8xutC993+7RlRc1jHMQkf4Dpx/Lsxx2V2PiBzWZZfs6gfXrGdZFp7RsWMP7LWAR3avqEOaJY9Za7V0vCLr3iF5rkHHndJnts12Iu0547vhoajjQsm5vRmzzNg5OxTmzFpTRUdgg20Jc5gOLfOc/7I7euyAfWbME3Q2KWm1mwJdRR3mDL7RsGX7wjfSXlXVcaLPHSN2SmHHhsJ9MbX3qMr9CGadkPyv7RbbuF9Dh6RP6ZaxYNyvrcN8L/LaVdjhGDP5JN9Nn9TYkVfpzq26I36/v3GhsOOfAgAAAAAAAAAAAAAAAAAAgGK8Afs4Kz4=
      </data>
    </layer>
    <objectgroup name="Objects" width="50" height="50">
      <object name="SpawnPoint" x="302" y="450"/>
    </objectgroup>
    </map>

    Then changed the line
    <image source="../Documents/somefolder/projectfolder/projectfolder/resourcefolder/tmw_desert_spacing.png" width="265" height="199"/>
    to just
    <image source="tmw_desert_spacing.png" width="265" height="199"/> because this file is located in the same directory of TileMap.tmx and those additional path prefix causes the error.

    Then everything should run smoothly.
    SamT
  • How would you push a block when you hit it, such as in making as sokoban type game? I want to be able to move around the tile map, but to be able to push a block when I come into contact with it.
    rcoull
  • Please, help. In log i have such error: Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Argument must be non-nil'

    //all log down here
    cocos2d: cocos2d-iphone v2.1
    cocos2d: compiled with Profiling Support: NO
    cocos2d: OS version: 6.1 (0x06010000)
    cocos2d: GL_VENDOR: Apple Computer, Inc.
    cocos2d: GL_RENDERER: Apple Software Renderer
    cocos2d: GL_VERSION: OpenGL ES 2.0 APPLE
    cocos2d: GL_MAX_TEXTURE_SIZE: 4096
    cocos2d: GL_MAX_TEXTURE_UNITS: 8
    cocos2d: GL_MAX_SAMPLES: 4
    cocos2d: GL supports PVRTC: YES
    cocos2d: GL supports BGRA8888 textures: YES
    cocos2d: GL supports NPOT textures: YES
    cocos2d: GL supports discard_framebuffer: YES
    cocos2d: GL supports shareable VAO: NO
    2013-09-28 23:35:31.532 Z-trouble[754:c07] Retina Display Not supported
    2013-09-28 23:35:31.546 Z-trouble[754:c07] cocos2d: animation started with frame interval: 60.00
    2013-09-28 23:35:31.549 Z-trouble[754:c07] cocos2d: surface size: 480x320
    2013-09-28 23:35:31.663 Z-trouble[754:c07] cocos2d: CCSpriteBatchNode: resizing TextureAtlas capacity from [876] to [1169].
    2013-09-28 23:35:31.666 Z-trouble[754:c07] cocos2d: CCSpriteBatchNode: resizing TextureAtlas capacity from [1169] to [1560].
    2013-09-28 23:35:31.669 Z-trouble[754:c07] cocos2d: CCSpriteBatchNode: resizing TextureAtlas capacity from [1560] to [2081].
    2013-09-28 23:35:31.672 Z-trouble[754:c07] cocos2d: CCSpriteBatchNode: resizing TextureAtlas capacity from [2081] to [2776].
    2013-09-28 23:35:31.676 Z-trouble[754:c07] -[CCFileUtils fullPathForFilename:resolutionType:] : cocos2d: Warning: File not found: player.png
    2013-09-28 23:35:31.677 Z-trouble[754:c07] cocos2d: Couldn't find file:player.png
    2013-09-28 23:35:31.678 Z-trouble[754:c07] *** Assertion failure in -[HelloWorldLayer addChild:], /Users/Dmitry/Documents/Z-trouble/Z-trouble/libs/cocos2d/CCNode.m:382
    2013-09-28 23:35:31.680 Z-trouble[754:c07] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Argument must be non-nil'
    *** First throw call stack:
    (0x2510012 0x1fe4e7e 0x250fe78 0x160e665 0x5e0e0 0xe3c41 0x5c6c5 0xe2de2 0xe4291 0x1ff8663 0xc4269 0xc28ba 0x5f1e4 0x336f2 0xb8d18 0x15b7fb4 0x15efb1a 0xb94ac 0xe22bf 0xb9bf2 0xbd089 0xb0d2dd 0x1ff86b0 0x3cdfc0 0x3c233c 0x3cdeaf 0xbac2bd 0xaf4b56 0xaf366f 0xaf3589 0xaf27e4 0xaf261e 0xaf33d9 0xaf62d2 0xba099c 0xaed574 0xaed76f 0xaed905 0xaf6917 0xe2893 0xaba157 0xaba747 0xabb94b 0xacccb5 0xacdbeb 0xabf698 0x3218df9 0x3218ad0 0x2485bf5 0x2485962 0x24b6bb6 0x24b5f44 0x24b5e1b 0xabb17a 0xabcffc 0xe20b6 0x2cb5)
    libc++abi.dylib: terminate called throwing an exception
    (lldb)
    karvozavr
  • Notes: Issues spawning the CCSprite _player. (Using xcode 5.0, cocos2d_2.x)

    I added the TileMap.tmx with ObjectLayer directly to the root "Resources" folder and spawn worked correctly. Tried adding absolute path to "self.tileMap = [CCTMXTiledMap tiledMapWithTMXFile:@"TileMap.tmx"];, and it worked for the Background layer, however not the Objects"

    Hope this helps anyone who has similar issues.
    timkropp77
  • Hi there is there anyway that we can enable the retina display without screwing up the view because when I enable the retina display in appdelegate.m, the view goes off the tile and shows black screen.
    rayjan
  • Hi I just have problem with enabling retina display. it won't work I mean if I enable the retina display, the view goes off screen. how can i fix this? I want retina display. btw this is regarding Charlie Fulton's tutorial.
    rayjan
  • Rayjan, did you solve the problem? I`ve the same one.
    MyBigBang
  • Rayjan, did you solve the problem? I`ve the same one. The screen is black when I run the project. Does anyone know how to fix it?
    MyBigBang
  • I am using cocos2d-3.0. I'm trying to isolate the problem as much as I can to make it easier for someone else to be able to give me more of an insight instead of being a noob and stating that I don't know what to do! lol. So this is the issue that I'm finally left with, please do have a quick look: http://gamedev.stackexchange.com/questi ... of-a-scene

    Cheers
    PkKataria
  • I would love to do this tutorial, but I am on the newest version of Cocos2d. Is there any way this can be updated for the new Cocos2d 3?
    zeeple
[ 1 , 2 ]

Other Items of Interest

Ray's Monthly Newsletter

Sign up to receive a monthly newsletter with my favorite dev links, and receive a free epic-length tutorial as a bonus!

Advertise with Us!

Hang Out With Us!

Every month, we have a free live Tech Talk - come hang out with us!


Coming up in May: Procedural Level Generation in Games with Kim Pedersen.

Sign Up - May

Coming up in June: WWDC Keynote - Podcasters React! with the podcasting team.

Sign Up - June

Vote For Our Next Book!

Help us choose the topic for our next book we write! (Choose up to three topics.)

    Loading ... Loading ...

Our Books

Our Team

Tutorial Team

  • Jake Gundersen

... 55 total!

Editorial Team

  • Alexis Gallagher

... 21 total!

Code Team

  • Orta Therox

... 1 total!

Translation Team

  • Rodrigo Salles

... 38 total!

Subject Matter Experts

... 4 total!