Git Product home page Git Product logo

tomlinthwaite / sktilemap Goto Github PK

View Code? Open in Web Editor NEW
57.0 8.0 18.0 905 KB

An addition to Apples Sprite Kit frame work for iOS & OSX which allows for the creation of tilemaps either programmatically or from a .tmx file (created in Tiled). SKTilemap is written purely in Swift and sets out to be a simple solution for all game programmers alike to add tilemaps to their Sprite Kit games.

License: MIT License

Swift 100.00%

sktilemap's Introduction

SKTilemap

iOS10 Beta Branch Released If you have always dreamed of using SKTilemap with iOS10 then I have good news. Now you can!

I'm currently in the process of writing a more in depth guide for using SKTilemap, you can find it on my website.

Table of Contents

Overview

An addition to Apples Sprite Kit frame work for iOS which allows for the creation of tilemaps either programmatically or from a .tmx file (created in Tiled). SKTilemap is written purely in Swift and sets out to be a simple solution for all game programmers alike to add tilemaps to their Sprite Kit games.

Why

I decided to write this because I couldn't find a good alternative written purely in Swift. I'm also a self taught programmer and this was a good learning exercise. I've tried to document the code as well as I can so it shouldn't be to hard to look through it and add features or change anything you want.

Supports

  • OSX
  • iOS

Requirements

  • Xcode 7.3
  • Swift 2.2

Usage

Simply add the SKTilemap*.swift files to your project and you're good to go.

In the future I will combine all of the files into a single file. For now while I'm still working on the project it's just easier to keep the classes seperate.

Loading a Tilemap from a .tmx

To load a tilemap from a .tmx file simply add the .tmx to your project (plus the associated images for your tiles) and use:

if let tilemap = SKTilemap.loadTMX(name: "awsome_map_made_in_Tiled") { 
    scene.addChild(tilemap)
    
    tilemap.enableTileClipping = true // Improve your performance!
}

Once the tilemap has been successfully loaded you can treat it as a normal SKNode. It's always best to load the tilemap within an if let or guard let statement because the loading can fail.

Quick Guide

Here's a quick overview of the API which should hopefully be self explanatory. I have tried to document everything in code as best I can if you get stuck. This is not all of the API, please see the wiki.

Tilemap Layers

Layers are also SKNode objects and can be added to an SKTilemap object. Each layer contains many SKTile objects (as children) that make up the visual look for that layer.

Adding, Getting and Removing Layers

tilemap.getLayer(name: "Tile Layer 1")
tilemap.getLayers()
tilemap.add(tileLayer: someLayer)
tilemap.add(tileLayer: someLayer, zPosition: 1000)
tilemap.removeLayer(name: "Tile Layer 87")

Adding, Getting and Removing Tiles from a Layer

layer.tileAtCoord(3, 3)
layer.tileAtPosition(CGPoint(x: 3,y: 3))
layer.setTileAtCoord(3, 3, tile: aTile)
layer.setTileAtCoord(3, 3, id: 90)
layer.removeTileAtCoord(3, 3)
layer.removeAllTiles()

Tile Coordinates & Positioning

layer.tilePositionAtCoord(x: 3, y: 3)
layer.coordAtPosition(position: CGPoint)

iOS Only

layer.coordAtTouchPosition(UITouch)
layer.tileAtTouchPosition(UITouch)

OSX Only

layer.coordAtMousePosition(NSEvent)
layer.tileAtMousePosition(NSEvent)

Object Groups

Will probably only be used if loading from a .tmx file.

Adding and Getting Object Groups

tilemap.add(objectGroup: AnObjectGroup)
tilemap.getObjectGroup(name: "Some Object Group")

Adding and Getting Objects

objectGroup.addObject(SomeObject)
objectGroup.getObject(id: 5)
objectGroup.getObjects()
objectGroup.getObjectAtCoord(32, 54)
objectGroup.getObjects(name: "Gold Coin")
objectGroup.getObjects(type: "enemy")

Tilesets

Tilesets are a collection of SKTileData objects. SKTileData objects act as a blueprint when creating individual tiles. Each SKTileData object has a unique ID number known as a GID (if you're familiar with Tiled).

Adding and Getting Tilesets

tilemap.add(tileset: SKTileset)
tilemap.getTileset(name: "coolest graphics eva")
tilemap.getTileData(id: 54)

Adding and Getting TileData

tileset.addTileData(spriteSheet: "a load of sheet sprites")
tileset.addTileData(id: 90, texture: SKTexture)
tileset.addTileData(id: 45, imageNamed: "Grass")
tileset.getTileData(id: 45)

TMX Support

I haven't yet implemented all of the features you can use to create a tilemap in Tiled. Here's a quick list of what is and isn't yet implemented. I hope to support all features in the future, but feel free to fork this project and add anything yourself. I've tried to make this list as comprehensive as possible but no doubt there are many things I've missed.

Supported

  • Orientation (Orthogonal, Isometric)
  • Tilesets (Separate Image, Sprite Sheet)
  • Tile Layers
  • Object Groups (Layers)
  • Encoding (Base64, CSV, XML)
  • Objects (Rectangular)
  • Properties for all types (Map, Layer, Objects etc...)
  • Animated Tiles
  • Tile Clipping (Useful for large maps!)
  • Path Finding

Not Supported

  • Orientation (Isometric Staggered, Hexagonal)
  • Tilesets (External)
  • Image Layers
  • Terrain Types
  • Compression (gzip, zlib)
  • Tile Flipping
  • Objects (Elipse, Polygon, Polyline)

Other

Feel free to visit my YouTube channel where I some times upload videos on game development stuff. I'm likely to put up some videos regarding this project, How-To's and what not. Also, although I like my current job as a chef I would really like a job in programming! I'm self taught and have no certification to my name but you never know, someone might read this and message me :P

License

MIT License

Copyright (c) 2016 Tom Linthwaite

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

sktilemap's People

Contributors

danielebarone avatar neoneye avatar tomlinthwaite avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

sktilemap's Issues

Visual error

Hello Tom.

I'm just testing your library and works pretty well!

My problem maybe has nothing to do with your library. I have added a node which the camera keeps on the center all the time. This node moves at constant velocity and does well when its moving at a low speed. But when I increase it, some vertical lines appear between the tiles. Do you know how to solve it? Thanks!

edit: btw It only happens when moving horizontally, and i'm using an iPad to test it (60 framerate)
tiles2

Incorrect gid returned

Hi Tom

Are you aware that the "gid" being returned by gid = node.tileData.id
is 1 higher than the tile ID shown in "Tiled" ?

Note : JSTileMap had same issue - so I suspect it may be the way Tiled is exporting the data

Is this something you can correct ?

Object layer processing

Hi Tom

Currently you can only get objects by id, position, name or type.
Would be good to be able to iterate through the Objects in the object layer like this -

    let objectGroup = tileMap.getObjectGroup(name: "Object Layer 1")
    for object in objectGroup {
        //process object
    }

However, this produces the error as objectGroup does not conform to protocol SequenceType
Would be good if you get the object group to conform to sequence type protocol
Note : this saves you from looping through the entire grid space looking for objects.

Thanks
Richard

Swift 3

Hi, m8

just wanted to see if you have already tried this on Xcode8 and Swift 3.
I am getting an error on loading the map, but can't figure it out why.

Support for OSX apps

Hello Tom,
thank you for your great work

To use your library in a OSX app, I have modified your "SKTileMap" by adding #if !os(OSX) ... #end in the "SKTilmapLayer.swift" for the following functions:

     #if !os(OSX)
    /* Returns a tile at a given touch position. A custom offset can also be used. */
    func tileAtTouchPosition(touch: UITouch, offset: CGPoint = CGPointZero) -> SKTilemapTile? {

        if let coord = coordAtTouchPosition(touch, offset: offset, round: true) {
            return tileAtCoord(coord)
        }

        return nil
    }
    #endif

AND:

    #if !os(OSX)
  func coordAtTouchPosition(touch: UITouch, offset: CGPoint = CGPointZero, round: Bool = true) -> CGPoint? {
        return coordAtPosition(touch.locationInNode(self), offset: offset, round: round)
    }
  #endif

Are you planning to make the library compatible to OSX apps as well?
Thank you for your consideration

Coordinate System does not match SpriteKit

By default - Tiled coordinate system puts (0,0) in the top left
By default - SpriteKit coordinate system puts (0,0) in the bottom left

This is resulting in Y values that start at 0 and reduce to -screen size
To correct this - I believe you can add Screen Height to the y position when tiles are loaded.

In SKTilemapLayer - fun tilePositionAtCoord

change

    case .Orthogonal:

        position = CGPoint(x: x * Int(tileSize.width) + Int(tileAnchorPoint.x * tileSize.width),
                           y: y * Int(-tileSize.height) - Int(tileSize.height - tileAnchorPoint.y * tileSize.height))

to

    case .Orthogonal:

        let tmpMapSize = Int(tilemap.size.height * tileSize.height)
        let tmpYpos = y * Int(-tileSize.height) - Int(tileSize.height - tileAnchorPoint.y * tileSize.height)

        position = CGPoint(x: x * Int(tileSize.width) + Int(tileAnchorPoint.x * tileSize.width),
                           y: tmpMapSize + tmpYpos)

Testing seems to produce the correct results with Y values now starting at 0 in the bottom of the screen
Additionally this change did not seem to produce any other side effects (but will require more testing)

Let me know what you think

Rgds
Richard

Cropped Nodes

Hi Tom

Great work so far on this - it looks and works really well.
Do you have any plans to support cropping ?
I have tile maps that are 50 * 500 - which creates a lot of objects and requires some form of cropping to keep frame rates at a reasonable level (Note : JSTileMap has similar built in)

TileMap aligned with the bottom left corner

Hello Tom,
brilliant job! I was looking for a library like yours for a long time.

I was just wondering if you are planning to have an option that allows the TileMap to be aligned to the bottom left corner of the screen. Currently, I see that the map has been centred in the middle of the screen.
Thank you
Daniele

Tile Map Loading Time

Hi Tom

I noticed the loading time for a large map is slow using SKTileMap.
As a test I loaded the identical map in two apps, one using SKTileMap, the other JSTileMap (https://github.com/slycrel/JSTileMap)

The results can be seen below in the debug log outputs.

SKTileMap loading time for 50* 500 Map (68 seconds)

08:38:09:817 -- GameScene.swift -- didMoveToView
08:39:17:463 -- GameScene.swift -- didMoveToView -- SETUP FINISHED

JSTileMap loading time for 50 * 500 Map (0.5 secs)

08:53:45:306 -- GameScene.swift -- didMoveToView
2016-04-22 08:53:45.567 Swifty[1691:1096158] Layer Tile Layer 1 has zPosition -60.000000
2016-04-22 08:53:45.621 Swifty[1691:1096158] Layer Tile Layer 2 has zPosition -40.000000
08:53:45:788 -- GameScene.swift -- didMoveToView -- SETUP FINISHED

Happy to provide more information if required

Rgds
Richard

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.