Repository navigation
Expand file tree
/
Copy pathmain.gd
More file actions
271 lines (237 loc) · 7.13 KB
/
Copy pathmain.gd
File metadata and controls
271 lines (237 loc) · 7.13 KB
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
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
extends Node2D
enum Shape { CIRCLE, SQUARE, HEXAGON }
var shape : Shape = Shape.SQUARE
@onready var pool_circle = $Pool_circle
@onready var pool_square = $Pool_square
@onready var slider_v = $CanvasLayer/HSlider
@onready var text_v = $CanvasLayer/text_v
@onready var victory = $CanvasLayer/victory
@onready var turn_based_button = $CanvasLayer/turn_based_button
@onready var show_history = $CanvasLayer/show_history
@onready var debug_text = $CanvasLayer/debug_text
var turn = 1
var swimmer: Vector2
var runner: Vector2
var runner_a : float = PI / 2
var mouse_control = false
var turn_by_turn: bool = false
@export var dt = 1.0 / 100.0 # can be modified in editor
var v = 3.0
var ghost_player: Vector2 = Vector2.ZERO
var vis_scale = 200.0
var paused = false
var pause_elapsed = 0.0
var runner_history = []
var swimmer_history = []
var game_elapsed = 0.0
func runner_turn() -> bool:
return turn%2 == 0
func swimmer_turn() -> bool:
return !runner_turn()
func is_in_shape(vec: Vector2):
match shape:
Shape.CIRCLE:
return vec.length() < 1.0
Shape.SQUARE:
return abs(vec.x) < 1.0 and abs(vec.y) < 1.0
Shape.HEXAGON:
return false
func check_victory():
if (runner.distance_to(swimmer)) < 0.06:
victory.visible = true
victory.text = "Runner wins!"
victory.add_theme_color_override("default_color", Color.ORANGE)
paused = true
else: if (!is_in_shape(swimmer)): #which, ironically, means that he indeed IS in shape
victory.visible = true
victory.text = "Swimmer wins!"
victory.add_theme_color_override("default_color", Color.DEEP_PINK)
paused = true
func init():
pool_circle.visible = shape == Shape.CIRCLE;
pool_square.visible = shape == Shape.SQUARE;
if shape == Shape.CIRCLE:
runner_a = PI / 2
if shape == Shape.SQUARE:
runner_a = 0.5
turn = 0;
runner = alpha_to_world(runner_a)
swimmer = Vector2(0.0, 0.0)
victory.visible = false
pause_elapsed = 0.0
paused = false
runner_history = []
runner_history.append(runner)
swimmer_history = []
swimmer_history.append(swimmer)
game_elapsed = 0.0
# called by Godot frame 1
func _ready() -> void:
init()
pool_circle.scale = Vector2.ONE * vis_scale * 2.0
pool_square.scale = Vector2.ONE * vis_scale * 2.0
func alpha_to_world(a: float) -> Vector2:
var res : Vector2
match shape:
Shape.CIRCLE:
res.x = cos(a)
res.y = - sin(a)
Shape.SQUARE:
if a > 4.0:
a -= 4.0
if a < 0:
a += 4.0
if (a >= 0 and a < 1):
res.x = a * 2.0 - 1.0
res.y = -1.0
if (a >= 1 and a < 2):
res.x = 1.0
res.y = (a - 1) * 2.0 - 1.0
if (a >= 2 and a < 3):
res.x = - ((a - 2) * 2.0 - 1.0)
res.y = 1.0
if (a >= 3 and a < 4):
res.x = - 1.0
res.y = - ((a - 3) * 2.0 - 1.0)
#debug_text.text = str(a)
Shape.HEXAGON:
pass
return res
func world_to_alpha(vec: Vector2) -> float:
var res : float = 0.0
match shape:
Shape.CIRCLE:
return atan2(- vec.y, vec.x)
Shape.SQUARE:
if (vec.x > 0 and abs(vec.y) <= abs(vec.x)): #right side
res = 1.5 + 0.5 * vec.y / vec.x #where 1.5 = RIGHT vector's alpha
if (vec.x < 0 and abs(vec.y) <= abs(vec.x)):
res = 3.5 + 0.5 * vec.y / vec.x #where 3.5 = LEFT vector's alpha
if (vec.y > 0 and abs(vec.x) < abs(vec.y)):
res = 2.5 - 0.5 * vec.x / vec.y #where 2.5 = DOWN vector's alpha
if (vec.y < 0 and abs(vec.x) < abs(vec.y)):
res = 0.5 - 0.5 * vec.x / vec.y #where 0.5 = UP vector's alpha
return res
Shape.HEXAGON:
return 0.0
return 0.0
# called by Godot every frame
func _process(delta: float) -> void:
if shape == Shape.SQUARE:
runner_a = wrapf(runner_a, 0.0, 4.0)
v = slider_v.value
text_v.text = str(v)
slider_v.release_focus()
turn_by_turn = turn_based_button.button_pressed
debug_text.text = "@Joran: ctrl F this" #use this wherever to display anything in this box
# you may delete the other line updating it I no longer need it
if (paused):
pause_elapsed += delta
if pause_elapsed > 1.0:
init()
return
else:
game_elapsed += delta
if (turn_by_turn):
var tdt = dt * 10
var mp = get_global_mouse_position() / vis_scale
if (swimmer_turn()):
var dir = mp - swimmer
if (dir.length() > tdt):
dir = dir.normalized() * tdt
ghost_player = swimmer + dir
if Input.is_action_just_pressed("lmb"):
swimmer = ghost_player
turn += 1
swimmer_history.append(ghost_player)
else: #runner_turn
var input_by_a: bool = true;
if (input_by_a):
var mouse_a = world_to_alpha(mp)
var diff = 0.0
if shape == Shape.CIRCLE:
diff = angle_difference(runner_a, mouse_a)
if shape == Shape.SQUARE:
diff = mouse_a - runner_a
diff = wrap(diff, -2, 2)
debug_text.text = str(diff)
if (abs(diff) > v * tdt):
if diff > 0:
ghost_player = alpha_to_world(runner_a + v * tdt)
else:
ghost_player = alpha_to_world(runner_a - v * tdt)
else:
ghost_player = alpha_to_world(mouse_a)
if Input.is_action_just_pressed("lmb"):
runner = ghost_player
runner_a = world_to_alpha(runner)
turn += 1
runner_history.append(ghost_player)
else:
#input by distance
var da = 0.0
var dist = mp.distance_to(runner)
if shape == Shape.SQUARE:
dist = mp.distance_to(runner) * 0.5 #no idea why let's be honest
if (dist > v * tdt):
dist = v * tdt
if shape == Shape.SQUARE:
dist = dist
var pos_1 = alpha_to_world(runner_a + dist)
var pos_2 = alpha_to_world(runner_a - dist)
if (mp.distance_to(pos_1) < mp.distance_to(pos_2)):
da = dist
ghost_player = pos_1
else:
da = - dist
ghost_player = pos_2
if Input.is_action_just_pressed("lmb"):
runner_a += da
runner = ghost_player
turn += 1
runner_history.append(ghost_player)
else:
var d : Vector2 = Vector2.ZERO
if Input.is_action_pressed("left"):
d.x -= 1
if Input.is_action_pressed("right"):
d.x += 1
if Input.is_action_pressed("up"):
d.y -= 1
if Input.is_action_pressed("down"):
d.y += 1
swimmer += d.normalized() * dt
var a : float = 0.0
if Input.is_action_pressed("dpad_left"):
a -= 1
if Input.is_action_pressed("dpad_right"):
a += 1
a = a * v * dt
runner_a += a
runner = alpha_to_world(runner_a)
if (game_elapsed > 0.15):
swimmer_history.append(swimmer)
runner_history.append(runner)
game_elapsed = 0.0
check_victory()
queue_redraw()
func _draw() -> void:
if (show_history.button_pressed): #put it before because ordering
for p in swimmer_history:
draw_circle(p * vis_scale, 2.0, Color.DEEP_PINK, true, -1.0, true)
for p in runner_history:
draw_circle(p * vis_scale, 2.0, Color.ORANGE, true, -1.0, true)
var f = 1.0
draw_circle(runner * vis_scale * f, 5.0, Color.ORANGE, true, -1.0, false)
draw_circle(swimmer * vis_scale, 5.0, Color.DEEP_PINK, true, -1.0, true)
if (turn_by_turn):
var c1 : Color = Color.WHITE if runner_turn() else Color.BLACK
var c2 : Color = Color.ORANGE if runner_turn() else Color.DEEP_PINK
draw_circle(ghost_player * vis_scale, 3.0, c1, true, -1.0, true)
draw_circle(ghost_player * vis_scale, 3.0, c2, false, 1.5, true)
func _on_button_circle_button_up() -> void:
shape = Shape.CIRCLE
init()
func _on_button_square_button_up() -> void:
shape = Shape.SQUARE
init()