fuzzyworld

godot-shooter / files / actors / Player.gd

Player.gd

Blame: the commit that last changed each line · file · history

b856550a 2023-10-30 Pavel Safronov1extends KinematicBody2D
f398dcb9 2023-11-02 Pavel Safronov2class_name Player
b856550a 2023-10-30 Pavel Safronov3
2b4497bb 2023-11-27 Pavel Safronov4const Damage = preload("res://effects/Damage.tscn")
16938031 2023-11-17 Pavel Safronov5const Weapons = preload("res://weapons/Weapons.gd")
ee6296b3 2023-11-17 Pavel Safronov6const Constants = preload("res://utils/Constants.gd")
5e4e3a9c 2023-11-08 Pavel Safronov7
0f8974b8 2023-12-01 Pavel Safronov8export var is_invincible = false
f3c75ae9 2023-11-15 Pavel Safronov9export var score = 0
ee6296b3 2023-11-17 Pavel Safronov10export var move_speed = Constants.SPEED
3fcb817e 2023-11-10 Pavel Safronov11export var health = 50
12export var max_health = 100
57783b1a 2023-11-06 Pavel Safronov13export var turn_rate = 0.03
cbc328fb 2023-11-17 Pavel Safronov14export var accel_rate = 1
bd0825dd 2023-11-09 Pavel Safronov15export var radar_min_radius = 350
f6120dba 2023-11-08 Pavel Safronov16export var radar_max_radius = 2000
cbc328fb 2023-11-17 Pavel Safronov17export var destination: Vector2
18export var is_destination_set: bool = false
f3c75ae9 2023-11-15 Pavel Safronov19signal player_died
cbc328fb 2023-11-17 Pavel Safronov20signal destination_set
f3c75ae9 2023-11-15 Pavel Safronov21signal debug
b856550a 2023-10-30 Pavel Safronov22
f3c75ae9 2023-11-15 Pavel Safronov23onready var hud = $UI/HUD
56eea835 2023-12-02 Pavel Safronov24onready var camera: Camera2D = $Camera2D
f3c75ae9 2023-11-15 Pavel Safronov25onready var static_controls = $Graphics/Alive/StaticControls
f6120dba 2023-11-08 Pavel Safronov26onready var radar_sprite = $Graphics/Alive/StaticControls/RadarSprite
27onready var radar_container = $Graphics/Alive/StaticControls/Radar
c39514ed 2023-12-01 Pavel Safronov28onready var pause_menu = $UI/PauseMenu
f3c75ae9 2023-11-15 Pavel Safronov29onready var scores_container = $UI/PauseMenu/CenterContainer/PanelContainer/VBoxContainer/TabContainer/Scores
30onready var scores_list = $UI/PauseMenu/CenterContainer/PanelContainer/VBoxContainer/TabContainer/Scores/ScoresList
31onready var pause_always_show_intro_check = $UI/PauseMenu/CenterContainer/PanelContainer/VBoxContainer/TabContainer/Pref/AlwaysShowIntroCheckBox
e96078c1 2023-11-17 Pavel Safronov32onready var pause_show_items_in_radar_check = $UI/PauseMenu/CenterContainer/PanelContainer/VBoxContainer/TabContainer/Pref/ShowItemsInRadarCheckBox
c39514ed 2023-12-01 Pavel Safronov33onready var intro_menu = $UI/IntroMenu
34onready var intro_always_show_intro_check = $UI/IntroMenu/CenterContainer/PanelContainer/VBoxContainer/AlwaysShowIntroCheckBox
f3c75ae9 2023-11-15 Pavel Safronov35onready var health_label = $Graphics/Alive/StaticControls/HealthLabel
36onready var trails = $Graphics/Alive/Trails
37onready var death_screen = $UI/DeathScreen
38onready var final_score_label = $UI/DeathScreen/CenterContainer/PanelContainer/VBoxContainer/FinalScoreLabel
3782f0cf 2023-11-29 Pavel Safronov39onready var player_to_target = $Graphics/Alive/PlayerToTarget
f3c75ae9 2023-11-15 Pavel Safronov40
16938031 2023-11-17 Pavel Safronov41const Utils = preload("res://utils/Utils.gd")
42const PopupControl = preload("res://utils/Popup.tscn")
b856550a 2023-10-30 Pavel Safronov43
bd0825dd 2023-11-09 Pavel Safronov44var weapon: Weapon
b856550a 2023-10-30 Pavel Safronov45var dead = false
a2c95335 2023-11-29 Pavel Safronov46var velocity: Vector2 = Vector2.UP * move_speed
f3c75ae9 2023-11-15 Pavel Safronov47var settings: Settings
f1a6c921 2023-12-01 Pavel Safronov48const zoom_step = 1.01
b856550a 2023-10-30 Pavel Safronov49
ddc65019 2023-11-29 Pavel Safronov50func create_default_weapon() -> Weapon:
c39514ed 2023-12-01 Pavel Safronov51 return Weapons.create_basic_gun()
ddc65019 2023-11-29 Pavel Safronov52
9dfa0893 2023-11-08 Pavel Safronov53func _ready() -> void:
afaeaa95 2023-12-01 Pavel Safronov54 velocity= Vector2.UP * move_speed
c8aa3c68 2023-12-01 Pavel Safronov55 weapon = create_default_weapon()
afaeaa95 2023-12-01 Pavel Safronov56
f3c75ae9 2023-11-15 Pavel Safronov57# Utils.remove_user_settings()
58 settings = Utils.load_user_settings()
59 settings.save_user_settings()
60 pause_always_show_intro_check.pressed = settings.show_intro
e96078c1 2023-11-17 Pavel Safronov61 pause_show_items_in_radar_check.pressed = settings.show_items
f3c75ae9 2023-11-15 Pavel Safronov62 if settings.show_intro:
9bc01bd5 2023-11-17 Pavel Safronov63 show_intro()
9dfa0893 2023-11-08 Pavel Safronov64
236d1677 2023-11-01 Pavel Safronov65func _process(_delta: float) -> void:
b856550a 2023-10-30 Pavel Safronov66 if dead:
67 return
8adb41dc 2023-11-19 Pavel Safronov68
f1a6c921 2023-12-01 Pavel Safronov69 # handle up/down actions
70 if Input.is_action_pressed("up"):
71 camera.zoom /= zoom_step
72 if Input.is_action_pressed("down"):
73 camera.zoom *= zoom_step
74
660d0c9d 2023-11-29 Pavel Safronov75 # set the rotation for static controls
76 static_controls.global_rotation = 0
77
78 # set progress bar value and color
8adb41dc 2023-11-19 Pavel Safronov79 var pb: ProgressBar = $Graphics/Alive/StaticControls/ProgressBar
80 var health_ratio = float(health) / float(max_health)
81 var health_percentage = health_ratio * 100
82 pb.value = health_percentage
83 if health_percentage < 20:
84 pb.modulate = Color.red
85 elif health_percentage < 60:
86 pb.modulate = Color.yellow
87 else:
88 pb.modulate = Color.blue
660d0c9d 2023-11-29 Pavel Safronov89
90 # add history to the trail
f3c75ae9 2023-11-15 Pavel Safronov91 trails.add_position(global_position)
660d0c9d 2023-11-29 Pavel Safronov92
93 # set HUD info, like score and current weapon
f3c75ae9 2023-11-15 Pavel Safronov94 hud.set_current_weapon(weapon)
95 hud.score = score
3782f0cf 2023-11-29 Pavel Safronov96
97 # shoot at closest enemy
98 var enemies = get_tree().get_nodes_in_group("enemies")
99 for e in enemies:
100 var enemy: Enemy = e
101 enemy.is_targeted = false
102
103 var filteredEnemies = Utils.filter(funcref(self,"filter_invalid_enemies"), enemies)
104 if filteredEnemies.size() > 0:
105 filteredEnemies.sort_custom(self, "sort_enemies_ascending_distance")
106 var closest_enemy: Enemy = filteredEnemies[0]
107 var dist = closest_enemy.global_position.distance_to(self.global_position)
108 if dist < self.weapon.shooting_range:
109 closest_enemy.is_targeted = true
110 self.shoot_at(closest_enemy.global_position)
111 player_to_target.points[0] = self.global_position
112 player_to_target.points[1] = closest_enemy.global_position
113
afaeaa95 2023-12-01 Pavel Safronov114func filter_invalid_enemies(enemy: Enemy) -> bool:
115 if enemy.dead:
116 return false
117 return true
118
3782f0cf 2023-11-29 Pavel Safronov119func sort_enemies_ascending_distance(a: Enemy,b: Enemy):
120 var distA = self.global_position.distance_to(a.global_position)
121 var distB = self.global_position.distance_to(b.global_position)
122 var result = distA < distB
123 return result
b856550a 2023-10-30 Pavel Safronov124
cbc328fb 2023-11-17 Pavel Safronov125func _physics_process(delta: float) -> void:
b856550a 2023-10-30 Pavel Safronov126 if dead:
127 return
660d0c9d 2023-11-29 Pavel Safronov128
129 # turn toward target
cbc328fb 2023-11-17 Pavel Safronov130 if is_destination_set:
131 turn_towards(destination, delta)
660d0c9d 2023-11-29 Pavel Safronov132
133 # limit movement speed
cbc328fb 2023-11-17 Pavel Safronov134 var speed = velocity.length()
135 if speed < move_speed:
136 velocity = velocity * (1 + delta * accel_rate)
137 speed = velocity.length()
138 if speed > move_speed:
139 velocity = velocity.normalized() * move_speed
b856550a 2023-10-30 Pavel Safronov140 velocity = move_and_slide(velocity)
660d0c9d 2023-11-29 Pavel Safronov141
142 # rotate to match velocity
e496c548 2023-11-06 Pavel Safronov143 global_rotation = velocity.angle() + PI/2.0
b856550a 2023-10-30 Pavel Safronov144
9bc01bd5 2023-11-17 Pavel Safronov145func show_intro() -> void:
146 get_tree().paused = true
147 intro_menu.visible = true
148
4ac09ada 2023-11-09 Pavel Safronov149func clear_radar():
f6120dba 2023-11-08 Pavel Safronov150 radar_sprite.modulate = Color(1,1,1,0)
151 var children = radar_container.get_children()
152 for child in children:
153 radar_container.remove_child(child)
154
fc5de8ee 2023-11-09 Pavel Safronov155func update_radar(items: Array, color: Color):
156 for i in items:
157 var item: Node = i
158 var diff = item.global_position - global_position
f6120dba 2023-11-08 Pavel Safronov159 var dist = diff.length()
660d0c9d 2023-11-29 Pavel Safronov160 var ratio = Utils.dist_to_ratio(dist, radar_min_radius, radar_max_radius) * .8 + .2
f6120dba 2023-11-08 Pavel Safronov161 if dist < radar_min_radius:
162 ratio = 0
163 var angle_to = Vector2.UP.angle_to(diff)
fc5de8ee 2023-11-09 Pavel Safronov164 var sprite: Sprite = radar_sprite.duplicate()
56eea835 2023-12-02 Pavel Safronov165 sprite.scale = camera.zoom / 4
fc5de8ee 2023-11-09 Pavel Safronov166 sprite.rotate(angle_to)
167 sprite.modulate = Color(color.r,color.g,color.b,ratio * .5)
168 radar_container.add_child(sprite)
f6120dba 2023-11-08 Pavel Safronov169
b856550a 2023-10-30 Pavel Safronov170func restart():
236d1677 2023-11-01 Pavel Safronov171 var _error = get_tree().reload_current_scene()
b856550a 2023-10-30 Pavel Safronov172
173func kill():
d99ccd2a 2023-11-04 Pavel Safronov174 if dead or is_invincible:
b856550a 2023-10-30 Pavel Safronov175 return
176 dead = true
f3c75ae9 2023-11-15 Pavel Safronov177 emit_signal("player_died")
178 add_high_score(score)
b856550a 2023-10-30 Pavel Safronov179 $Graphics/Dead.show()
180 $Graphics/Alive.hide()
f3c75ae9 2023-11-15 Pavel Safronov181 final_score_label.text = "Final score: %s" % score
182 death_screen.show()
b856550a 2023-10-30 Pavel Safronov183 z_index = -1
a670e302 2023-11-07 Pavel Safronov184 get_tree().paused = true
b856550a 2023-10-30 Pavel Safronov185
eb5388a0 2023-11-06 Pavel Safronov186func heal(amount: int = 1):
187 if dead:
188 return
189 health += amount
2b4497bb 2023-11-27 Pavel Safronov190 add_damage_label(-amount)
eb5388a0 2023-11-06 Pavel Safronov191 if health > max_health:
192 health = max_health
193
d8d02b36 2023-11-06 Pavel Safronov194func speed_up(delta: int = 10):
195 if dead:
196 return
197 move_speed += delta
198
f398dcb9 2023-11-02 Pavel Safronov199func hurt(damage_amount: int = 1):
d99ccd2a 2023-11-04 Pavel Safronov200 if dead or is_invincible:
b856550a 2023-10-30 Pavel Safronov201 return
fa5168b2 2023-11-08 Pavel Safronov202 else:
203 health -= damage_amount
2b4497bb 2023-11-27 Pavel Safronov204 add_damage_label(damage_amount)
fa5168b2 2023-11-08 Pavel Safronov205 if health <= 0:
206 kill()
b856550a 2023-10-30 Pavel Safronov207
2b4497bb 2023-11-27 Pavel Safronov208func add_damage_label(damage_amount: int = 5) -> void:
209 var damage_label: Damage = Damage.instance()
210 damage_label.value = -damage_amount
211 damage_label.position = self.position
212 get_tree().root.add_child(damage_label)
213
cbc328fb 2023-11-17 Pavel Safronov214func turn_towards(dest: Vector2, _delta: float):
215 var to_dir = (dest - global_position).normalized()
e496c548 2023-11-06 Pavel Safronov216 var curr_dir = velocity.normalized()
217 var dir_diff = to_dir - curr_dir
f54990a1 2023-11-08 Pavel Safronov218 var change = dir_diff * turn_rate * move_speed
e496c548 2023-11-06 Pavel Safronov219 velocity = (velocity + change).normalized() * move_speed
b856550a 2023-10-30 Pavel Safronov220
f398dcb9 2023-11-02 Pavel Safronov221func shoot_at(pos: Vector2):
e9f81b98 2023-11-29 Pavel Safronov222 if weapon.ammo != INF && weapon.ammo <= 0:
223 weapon = create_default_weapon()
f295bf46 2023-11-29 Pavel Safronov224 weapon.try_shoot(self, pos)
f398dcb9 2023-11-02 Pavel Safronov225
f3c75ae9 2023-11-15 Pavel Safronov226func set_objective(objective: String) -> void:
227 hud.objective = objective
228
229func _on_StartButton_pressed() -> void:
230 get_tree().paused = false
231 intro_menu.visible = false
232 settings.show_intro = intro_always_show_intro_check.pressed
233 settings.save_user_settings()
234
235func set_intro_dialog(enabled: bool) -> void:
236 settings.show_intro = enabled
237 settings.save_user_settings()
238
239func _on_PauseAlwaysShowIntroCheckBox_pressed() -> void:
240 var show_intro = pause_always_show_intro_check.pressed
241 set_intro_dialog(show_intro)
242
e96078c1 2023-11-17 Pavel Safronov243func _on_ShowItemsInRadarCheckBox_pressed() -> void:
244 var show_items = pause_show_items_in_radar_check.pressed
245 settings.show_items = show_items
246 settings.save_user_settings()
247
176d22db 2023-12-01 Pavel Safronov248func sort_high_scores(a, b):
249 return (a as Settings.HighScore).score > (b as Settings.HighScore).score
250
f3c75ae9 2023-11-15 Pavel Safronov251func add_high_score(new_score: int) -> void:
252 var hs = Settings.HighScore.new(new_score, Time.get_datetime_dict_from_system())
253 var hss = settings.high_scores
254 hss.push_back(hs)
176d22db 2023-12-01 Pavel Safronov255 hss.sort_custom(self, "sort_high_scores")
256 while hss.size() > 10:
257 hss.pop_back()
258 settings.high_scores = hss
f3c75ae9 2023-11-15 Pavel Safronov259 settings.save_user_settings()
260
261func _on_LinkButton_pressed() -> void:
262 get_tree().paused = true
6b68bafd 2026-10-27 Pavel Safronov263 var _err = OS.shell_open("https://code.fuzzyworld.net/godot-shooter/")
f3c75ae9 2023-11-15 Pavel Safronov264 get_tree().paused = true
265
cbc328fb 2023-11-17 Pavel Safronov266func _on_HUD_position_set(event_pos: Vector2) -> void:
267 var width = ProjectSettings.get("display/window/size/width")
268 var height = ProjectSettings.get("display/window/size/height")
269 var mid = Vector2(width / 2.0, height / 2.0)
f1a6c921 2023-12-01 Pavel Safronov270 var pos = camera_scale(event_pos) + self.position - camera_scale(mid)
cbc328fb 2023-11-17 Pavel Safronov271 set_destination(pos)
272 emit_signal("destination_set")
f3c75ae9 2023-11-15 Pavel Safronov273
f1a6c921 2023-12-01 Pavel Safronov274func camera_scale(pos: Vector2) -> Vector2:
275 var scaled_pos = Vector2(pos.x * camera.zoom.x, pos.y * camera.zoom.y)
276 return scaled_pos
277
f3c75ae9 2023-11-15 Pavel Safronov278func show_message(message: String, duration_seconds: int = 2) -> void:
279 hud.show_message(message, duration_seconds)
280
281func _on_HUD_paused() -> void:
282 get_tree().paused = true
c39514ed 2023-12-01 Pavel Safronov283 pause_menu.show()
cbc328fb 2023-11-17 Pavel Safronov284 clear_destination()
f3c75ae9 2023-11-15 Pavel Safronov285
286func _on_ResumeButton_pressed() -> void:
287 get_tree().paused = false
c39514ed 2023-12-01 Pavel Safronov288 pause_menu.hide()
f3c75ae9 2023-11-15 Pavel Safronov289
290func _on_HUD_debug_signal() -> void:
291 emit_signal("debug")
292
cbc328fb 2023-11-17 Pavel Safronov293func set_destination(pos: Vector2) -> void:
294 destination = pos
295 is_destination_set = true
296 emit_signal("destination_set")
297func clear_destination() -> void:
298 is_destination_set = false
299 emit_signal("destination_set")
300
301func _on_StartNewGameButton_pressed() -> void:
302 get_tree().paused = false
303 restart()
636e5224 2023-12-01 Pavel Safronov304
305
306func _on_Button_pressed() -> void:
307 var _err = get_tree().reload_current_scene()
308 get_tree().paused = false