Last active
October 14, 2015 22:42
-
-
Save guregu/48e6b50e70fad59049c0 to your computer and use it in GitHub Desktop.
engi + tiled
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package tiled | |
import ( | |
"encoding/json" | |
"fmt" | |
"io" | |
"os" | |
"path/filepath" | |
"github.com/guregu/eng" | |
) | |
const tilesetName = "tileset/%s" | |
type Map struct { | |
Width int `json:"width"` | |
Height int `json:"height"` | |
TileWidth int `json:"tilewidth"` | |
TileHeight int `json:"tileheight"` | |
Layers []Layer `json:"layers"` | |
Tilesets []Tileset `json:"tilesets"` | |
Tiles map[int]*engi.Region | |
} | |
func (m *Map) setup() { | |
added := make(map[string]struct{}) | |
for _, ts := range m.Tilesets { | |
if _, exists := added[ts.Name]; exists { | |
continue | |
} | |
added[ts.Name] = struct{}{} | |
for gid, r := range ts.Tiles() { | |
m.Tiles[gid] = r | |
} | |
} | |
} | |
type Layer struct { | |
Data []int `json:"data"` // TileIDs | |
X int `json:"x"` | |
Y int `json:"y"` | |
Width int `json:"width"` | |
Height int `json:"height"` | |
Visible bool `json:"visible"` | |
Name string `json:"name"` | |
NextObjectID int `json:"nextobjectid"` // ?? | |
Opacity int `json:"opacity"` // ?? | |
Type string `json:"type"` // ?? | |
Objects []Object `json:"objects"` | |
} | |
type Object struct { | |
ID int | |
Name string | |
Properties map[string]string | |
Rotation float64 | |
Type string | |
Visible bool | |
X, Y float32 | |
Height, Width float32 | |
} | |
type Tileset struct { | |
FirstGID int `json:"firstgid"` | |
Image string `json:"image"` | |
ImageHeight int `json:"imageheight"` | |
ImageWidth int `json:"imagewidth"` | |
Margin int `json:"margin"` | |
Spacing int `json:"spacing"` | |
TileHeight int `json:"tileheight"` | |
TileWidth int `json:"tilewidth"` | |
Name string `json:"name"` | |
} | |
func (ts Tileset) Tiles() map[int]*engi.Region { | |
tiles := make(map[int]*engi.Region) | |
gid := ts.FirstGID | |
tex := ts.Texture() | |
w := (ts.ImageWidth - ts.Margin) / (ts.TileWidth + ts.Spacing) | |
h := (ts.ImageHeight - ts.Margin) / (ts.TileHeight + ts.Spacing) | |
for y := 0; y < h; y++ { | |
for x := 0; x < w; x++ { | |
u := ts.Margin + (ts.TileWidth+ts.Spacing)*x | |
v := ts.Margin + (ts.TileHeight+ts.Spacing)*y | |
r := engi.NewRegion(tex, u, v, ts.TileWidth, ts.TileHeight) | |
tiles[gid] = r | |
gid++ | |
} | |
} | |
return tiles | |
} | |
func (ts Tileset) Texture() *engi.Texture { | |
name := fmt.Sprintf(tilesetName, ts.Name) | |
return engi.Files.Image(name) | |
} | |
func Load(r io.Reader, tilesetPath string) (m Map, err error) { | |
err = json.NewDecoder(r).Decode(&m) | |
if err != nil { | |
return | |
} | |
m.Tiles = make(map[int]*engi.Region) | |
added := make(map[string]struct{}) | |
for _, ts := range m.Tilesets { | |
name := fmt.Sprintf(tilesetName, ts.Name) | |
if _, exists := added[name]; exists { | |
continue | |
} | |
added[name] = struct{}{} | |
file := filepath.Base(ts.Image) | |
fmt.Println("loading", filepath.Join(tilesetPath, file)) | |
engi.Files.Add(name, filepath.Join(tilesetPath, file)) | |
} | |
engi.Files.Load(func() { | |
m.setup() | |
}) | |
return | |
} | |
func LoadFile(path, tilesetPath string) (m Map, err error) { | |
f, err := os.Open(path) | |
if err != nil { | |
return Map{}, err | |
} | |
defer f.Close() | |
return Load(f, tilesetPath) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Here's how you actually draw the map: