summaryrefslogtreecommitdiff
path: root/player/player.gd
blob: 4257f2a77ab9397efcf65afb9c4a351ff7700daa (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
class_name Player
extends Character


var is_invincible := false

@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:
		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()
	
	
	elif 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


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()
			)
			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)
			)
			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
			get_tree().change_scene_to_file("res://stage/stage_01.tscn")