diff options
Diffstat (limited to 'engine')
| -rw-r--r-- | engine/Components/Player.go | 62 | ||||
| -rw-r--r-- | engine/Components/World.go | 18 | ||||
| -rw-r--r-- | engine/CoreObjects/Collider.go | 85 | ||||
| -rw-r--r-- | engine/CoreObjects/Direction.go | 10 | ||||
| -rw-r--r-- | engine/Dynamic/Descriptors/World.go | 5 | ||||
| -rw-r--r-- | engine/Packages/TestPackage/Worlds/Main.json | 3 | ||||
| -rw-r--r-- | engine/Render/initWindow.go | 2 | ||||
| -rw-r--r-- | engine/Settings/State.go | 10 |
8 files changed, 182 insertions, 13 deletions
diff --git a/engine/Components/Player.go b/engine/Components/Player.go index 38a4636..cb8d459 100644 --- a/engine/Components/Player.go +++ b/engine/Components/Player.go @@ -1,50 +1,90 @@ package components import ( + "fmt" + coreobjects "github.com/DegustatorPonos/RuinesOfRafdolon/CoreObjects" + settings "github.com/DegustatorPonos/RuinesOfRafdolon/Settings" rl "github.com/gen2brain/raylib-go/raylib" ) type Player struct { + ParentScene *World Position rl.Vector2 + FaceDirection coreobjects.Direction Texture rl.Texture2D + + Collider coreobjects.Collider +} + +func (base *Player) Init(manager coreobjects.SceneManager) { + if err := base.setParentScene(manager); err != nil { + panic(err.Error()) + } + base.Collider = (&coreobjects.BoxCollider{}).Init( + base.Position.X, + base.Position.Y, + 32, 32) // TODO: Change this to player description } -func (base *Player) Create(_ 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 { + 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)") + } + base.ParentScene = baseScene + return nil } func (base *Player) Destroy() { } +func (base *Player) Move(delta rl.Vector2) { + var newLocation = rl.Vector2Add(base.Position, delta) + if !base.Collider.CanMove(base.ParentScene.GetStaticColliders(), + newLocation.X, newLocation.Y) { + return + } + base.Collider.MoveTo(newLocation.X, newLocation.Y) + base.Position = newLocation +} + func (base *Player) Update() { var speed = 150 * rl.GetFrameTime() + var delta = rl.Vector2{} if rl.IsKeyDown(rl.KeyW) { - base.Position.Y -= speed + delta.Y -= speed } if rl.IsKeyDown(rl.KeyS) { - base.Position.Y += speed + delta.Y += speed } if rl.IsKeyDown(rl.KeyA) { - base.Position.X -= speed + delta.X -= speed } if rl.IsKeyDown(rl.KeyD) { - base.Position.X += speed + delta.X += speed } + base.Move(delta) } func (base *Player) Draw() { rl.DrawTexture(base.Texture, - int32(base.Position.X), - int32(base.Position.Y), - rl.White) + int32(base.Position.X), + int32(base.Position.Y), + rl.White) + if settings.State.DrawColliders { + base.Collider.Draw() + } } -func (base Player) SnapCamera (camera *rl.Camera2D) { +// Centers the camera center to the player +func (base Player) SnapCamera(camera *rl.Camera2D) { var offset = rl.Vector2 { X: float32(base.Texture.Width) / 2, Y: float32(base.Texture.Height) / 2, } camera.Target = rl.Vector2Add(base.Position, offset) - camera.Offset.X = float32(rl.GetScreenWidth()) / 2 - camera.Offset.Y = float32(rl.GetScreenHeight()) / 2 + camera.Offset.X = float32(int32(rl.GetScreenWidth() / 2)) + camera.Offset.Y = float32(int32(rl.GetScreenHeight() / 2)) } diff --git a/engine/Components/World.go b/engine/Components/World.go index 7e6e8e3..2b7954a 100644 --- a/engine/Components/World.go +++ b/engine/Components/World.go @@ -14,13 +14,20 @@ type World struct { Player *Player Camera *rl.Camera2D + + // ========== Cache ========== + + // the collection of the colliders that belong to static objects - world, buildings, etc + staticColliders []*coreobjects.Collider } func (base *World) Create(manager coreobjects.SceneManager) { base.Manager = manager + base.Player.Init(manager) } func (base *World) Destroy() { + base.Player.Destroy() } func (base *World) Update() { @@ -34,6 +41,17 @@ func (base *World) handleZoom() { base.Camera.Zoom += zoomSpeed * rl.GetMouseWheelMove() } +func (base *World) collectStaticColliders() { + base.staticColliders = make([]*coreobjects.Collider, 0) +} + +func (base *World) GetStaticColliders() []*coreobjects.Collider { + if base.staticColliders == nil { + base.collectStaticColliders() + } + return base.staticColliders +} + func (base *World) Draw() { rl.BeginMode2D(*base.Camera) defer rl.EndMode2D() diff --git a/engine/CoreObjects/Collider.go b/engine/CoreObjects/Collider.go new file mode 100644 index 0000000..93cbee6 --- /dev/null +++ b/engine/CoreObjects/Collider.go @@ -0,0 +1,85 @@ +package coreobjects + +import ( + "image/color" + + rl "github.com/gen2brain/raylib-go/raylib" +) + +var ColliderColour color.RGBA = color.RGBA{ 154, 20, 184, 255 / 2 } + +type Collider interface { + Init(x float32, y float32, height float32, width float32) Collider + MoveIfPossible(colliders []*Collider, dx float32, dy float32) + Move(dx float32, dy float32) + MoveTo(x float32, y float32) + Intersects(x float32, y float32) bool + CanMove(colliders []*Collider, dx float32, dy float32) bool + + Draw() +} + +type BoxCollider struct { + Location rl.Rectangle +} + +func (base *BoxCollider) Init(x float32, y float32, height float32, width float32) Collider { + base.Location = rl.Rectangle{ + X: x, + Y: y, + Width: width, + Height: height, + } + return base +} + +func (base *BoxCollider) Intersects(x float32, y float32) bool { + if base.Location.X < x || base.Location.Y < y { + return false + } + if base.Location.X + base.Location.Width > x || base.Location.Y + base.Location.Height > y { + return false + } + return true +} + +func (base *BoxCollider) Move(dx float32, dy float32) { + base.Location.X += dx + base.Location.Y += dy +} + +func (base *BoxCollider) MoveTo(x float32, y float32) { + base.Location.X = x + base.Location.Y = y +} + +func (base *BoxCollider) MoveIfPossible(colliders []*Collider, dx float32, dy float32) { + if base.CanMove(colliders, dx, dy) { + base.Move(dx, dy) + } +} + +func (base *BoxCollider) Draw() { + rl.DrawRectangle(base.Location.ToInt32().X, + base.Location.ToInt32().Y, + base.Location.ToInt32().Width, + base.Location.ToInt32().Height, + ColliderColour) +} + +func (base *BoxCollider) CanMove(colliders []*Collider, dx float32, dy float32) bool { + var x = base.Location.X + dx + var y = base.Location.Y + dy + var width = base.Location.Width + var height = base.Location.Height + // TODO: optimise + for _, v := range colliders { + if (*v).Intersects(x, y) || + (*v).Intersects(x + width, y) || + (*v).Intersects(x, y + height) || + (*v).Intersects(x + width, y + height) { + return false + } + } + return true +} diff --git a/engine/CoreObjects/Direction.go b/engine/CoreObjects/Direction.go new file mode 100644 index 0000000..c928018 --- /dev/null +++ b/engine/CoreObjects/Direction.go @@ -0,0 +1,10 @@ +package coreobjects + +type Direction uint8 + +const ( + Up Direction = iota + Down + Left + Right +) diff --git a/engine/Dynamic/Descriptors/World.go b/engine/Dynamic/Descriptors/World.go index ec02935..0a6a7d9 100644 --- a/engine/Dynamic/Descriptors/World.go +++ b/engine/Dynamic/Descriptors/World.go @@ -10,6 +10,7 @@ type WorldDescriptor struct { // Deprecated TileSize rl.Vector2 `json:"-"` FloorMap []FloorPiece + DefaultStartingPosition rl.Vector2 } func (base *WorldDescriptor) IsValid() error { @@ -36,7 +37,8 @@ func (base WorldDescriptor) Parse() components.World { Name: base.Name, Floor: make([]components.FloorTile, 0, len(base.FloorMap)), Player: &components.Player{ - Texture: *components.Resources.Textures.Textures[3], + Texture: *components.Resources.Textures.Textures[3], // TODO: Change + Position: base.DefaultStartingPosition, }, Camera: &rl.Camera2D{ @@ -46,6 +48,7 @@ func (base WorldDescriptor) Parse() components.World { Zoom: 1, }, } + for _, v := range base.FloorMap { var texture, textureErr = components.Resources.Textures.GetTextureByName(v.Texture) if textureErr != nil { diff --git a/engine/Packages/TestPackage/Worlds/Main.json b/engine/Packages/TestPackage/Worlds/Main.json index 3030640..79da91f 100644 --- a/engine/Packages/TestPackage/Worlds/Main.json +++ b/engine/Packages/TestPackage/Worlds/Main.json @@ -5,5 +5,6 @@ "Position": { "X": 0, "Y": 0 }, "Texture": "testPackage/TestWorld.png" } - ] + ], + "DefaultStartingPosition": { "X": 64, "Y": 64 } } diff --git a/engine/Render/initWindow.go b/engine/Render/initWindow.go index 37728db..9142493 100644 --- a/engine/Render/initWindow.go +++ b/engine/Render/initWindow.go @@ -14,6 +14,8 @@ func InitWindow() { func StartLoop(manager coreobjects.SceneManager, startScene coreobjects.Scene) { manager.ChangeScene(startScene) + rl.SetTargetFPS(60) + for !rl.WindowShouldClose() { manager.Update() rl.BeginDrawing() diff --git a/engine/Settings/State.go b/engine/Settings/State.go new file mode 100644 index 0000000..1db8024 --- /dev/null +++ b/engine/Settings/State.go @@ -0,0 +1,10 @@ +package settings + +// The state of the mgame that is not saved between sessions +type GlobalState struct { + DrawColliders bool +} + +var State = GlobalState { + DrawColliders: true, +} |
