Add new map and tileset files for Windows release

- Created test.tmj and test.tsj files in the maps directory.
- Added tileset.tsj with configuration for the MainTileset including image path and dimensions.
This commit is contained in:
2026-04-26 02:35:31 +02:00
parent 93abb31ba7
commit 16ae22bcba
255 changed files with 401031 additions and 237 deletions

View File

@@ -3,9 +3,11 @@ package entities
import (
"encoding/json"
"fmt"
"log"
"os"
"github.com/go-gl/mathgl/mgl64"
"github.com/hajimehoshi/ebiten/v2"
"github.com/hajimehoshi/ebiten/v2/ebitenutil"
)
@@ -49,7 +51,7 @@ func (w *World) SetEntityAt(x, y, z int, e Entity) {
// Convert absolute 3D position to Grid index
func ToGridIndex(pos mgl64.Vec3) (int, int, int) {
return int(pos[0]/TileSize), int(pos[1]/TileSize), int(pos[2]/TileSize)
return int(pos[0] / TileSize), int(pos[1] / TileSize), int(pos[2] / TileSize)
}
type TiledLayer struct {
@@ -70,41 +72,103 @@ type Portal struct {
pos mgl64.Vec3
TargetMap string
}
func (p *Portal) Pos() mgl64.Vec3 { return p.pos }
func (p *Portal) SetPos(pos mgl64.Vec3) { p.pos = pos }
func (p *Portal) IsBlocking() bool { return false }
func (p *Portal) IsMovable() bool { return false }
func (p *Portal) Move(dx, dy, dz float64) {}
func (p *Portal) Damage(amount int) {}
func (p *Portal) Pickup() bool { return false }
func (p *Portal) GetHealth() int { return 100 }
func (p *Portal) DrawSide(screen interface{}, x, y float64) {}
func (p *Portal) DrawTop(screen interface{}, x, y float64) {}
func (p *Portal) Pos() mgl64.Vec3 { return p.pos }
func (p *Portal) SetPos(pos mgl64.Vec3) { p.pos = pos }
func (p *Portal) IsBlocking() bool { return false }
func (p *Portal) IsMovable() bool { return false }
func (p *Portal) Move(dx, dy, dz float64) {}
func (p *Portal) Damage(amount int) {}
func (p *Portal) Pickup() bool { return false }
func (p *Portal) GetHealth() int { return 100 }
func (p *Portal) DrawSide(screen interface{}, x, y float64, tint, alpha float32) {}
func (p *Portal) DrawTop(screen interface{}, x, y float64, tint, alpha float32) {}
// EntityDef definierar egenskaperna för ett tile-id
type EntityDef struct {
ID int `json:"id"`
TiledID int `json:"tiled_id"`
Solid bool `json:"solid"`
TargetMap string `json:"target_map,omitempty"`
Sprites struct {
Top string `json:"top"`
Side string `json:"side"`
} `json:"sprites"`
}
type EntityDefs struct {
EntityTypes map[string]EntityDef `json:"entity_types"`
}
var loadedDefs *EntityDefs
var loadedImages map[string]*ebiten.Image
// Ladda en värld från Tiled Export (.tmj)
func LoadWorldFromTiled(tmjPath string) (*World, error) {
log.Printf("Laddar värld från '%s'...", tmjPath)
if loadedDefs == nil {
defsData, err := os.ReadFile("assets/entity_defs.json")
if err == nil {
var defs EntityDefs
json.Unmarshal(defsData, &defs)
loadedDefs = &defs
log.Printf("Laddade %d st entity definitions från JSON.", len(defs.EntityTypes))
} else {
log.Printf("Varning: Kunde inte läsa entity_defs.json: %v", err)
}
}
fileData, err := os.ReadFile(tmjPath)
if err != nil {
log.Printf("Kunde inte läsa map %s: %v", tmjPath, err)
return nil, fmt.Errorf("kunde inte lasa map %s: %v", tmjPath, err)
}
var tMap TiledMap
if err := json.Unmarshal(fileData, &tMap); err != nil {
log.Printf("Kunde inte parsa JSON i %s: %v", tmjPath, err)
return nil, err
}
log.Printf("Map parsead med %d lager.", len(tMap.Layers))
w := NewWorld(tMap.Width, 10, tMap.Height) // 10 i djup(height y), tileHeight z = height i Json
tile12, _, _ := ebitenutil.NewImageFromFile("assets/images/1 Tiles/Tile_12.png")
tile02, _, _ := ebitenutil.NewImageFromFile("assets/images/1 Tiles/Tile_02.png")
tile31, _, _ := ebitenutil.NewImageFromFile("assets/images/1 Tiles/Tile_31.png")
// Preload images (simple abstraction)
loadImage := func(name string) *ebiten.Image {
if loadedImages == nil {
loadedImages = make(map[string]*ebiten.Image)
}
if img, ok := loadedImages[name]; ok {
return img
}
img, _, err := ebitenutil.NewImageFromFile("assets/images/1 Tiles/" + name + ".png")
if err != nil {
fmt.Println("Warning, missing image:", name)
}
loadedImages[name] = img
return img
}
// Mappa ID till Def
idToDef := make(map[int]EntityDef)
if loadedDefs != nil {
for _, def := range loadedDefs.EntityTypes {
idToDef[def.TiledID] = def
}
}
tile12 := loadImage("Tile_12")
tile02 := loadImage("Tile_02")
tile31 := loadImage("Tile_31")
for _, layer := range tMap.Layers {
if layer.Type != "tilelayer" {
continue
}
var yLevel int
addedTiles := 0
fmt.Sscanf(layer.Name, "Y%d", &yLevel)
if yLevel < 0 || yLevel >= 10 {
continue
@@ -114,23 +178,36 @@ func LoadWorldFromTiled(tmjPath string) (*World, error) {
if tileID == 0 {
continue
}
addedTiles++
x := i % layer.Width
z := i / layer.Width
var ent Entity
if tileID == 3 { // Portal ID
target := "room2"
if tmjPath == "mapp-maker/room2.tmj" {
target = "room1"
}
ent = &Portal{ TargetMap: target }
} else {
// Mark
if yLevel < 9 {
ent = &Tile{ SideImg: tile12, TopImg: tile12 }
def, ok := idToDef[tileID]
if ok {
topImg := loadImage(def.Sprites.Top) // Om vi har generiska namn
sideImg := loadImage(def.Sprites.Side)
if def.TargetMap != "" {
ent = &Portal{TargetMap: def.TargetMap}
} else {
ent = &Tile{ SideImg: tile02, TopImg: tile31 }
ent = &Tile{SideImg: sideImg, TopImg: topImg}
}
} else {
// Fallback om def saknas
if tileID == 3 { // Portal ID
target := "room2"
if tmjPath == "assets/maps/room2.tmj" {
target = "room1"
}
ent = &Portal{TargetMap: target}
} else {
if yLevel < 9 {
ent = &Tile{SideImg: tile12, TopImg: tile12}
} else {
ent = &Tile{SideImg: tile02, TopImg: tile31}
}
}
}
@@ -139,148 +216,4 @@ func LoadWorldFromTiled(tmjPath string) (*World, error) {
}
return w, nil
}package entities
import (
"encoding/json"
"fmt"
"log"
"os"
"github.com/go-gl/mathgl/mgl64"
"github.com/hajimehoshi/ebiten/v2"
"github.com/hajimehoshi/ebiten/v2/ebitenutil"
)
const (
TileSize = 32.0 // Varje block ar 32x32 world units
)
type World struct {
Width, Height, Depth int
Grid [][][]Entity
PortalTrigger string // Håller reda på om vi ska byta rum
}
func NewWorld(w, h, d int) *World {
grid := make([][][]Entity, w)
for x := 0; x < w; x++ {
grid[x] = make([][]Entity, h)
for y := 0; y < h; y++ {
grid[x][y] = make([]Entity, d)
}
}
return &World{Width: w, Height: h, Depth: d, Grid: grid, PortalTrigger: ""}
}
func (w *World) GetEntityAt(x, y, z int) Entity {
if x < 0 || x >= w.Width || y < 0 || y >= w.Height || z < 0 || z >= w.Depth {
return nil
}
return w.Grid[x][y][z]
}
func (w *World) SetEntityAt(x, y, z int, e Entity) {
if x < 0 || x >= w.Width || y < 0 || y >= w.Height || z < 0 || z >= w.Depth {
return
}
w.Grid[x][y][z] = e
if e != nil {
e.SetPos(mgl64.Vec3{float64(x), float64(y), float64(z)})
}
}
// Convert absolute 3D position to Grid index
func ToGridIndex(pos mgl64.Vec3) (int, int, int) {
return int(pos[0]), int(pos[1]), int(pos[2])
}
type TiledLayer struct {
Data []int `json:"data"`
Height int `json:"height"`
Name string `json:"name"`
Width int `json:"width"`
Type string `json:"type"`
}
type TiledMap struct {
Height int `json:"height"`
Width int `json:"width"`
Layers []TiledLayer `json:"layers"`
}
type Portal struct {
pos mgl64.Vec3
TargetMap string
}
func (p *Portal) Pos() mgl64.Vec3 { return p.pos }
func (p *Portal) SetPos(pos mgl64.Vec3) { p.pos = pos }
func (p *Portal) IsBlocking() bool { return false }
func (p *Portal) IsMovable() bool { return false }
func (p *Portal) Move(dx, dy, dz float64) {}
func (p *Portal) Damage(amount int) {}
func (p *Portal) Pickup() bool { return false }
func (p *Portal) GetHealth() int { return 100 }
func (p *Portal) DrawSide(screen interface{}, x, y float64) {}
func (p *Portal) DrawTop(screen interface{}, x, y float64) {}
// Ladda en värld från Tiled Export (.tmj)
func LoadWorldFromTiled(tmjPath string) (*World, error) {
fileData, err := os.ReadFile(tmjPath)
if err != nil {
return nil, fmt.Errorf("kunde inte lasa map %s: %v", tmjPath, err)
}
var tMap TiledMap
if err := json.Unmarshal(fileData, &tMap); err != nil {
return nil, err
}
w := NewWorld(tMap.Width, 10, tMap.Height) // 10 i djup(height y), tileHeight z = height i Json
tile12, _, _ := ebitenutil.NewImageFromFile("assets/images/1 Tiles/Tile_12.png")
tile02, _, _ := ebitenutil.NewImageFromFile("assets/images/1 Tiles/Tile_02.png")
tile31, _, _ := ebitenutil.NewImageFromFile("assets/images/1 Tiles/Tile_31.png")
for _, layer := range tMap.Layers {
if layer.Type != "tilelayer" {
continue
}
var yLevel int
fmt.Sscanf(layer.Name, "Y%d", &yLevel)
if yLevel < 0 || yLevel >= 10 {
continue
}
for i, tileID := range layer.Data {
if tileID == 0 {
continue
}
x := i % layer.Width
z := i / layer.Width
var ent Entity
if tileID == 3 { // Portal ID
log.Println("Hittade portal vid", x, yLevel, z)
target := "room2"
if tmjPath == "mapp-maker/room2.tmj" {
target = "room1"
}
ent = &Portal{ TargetMap: target }
} else {
// Mark
if yLevel < 9 {
ent = &Tile{ SideImg: tile12, TopImg: tile12 }
} else {
ent = &Tile{ SideImg: tile02, TopImg: tile31 }
}
}
w.SetEntityAt(x, yLevel, z, ent)
}
}
return w, nil
}