Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Save/Load Tileset #35

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions assets/tilesets/testLoadTileset.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<tileset version="1.2" tiledversion="1.2.3" name="ProjectUtumno_full" tilewidth="32" tileheight="32" tilecount="6080" columns="64">
<image source="ProjectUtumno_full.png" width="2048" height="3040"/>
<tile id="116" type="door"></tile>
</tileset>
13 changes: 13 additions & 0 deletions assets/tilesets/testLoadTilesetTile.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<tileset version="1.2" tiledversion="1.2.3" name="ProjectUtumno_full" tilewidth="32" tileheight="32" tilecount="6080" columns="64">
<image source="ProjectUtumno_full.png" width="2048" height="3040"/>
<tile id="464">
<objectgroup opacity="1" visible="true" draworder="index">
<object id="1" x="-0.25" y="17.75" width="32.375" height="6.125" visible="true"/>
</objectgroup>
<animation>
<frame tileid="75" duration="500"/>
<frame tileid="76" duration="500"/>
</animation>
</tile>
</tileset>
3 changes: 0 additions & 3 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,7 @@ github.com/disintegration/imaging v1.6.2 h1:w1LecBlG2Lnp8B3jk5zSuNqd7b4DXhcjwek1
github.com/disintegration/imaging v1.6.2/go.mod h1:44/5580QXChDfwIclfc/PCwrr44amcmDAg8hxG0Ewe4=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/objx v0.1.0 h1:4G4v2dO3VZwixGIRoQ5Lfboy6nUhCyYzaqnIAPPhYs4=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0=
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
golang.org/x/image v0.0.0-20191009234506-e7c1f5e7dbb8 h1:hVwzHzIUGRjiF7EcUjqNxk3NCfkPxbDKRdnNE1Rpg0U=
Expand Down
26 changes: 26 additions & 0 deletions tiled.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,3 +86,29 @@ func (l *Loader) LoadFromFile(fileName string) (*Map, error) {
dir := filepath.Dir(fileName)
return l.LoadFromReader(dir, f)
}

// LoadTilesetFromReader loads a .tsx file into a Tileset structure
func LoadTilesetFromReader(baseDir string, r io.Reader) (*Tileset, error) {
d := xml.NewDecoder(r)

m := &Tileset{
baseDir: baseDir,
SourceLoaded: true,
}
if err := d.Decode(m); err != nil {
return nil, err
}

return m, nil
}

// SaveTilesetToWriter saves a Tileset structure into a given writer
func SaveTilesetToWriter(tileset *Tileset, w io.Writer) error {
encoder := xml.NewEncoder(w)
encoder.Indent("", " ")
return encoder.Encode(tileset)
}

func b(v bool) *bool {
return &v
}
6 changes: 3 additions & 3 deletions tiled_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,12 +85,12 @@ func TestLoadFromFile(t *testing.T) {
// Test ObjectGroups.Visible defaults to true
assert.Len(t, m.ObjectGroups, 1)
assert.Equal(t, uint32(2), m.ObjectGroups[0].ID)
assert.Equal(t, true, m.ObjectGroups[0].Visible)
assert.Equal(t, true, *m.ObjectGroups[0].Visible)

// Test Object.Visible defaults to true
assert.Len(t, m.ObjectGroups[0].Objects, 1)
assert.Equal(t, uint32(2), m.ObjectGroups[0].Objects[0].ID)
assert.Equal(t, true, m.ObjectGroups[0].Objects[0].Visible)
assert.Equal(t, true, *m.ObjectGroups[0].Objects[0].Visible)
}

func TestLoadFromFileError(t *testing.T) {
Expand Down Expand Up @@ -197,7 +197,7 @@ func TestFont(t *testing.T) {
assert.Equal(t, false, text.Italic)
assert.Equal(t, false, text.Underline)
assert.Equal(t, false, text.Strikethrough)
assert.Equal(t, true, text.Kerning)
assert.Equal(t, true, *text.Kerning)
assert.Equal(t, "left", text.HAlign)
assert.Equal(t, "top", text.VAlign)
}
Expand Down
6 changes: 3 additions & 3 deletions tmx_defaults.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,20 +57,20 @@ func (a *aliasMap) SetDefaults() {

// SetDefaults provides default values for Object.
func (a *aliasObject) SetDefaults() {
a.Visible = true
a.Visible = b(true)
}

// SetDefaults provides default values for ObjectGroup.
func (a *aliasObjectGroup) SetDefaults() {
a.Visible = true
a.Visible = b(true)
a.Opacity = 1
}

// SetDefaults provides default values for Text.
func (a *aliasText) SetDefaults() {
a.FontFamily = "sans-serif"
a.Size = 16
a.Kerning = true
a.Kerning = b(true)
a.HAlign = "left"
a.VAlign = "top"
a.Color = &HexColor{}
Expand Down
2 changes: 1 addition & 1 deletion tmx_group.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ type Group struct {
// Whether the layer is shown (1) or hidden (0). Defaults to 1.
Visible bool `xml:"visible,attr"`
// Custom properties
Properties Properties `xml:"properties>property"`
Properties *Properties `xml:"properties"`
// Map layers
Layers []*Layer `xml:"layer"`
// Map object groups
Expand Down
12 changes: 6 additions & 6 deletions tmx_image.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ type ImageLayer struct {
// Whether the layer is shown (1) or hidden (0). Defaults to 1.
Visible bool `xml:"visible,attr"`
// Custom properties
Properties Properties `xml:"properties>property"`
Properties *Properties `xml:"properties"`
// The group image
Image *Image `xml:"image"`
}
Expand All @@ -69,16 +69,16 @@ func (l *ImageLayer) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error
// Image source
type Image struct {
// Used for embedded images, in combination with a data child element. Valid values are file extensions like png, gif, jpg, bmp, etc.
Format string `xml:"format,attr"`
Format string `xml:"format,attr,omitempty"`
// The reference to the tileset image file
Source string `xml:"source,attr"`
// Defines a specific color that is treated as transparent (example value: "#FF00FF" for magenta).
// Up until Tiled 0.12, this value is written out without a # but this is planned to change.
Trans *HexColor `xml:"trans,attr"`
Trans *HexColor `xml:"trans,attr,omitempty"`
// The image width in pixels (optional, used for tile index correction when the image changes)
Width int `xml:"width,attr"`
Width int `xml:"width,attr,omitempty"`
// The image height in pixels (optional)
Height int `xml:"height,attr"`
Height int `xml:"height,attr,omitempty"`
// Embedded image content
Data *Data `xml:"data,attr"`
Data *Data `xml:"data,attr,omitempty"`
}
2 changes: 1 addition & 1 deletion tmx_layer.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ type Layer struct {
// Rendering offset for this layer in pixels. Defaults to 0. (since 0.14)
OffsetY int `xml:"offsety,attr"`
// Custom properties
Properties Properties `xml:"properties>property"`
Properties *Properties `xml:"properties"`
// This is the attribute you'd like to use, not Data. Tile entry at (x,y) is obtained using l.DecodedTiles[y*map.Width+x].
Tiles []*LayerTile
// Data
Expand Down
2 changes: 1 addition & 1 deletion tmx_map.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ type Map struct {
// Stores the next available ID for new objects. This number is stored to prevent reuse of the same ID after objects have been removed. (since 0.11)
NextObjectID uint32 `xml:"nextobjectid,attr"`
// Custom properties
Properties *Properties `xml:"properties>property"`
Properties *Properties `xml:"properties"`
// Map tilesets
Tilesets []*Tileset `xml:"tileset"`
// Map layers
Expand Down
75 changes: 38 additions & 37 deletions tmx_object.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,25 +40,25 @@ type ObjectGroup struct {
// Unique ID of the layer.
// Each layer that added to a map gets a unique id. Even if a layer is deleted,
// no layer ever gets the same ID. Can not be changed in Tiled. (since Tiled 1.2)
ID uint32 `xml:"id,attr"`
ID uint32 `xml:"id,attr,omitempty"`
// The name of the object group.
Name string `xml:"name,attr"`
Name string `xml:"name,attr,omitempty"`
// The color used to display the objects in this group.
Color *HexColor `xml:"color,attr"`
Color *HexColor `xml:"color,attr,omitempty"`
// The opacity of the layer as a value from 0 to 1. Defaults to 1.
Opacity float32 `xml:"opacity,attr"`
Opacity float32 `xml:"opacity,attr,omitempty"`
// Whether the layer is shown (1) or hidden (0). Defaults to 1.
Visible bool `xml:"visible,attr"`
Visible *bool `xml:"visible,attr"`
// Rendering offset for this layer in pixels. Defaults to 0. (since 0.14)
OffsetX int `xml:"offsetx,attr"`
OffsetX int `xml:"offsetx,attr,omitempty"`
// Rendering offset for this layer in pixels. Defaults to 0. (since 0.14)
OffsetY int `xml:"offsety,attr"`
OffsetY int `xml:"offsety,attr,omitempty"`
// Whether the objects are drawn according to the order of appearance ("index") or sorted by their y-coordinate ("topdown"). Defaults to "topdown".
DrawOrder string `xml:"draworder,attr"`
DrawOrder string `xml:"draworder,attr,omitempty"`
// Custom properties
Properties Properties `xml:"properties>property"`
Properties *Properties `xml:"properties,omitempty"`
// Group objects
Objects []*Object `xml:"object"`
Objects []*Object `xml:"object,omitempty"`
}

// DecodeObjectGroup decodes object group data
Expand Down Expand Up @@ -94,37 +94,37 @@ func (g *ObjectGroup) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error
type Object struct {
// Unique ID of the object. Each object that is placed on a map gets a unique id. Even if an object was deleted, no object gets the same ID.
// Can not be changed in Tiled Qt. (since Tiled 0.11)
ID uint32 `xml:"id,attr"`
ID uint32 `xml:"id,attr,omitempty"`
// The name of the object. An arbitrary string.
Name string `xml:"name,attr"`
Name string `xml:"name,attr,omitempty"`
// The type of the object. An arbitrary string.
Type string `xml:"type,attr"`
Type string `xml:"type,attr,omitempty"`
// The x coordinate of the object.
X float64 `xml:"x,attr"`
X float64 `xml:"x,attr,omitempty"`
// The y coordinate of the object.
Y float64 `xml:"y,attr"`
Y float64 `xml:"y,attr,omitempty"`
// The width of the object (defaults to 0).
Width float64 `xml:"width,attr"`
Width float64 `xml:"width,attr,omitempty"`
// The height of the object (defaults to 0).
Height float64 `xml:"height,attr"`
Height float64 `xml:"height,attr,omitempty"`
// The rotation of the object in degrees clockwise (defaults to 0). (since 0.10)
Rotation float64 `xml:"rotation,attr"`
Rotation float64 `xml:"rotation,attr,omitempty"`
// An reference to a tile (optional).
GID uint32 `xml:"gid,attr"`
GID uint32 `xml:"gid,attr,omitempty"`
// Whether the object is shown (1) or hidden (0). Defaults to 1. (since 0.9)
Visible bool `xml:"visible,attr"`
Visible *bool `xml:"visible,attr"`
// Custom properties
Properties Properties `xml:"properties>property"`
Properties *Properties `xml:"properties,omitempty"`
// Used to mark an object as an ellipse. The existing x, y, width and height attributes are used to determine the size of the ellipse.
Ellipses []*Ellipse `xml:"ellipse"`
Ellipses []*Ellipse `xml:"ellipse,omitempty"`
// Polygons
Polygons []*Polygon `xml:"polygon"`
Polygons []*Polygon `xml:"polygon,omitempty"`
// Poly lines
PolyLines []*PolyLine `xml:"polyline"`
PolyLines []*PolyLine `xml:"polyline,omitempty"`
// Text
Text *Text `xml:"text"`
Text *Text `xml:"text,omitempty"`
// Template
TemplateSource string `xml:"template,attr"`
TemplateSource string `xml:"template,attr,omitempty"`
TemplateLoaded bool `xml:"-"`
Template *Template
}
Expand Down Expand Up @@ -241,31 +241,32 @@ type Text struct {
// The actual text
Text string `xml:",chardata"`
// The font family used (default: "sans-serif")
FontFamily string `xml:"fontfamily,attr"`
FontFamily string `xml:"fontfamily,attr,omitempty"`
// The size of the font in pixels (not using points, because other sizes in the TMX format are also using pixels) (default: 16)
Size int `xml:"pixelsize,attr"`
Size int `xml:"pixelsize,attr,omitempty"`
// Whether word wrapping is enabled (1) or disabled (0). Defaults to 0.
Wrap bool `xml:"wrap,attr"`
Wrap bool `xml:"wrap,attr,omitempty"`
// Color of the text in #AARRGGBB or #RRGGBB format (default: #000000)
Color *HexColor `xml:"color,attr"`
Color *HexColor `xml:"color,attr,omitempty"`
// Whether the font is bold (1) or not (0). Defaults to 0.
Bold bool `xml:"bold,attr"`
Bold bool `xml:"bold,attr,omitempty"`
// Whether the font is italic (1) or not (0). Defaults to 0.
Italic bool `xml:"italic,attr"`
Italic bool `xml:"italic,attr,omitempty"`
// Whether a line should be drawn below the text (1) or not (0). Defaults to 0.
Underline bool `xml:"underline,attr"`
Underline bool `xml:"underline,attr,omitempty"`
// Whether a line should be drawn through the text (1) or not (0). Defaults to 0.
Strikethrough bool `xml:"strikeout,attr"`
Strikethrough bool `xml:"strikeout,attr,omitempty"`
// Whether kerning should be used while rendering the text (1) or not (0). Default to 1.
Kerning bool `xml:"kerning,attr"`
Kerning *bool `xml:"kerning,attr,omitempty"`
// Horizontal alignment of the text within the object (left (default), center, right or justify (since Tiled 1.2.1))
HAlign string `xml:"halign,attr"`
HAlign string `xml:"halign,attr,omitempty"`
// Vertical alignment of the text within the object (top (default), center or bottom)
VAlign string `xml:"valign,attr"`
VAlign string `xml:"valign,attr,omitempty"`
}

// UnmarshalXML decodes a single XML element beginning with the given start element.
func (t *Text) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {

item := aliasText{}
item.SetDefaults()

Expand Down
14 changes: 8 additions & 6 deletions tmx_property.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,9 @@ package tiled
import "strconv"

// Properties wraps any number of custom properties
type Properties []*Property
type Properties struct {
Property []*Property `xml:"property"`
}

// Property is used for custom properties
type Property struct {
Expand All @@ -43,7 +45,7 @@ type Property struct {
// Get finds all properties by specified name
func (p Properties) Get(name string) []string {
var values []string
for _, property := range p {
for _, property := range p.Property {
if property.Name == name {
values = append(values, property.Value)
}
Expand All @@ -54,7 +56,7 @@ func (p Properties) Get(name string) []string {
// GetString finds first string property by specified name
func (p Properties) GetString(name string) string {
var v string
for _, property := range p {
for _, property := range p.Property {
if property.Name == name {
if property.Type == "" {
return property.Value
Expand All @@ -68,7 +70,7 @@ func (p Properties) GetString(name string) string {

// GetBool finds first bool property by specified name
func (p Properties) GetBool(name string) bool {
for _, property := range p {
for _, property := range p.Property {
if property.Name == name && property.Type == "boolean" {
return property.Value == "true"
}
Expand All @@ -78,7 +80,7 @@ func (p Properties) GetBool(name string) bool {

// GetInt finds first int property by specified name
func (p Properties) GetInt(name string) int {
for _, property := range p {
for _, property := range p.Property {
if property.Name == name && property.Type == "int" {
v, err := strconv.Atoi(property.Value)
if err != nil {
Expand All @@ -92,7 +94,7 @@ func (p Properties) GetInt(name string) int {

// GetFloat finds first float property by specified name
func (p Properties) GetFloat(name string) float64 {
for _, property := range p {
for _, property := range p.Property {
if property.Name == name && property.Type == "float" {
v, err := strconv.ParseFloat(property.Value, 64)
if err != nil {
Expand Down
Loading