summaryrefslogtreecommitdiff
path: root/engine/Components/World.go
blob: ccbe99f41881acdb41f5c124e9af9fbd2be9ec9b (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
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
package components

import (
	coreobjects "github.com/DegustatorPonos/RuinesOfRafdolon/CoreObjects"
	rl "github.com/gen2brain/raylib-go/raylib"
)

// The scene implimetation that represents one playable scene
type World struct {
	Manager *coreobjects.SceneManager
	Name string
	Floor []FloorTile
	StaticObjects []coreobjects.GameObject

	Player *Player
	Camera *rl.Camera2D
	layersStatic layering

	// ========== Cache ==========

	// the collection of the colliders that belong to static objects - world, buildings, etc
	staticColliders []*coreobjects.Collider

	updateQueue []coreobjects.UpdateFunction
}

func (base *World) Create(manager *coreobjects.SceneManager) {
	base.Manager = manager
	base.Player.Init(manager)
	// The max length will be higher but this length is guaranteed
	base.updateQueue = make([]coreobjects.UpdateFunction, 0, len(base.StaticObjects))
	for _, v := range base.StaticObjects {
		v.Init(manager)
		base.updateQueue = append(base.updateQueue, v.Update)
	}
	base.layersStatic = layering{}
	base.generateStaticLayers()
}

func (base *World) GetUpdateFunctions() []coreobjects.UpdateFunction {
	return base.updateQueue
}

func (base *World) Destroy() {
	base.Player.Destroy()
}

func (base *World) Update() {
	for _, v := range base.StaticObjects {
		v.Update()
	}
	base.Player.Update()
	base.Player.SnapCamera(base.Camera)
	base.handleZoom()
}

func (base *World) handleZoom() {
	var zoomSpeed = 50 * rl.GetFrameTime()
	base.Camera.Zoom += zoomSpeed * rl.GetMouseWheelMove()
}

func (base *World) collectStaticColliders() {
	base.staticColliders = make([]*coreobjects.Collider, 0)
	for _, obj := range base.StaticObjects {
		for _, v := range obj.GetColliders() {
			base.staticColliders = append(base.staticColliders, &v)
		}
	}
}

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()
	for _, v := range base.Floor {
		v.Draw()
	}
	base.drawObjects()
}

func (base *World) drawObjects() {
	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
			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 {
		base.layersStatic.Insert(v)
	}
}

func (base *World) GetMousePosition() rl.Vector2 {
	return rl.GetScreenToWorld2D(rl.GetMousePosition(), *base.Camera)
}

// The single texture drawn at level 0 of the world
type FloorTile struct {
	Position rl.Vector2
	Texture *rl.Texture2D
}

func (base *FloorTile) Draw() {
	rl.DrawTexture(
		*base.Texture,
		int32(base.Position.X), 
		int32(base.Position.Y),
		rl.White,
	)
}