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
|
class_name Player
extends Character
var is_invincible := false
var mobile_controls: MobileControls
@onready var camera := $Camera2D
func _ready() -> void:
super._ready()
$AnimatedSprite2D.modulate = Color(max(0.1, randf()), max(0.1, randf()), max(0.1, randf()))
func _process(_delta: float) -> void:
if current_state == State.Idle or current_state == State.Walk:
if Input.is_action_pressed("ui_left"):
walk(Direction.Left)
elif Input.is_action_pressed("ui_right"):
walk(Direction.Right)
else:
idle()
if Input.is_action_pressed("ui_up"):
jump()
if Input.is_action_pressed("ui_down"):
if not is_on_bottom_floor():
fall()
if not is_on_floor():
fall()
if Input.is_action_just_pressed("ui_accept"):
change_type_random()
func invincible(duration: float):
is_invincible = true
var tween := get_tree().create_tween().set_loops(int(duration / 0.5))
tween.tween_property($AnimatedSprite2D, "self_modulate", Color(1.0, 1.0, 1.0, 0.25), 0.25)
tween.tween_property($AnimatedSprite2D, "self_modulate", Color(1.0, 1.0, 1.0, 1.0), 0.25)
await tween.finished
is_invincible = false
(func(): # re-trigger area entered
$Collision.monitoring = false
$Collision.monitoring = true
).call_deferred()
enum Result {
Draw,
Win,
Lose,
}
static func is_rock_paper_scissors_win(player: Character, opponent: Character) -> Result:
if player.current_type == Type.Rock and opponent.current_type == Type.Scissors:
return Result.Win
elif player.current_type == Type.Paper and opponent.current_type == Type.Rock:
return Result.Win
elif player.current_type == Type.Scissors and opponent.current_type == Type.Paper:
return Result.Win
elif player.current_type == Type.Rock and opponent.current_type == Type.Paper:
return Result.Lose
elif player.current_type == Type.Paper and opponent.current_type == Type.Scissors:
return Result.Lose
elif player.current_type == Type.Rock and opponent.current_type == Type.Paper:
return Result.Lose
elif player.current_type == Type.Scissors and opponent.current_type == Type.Rock:
return Result.Lose
else:
return Result.Draw
func _on_collision_area_entered(area: Area2D) -> void:
if area.is_in_group("item"):
var item: Item = area.get_parent()
item.apply(self)
elif area.is_in_group("opponent"):
if is_invincible or current_state == State.Transform:
return
var opponent: Character = area.get_parent()
var result := Player.is_rock_paper_scissors_win(self, opponent)
if result == Result.Draw:
type_change_finished.connect(func():
change_type_random()
invincible(1.0)
)
is_invincible = true
animate_type_change()
elif result == Result.Win:
(get_tree().get_first_node_in_group("hud") as HUD).score += 1
SoundManager.get_node("OpponentHit").play()
type_change_finished.connect(func():
change_type_random()
invincible(1.0)
)
is_invincible = true
animate_type_change()
opponent.process_mode = Node.PROCESS_MODE_DISABLED
var tween = get_tree().create_tween()
tween.tween_property(
opponent,
"position",
position + (opponent.position - position) * 10,
0.5
)
await tween.finished
opponent.queue_free()
await get_tree().process_frame
if (get_tree().current_scene as Stage).has_win_condition():
await get_tree().create_timer(2.0).timeout
get_tree().change_scene_to_file("res://stage/stage_01.tscn")
elif result == Result.Lose:
(func(): $Collision.process_mode = Node.PROCESS_MODE_DISABLED).call_deferred()
set_process(false)
if vertical_tween: vertical_tween.stop()
SoundManager.get_node("PlayerKO").play()
$AnimatedSprite2D.play("ko")
await $AnimatedSprite2D.animation_finished
SoundManager.get_node("PlayerKO").stop()
visible = false
await get_tree().create_timer(0.3).timeout
get_tree().change_scene_to_file("res://stage/stage_01.tscn")
|