summaryrefslogtreecommitdiff
path: root/engine/Components/Player.go
blob: ba92a1655b53d201689c173d2d6d0abcbdff65f3 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
package components

import (
	"fmt"

	coreobjects "github.com/DegustatorPonos/RuinesOfRafdolon/CoreObjects"
	settings "github.com/DegustatorPonos/RuinesOfRafdolon/Settings"
	rl "github.com/gen2brain/raylib-go/raylib"
)

// TODO: Change this to be determined by package
const playerHeight int32 = 32
// TODO: Change this to be determined by package
const playerWidth int32 = 32

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,
		float32(playerWidth),
		float32(playerHeight))
}

// 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(), 
		delta.X, delta.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) {
		delta.Y -= speed
	}
	if rl.IsKeyDown(rl.KeyS) {
		delta.Y += speed
	}
	if rl.IsKeyDown(rl.KeyA) {
		delta.X -= speed
	}
	if rl.IsKeyDown(rl.KeyD) {
		delta.X += speed
	}
	base.Move(rl.Vector2{X: delta.X, Y: 0})
	base.Move(rl.Vector2{X: 0, Y: delta.Y})
}

func (base *Player) Draw() {
	var xOffset, yOffset = base.getSpriteOffset()
	rl.DrawTexture(base.Texture, 
		int32(base.Position.X) - xOffset,
		int32(base.Position.Y) - yOffset,
		rl.White)
	if settings.State.DrawColliders {
		base.Collider.Draw()
	}
}

// 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
}

// If the player model size doesn't align with the sprite this function will
// return the offset
func (base *Player) getSpriteOffset() (int32, int32) {
	var y = base.Texture.Height - playerHeight
	var x = (base.Texture.Width - playerWidth) / 2
	return x, y
}