3.4. Create Physics and other Shapes Document

Previous: 3.3. Create GameplayKit GraphsReturn to Index


Physics and other shapes can be created easily from Objects and Tiles.

Create Shapes from Objects

Each TKObject instance has a path property which defines the Object’s shape. Use this in any methods that requires CGPathRef instances, such as SpriteKit SKPhysicsBody or SKShapeNode:

@property (readonly, nonnull) CGPathRef path;

Note that the path reference is owned by the TKObject instance, therefore you must not call CGPathRelease() on this path!

If you need an array (C memory buffer) of CGPoint as vertices instead, you can get the vertices array and the number of vertices in the object as follows:

@property (readonly, nullable) CGPoint *vertices
@property (readonly) NSUInteger vertexCount

Again, the vertices buffer is owned by the TKObject and you must therefore not call free() on this buffer!

Shapes from Collision Layer Objects

Note that you can also get these Object shapes from tile collisions. The TKTileset class gives you access to the TKObjectLayer instances of each tile:

-(nullable TKObjectLayer*)collisionLayerForLocalTile:(TKTileGID)localTile;

You can either get a tileset for a tile GID or by its name, and then get the tile’s TKObjectLayer collision layer:

TKTileset* tileset = [mapNode.map tilesetForTile:123];  // or:
TKTileset* tileset = [mapNode.map tilesetNamed:@"Es ist mein Tile Set"];

TKTileGID localTile = [tileset convertToLocalTile:123];
TKObjectLayer* collisionLayer = [tileset collisionLayerForLocalTile:localTile];

// Swift
let tileset = mapNode.map.tilesetForTile(123)  // or:
let tileset = mapNode.map.tilesetNamed("Es ist mein Tile Set")

let localTile = tileset.convertToLocalTile(123)
let collisionLayer = tileset.collisionLayerForLocalTile(localTile)

Then enumerate over the objects on the collisionLayer and use the TKObject shape properties mentioned earlier:

for (TKObject* object in collisionLayer.objects) {
    CGPathRef path = object.path;
    // more of your code here ...
}

// Swift
for object in collisionLayer.objects {
    let path = object.path
    // more of your code here ...
}

Create Shapes from Tiles

Individual tiles also have a shape. On orthogonal maps they are rectangles, on isometric maps they are rhombuses and on hexagonal maps they are, well, hexagons.

The TKTileLayer class has a method that allows you to generate the vertices of a tile at a given coordinate:

-(nonnull CGPoint*)createVerticesForTileAt:(TKPoint)coord 
                                   winding:(TKVertexWinding)winding;

In this instance, you’ll take ownership of the returned CGPoint* memory buffer so you must call free() on this buffer when you are done using it!

Tip: If you want the above method to return an array of normalized (unit) CGPoint coordinates simply pass in TKPointZero as the coordinate. Then the returned points will be relative to the tile’s origin (its lower-left coordinate).

Also on the TKTileLayer class is this method:

-(CGPoint)pointOffsetFor:(TKTileOffset)offsetType;

The TKTileOffset enum specifies which point you’d like to retrieve. The returned point is relative to the tile’s origin. This can be useful if you only need specific vertices of a tile’s shape.


Previous: 3.3. Create GameplayKit GraphsReturn to Index