summaryrefslogtreecommitdiff
path: root/engine/CoreObjects/DynamicObject.go
blob: 9b309dd0b992f15319fab612b412250cbcd0dc0f (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
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
package coreobjects

import (
	"fmt"

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

// The size of the font used in the overaly
const objectOverlayTextSize int32 = 12
// An offset of the overlay compared to the mouse position
const objectOveralyOffset float32 = 10
// An offset of the overlay compared to the mouse position
const objectOveralyPadding int32 = 3
// The color of the overlay text
var objectOverlayTextColor = rl.Black
// The color of the overlay background
var objectOverlayBackgroundColor = rl.LightGray

// An object loaded from the package. Impmiments GameObject interface
type DynamicObject struct {
	PrototypeName string `json:"-"`
	Position rl.Vector2
	YLevelOffset float32
	Textures []*TextureBlock
	Colliders []*ColliderBlock

	parentScene Scene
	showTooltip bool
}

// The dynamic objects can contain multiple textures. This struct
// represents one of those parts
type TextureBlock struct {
	Texture *rl.Texture2D
	// The space occupied by the sprite in world relative to the base object position
	Window *rl.Rectangle

	// The base rectangle of the texture (calculated once in the initialization step)
	baseRect *rl.Rectangle
}

// Inintializes the texture block for futher render
func (base *TextureBlock) init() {
	base.baseRect = &rl.Rectangle{
		X: 0,
		Y: 0,
		Height: float32(base.Texture.Height),
		Width: float32(base.Texture.Width),
	}
}

func (base *TextureBlock) draw(objPos *rl.Vector2) {
	var targetWindow = rl.Rectangle {
		X: base.Window.X + objPos.X,
		Y: base.Window.Y + objPos.Y,
		Width: base.Window.Width,
		Height: base.Window.Height,
	}
	rl.DrawTexturePro(*base.Texture,
		*base.baseRect,
		targetWindow,
		rl.Vector2Zero(),
		0, rl.White)
}

type ColliderBlock struct {
	Collider Collider
	Offset rl.Vector2
}

func (base *DynamicObject) Init(manager *SceneManager) {
	if manager.SelectedScene == nil {
		panic("Failed to initialize a dynamic object: the scene was not selected")
	}
	base.parentScene = manager.SelectedScene
	for _, v := range base.Textures {
		v.init()
	}
}

func (base *DynamicObject) Destroy() {
}

func (base *DynamicObject) Update() {
	if settings.State.DrawColliders {
		base.showTooltip = false
		var mousePosition = base.parentScene.GetMousePosition()
		for _, v := range base.Colliders {
			if v.Collider.Intersects(mousePosition.X, mousePosition.Y) {
				base.showTooltip = true
				return
			}
		}
	}
}

func (base *DynamicObject) drawOverlay() {
	var mousePoint = base.parentScene.GetMousePosition()
	var text = fmt.Sprintf("Proto: %s", base.PrototypeName)
	var overlayPosX = mousePoint.X + objectOveralyOffset
	var overlayPosY = mousePoint.Y
	var size = rl.MeasureText(text, objectOverlayTextSize)

	rl.DrawRectangle(
		int32(overlayPosX), 
		int32(overlayPosY),
		size + objectOveralyPadding * 2,
		objectOverlayTextSize + objectOveralyPadding, 
		objectOverlayBackgroundColor)

	rl.DrawText(string(text), 
		int32(overlayPosX) + objectOveralyPadding, 
		int32(overlayPosY),
		objectOverlayTextSize,
		objectOverlayTextColor)
}

func (base *DynamicObject) Draw() {
	for _, v := range base.Textures {
		v.draw(&base.Position)
	}
	if settings.State.DrawColliders {
		for _, v := range base.Colliders {
			v.Collider.Draw()
			if base.showTooltip {
				base.drawOverlay()
			}
		}
	}
}

func (base *DynamicObject) MoveTo(x float32, y float32) {
	base.Position = rl.Vector2 { X: x, Y: y }
	for _, v := range base.Colliders {
		v.Collider.MoveTo(x + v.Offset.X, y + v.Offset.Y)
	}
}

func (base *DynamicObject) Clone() *DynamicObject {
	var outp = DynamicObject {
		PrototypeName: base.PrototypeName,
		YLevelOffset: base.YLevelOffset,
		Position: base.Position,
		Textures: base.Textures,
		Colliders: base.cloneColliders(),
	}
	return &outp
}

func (base *DynamicObject) cloneColliders() []*ColliderBlock {
	var outp = make([]*ColliderBlock, len(base.Colliders))
	for i, v := range base.Colliders {
		 outp[i] = &ColliderBlock {
			Collider: v.Collider.Clone(),
			Offset: v.Offset,
		}
	}
	return outp
}

func (base *DynamicObject) GetColliders() []Collider {
	var outp = make([]Collider, 0, len(base.Colliders))
	for _, v := range base.Colliders {
		outp = append(outp, v.Collider)
	}
	return outp
}

func (base *DynamicObject) GetYIndex() float32 {
	return base.Position.Y + base.YLevelOffset
}