func (project *Project) LevelAt(x, y int) *Level {
	for _, level := range project.Levels {
		rect := image.Rect(level.WorldX, level.WorldY, level.WorldX+level.Width, level.WorldY+level.Height)
		if rect.Min.X <= x && rect.Min.Y <= y && rect.Max.X >= x && rect.Max.Y >= y {
			return level
		}
	}
	return nil
}
LevelAt returns the level that "contains" the point indicated by the X and Y values given, or nil if one isn't found.
package ldtkgo
import (
	"encoding/json"
	"errors"
	"image"
	"image/color"
	"io/ioutil"
	"path/filepath"
	"strconv"
	"github.com/tidwall/gjson"
)
const (
	LayerTypeIntGrid  = "IntGrid"
	LayerTypeAutoTile = "AutoLayer"
	LayerTypeTile     = "Tiles"
	LayerTypeEntity   = "Entities"
)
const (
	WorldLayoutHorizontal = "LinearHorizontal"
	WorldLayoutVertical   = "LinearVertical"
	WorldLayoutFree       = "Free"
	WorldLayoutGridVania  = "GridVania"
)
type Property struct {
	Identifier string      `json:"__identifier"`
	Type       string      `json:"__type"`   
	Value      interface{} `json:"__value"`  
}
func (p *Property) AsInt() int {
	return int(p.AsFloat64())
}
func (p *Property) AsFloat64() float64 {
	return p.Value.(float64)
}
func (p *Property) AsString() string {
	return p.Value.(string)
}
func (p *Property) AsBool() bool {
	return p.Value.(bool)
}
func (p *Property) AsArray() []interface{} {
	return p.Value.([]interface{})
}
func (p *Property) AsMap() map[string]interface{} {
	return p.Value.(map[string]interface{})
}
func (p *Property) IsNull() bool {
	return p.Value == nil
}
func (p *Property) AsColor() color.Color {
	color, _ := parseHexColorFast(p.AsString())
	return color
}
type Entity struct {
	Identifier string      `json:"__identifier"`    
	Position   []int       `json:"px"`              
	Width      int         `json:"width"`           
	Height     int         `json:"height"`          
	Properties []*Property `json:"fieldInstances"`  
	Pivot      []float32   `json:"__pivot"`         
}
func (entity *Entity) PropertyByIdentifier(id string) *Property {
	for _, p := range entity.Properties {
		if p.Identifier == id {
			return p
		}
	}
	return nil
}
type Integer struct {
	Position []int `json:"-"`        
	Value    int   `json:"v"`        
	ID       int   `json:"coordID"`  
}
type EnumSet []string
func (e EnumSet) Contains(enum string) bool {
	for _, v := range e {
		if v == enum {
			return true
		}
	}
	return false
}
type Tile struct {
	Position []int `json:"px"`  
	Src      []int  
	Flip     byte  `json:"f"`  
	ID       int   `json:"t"`  
}
func (t *Tile) FlipX() bool {
	return t.Flip&1 > 0
}
func (t *Tile) FlipY() bool {
	return t.Flip&2 > 0
}
type Layer struct {
	Identifier string   `json:"__identifier"`      
	GridSize   int      `json:"__gridsize"`        
	OffsetX    int      `json:"__pxTotalOffsetX"`  
	OffsetY    int      `json:"__pxTotalOffsetY"`
	CellWidth  int      `json:"__cWid"`  
	CellHeight int      `json:"__cHei"`  
	Type       string   `json:"__type"`  
	Tileset    *Tileset `json:"-"`       
	TilesetUID int        `json:"__tilesetDefUid"`  
	IntGrid    []*Integer `json:"-"`
	AutoTiles  []*Tile    `json:"autoLayerTiles"`  
	Tiles      []*Tile    `json:"gridTiles"`
	Entities   []*Entity  `json:"entityInstances"`
	Visible    bool       `json:"visible"`  
}
func (layer *Layer) AllTiles() []*Tile {
	return append(append([]*Tile{}, layer.Tiles...), layer.AutoTiles...)
}
func (layer *Layer) EntityByIdentifier(identifier string) *Entity {
	for _, entity := range layer.Entities {
		if entity.Identifier == identifier {
			return entity
		}
	}
	return nil
}
func (layer *Layer) ToGridPosition(x, y int) (int, int) {
	x /= layer.GridSize
	y /= layer.GridSize
	return x, y
}
func (layer *Layer) FromGridPosition(x, y int) (int, int) {
	x *= layer.GridSize
	y *= layer.GridSize
	return x, y
}
func (layer *Layer) TileAt(x, y int) *Tile {
	for _, tile := range layer.Tiles {
		cx, cy := layer.ToGridPosition(tile.Position[0], tile.Position[1])
		if cx == x && cy == y {
			return tile
		}
	}
	return nil
}
func (layer *Layer) AutoTileAt(x, y int) *Tile {
	for _, autoTile := range layer.AutoTiles {
		cx, cy := layer.ToGridPosition(autoTile.Position[0], autoTile.Position[1])
		if cx == x && cy == y {
			return autoTile
		}
	}
	return nil
}
func (layer *Layer) IntegerAt(x, y int) *Integer {
	for _, integer := range layer.IntGrid {
		cx, cy := layer.ToGridPosition(integer.Position[0], integer.Position[1])
		if cx == x && cy == y {
			return integer
		}
	}
	return nil
}
type Tileset struct {
	Path       string `json:"relPath"`  
	ID         int    `json:"uid"`
	GridSize   int    `json:"tileGridSize"`
	Spacing    int
	Padding    int
	Width      int `json:"pxWid"`
	Height     int `json:"pxHei"`
	Identifier string
	CustomData map[int]string  `json:"-"`  
	Enums      map[int]EnumSet `json:"-"`  
}
func (t *Tileset) CustomDataForTile(tileID int) string {
	if data, exists := t.CustomData[tileID]; exists {
		return data
	}
	return ""
}
func (t *Tileset) EnumsForTile(tileID int) EnumSet {
	if data, exists := t.Enums[tileID]; exists {
		return data
	}
	return EnumSet{}
}
type BGImage struct {
	Path     string
	ScaleX   float64
	ScaleY   float64
	CropRect []float64
}
type Level struct {
	BGImage       *BGImage `json:"-"`  
	WorldX        int       
	WorldY        int
	Width         int         `json:"pxWid"`  
	Height        int         `json:"pxHei"`
	Identifier    string       
	BGColorString string      `json:"__bgColor"`
	BGColor       color.Color `json:"-"`               
	Layers        []*Layer    `json:"layerInstances"`  
	Properties    []*Property `json:"fieldInstances"`  
}
func (level *Level) LayerByIdentifier(identifier string) *Layer {
	for _, layer := range level.Layers {
		if layer.Identifier == identifier {
			return layer
		}
	}
	return nil
}
func (level *Level) PropertyByIdentifier(id string) *Property {
	for _, p := range level.Properties {
		if p.Identifier == id {
			return p
		}
	}
	return nil
}
type Project struct {
	WorldLayout     string
	WorldGridWidth  int
	WorldGridHeight int
	BGColorString   string      `json:"defaultLevelBgColor"`
	BGColor         color.Color `json:"-"`
	JSONVersion     string
	Levels          []*Level
	Tilesets        []*Tileset
	IntGridNames    []string
}