godot-shooter / files / scenes / World.gd
World.gd
5b18ed86 2023-11-01 Pavel Safronov | 1 | extends Node2D |
| 2 | ||
93d86765 2023-11-17 Pavel Safronov | 3 | const Enemy = preload("res://actors/Enemy.tscn") |
| 4 | const Bomb = preload("res://weapons/Bomb.tscn") | |
| 5 | ||
16938031 2023-11-17 Pavel Safronov | 6 | const Utils = preload("res://utils/Utils.gd") |
| 7 | const Weapons = preload("res://weapons/Weapons.gd") | |
| 8 | const PowerUp = preload("res://items/PowerUp.tscn") | |
| 9 | const Settings = preload("res://utils/Settings.gd") | |
f3c75ae9 2023-11-15 Pavel Safronov | 10 | onready var player: Player = $Player |
62151b90 2023-11-29 Pavel Safronov | 11 | onready var update_timer = $UpdateTimer |
afb9a0a5 2023-11-30 Pavel Safronov | 12 | onready var navigation_polygon_instance: NavigationPolygonInstance = $NavigationPolygonInstance |
a45831a2 2023-12-01 Pavel Safronov | 13 | onready var environment_node = $Environment |
4ac09ada 2023-11-09 Pavel Safronov | 14 | |
44475e04 2023-11-08 Pavel Safronov | 15 | var generators = [ |
6a08f6b2 2023-12-01 Pavel Safronov | 16 | ConstantItemGenerator.new("create_enemy", self, "enemies", 5), |
c65ec260 2023-12-01 Pavel Safronov | 17 | ConstantItemGenerator.new("create_health", self, "health", 20), |
c2827327 2023-11-10 Pavel Safronov | 18 | ConstantItemGenerator.new("create_weapon", self, "weapon", 10), |
93d86765 2023-11-17 Pavel Safronov | 19 | ConstantItemGenerator.new("create_bomb", self, "bombs", 10), |
212b7b25 2023-11-08 Pavel Safronov | 20 | LevelItemGenerator.new(5, "create_gold", self, "gold", 5), |
44475e04 2023-11-08 Pavel Safronov | 21 | ] |
212b7b25 2023-11-08 Pavel Safronov | 22 | var completed_objectives = 0 |
f6120dba 2023-11-08 Pavel Safronov | 23 | var max_objectives = 5 |
4cb0d97e 2023-11-10 Pavel Safronov | 24 | var item_replacement_distance = 2000 |
641b63b5 2023-11-10 Pavel Safronov | 25 | var is_dragging = false |
636e5224 2023-12-01 Pavel Safronov | 26 | var is_game_over = false |
56eea835 2023-12-02 Pavel Safronov | 27 | export var starting_zoom = 1.5 |
44475e04 2023-11-08 Pavel Safronov | 28 | |
| 29 | func enemy_killed(_position: Vector2): | |
f3c75ae9 2023-11-15 Pavel Safronov | 30 | player.score += 5 |
bfa99fb9 2023-12-01 Pavel Safronov | 31 | func health_consumed(_power_up): |
a45831a2 2023-12-01 Pavel Safronov | 32 | player.heal(20) |
6b8f57b9 2023-11-17 Pavel Safronov | 33 | player.score += 1 |
bfa99fb9 2023-12-01 Pavel Safronov | 34 | func gold_consumed(_power_up): |
fc5de8ee 2023-11-09 Pavel Safronov | 35 | completed_objectives += 1 |
f85124dd 2023-11-17 Pavel Safronov | 36 | var points = 5 * (completed_objectives+1) |
| 37 | player.score += points | |
5320761c 2023-11-17 Pavel Safronov | 38 | player.show_message("+%d points" % points) |
a45831a2 2023-12-01 Pavel Safronov | 39 | player.health = player.max_health |
bfa99fb9 2023-12-01 Pavel Safronov | 40 | func weapon_consumed(power_up): |
| 41 | var data = power_up.data | |
8b763d15 2023-11-11 Pavel Safronov | 42 | var weapon: Weapon = data |
5be558de 2023-11-17 Pavel Safronov | 43 | var is_same_weapon = player.weapon.name == weapon.name |
8b763d15 2023-11-11 Pavel Safronov | 44 | if is_same_weapon && weapon.ammo != INF: |
5be558de 2023-11-17 Pavel Safronov | 45 | player.weapon.ammo += player.weapon.reload_size |
8b763d15 2023-11-11 Pavel Safronov | 46 | else: |
5be558de 2023-11-17 Pavel Safronov | 47 | player.weapon = weapon |
bfa99fb9 2023-12-01 Pavel Safronov | 48 | func bomb_consumed(power_up): |
| 49 | var pos: Vector2 = power_up.global_position | |
93d86765 2023-11-17 Pavel Safronov | 50 | var bomb = Bomb.instance() |
a45831a2 2023-12-01 Pavel Safronov | 51 | environment_node.call_deferred("add_child",bomb) |
93d86765 2023-11-17 Pavel Safronov | 52 | bomb.position = pos |
8b763d15 2023-11-11 Pavel Safronov | 53 | |
44475e04 2023-11-08 Pavel Safronov | 54 | func create_enemy() -> Enemy: |
969fd5af 2023-11-06 Pavel Safronov | 55 | var enemy = Enemy.instance() |
6ad40cea 2023-12-01 Pavel Safronov | 56 | enemy.position = get_new_environment_position(1) |
969fd5af 2023-11-06 Pavel Safronov | 57 | enemy.connect("enemy_killed", self, "enemy_killed") |
44475e04 2023-11-08 Pavel Safronov | 58 | return enemy |
| 59 | func create_health() -> PowerUp: | |
11ed9f7a 2023-11-08 Pavel Safronov | 60 | var health = PowerUp.instance() |
0d392ff8 2023-11-10 Pavel Safronov | 61 | health.position = get_new_environment_position(randf() + .5) |
ddae17d7 2023-11-08 Pavel Safronov | 62 | health.connect("consumed", self, "health_consumed") |
11ed9f7a 2023-11-08 Pavel Safronov | 63 | health.label = "+HP" |
| 64 | health.color = Color.green | |
44475e04 2023-11-08 Pavel Safronov | 65 | return health |
93d86765 2023-11-17 Pavel Safronov | 66 | func create_bomb() -> PowerUp: |
| 67 | var bomb = PowerUp.instance() | |
| 68 | var pos = get_new_environment_position(randf() + .5) | |
| 69 | bomb.position = pos | |
| 70 | bomb.connect("consumed", self, "bomb_consumed") | |
| 71 | bomb.label = "BOMB" | |
| 72 | bomb.color = Color.purple | |
| 73 | return bomb | |
0d392ff8 2023-11-10 Pavel Safronov | 74 | func create_gold(pos: Vector2 = get_new_environment_position(1 + randf())) -> PowerUp: |
44475e04 2023-11-08 Pavel Safronov | 75 | var gold = PowerUp.instance() |
| 76 | gold.position = pos | |
| 77 | gold.connect("consumed", self, "gold_consumed") | |
fc5de8ee 2023-11-09 Pavel Safronov | 78 | gold.label = "" |
44475e04 2023-11-08 Pavel Safronov | 79 | gold.color = Color.gold |
| 80 | return gold | |
5e4e3a9c 2023-11-08 Pavel Safronov | 81 | func create_weapon() -> PowerUp: |
8b763d15 2023-11-11 Pavel Safronov | 82 | var weapon: PowerUp = PowerUp.instance() |
0d392ff8 2023-11-10 Pavel Safronov | 83 | weapon.position = get_new_environment_position(randf() + .5) |
8b763d15 2023-11-11 Pavel Safronov | 84 | var _err = weapon.connect("consumed", self, "weapon_consumed") |
| 85 | var r = randf() | |
c3ac3ece 2023-11-11 Pavel Safronov | 86 | if r < .45: |
8b763d15 2023-11-11 Pavel Safronov | 87 | weapon.data = Weapons.create_rocket_gun() |
| 88 | weapon.label = "ROC" | |
| 89 | weapon.color = Color.red | |
c3ac3ece 2023-11-11 Pavel Safronov | 90 | elif r < .9: |
023ec2fb 2023-11-29 Pavel Safronov | 91 | weapon.data = Weapons.create_smg_gun() |
8b763d15 2023-11-11 Pavel Safronov | 92 | weapon.label = "SMG" |
| 93 | weapon.color = Color.orange | |
| 94 | else: | |
| 95 | weapon.data = Weapons.create_basic_gun() | |
| 96 | weapon.label = "LZR" | |
| 97 | weapon.color = Color.pink | |
5e4e3a9c 2023-11-08 Pavel Safronov | 98 | return weapon |
5b18ed86 2023-11-01 Pavel Safronov | 99 | |
c1061565 2023-11-07 Pavel Safronov | 100 | func get_new_item_pos(dist_ratio: float = 1.0) -> Vector2: |
5b18ed86 2023-11-01 Pavel Safronov | 101 | var pos_angle = randi() % 360 |
| 102 | var unit_vector = Vector2.UP.rotated(pos_angle) | |
0bfcffe2 2023-11-07 Pavel Safronov | 103 | var size = get_viewport().get_visible_rect().size |
| 104 | var max_side = max(size.x, size.y) | |
da9d123a 2023-11-07 Pavel Safronov | 105 | var screen_radius = max_side + 10 |
c1061565 2023-11-07 Pavel Safronov | 106 | var enemy_spawn_dist = screen_radius * dist_ratio |
5b18ed86 2023-11-01 Pavel Safronov | 107 | var pos = unit_vector * enemy_spawn_dist + $Player.global_position |
969fd5af 2023-11-06 Pavel Safronov | 108 | return pos |
0d392ff8 2023-11-10 Pavel Safronov | 109 | func get_new_environment_position(dist_ratio: float = 1.0) -> Vector2: |
| 110 | var potential_pos: Vector2 | |
| 111 | while true: | |
| 112 | # find the positions of the closest Environment items | |
a45831a2 2023-12-01 Pavel Safronov | 113 | var items = environment_node.get_children() |
0d392ff8 2023-11-10 Pavel Safronov | 114 | potential_pos = get_new_item_pos(dist_ratio) |
| 115 | var closest_pos = 10000 | |
| 116 | for i in items: | |
| 117 | var item: Node2D = i | |
| 118 | var pos = item.global_position | |
| 119 | var dist = potential_pos.distance_to(pos) | |
| 120 | if dist < closest_pos: | |
| 121 | closest_pos = dist | |
| 122 | var is_too_close = closest_pos < 50 | |
| 123 | var found_one = !is_too_close | |
| 124 | if found_one: | |
| 125 | break | |
| 126 | return potential_pos | |
| 127 | ||
7929daa8 2023-11-30 Pavel Safronov | 128 | func _ready() -> void: |
56eea835 2023-12-02 Pavel Safronov | 129 | player.camera.zoom = Vector2(starting_zoom, starting_zoom) |
7929daa8 2023-11-30 Pavel Safronov | 130 | run_generators() |
6ad40cea 2023-12-01 Pavel Safronov | 131 | # # position first two enemies |
| 132 | # var enemies = get_tree().get_nodes_in_group("enemies") | |
| 133 | # var enemy1: Enemy = enemies[0] | |
| 134 | # enemy1.position = Vector2(-300, 200) | |
| 135 | # var enemy2: Enemy = enemies[1] | |
| 136 | # enemy2.position = Vector2(300, 200) | |
7929daa8 2023-11-30 Pavel Safronov | 137 | pass |
| 138 | ||
| 139 | func run_generators() -> void: | |
| 140 | for g in generators: | |
| 141 | var generator = g | |
| 142 | while true: | |
| 143 | var is_done = generator.run($Environment) | |
| 144 | if is_done: | |
| 145 | break | |
| 146 | pass | |
| 147 | ||
641b63b5 2023-11-10 Pavel Safronov | 148 | func _input(_event: InputEvent) -> void: |
5be558de 2023-11-17 Pavel Safronov | 149 | if player.dead: |
1e3c7d1f 2023-11-06 Pavel Safronov | 150 | return |
a71b5173 2023-11-02 Pavel Safronov | 151 | |
8c2ffd3f 2023-11-02 Pavel Safronov | 152 | func _process(_delta: float) -> void: |
636e5224 2023-12-01 Pavel Safronov | 153 | if is_game_over: |
| 154 | return | |
| 155 | ||
afb9a0a5 2023-11-30 Pavel Safronov | 156 | # move navigation polygon around the player, navigation won't work outside of this polygon |
| 157 | var nav_size = Vector2(item_replacement_distance * 2 * 5, item_replacement_distance * 2 * 5) | |
| 158 | var nav_pos = player.global_position - (nav_size * 0.5) | |
| 159 | var vertices = PoolVector2Array([ | |
| 160 | nav_pos, | |
| 161 | nav_pos + Vector2(nav_size.x, 0), | |
| 162 | nav_pos + nav_size, | |
| 163 | nav_pos + Vector2(0, nav_size.y) | |
| 164 | ]) | |
| 165 | var polygon = NavigationPolygon.new() | |
| 166 | polygon.set_vertices(vertices) | |
| 167 | var indices = PoolIntArray([0, 1, 2, 3]) | |
| 168 | polygon.add_polygon(indices) | |
| 169 | navigation_polygon_instance.navpoly = polygon | |
| 170 | ||
| 171 | # set the objective text | |
f3c75ae9 2023-11-15 Pavel Safronov | 172 | player.set_objective("%s / %s" % [completed_objectives, max_objectives]) |
afb9a0a5 2023-11-30 Pavel Safronov | 173 | |
| 174 | # if all objectives are complete, show the game finished menu | |
212b7b25 2023-11-08 Pavel Safronov | 175 | var all_done = completed_objectives == max_objectives |
| 176 | if all_done: | |
636e5224 2023-12-01 Pavel Safronov | 177 | is_game_over = true |
0d177436 2023-11-15 Pavel Safronov | 178 | var score = player.score |
f3c75ae9 2023-11-15 Pavel Safronov | 179 | player.add_high_score(score) |
fc5de8ee 2023-11-09 Pavel Safronov | 180 | var final_message = "You won with %s points!" % score |
0d177436 2023-11-15 Pavel Safronov | 181 | $Player/UI/GameFinishedMenu.find_node("Label").text = final_message |
| 182 | $Player/UI/GameFinishedMenu.show() | |
636e5224 2023-12-01 Pavel Safronov | 183 | $Player/UI/HUD.is_game_over = true |
a45831a2 2023-12-01 Pavel Safronov | 184 | get_tree().paused = true |
212b7b25 2023-11-08 Pavel Safronov | 185 | return |
| 186 | ||
7929daa8 2023-11-30 Pavel Safronov | 187 | run_generators() |
afb9a0a5 2023-11-30 Pavel Safronov | 188 | |
| 189 | # position the destination | |
cbc328fb 2023-11-17 Pavel Safronov | 190 | $Destination.visible = player.is_destination_set |
| 191 | $Destination.global_position = player.destination | |
4ac09ada 2023-11-09 Pavel Safronov | 192 | |
afb9a0a5 2023-11-30 Pavel Safronov | 193 | # clear radar and populate with all items |
| 194 | var enemies = get_tree().get_nodes_in_group("enemies") | |
| 195 | var filteredEnemies = Utils.filter(funcref(self,"filter_invalid_enemies"), enemies) | |
| 196 | player.clear_radar() | |
| 197 | player.update_radar(get_tree().get_nodes_in_group("gold"), Color.gold) | |
| 198 | player.update_radar(filteredEnemies, Color.red) | |
e96078c1 2023-11-17 Pavel Safronov | 199 | if player.settings.show_items: |
| 200 | player.update_radar(get_tree().get_nodes_in_group("health"), Color.gray) | |
| 201 | player.update_radar(get_tree().get_nodes_in_group("weapons"), Color.white) | |
93d86765 2023-11-17 Pavel Safronov | 202 | player.update_radar(get_tree().get_nodes_in_group("bombs"), Color.purple) |
e96078c1 2023-11-17 Pavel Safronov | 203 | |
6e5e56fe 2023-11-02 Pavel Safronov | 204 | func _on_Destination_body_entered(body: Node) -> void: |
5be558de 2023-11-17 Pavel Safronov | 205 | if body == player: |
cbc328fb 2023-11-17 Pavel Safronov | 206 | player.clear_destination() |
f398dcb9 2023-11-02 Pavel Safronov | 207 | |
52220002 2023-11-06 Pavel Safronov | 208 | func filter_invalid_enemies(enemy: Enemy) -> bool: |
| 209 | if enemy.dead: | |
| 210 | return false | |
| 211 | return true | |
f398dcb9 2023-11-02 Pavel Safronov | 212 | |
| 213 | func _on_ShootTimer_timeout() -> void: | |
5be558de 2023-11-17 Pavel Safronov | 214 | if player.dead: |
f398dcb9 2023-11-02 Pavel Safronov | 215 | return |
52220002 2023-11-06 Pavel Safronov | 216 | |
| 217 | func _on_Button_pressed() -> void: | |
| 218 | get_tree().paused = false | |
04130db8 2023-11-07 Pavel Safronov | 219 | $UI/PauseMenu.hide() |
44475e04 2023-11-08 Pavel Safronov | 220 | |
212b7b25 2023-11-08 Pavel Safronov | 221 | func _on_Game_over_button_pressed() -> void: |
| 222 | $UI/GameFinishedMenu.hide() | |
5f3f5126 2023-11-10 Pavel Safronov | 223 | restart() |
44475e04 2023-11-08 Pavel Safronov | 224 | |
5f3f5126 2023-11-10 Pavel Safronov | 225 | func restart() -> void: |
| 226 | get_tree().paused = false | |
| 227 | var _err = get_tree().reload_current_scene() | |
| 228 | ||
f3c75ae9 2023-11-15 Pavel Safronov | 229 | func _on_Player_debug() -> void: |
0d177436 2023-11-15 Pavel Safronov | 230 | # player.score += 1 |
| 231 | # player.kill() | |
a45831a2 2023-12-01 Pavel Safronov | 232 | # player.score = 123 |
0d177436 2023-11-15 Pavel Safronov | 233 | # completed_objectives = max_objectives |
0386b89d 2023-11-17 Pavel Safronov | 234 | # player.debug() |
a45831a2 2023-12-01 Pavel Safronov | 235 | # weapon_consumed(Weapons.create_rocket_gun()) |
| 236 | pass | |
ede9acdd 2023-11-17 Pavel Safronov | 237 | |
| 238 | func _on_Player_destination_set() -> void: | |
| 239 | $Destination.visible = player.is_destination_set | |
| 240 | $Destination.global_position = player.destination | |
| 241 | pass | |
62151b90 2023-11-29 Pavel Safronov | 242 | |
| 243 | func _on_UpdateTimer_timeout() -> void: | |
a45831a2 2023-12-01 Pavel Safronov | 244 | var env_items = environment_node.get_children() |
| 245 | for ei in env_items: | |
| 246 | var item = ei as Node2D | |
| 247 | var enemy := item as Enemy | |
| 248 | if enemy: | |
| 249 | # if item is enemy, have them target the player | |
| 250 | enemy.set_target($Player.position) | |
| 251 | ||
| 252 | var diff = item.global_position - player.global_position | |
62151b90 2023-11-29 Pavel Safronov | 253 | var dist = diff.length() |
| 254 | var is_too_far = dist > item_replacement_distance | |
| 255 | if is_too_far: | |
| 256 | var new_pos = get_new_environment_position(1 + randf()) | |
a45831a2 2023-12-01 Pavel Safronov | 257 | Utils.log("moving distant item from", item.global_position, "to", new_pos) |
| 258 | if enemy: | |
| 259 | enemy.teleport(new_pos) | |
| 260 | else: | |
| 261 | item.global_position = new_pos |