fuzzyworld

godot-shooter / change-html-template / files / World.gd

Branch change-html-template · default branch · all branches

World.gd

4.6 KB · history · blame

1extends Node2D
2
3const Utils = preload("res://Utils.gd")
4const Enemy = preload("res://Enemy.tscn")
5const Health = preload("res://HealPowerUp.tscn")
6const Speed = preload("res://SpeedPowerUp.tscn")
7var destination: Vector2
8var is_destination_set = false
9var min_items_dict = {
10 "create_enemy": 10,
11 "create_health": 2,
12 "create_speed": 2,
13}
14
15func enemy_killed():
16 $CanvasLayer/HUD.score += 1
17
18func create_enemy():
19 var enemy = Enemy.instance()
20 enemy.position = get_new_item_pos()
21 enemy.add_to_group("enemies")
22 enemy.connect("enemy_killed", self, "enemy_killed")
23 enemy.connect("tree_exiting", self, "create_enemy")
24 $Environment.call_deferred("add_child", enemy)
25
26func create_health():
27 var health = Health.instance()
28 health.position = get_new_item_pos(1 + randf())
29 health.connect("tree_exiting", self, "create_health")
30 $Environment.call_deferred("add_child", health)
31
32func create_speed():
33 var speed = Speed.instance()
34 speed.position = get_new_item_pos(1 + randf())
35 speed.connect("tree_exiting", self, "create_speed")
36 $Environment.call_deferred("add_child", speed)
37
38func _ready() -> void:
39 # create items
40 for creator in min_items_dict:
41 var count = min_items_dict[creator]
42 for n in count:
43 var function = funcref(self, creator)
44 function.call_func()
45
46func get_new_item_pos(dist_ratio: float = 1.0) -> Vector2:
47 var pos_angle = randi() % 360
48 var unit_vector = Vector2.UP.rotated(pos_angle)
49 var size = get_viewport().get_visible_rect().size
50 var max_side = max(size.x, size.y)
51 var screen_radius = max_side + 10
52 var enemy_spawn_dist = screen_radius * dist_ratio
53 var pos = unit_vector * enemy_spawn_dist + $Player.global_position
54 return pos
55
56func _input(event: InputEvent) -> void:
57 if $Player.dead:
58 return
59 var width = ProjectSettings.get("display/window/size/width")
60 var height = ProjectSettings.get("display/window/size/height")
61 var mid = Vector2(width / 2.0, height / 2.0)
62 if event is InputEventScreenTouch && event.pressed:
63 var result = event.position + $Player.position - mid
64 set_destination(result)
65 if event is InputEventScreenDrag:
66 var result = event.position + $Player.position - mid
67 set_destination(result)
68 if event is InputEventMouseMotion:
69 var result = event.position + $Player.position - mid
70 set_destination(result)
71
72func _process(_delta: float) -> void:
73 if Input.is_action_just_pressed("pause"):
74 get_tree().paused = true
75 $CanvasLayer/PauseMenu.show()
76
77 if is_destination_set:
78 $Player.turn_towards(destination)
79 $Destination.visible = true
80 else:
81 $Destination.visible = false
82
83 var enemies = get_tree().get_nodes_in_group("enemies")
84 var filteredEnemies = Utils.filter(funcref(self,"filter_invalid_enemies"), enemies)
85 for e in filteredEnemies:
86 var enemy: Enemy = e
87 enemy.turn_towards($Player.position)
88
89 # remove environment nodes that are too far away
90 # as they are removed, they should replace themselves
91 var screen_radius = get_viewport().get_visible_rect().size.length() / 2 + 10
92 var env_items = $Environment.get_children()
93 Utils.log("env items", env_items.size())
94 for i in env_items:
95 var item: Node2D = i
96 var diff = $Player.global_position - item.global_position
97 var dist = diff.length()
98 var is_too_far = dist > (2.0 * screen_radius)
99 if is_too_far:
100 item.queue_free()
101
102func set_destination(pos: Vector2) -> void:
103 destination = pos
104 is_destination_set = true
105 $Destination.global_position = pos
106 $Destination.visible = true
107
108func _on_Destination_body_entered(body: Node) -> void:
109 if body == $Player:
110 is_destination_set = false
111
112func sort_enemies_ascending_distance(a: Enemy,b: Enemy):
113 var distA = $Player.global_position.distance_to(a.global_position)
114 var distB = $Player.global_position.distance_to(b.global_position)
115 var result = distA < distB
116 return result
117
118func filter_invalid_enemies(enemy: Enemy) -> bool:
119 if enemy.dead:
120 return false
121 return true
122
123func _on_ShootTimer_timeout() -> void:
124 if $Player.dead:
125 return
126 var enemies = get_tree().get_nodes_in_group("enemies")
127 for e in enemies:
128 var enemy: Enemy = e
129 enemy.is_targeted = false
130
131 var filteredEnemies = Utils.filter(funcref(self,"filter_invalid_enemies"), enemies)
132 if filteredEnemies.size() > 0:
133 filteredEnemies.sort_custom(self, "sort_enemies_ascending_distance")
134 var closest_enemy: Enemy = filteredEnemies[0]
135 var dist = closest_enemy.global_position.distance_to($Player.global_position)
136 if dist < $Player.shooting_range:
137 closest_enemy.is_targeted = true
138 $Player.shoot_at(closest_enemy.global_position)
139 $PlayerToTarget.points[0] = $Player.global_position
140 $PlayerToTarget.points[1] = closest_enemy.global_position
141
142func _on_Button_pressed() -> void:
143 get_tree().paused = false
144 $CanvasLayer/PauseMenu.hide()