title: Tilemap platform collision detection with Cocos2d
body: <p>I'm getting my feet wet with game development by working on a platformer using Cocos2d for iPhone. I'm struggling a bit in getting collision detection running so that my character will have his jump action cancelled when he hits a platform.</p>
  
  <p>I'm using a technique from <a href="http://www.raywenderlich.com/1186/collisions-and-collectables-how-to-make-a-tile-based-game-with-cocos2d-part-2" rel="nofollow">this tutorial</a> where I create a separate layer of "meta tiles". The problem is that collision detection does not occur until the character sprite is well within the collidable tile, not on top of it.</p>
  
  <p>I'm using the code below to determine the tile coordinate based on my character sprite's current position:</p>
  
  <pre><code>    - (CGPoint) tileCoordForPosition: (CGPoint) position {
      int x = position.x / tileMap.tileSize.width;
      int y = ((tileMap.mapSize.height * tileMap.tileSize.height) - position.y) / tileMap.tileSize.height;
      return ccp(x, y);
  }
  </code></pre>
  
  <p>I tried various techniques, even trying to figure out what tile was below my character using this code:</p>
  
  <pre><code>- (void) update: (ccTime) dt {
      BOOL isCollision = NO;
      if (firstRun) {
          oldY = player.position.y;
          firstRun = NO;
      }
      CGPoint oneTileDown = ccp(player.position.x, player.position.y / 2);
      CGPoint tileCoord = [gameplayLayer tileCoordForPosition:oneTileDown];
      int tileGid = [gameplayLayer.meta tileGIDAt:tileCoord];
  
      if (tileGid) {
          NSDictionary* tileProperties = [gameplayLayer.tileMap propertiesForGID:tileGid];
          if (tileProperties) {
              NSString* collision = [tileProperties valueForKey:@"Collidable"];
              if (collision &amp;&amp; [collision compare:@"True"] == NSOrderedSame) {
                  //CCLOG(@"Collision Below");
                  isCollision = YES;
                  if (player.characterState == kStateFalling) {
                      [player stopAllActions];
                  }
              }
          }
      }
  
      if (oldY &lt; player.position.y) {
          CCLOG(@"Character is jumping");
          player.characterState = kStateJumping;
      }
      else if (oldY &gt; player.position.y) {
          CCLOG(@"Character is falling");
          player.characterState = kStateFalling;
      }
  
      oldY = player.position.y;
  }
  </code></pre>
  
  <p>But the same problem happens: my character jumps, lands inside of the collision tile and is stopped instead of landing on top of the tile.</p>
  
  <p>Is there a better way of checking for collision in a tilemap?</p>