Skip to content

Commit

Permalink
Add tile map and tile set importers
Browse files Browse the repository at this point in the history
  • Loading branch information
STREGA committed Sep 4, 2023
1 parent 0afb58c commit cba634f
Show file tree
Hide file tree
Showing 4 changed files with 192 additions and 13 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
/*
* Copyright © 2023 Dustin Collins (Strega's Gate)
* All Rights Reserved.
*
* http://stregasgate.com
*/

import Foundation

fileprivate struct TMJFile: Decodable {
let type: String
let compressionlevel: Int
let orientation: String
let renderorder: String
let infinite: Bool
let tileheight: Int
let tilewidth: Int
let width: Int
let height: Int
let layers: [Layer]
struct Layer: Decodable {
let id: Int
let name: String
let type: String
let visible: Bool
let opacity: Float
let x: Int
let y: Int
let width: Int
let height: Int
let data: [Int32]
}
let nextlayerid: Int
let nextobjectid: Int
let version: String
let tiledversion: String
}

public class TiledTMJImporter: TileMapImporter {
public required init() {}

public func process(data: Data, baseURL: URL, options: TileMapImporterOptions) async throws -> TileMap {
let file = try JSONDecoder().decode(TMJFile.self, from: data)

var layers: [TileMap.Layer] = []
layers.reserveCapacity(file.layers.count)
for fileLayer in file.layers {
var tiles: [[TileMap.Tile]] = []
let count = fileLayer.width * fileLayer.height
for start in stride(from: 0, through: count, by: fileLayer.width) {
let subset = fileLayer.data[start ..< start + fileLayer.width]
tiles.append(subset.map({ rawID in
var options: TileMap.Tile.Options = []
var flags = TileMap.Tile.Options(rawValue: UInt(rawID))
if flags.contains(.flippedHorizontal) {
options.insert(.flippedHorizontal)
}
if flags.contains(.flippedVertical) {
options.insert(.flippedVertical)
}
if flags.contains(.flippedDiagonal) {
options.insert(.flippedDiagonal)
}
if flags.contains(.rotatedHexagonal120) {
options.insert(.rotatedHexagonal120)
}
flags.remove([.flippedHorizontal, .flippedVertical, .flippedDiagonal, .rotatedHexagonal120])
return TileMap.Tile(id: Int(flags.rawValue), options: options)
}))
}
let layer = TileMap.Layer(name: fileLayer.name,
size: Size2(Float(fileLayer.width), Float(fileLayer.height)),
tileSize: Size2(Float(file.tilewidth), Float(file.tileheight)),
tiles: tiles)
layers.append(layer)
}

return TileMap(layers: layers)
}

static public func supportedFileExtensions() -> [String] {
return ["tmj"]
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
/*
* Copyright © 2023 Dustin Collins (Strega's Gate)
* All Rights Reserved.
*
* http://stregasgate.com
*/

import Foundation

fileprivate struct TSJFile: Decodable {
let columns: Int
let image: String
let imageheight: Int
let imagewidth: Int
let margin: Int
let name: String
let spacing: Int
let tilecount: Int
let tiledversion: String
let tileheight: Int
let tilewidth: Int
let type: String
let version: String
let tiles: [Tile]?

struct Tile: Decodable {
let id: Int
let properties: [Property]?

struct Property: Decodable {
let name: String
let type: String
let value: String
}
}
}

public class TiledTSJImporter: TileSetImporter {
public required init() {}

public func process(data: Data, baseURL: URL, options: TileSetImporterOptions) async throws -> TileSet {
let file = try JSONDecoder().decode(TSJFile.self, from: data)

let tiles: [Tile] = (0 ..< file.tilecount).map({ id in
var properties: [String: String] = [:]
if let fileTiles = file.tiles {
if let fileTile = fileTiles.first(where: {$0.id == id}) {
if let fileTileProperties = fileTile.properties {
for property in fileTileProperties {
properties[property.name] = property.value
}
}
}
}
return Tile(id: id, properties: properties, colliders: nil)
})

return TileSet(textureName: file.image,
textureSize: Size2(Float(file.imagewidth), Float(file.imageheight)),
count: file.tilecount,
columns: file.columns,
tileSize: Size2(Float(file.tilewidth), Float(file.tileheight)),
tiles: tiles)
}

static public func supportedFileExtensions() -> [String] {
return ["tsj"]
}
}
24 changes: 17 additions & 7 deletions Sources/GateEngine/Resources/ResourceManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,20 +11,30 @@ import class Foundation.FileManager

extension ResourceManager {
struct Importers {
internal var textureImporters: [any TextureImporter.Type] = [PNGImporter.self]
internal var textureImporters: [any TextureImporter.Type] = [
PNGImporter.self
]

internal var geometryImporters: [any GeometryImporter.Type] = [
GLTransmissionFormat.self, WavefrontOBJImporter.self,
GLTransmissionFormat.self,
WavefrontOBJImporter.self,
]

internal var skeletonImporters: [any SkeletonImporter.Type] = [
GLTransmissionFormat.self,
]
internal var skinImporters: [any SkinImporter.Type] = [
GLTransmissionFormat.self,
]
internal var skeletonImporters: [any SkeletonImporter.Type] = [GLTransmissionFormat.self]
internal var skinImporters: [any SkinImporter.Type] = [GLTransmissionFormat.self]
internal var skeletalAnimationImporters: [any SkeletalAnimationImporter.Type] = [
GLTransmissionFormat.self
GLTransmissionFormat.self,
]

internal var tileSetImporters: [any TileSetImporter.Type] = [ /*TiledTileSetImporter.self*/
internal var tileSetImporters: [any TileSetImporter.Type] = [
TiledTSJImporter.self,
]
internal var tileMapImporters: [any TileMapImporter.Type] = [ /*TiledTileMapImporter.self*/
internal var tileMapImporters: [any TileMapImporter.Type] = [
TiledTMJImporter.self,
]
}
}
Expand Down
28 changes: 22 additions & 6 deletions Sources/GateEngine/Resources/Tiles/TileMap.swift
Original file line number Diff line number Diff line change
Expand Up @@ -17,22 +17,38 @@ public class TileMap {
init(layers: [Layer]) {
self.layers = layers
}

public struct Tile {
public let id: Int
public let options: Options
public struct Options: OptionSet {
public let rawValue: UInt
public init(rawValue: UInt) {
self.rawValue = rawValue
}

public static let flippedHorizontal = Options(rawValue: 0x80000000)
public static let flippedVertical = Options(rawValue: 0x40000000)
public static let flippedDiagonal = Options(rawValue: 0x20000000)
public static let rotatedHexagonal120 = Options(rawValue: 0x10000000)
}
}

public class Layer {
public let name: String?
public let size: Size2
public let tileSize: Size2
public let tileIndices: [[Int]]
public let tiles: [[Tile]]

public var rows: Int {
return tileIndices.count
return tiles.count
}
public var columns: Int {
return tileIndices.first?.count ?? 0
return tiles.first?.count ?? 0
}

public func tileIndexAtCoordinate(column: Int, row: Int) -> Int {
return tileIndices[row][column]
return tiles[row][column].id
}

public func tileIndexAtPosition(_ position: Position2) -> Int {
Expand All @@ -45,11 +61,11 @@ public class TileMap {
return (Position2(Float(column), Float(row)) * tileSize)
}

init(name: String?, size: Size2, tileSize: Size2, tileIndices: [[Int]]) {
init(name: String?, size: Size2, tileSize: Size2, tiles: [[Tile]]) {
self.name = name
self.size = size
self.tileSize = tileSize
self.tileIndices = tileIndices
self.tiles = tiles
}
}
}

0 comments on commit cba634f

Please sign in to comment.