-
Notifications
You must be signed in to change notification settings - Fork 0
/
player.gd
396 lines (309 loc) · 9.64 KB
/
player.gd
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
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
extends KinematicBody2D
# state
# - 'idle' without the ball
# - 'catch_ball' with the ball
# - 'dash' dash
# - when the player catch the ball `block_action_shot` is set to `true`, the shot is enable again when the player
# is has the ball and doens't have any action button pressed
# - when the player dash `block_action_dash` is set to `true`, the dash is enable again when the player
# is idle and doens't have any action button pressed
# - the movement is blocked after shot during x milliseconds, when the movevement is avalible again ignore the main action button util release
# - shot strength depends in the time between the catch and the shot
# - automatic shot after x millisenconds
# - TODO: the player is looking to the las place wher he was looking (left-right)
var movement = Vector2()
var state = "idle"
var player_area = "left"
var control
var anim
var player_orientation = "right"
const SHOT_DURATION = 500 #TODO: configuratble?
const AXIS_SENSITIVITY = 0.3
# shot
var block_action_shot = false
var last_shot_time = 0
var last_catch_time = 0
# dash
var block_action_dash = false
var last_dash_init_time
var dash_orientation
var player_config
func _ready():
control = get_node("/root/control")
set_fixed_process(true)
func stop():
set_animation("standing")
func set_player_orientation(new_orientation):
player_orientation = new_orientation
if player_orientation == 'left':
get_node("Sprite").set_scale(Vector2(-1, 1))
elif player_orientation == "right":
get_node("Sprite").set_scale(Vector2(1, 1))
func reset_player_orientation():
var player_area = get_player_area()
if player_area == "left":
set_player_orientation("right")
elif player_area == "right":
set_player_orientation("left")
func has_the_ball():
return state == "catch_ball"
func set_player_config(config):
player_config = config
func get_last_catch_time():
return last_catch_time
func set_action(action_name):
if action_name == "dash":
block_action_dash = true
elif action_name == "catch_ball":
last_catch_time = OS.get_ticks_msec()
block_action_shot = true
block_action_dash = true
state = action_name
func search_speed_by_time(list_speeds, time):
for shot_config in list_speeds:
if "max" in shot_config && shot_config["min"] <= time && shot_config["max"] >= time:
return shot_config.speed
elif not "max" in shot_config && shot_config["min"] <= time:
return shot_config.speed
func get_speed(player_axis, time,is_secondary):
if player_axis.x < 0:
player_axis.x = -player_axis.x
if player_axis.x > 1:
player_axis.x = 1
if is_secondary:
return search_speed_by_time(player_config.shots_strength.secondary, time)
if !is_axis_pressed():
return search_speed_by_time(player_config.shots_strength.straight, time)
for shot_config in player_config.shots_strength.normal_shots:
if player_axis.x >= shot_config.min_angle && shot_config.max_angle >= player_axis.x:
return search_speed_by_time(shot_config.speeds, time)
print(player_axis)
print(time)
print(is_secondary)
func shot(player_axis, is_secondary):
last_shot_time = OS.get_ticks_msec()
var player_area = get_player_area()
var diff = last_shot_time - last_catch_time
var ball = control.get_ball()
#normalize shot angle
if player_area == "left":
if player_axis.x < player_config.min_shot_angle:
player_axis.x = player_config.min_shot_angle
elif player_area == "right":
if player_axis.x > -player_config.min_shot_angle:
player_axis.x = -player_config.min_shot_angle
var speed = get_speed(player_axis, diff, is_secondary)
# a/b = c/x -> (b/a = c/x) // ((a*c)/b)
if is_secondary:
var player_area = get_player_area()
var player_area_width = 328
var player_area_height = 334
var min_area2 = 340
var max_area2 = 540
var min_area1 = 80
var max_area1 = 300
var x
var y
if diff != 0:
if player_area == "left":
x = min_area2 + ((100 * player_area_width) / (diff*2))
if x > max_area2:
x = max_area2
else:
x = (diff*2) * 100 / player_area_width
if x < min_area1:
x = min_area1
elif x > max_area1:
x = max_area1
elif player_area == "right":
x = min_area1
else:
x = min_area2
if is_axis_pressed():
var percent = ((player_area_height / 2) * (player_axis.y * 100)) / 100
y = get_pos().y + percent
else:
y = get_pos().y
if y > player_area_height:
y = 330
elif y < 70:
y = 90
var destination = Vector2(x, y)
set_action("idle")
ball.shot2(destination, speed)
else:
set_action("idle")
if !is_axis_pressed():
if player_area == "left":
ball.shot(Vector2(1, 0), speed)
else:
ball.shot(Vector2(-1, 0), speed)
else:
ball.shot(player_axis.normalized(), speed)
func catch():
reset_player_orientation()
set_action("catch_ball")
func are_shot_available():
if block_action_shot:
return false
if state == "catch_ball":
return true
return false
func are_move_actions_available():
var time = OS.get_ticks_msec()
if (time - last_shot_time) < player_config.time_movement_block_after_shot:
return false
if state == "idle":
return true
return false
func is_player():
return true
func get_player_area():
return player_area
func set_player_area(area):
player_area = area
if area == "right":
set_player_orientation("left")
else:
set_player_orientation("right")
func is_action_pressed(action):
return Input.is_action_pressed(get_player_event(action))
func is_action_key_pressed():
if is_action_pressed("main"):
return true
return false
func is_axis_pressed():
var axis_pos = get_axis_pos()
if axis_pos.x > AXIS_SENSITIVITY || axis_pos.x < -AXIS_SENSITIVITY:
return true
if axis_pos.y > AXIS_SENSITIVITY || axis_pos.y < -AXIS_SENSITIVITY:
return true
return false
func get_player_orientation():
if is_action_pressed("up"):
if is_action_pressed("right"):
return "up-right"
elif is_action_pressed("left"):
return "up-left"
else:
return "up"
elif is_action_pressed("down"):
if is_action_pressed("right"):
return "down-right"
elif is_action_pressed("left"):
return "down-left"
else:
return "down"
elif is_action_pressed("left"):
return "left"
elif is_action_pressed("right"):
return "right"
func get_player_event(event):
if player_area == "right":
return "player2_" + event
else:
return "player1_" + event
func get_player_ball_position():
var pos = get_pos()
if player_area == "right":
pos.x -= 40
return pos
else:
pos.x += 40
return pos
func is_automatic_shot():
var current_time = OS.get_ticks_msec()
return (current_time - last_catch_time) >= player_config.time_automatic_shot
func get_axis_pos():
var player_device = get_player_device()
return Vector2(Input.get_joy_axis(player_device, 0), Input.get_joy_axis(player_device, 1))
func shot_animation():
pass
func set_animation(new_anim):
if (new_anim != anim):
if (new_anim == 'stop'):
stop()
else:
if new_anim == "walk-front":
get_node("anim").play("start-front")
get_node("anim").queue(new_anim)
elif new_anim == "walk-lateral":
get_node("anim").play("start-lateral")
get_node("anim").queue(new_anim)
elif new_anim == "walk-back":
get_node("anim").play("start-walk-back")
get_node("anim").queue(new_anim)
else:
if new_anim == "standing" && anim == "walk-front":
get_node("anim").play("end-front")
get_node("anim").queue("standing")
elif new_anim == "standing" && anim == "walk-lateral":
get_node("anim").play("end-lateral")
get_node("anim").queue("standing")
elif new_anim == "standing" && anim == "walk-back":
get_node("anim").play("end-back")
get_node("anim").queue("standing")
else:
get_node("anim").play(new_anim)
anim = new_anim
func get_player_device():
if get_player_area() == "left":
return 0
elif get_player_area() == "right":
return 1
func _fixed_process(delta):
var new_anim = "standing"
var new_reverse_siding = true
if !control.main_loop:
return
var current_time = OS.get_ticks_msec()
if !is_action_key_pressed() && state == 'idle':
block_action_dash = false
if !is_action_key_pressed() && state == 'catch_ball':
block_action_shot = false
# shot
if are_shot_available() && (is_action_pressed("main") || is_action_pressed("secondary") || is_automatic_shot()):
var is_secondary = is_action_pressed("secondary")
var player_axis = get_axis_pos()
shot(player_axis, is_secondary)
# movement
movement.x = 0
movement.y = 0
var initialX = movement.x
var initialY = movement.y
# check dash duration
if state == "dash" && (current_time - last_dash_init_time) >= player_config.dash_duration:
set_action("idle")
if are_move_actions_available():
var player_area = get_player_area()
if is_action_pressed("main") && is_axis_pressed() && !block_action_dash:
last_dash_init_time = current_time
#dash_orientation = get_player_orientation()
dash_orientation = get_axis_pos()
set_action("dash")
# move
else:
var axis_pos = get_axis_pos()
if axis_pos.x > AXIS_SENSITIVITY || axis_pos.x < -AXIS_SENSITIVITY:
movement.x = axis_pos.x * player_config.player_speed
if axis_pos.y > AXIS_SENSITIVITY || axis_pos.y < -AXIS_SENSITIVITY:
movement.y = axis_pos.y * player_config.player_speed
if axis_pos.y > AXIS_SENSITIVITY:
new_anim = "walk-front"
elif axis_pos.y < -AXIS_SENSITIVITY:
new_anim = "walk-back"
if axis_pos.x > AXIS_SENSITIVITY:
new_anim = "walk-lateral"
set_player_orientation("right")
elif axis_pos.x < -AXIS_SENSITIVITY:
new_anim = "walk-lateral"
set_player_orientation("left")
#dash
elif state == "dash":
movement = dash_orientation * player_config.dash_speed
if initialX != movement.x || initialY != movement.y:
var motion = movement * delta
if test_move(motion):
new_anim = "standing"
move(motion)
set_animation(new_anim)