summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--engine/Components/Player.go62
-rw-r--r--engine/Components/World.go18
-rw-r--r--engine/CoreObjects/Collider.go85
-rw-r--r--engine/CoreObjects/Direction.go10
-rw-r--r--engine/Dynamic/Descriptors/World.go5
-rw-r--r--engine/Packages/TestPackage/Worlds/Main.json3
-rw-r--r--engine/Render/initWindow.go2
-rw-r--r--engine/Settings/State.go10
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,
+}