summaryrefslogtreecommitdiff
path: root/player/player.gd
blob: 86284ae0ceb15c235d59d783a954f565c32a198c (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
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_solid_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")