summaryrefslogtreecommitdiff
path: root/engine
diff options
context:
space:
mode:
authorPhyscik <mynameisgennadiy@vk.com>2026-01-29 21:48:23 +0500
committerPhyscik <mynameisgennadiy@vk.com>2026-01-29 21:48:23 +0500
commit45b7d0ce612921729d925a7111e4d1aeba3ef849 (patch)
treee8abfd366e046c9b7205cb5452dcd0615dc75c08 /engine
parent9c10e3ab194115f50f0d67044ef34d386be7fa9a (diff)
GUI layout init
Diffstat (limited to 'engine')
-rw-r--r--engine/Components/Player.go4
-rw-r--r--engine/Components/World.go4
-rw-r--r--engine/CoreObjects/DynamicObject.go2
-rw-r--r--engine/CoreObjects/GameObject.go2
-rw-r--r--engine/CoreObjects/OverlayScene.go2
-rw-r--r--engine/CoreObjects/Scene.go4
-rw-r--r--engine/Render/initWindow.go2
-rw-r--r--engine/UI/Label.go21
-rw-r--r--engine/UI/Menu.go165
-rw-r--r--engine/UI/UIElement.go11
-rw-r--r--engine/main.go34
11 files changed, 240 insertions, 11 deletions
diff --git a/engine/Components/Player.go b/engine/Components/Player.go
index fe8c5ef..ba92a16 100644
--- a/engine/Components/Player.go
+++ b/engine/Components/Player.go
@@ -22,7 +22,7 @@ type Player struct {
Collider coreobjects.Collider
}
-func (base *Player) Init(manager coreobjects.SceneManager) {
+func (base *Player) Init(manager *coreobjects.SceneManager) {
if err := base.setParentScene(manager); err != nil {
panic(err.Error())
}
@@ -34,7 +34,7 @@ func (base *Player) Init(manager coreobjects.SceneManager) {
}
// Tries to set a parent scene as a world and returns an error if failed
-func (base *Player) setParentScene(manager coreobjects.SceneManager) error {
+func (base *Player) setParentScene(manager *coreobjects.SceneManager) error {
var baseScene, ok = manager.SelectedScene.(*World)
if !ok {
return fmt.Errorf( "Failed to create a player instance: the base scene is not a playable world (assertion failed)")
diff --git a/engine/Components/World.go b/engine/Components/World.go
index 26c1a83..c7a96df 100644
--- a/engine/Components/World.go
+++ b/engine/Components/World.go
@@ -7,7 +7,7 @@ import (
// The scene implimetation that represents one playable scene
type World struct {
- Manager coreobjects.SceneManager
+ Manager *coreobjects.SceneManager
Name string
Floor []FloorTile
StaticObjects []coreobjects.GameObject
@@ -24,7 +24,7 @@ type World struct {
staticColliders []*coreobjects.Collider
}
-func (base *World) Create(manager coreobjects.SceneManager) {
+func (base *World) Create(manager *coreobjects.SceneManager) {
base.Manager = manager
base.Player.Init(manager)
for _, v := range base.StaticObjects {
diff --git a/engine/CoreObjects/DynamicObject.go b/engine/CoreObjects/DynamicObject.go
index 36614d6..0a10f0a 100644
--- a/engine/CoreObjects/DynamicObject.go
+++ b/engine/CoreObjects/DynamicObject.go
@@ -42,7 +42,7 @@ type ColliderBlock struct {
Offset rl.Vector2
}
-func (base *DynamicObject) Init(manager SceneManager) {
+func (base *DynamicObject) Init(manager *SceneManager) {
if manager.SelectedScene == nil {
panic("Failed to initialize a dynamic object: the scene was not selected")
}
diff --git a/engine/CoreObjects/GameObject.go b/engine/CoreObjects/GameObject.go
index 9ff1b87..fb7d243 100644
--- a/engine/CoreObjects/GameObject.go
+++ b/engine/CoreObjects/GameObject.go
@@ -1,7 +1,7 @@
package coreobjects
type GameObject interface {
- Init(SceneManager)
+ Init(*SceneManager)
Destroy()
Update()
Draw()
diff --git a/engine/CoreObjects/OverlayScene.go b/engine/CoreObjects/OverlayScene.go
index 3c79b78..73aa987 100644
--- a/engine/CoreObjects/OverlayScene.go
+++ b/engine/CoreObjects/OverlayScene.go
@@ -11,7 +11,7 @@ type OveralyScene struct {
FPS FpsMeter
}
-func (base *OveralyScene) Create(_ SceneManager) {
+func (base *OveralyScene) Create(_ *SceneManager) {
}
func (base *OveralyScene) Destroy() {
diff --git a/engine/CoreObjects/Scene.go b/engine/CoreObjects/Scene.go
index a945bec..594778f 100644
--- a/engine/CoreObjects/Scene.go
+++ b/engine/CoreObjects/Scene.go
@@ -8,7 +8,7 @@ type SceneManager struct {
}
type Scene interface {
- Create(SceneManager)
+ Create(*SceneManager)
Destroy()
Update()
Draw()
@@ -27,7 +27,7 @@ func (base *SceneManager) ChangeScene(newScene Scene) {
base.SelectedScene.Destroy()
}
base.SelectedScene = newScene
- base.SelectedScene.Create(*base)
+ base.SelectedScene.Create(base)
}
func (base *SceneManager) Update() {
diff --git a/engine/Render/initWindow.go b/engine/Render/initWindow.go
index 4b3dc59..e131b99 100644
--- a/engine/Render/initWindow.go
+++ b/engine/Render/initWindow.go
@@ -22,7 +22,7 @@ func InitWindow() {
func StartLoop(manager coreobjects.SceneManager, startScene coreobjects.Scene) {
manager.ChangeScene(startScene)
- rl.SetTargetFPS(60)
+ // rl.SetTargetFPS(60)
for !rl.WindowShouldClose() {
manager.Update()
diff --git a/engine/UI/Label.go b/engine/UI/Label.go
new file mode 100644
index 0000000..f0a3c97
--- /dev/null
+++ b/engine/UI/Label.go
@@ -0,0 +1,21 @@
+package ui
+
+import rl "github.com/gen2brain/raylib-go/raylib"
+
+type Label struct {
+ Text string
+}
+
+func (base *Label) Init(Menu) {
+}
+
+func (base *Label) Destroy() {
+}
+
+func (base *Label) Update() {
+}
+
+func (base *Label) Draw(position *rl.Rectangle) {
+ // rl.TraceLog(rl.LogInfo, "Drawn at %v/%v/%v/%v", position.X, position.Y, position.Width, position.Height)
+ rl.DrawRectangleRec(*position, rl.Green)
+}
diff --git a/engine/UI/Menu.go b/engine/UI/Menu.go
new file mode 100644
index 0000000..c376839
--- /dev/null
+++ b/engine/UI/Menu.go
@@ -0,0 +1,165 @@
+package ui
+
+import (
+ coreobjects "github.com/DegustatorPonos/RuinesOfRafdolon/CoreObjects"
+ settings "github.com/DegustatorPonos/RuinesOfRafdolon/Settings"
+ rl "github.com/gen2brain/raylib-go/raylib"
+)
+
+// Scene implimetation that contains aligned UI elements
+type Menu struct {
+ manager *coreobjects.SceneManager
+ // The space between the window border and the grid. Measured in fractions of a screen. [0; 1]
+ PaddingX float32
+ // The space between the window border and the grid. Measured in fractions of a screen. [0; 1]
+ PaddingY float32
+ // Spaces between the rows
+ Spacing float32
+ // A horizontal line of elements
+ Rows []*GridRow
+
+ cache *layoutCache
+}
+
+// The pixel scalin
+type layoutCache struct {
+ // The resolution the cache was calculated for
+ ScreenResolution rl.Vector2
+ // Horizontal offset in pixels
+ OffsetX float32
+ // Vertical offset in pixels
+ OffsetY float32
+ // The Y size of a row
+ Width float32
+ // The horizontal start and end of each row.
+ // Index of an array is representive with row index
+ RowLocations []rl.Vector2
+}
+
+func (base *layoutCache) CalculateOffsets(paddingX float32, paddingY float32) {
+ base.OffsetX = (base.ScreenResolution.X * paddingX)
+ base.OffsetY = (base.ScreenResolution.Y * paddingY)
+ base.Width = base.ScreenResolution.X - base.OffsetX * 2
+}
+
+func (base *layoutCache) CalculateRowsLocations (rows []*GridRow, WeightToPixels float32, spacing float32) {
+ var spacingPixels = (base.ScreenResolution.Y * spacing)
+ base.RowLocations = make([]rl.Vector2, len(rows))
+ var y float32 = base.OffsetY
+ for i, v := range rows {
+ var rowHeight = (WeightToPixels * v.HeightWeight)
+ base.RowLocations[i] = rl.Vector2 {
+ X: y,
+ Y: rowHeight,
+ }
+ y += rowHeight + spacingPixels
+ }
+}
+
+func (base *Menu) Create(manager *coreobjects.SceneManager) {
+ base.manager = manager
+ base.cache = &layoutCache{}
+ base.generateLayout()
+}
+
+func (base *Menu) Destroy() {
+}
+
+func (base *Menu) Update() {
+}
+
+func (base *Menu) Draw() {
+ rl.ClearBackground(rl.Black)
+ base.generateLayout()
+ if settings.State.DrawColliders {
+ base.drawPaddings()
+ }
+
+ for i, v := range base.Rows {
+ var verticalSpacing = base.cache.RowLocations[i]
+ v.Draw(rl.Rectangle{
+ X: base.cache.OffsetX,
+ Y: verticalSpacing.X,
+ Width: base.cache.Width,
+ Height: verticalSpacing.Y,
+ })
+ }
+}
+
+func (base *Menu) drawPaddings() {
+ // Horizontal
+ rl.DrawRectangle(0, 0,
+ int32(base.cache.ScreenResolution.X),
+ int32(base.cache.OffsetY),
+ rl.Red)
+ rl.DrawRectangle(0,
+ int32(base.cache.ScreenResolution.Y) - int32(base.cache.OffsetY),
+ int32(base.cache.ScreenResolution.X),
+ int32(base.cache.OffsetY),
+ rl.Red)
+ // Vertical
+ rl.DrawRectangle(0,
+ int32(base.cache.OffsetY),
+ int32(base.cache.OffsetX),
+ int32(base.cache.ScreenResolution.Y - base.cache.OffsetY * 2),
+ rl.Blue)
+ rl.DrawRectangle(
+ int32(base.cache.ScreenResolution.X - base.cache.OffsetX),
+ int32(base.cache.OffsetY),
+ int32(base.cache.OffsetX),
+ int32(base.cache.ScreenResolution.Y - base.cache.OffsetY * 2),
+ rl.Blue)
+}
+
+// Generates all the offsets and scales for the rendering
+func (base *Menu) generateLayout() {
+ if rl.GetScreenWidth() == int(base.cache.ScreenResolution.X) &&
+ rl.GetScreenHeight() == int(base.cache.ScreenResolution.Y) {
+ return
+ }
+
+ base.cache.ScreenResolution = rl.Vector2{
+ X: float32(rl.GetScreenWidth()),
+ Y: float32(rl.GetScreenHeight()),
+ }
+ base.cache.CalculateOffsets(base.PaddingX, base.PaddingY)
+ var weightToScale = base.getWeightToPixelRatio()
+ base.cache.CalculateRowsLocations(base.Rows, weightToScale, base.Spacing)
+}
+
+// Sums up all the weights
+func (base *Menu) getWeightToPixelRatio() float32 {
+ var rowsAmount = len(base.Rows)
+ var sum float32 = 0
+ for _, v := range base.Rows {
+ sum += v.HeightWeight
+ }
+ var spacingPixels = base.cache.ScreenResolution.Y * base.Spacing
+ var spacing = float32(rowsAmount - 1) * spacingPixels
+ if spacing < 0 {
+ spacing = 0
+ }
+ return (base.cache.ScreenResolution.Y - 2 * base.cache.OffsetY - spacing) / sum
+}
+
+func (base *Menu) GetMousePosition() rl.Vector2 {
+ return rl.GetMousePosition()
+}
+
+type GridRow struct {
+ // A portion of the screen the row will occupy
+ HeightWeight float32
+ // The objects that lay in this row
+ Objects []UIElement
+
+ location rl.Rectangle
+}
+
+func (base *GridRow) Draw(span rl.Rectangle) {
+ // TODO: Add horizontal spacing
+ for _, v := range base.Objects {
+ v.Draw(&span)
+ }
+}
+
+
diff --git a/engine/UI/UIElement.go b/engine/UI/UIElement.go
new file mode 100644
index 0000000..86475f7
--- /dev/null
+++ b/engine/UI/UIElement.go
@@ -0,0 +1,11 @@
+package ui
+
+import rl "github.com/gen2brain/raylib-go/raylib"
+
+type UIElement interface {
+ Init(Menu)
+ Destroy()
+ Update()
+ // Draw the element with the given size
+ Draw(*rl.Rectangle)
+}
diff --git a/engine/main.go b/engine/main.go
index b1a2be1..50e0326 100644
--- a/engine/main.go
+++ b/engine/main.go
@@ -8,6 +8,7 @@ import (
dynamic "github.com/DegustatorPonos/RuinesOfRafdolon/Dynamic"
render "github.com/DegustatorPonos/RuinesOfRafdolon/Render"
settings "github.com/DegustatorPonos/RuinesOfRafdolon/Settings"
+ ui "github.com/DegustatorPonos/RuinesOfRafdolon/UI"
)
func main() {
@@ -28,6 +29,37 @@ func main() {
// var field = descriptor.GenerateMap()
+
var manager = coreobjects.InitSceneManager()
- render.StartLoop(manager, components.Resources.Worlds["MainWorld"])
+ // render.StartLoop(manager, components.Resources.Worlds["MainWorld"])
+ var menu = menu_test()
+ render.StartLoop(manager, menu)
+}
+
+func menu_test() *ui.Menu {
+ return &ui.Menu{
+ PaddingX: 0.05,
+ PaddingY: 0.1,
+ Spacing: 0.025,
+ Rows: []*ui.GridRow {
+ {
+ HeightWeight: 1,
+ Objects: []ui.UIElement {
+ &ui.Label{ Text: "Ruines of Rafdolon" },
+ },
+ },
+ {
+ HeightWeight: 1,
+ Objects: []ui.UIElement {
+ &ui.Label{ Text: "Ruines of Rafdolon" },
+ },
+ },
+ {
+ HeightWeight: 1,
+ Objects: []ui.UIElement {
+ &ui.Label{ Text: "Test text" },
+ },
+ },
+ },
+ }
}