From bc11ae4b42547ace656381fb0ed0b3604350fcb1 Mon Sep 17 00:00:00 2001 From: Physcik Date: Tue, 27 Jan 2026 18:37:27 +0500 Subject: Sprites layering --- engine/Components/Layering.go | 67 +++++++++++++++++++++++++++++++++ engine/Components/World.go | 33 ++++++++++++++++- engine/Components/World/Tile.go | 40 -------------------- engine/Components/World/World.go | 68 ---------------------------------- engine/CoreObjects/DynamicObject.go | 6 +++ engine/CoreObjects/GameObject.go | 1 + engine/Dynamic/Descriptors/Objects.go | 2 + engine/Render/initWindow.go | 10 ++++- packages/TestPackage/Objects/Barn.json | 1 + packages/TestPackage/Worlds/Main.json | 6 ++- 10 files changed, 122 insertions(+), 112 deletions(-) create mode 100644 engine/Components/Layering.go delete mode 100644 engine/Components/World/Tile.go delete mode 100644 engine/Components/World/World.go diff --git a/engine/Components/Layering.go b/engine/Components/Layering.go new file mode 100644 index 0000000..3e42b44 --- /dev/null +++ b/engine/Components/Layering.go @@ -0,0 +1,67 @@ +package components + +type LayeringElement interface { + Draw() + // returnt Y-index of the element + GetYIndex() float32 +} + +// Stores elements by their Y-layer ordered in decreasing order. +// Used to draw objects in the correct order on screen +type layering struct { + ObjectCount int + firstLayer *layer +} + +func (base *layering) Insert(new LayeringElement) { + base.ObjectCount += 1 + var y = new.GetYIndex() + var newLayer = layer { + Index: y, + Objects: []LayeringElement { new }, + } + if base.firstLayer == nil { + base.firstLayer = &newLayer + return + } + + // The first layer is greater than the current first layer + if base.firstLayer.Index > y { + newLayer.next = base.firstLayer + base.firstLayer = &newLayer + return + } + + var current = base.firstLayer + var next *layer + for { + if current == nil { + break + } + next = current.Next() + if current.Index == y { + current.Objects = append(current.Objects, new) + return + } + if y < current.Index && y > next.Index { + newLayer.next = next + current.next = &newLayer + return + } + if current.Next() == nil { + current.next = &newLayer + return + } + next = current + } +} + +type layer struct { + Index float32 + Objects []LayeringElement + next *layer +} + +func (base *layer) Next() *layer { + return base.next +} diff --git a/engine/Components/World.go b/engine/Components/World.go index 3f7a0d4..0c322ba 100644 --- a/engine/Components/World.go +++ b/engine/Components/World.go @@ -16,6 +16,8 @@ type World struct { Camera *rl.Camera2D + layersStatic layering + // ========== Cache ========== // the collection of the colliders that belong to static objects - world, buildings, etc @@ -25,6 +27,8 @@ type World struct { func (base *World) Create(manager coreobjects.SceneManager) { base.Manager = manager base.Player.Init(manager) + base.layersStatic = layering{} + base.generateStaticLayers() } func (base *World) Destroy() { @@ -64,10 +68,35 @@ func (base *World) Draw() { for _, v := range base.Floor { v.Draw() } + + var playerDrawn = false + var layer = base.layersStatic.firstLayer + var i = 0 + for { + if layer == nil { + break + } + if !playerDrawn && base.Player.Position.Y < layer.Index { + playerDrawn = true + // fmt.Printf("Player drawn at layer %d\n", i) + base.Player.Draw() + } + for _, v := range layer.Objects { + v.Draw() + } + layer = layer.Next() + i++ + } + // Ensure that the player was drawn + if !playerDrawn { + base.Player.Draw() + } +} + +func (base *World) generateStaticLayers() { for _, v := range base.StaticObjects { - v.Draw() + base.layersStatic.Insert(v) } - base.Player.Draw() } // The single texture drawn at level 0 of the world diff --git a/engine/Components/World/Tile.go b/engine/Components/World/Tile.go deleted file mode 100644 index a8ee827..0000000 --- a/engine/Components/World/Tile.go +++ /dev/null @@ -1,40 +0,0 @@ -// DEPRECATED -package world - -import ( - descriptors "github.com/DegustatorPonos/RuinesOfRafdolon/Dynamic/Descriptors" - rl "github.com/gen2brain/raylib-go/raylib" -) - -// The square that will be displayed at the screen -type Tile interface { - Update() - Draw() -} - -type StandardTile struct { - X float32 - Y float32 - ParentWorld *World - Descriptor descriptors.TileDescriptor -} - -func (base *StandardTile) Update() { -} - -func (base *StandardTile) Draw() { - rl.DrawTexture(base.ParentWorld.Textures[base.Descriptor.TextureId], - int32(base.X) * int32(base.ParentWorld.TileSize.X), - int32(base.Y) * int32(base.ParentWorld.TileSize.Y), - rl.White) - if base.Descriptor.OveralyTextureId != 0 { - var overlayTexture = base.ParentWorld.Textures[base.Descriptor.OveralyTextureId] - var dx = (base.ParentWorld.TileSize.X - float32(overlayTexture.Width)) / 2 - var dy = (float32(overlayTexture.Height) - base.ParentWorld.TileSize.Y) - - rl.DrawTexture(overlayTexture, - int32(base.X) * int32(base.ParentWorld.TileSize.X) + int32(dx), - int32(base.Y) * int32(base.ParentWorld.TileSize.Y) - int32(dy), - rl.White) - } -} diff --git a/engine/Components/World/World.go b/engine/Components/World/World.go deleted file mode 100644 index 8809409..0000000 --- a/engine/Components/World/World.go +++ /dev/null @@ -1,68 +0,0 @@ -// DEPRECATED -package world - -import ( - coreobjects "github.com/DegustatorPonos/RuinesOfRafdolon/CoreObjects" - rl "github.com/gen2brain/raylib-go/raylib" -) - -var Texture rl.Texture2D - -// The scene full of tiles -type World struct { - Name string `json:"name"` - TileSize rl.Vector2 `json:"tilesize"` - TextureNames map[int]string `json:"textures"` - Textures map[int]rl.Texture2D `json:"-"` - Tiles [][]Tile `json:"tiles"` - Camera rl.Camera2D `json:"-"` -} - -func (base *World) IsValid() error { - return nil -} - -func (base *World) Create(_ coreobjects.SceneManager) { - base.Textures = map[int]rl.Texture2D{} - for k, v := range base.TextureNames { - var image = rl.LoadImage(v) - base.Textures[k] = rl.LoadTextureFromImage(image) - rl.UnloadImage(image) - } - - base.Camera = rl.Camera2D{} - base.Camera.Target = rl.Vector2 { X: 0, Y: 0 } - base.Camera.Offset = rl.Vector2 { X: 0, Y: 0 } - base.Camera.Rotation = 0 - base.Camera.Zoom = 2 -} - -func (base *World) Destroy() { - rl.UnloadTexture(Texture) -} - -func (base *World) Update() { - if rl.IsKeyDown(rl.KeyW) { - base.Camera.Target.Y -= 0.3 - } - if rl.IsKeyDown(rl.KeyS) { - base.Camera.Target.Y += 0.3 - } - if rl.IsKeyDown(rl.KeyA) { - base.Camera.Target.X -= 0.3 - } - if rl.IsKeyDown(rl.KeyD) { - base.Camera.Target.X += 0.3 - } -} - -func (base *World) Draw() { - rl.BeginMode2D(base.Camera) - defer rl.EndMode2D() - - for _, r := range base.Tiles { - for _, v := range r { - v.Draw() - } - } -} diff --git a/engine/CoreObjects/DynamicObject.go b/engine/CoreObjects/DynamicObject.go index 0462ebb..cf1378f 100644 --- a/engine/CoreObjects/DynamicObject.go +++ b/engine/CoreObjects/DynamicObject.go @@ -5,6 +5,7 @@ import rl "github.com/gen2brain/raylib-go/raylib" // An object loaded from the package. Impmiments GameObject interface type DynamicObject struct { Position rl.Vector2 + YLevelOffset float32 Textures []*TextureBlock Colliders []*ColliderBlock } @@ -51,6 +52,7 @@ func (base *DynamicObject) MoveTo(x float32, y float32) { func (base *DynamicObject) Clone() *DynamicObject { var outp = DynamicObject { + YLevelOffset: base.YLevelOffset, Position: base.Position, Textures: base.Textures, Colliders: base.cloneColliders(), @@ -77,3 +79,7 @@ func (base *DynamicObject) GetColliders() []Collider { } return outp } + +func (base *DynamicObject) GetYIndex() float32 { + return base.Position.Y + base.YLevelOffset +} diff --git a/engine/CoreObjects/GameObject.go b/engine/CoreObjects/GameObject.go index 087e1e9..186da1f 100644 --- a/engine/CoreObjects/GameObject.go +++ b/engine/CoreObjects/GameObject.go @@ -6,4 +6,5 @@ type GameObject interface { Update() Draw() GetColliders() []Collider + GetYIndex() float32 } diff --git a/engine/Dynamic/Descriptors/Objects.go b/engine/Dynamic/Descriptors/Objects.go index fa67889..4dbee34 100644 --- a/engine/Dynamic/Descriptors/Objects.go +++ b/engine/Dynamic/Descriptors/Objects.go @@ -14,6 +14,7 @@ const ObjectsDirName string = "Objects" type ObjectDescriptor struct { Name string + YLevelOffset float64 Textures []*ObjectTextureBlock Colliders []*ObjectColliderBlock } @@ -74,6 +75,7 @@ func (base *ObjectDescriptor) parseColliders() []*coreobjects.ColliderBlock { func (base *ObjectDescriptor) Parse() coreobjects.DynamicObject { return coreobjects.DynamicObject { + YLevelOffset: float32(base.YLevelOffset), Textures: base.parseTextures(), Colliders: base.parseColliders(), } diff --git a/engine/Render/initWindow.go b/engine/Render/initWindow.go index 9142493..4b3dc59 100644 --- a/engine/Render/initWindow.go +++ b/engine/Render/initWindow.go @@ -1,14 +1,22 @@ package render import ( + "fmt" + coreobjects "github.com/DegustatorPonos/RuinesOfRafdolon/CoreObjects" + settings "github.com/DegustatorPonos/RuinesOfRafdolon/Settings" rl "github.com/gen2brain/raylib-go/raylib" ) func InitWindow() { rl.SetConfigFlags(rl.FlagWindowResizable) - rl.InitWindow(800, 450, "xdx") + var titleString = fmt.Sprintf("Ruines of Rafdolon v.%d.%d.%d", + settings.Current.Version.MajorVersion, + settings.Current.Version.MinorVersion, + settings.Current.Version.Patch) + + rl.InitWindow(800, 450, titleString) } func StartLoop(manager coreobjects.SceneManager, startScene coreobjects.Scene) { diff --git a/packages/TestPackage/Objects/Barn.json b/packages/TestPackage/Objects/Barn.json index 8bb6ae6..7dd05a7 100644 --- a/packages/TestPackage/Objects/Barn.json +++ b/packages/TestPackage/Objects/Barn.json @@ -1,5 +1,6 @@ { "Name": "barn", + "YLevelOffset": 76, "Textures": [ { "Name": "testPackage/barn_v1.png", diff --git a/packages/TestPackage/Worlds/Main.json b/packages/TestPackage/Worlds/Main.json index 8e264a1..84c8957 100644 --- a/packages/TestPackage/Worlds/Main.json +++ b/packages/TestPackage/Worlds/Main.json @@ -10,7 +10,11 @@ "StaticObjects": [ { "Object": "testPackage/barn", - "Position": { "X": 0, "Y": 0 } + "Position": { "X": 256, "Y": 128 } + }, + { + "Object": "testPackage/barn", + "Position": { "X": 256, "Y": 0 } } ] } -- cgit v1.3