fuzzyworld

godot-shooter / commit

Reworked how items are generated.

212b7b2549f61db16ea1f225d07f951a957e0b03 · Pavel Safronov · 2023-11-08 06:34:17 -0800 · parents fa5168b2c0cc

Reworked how items are generated.
Added an objective (kill all enemies) that will trigger Game Over screen when reached.
 ItemGenerator.gd => ConstantItemGenerator.gd |  2 +-
 HUD.gd                                       |  4 +--
 HUD.tscn                                     |  6 ++--
 LevelItemGenerator.gd                        | 34 +++++++++++++++++++++
 World.gd                                     | 26 ++++++++++++----
 World.tscn                                   | 44 +++++++++++++++++++++++++---
 project.godot                                | 12 ++++++--
 7 files changed, 109 insertions(+), 19 deletions(-)

diff --git a/ItemGenerator.gd b/ConstantItemGenerator.gd
similarity index 94%
rename from ItemGenerator.gd
rename to ConstantItemGenerator.gd
index 2c369f7..360f741 100644
--- a/ItemGenerator.gd
+++ b/ConstantItemGenerator.gd
@@ -1,4 +1,4 @@
-class_name ItemGenerator
+class_name ConstantItemGenerator
 
 const Utils = preload("res://Utils.gd")
 var item_count: int
diff --git a/HUD.gd b/HUD.gd
index 75ba09f..c858231 100644
--- a/HUD.gd
+++ b/HUD.gd
@@ -5,7 +5,7 @@ export var score = 0
 export var level = 1
 export var objective = "1/17"
 
-onready var label = $CanvasLayer/Label
+onready var label = $CanvasLayer/MessageLabel
 onready var animation_player = $AnimationPlayer
 onready var score_label = $HBoxContainer/Score
 onready var level_label = $MarginContainer/HBoxContainer2/Level
@@ -49,4 +49,4 @@ func show_message(message: String, duration_seconds: int = 2) -> void:
 	animation_player.queue(new_fade_out)
 	
 func set_label_text(new_text: String) -> void:
-	$CanvasLayer/Label.text = new_text
+	label.text = new_text
diff --git a/HUD.tscn b/HUD.tscn
index aa7a573..6e38069 100644
--- a/HUD.tscn
+++ b/HUD.tscn
@@ -85,20 +85,20 @@ margin_right = 480.0
 margin_bottom = 74.0
 
 [node name="LevelText" type="Label" parent="MarginContainer/HBoxContainer2"]
+visible = false
 margin_top = 9.0
 margin_right = 118.0
 margin_bottom = 65.0
 text = "Level:"
 
 [node name="Level" type="Label" parent="MarginContainer/HBoxContainer2"]
-margin_left = 126.0
+visible = false
 margin_top = 9.0
-margin_right = 139.0
+margin_right = 13.0
 margin_bottom = 65.0
 text = "1"
 
 [node name="Objective" type="Label" parent="MarginContainer/HBoxContainer2"]
-visible = false
 margin_left = 407.0
 margin_right = 480.0
 margin_bottom = 74.0
diff --git a/LevelItemGenerator.gd b/LevelItemGenerator.gd
new file mode 100644
index 0000000..d3be1c6
--- /dev/null
+++ b/LevelItemGenerator.gd
@@ -0,0 +1,34 @@
+class_name LevelItemGenerator
+
+const Utils = preload("res://Utils.gd")
+var generated_count: int = 0
+var simultaneous_count: int = 1
+
+var item_count: int
+var creator_name: String
+var instance_object: Object
+var group_name: String
+
+func _init(count, creator, instance, group, sim_count = 1) -> void:
+	item_count = count
+	creator_name = creator
+	group_name = group
+	instance_object = instance
+	simultaneous_count = sim_count
+
+func run(node: Node) -> bool:
+	var items = node.get_tree().get_nodes_in_group(group_name)
+	var generated_enough = generated_count == item_count
+	var finished = generated_enough && items.size() == 0
+	if finished:
+		return true
+	if generated_enough:
+		return false
+	var should_add = items.size() < simultaneous_count
+	if should_add:
+		var item: Node = funcref(instance_object, creator_name).call_func()
+		item.add_to_group(group_name)
+		node.add_child(item)
+		items = node.get_tree().get_nodes_in_group(group_name)
+		generated_count += 1
+	return false
diff --git a/World.gd b/World.gd
index da851b3..ab69107 100644
--- a/World.gd
+++ b/World.gd
@@ -9,15 +9,18 @@ var height = ProjectSettings.get("display/window/size/height")
 var destination: Vector2
 var is_destination_set = false
 var generators = [
-	ItemGenerator.new(10, "create_enemy", self, "enemies"),
-	ItemGenerator.new(5, "create_health", self, "health"),
-	ItemGenerator.new(10, "create_shield", self, "shields"),
-	ItemGenerator.new(5, "create_gold", self, "gold"),
+	LevelItemGenerator.new(4, "create_enemy", self, "enemies", 2),
+	LevelItemGenerator.new(10, "create_health", self, "health", 10),
+	LevelItemGenerator.new(3, "create_shield", self, "shields", 3),
+	LevelItemGenerator.new(5, "create_gold", self, "gold", 5),
 ]
+var completed_objectives = 0
+var max_objectives = 4
 
 func enemy_killed(_position: Vector2):
 	$UI/HUD.score += 1
 	$UI/HUD.show_message("Enemy killed!", 1)
+	completed_objectives += 1
 func health_consumed():
 	$Player.heal()
 	$UI/HUD.show_message("+1 health", 1)
@@ -87,9 +90,16 @@ func _process(_delta: float) -> void:
 		$UI/PauseMenu.show()
 		return
 
+	$UI/HUD.objective = "%s / %s" % [completed_objectives, max_objectives]
+	var all_done = completed_objectives == max_objectives
+	if all_done:
+		get_tree().paused = true
+		$UI/GameFinishedMenu.show()
+		return
+
 	for g in generators:
-		var generator: ItemGenerator = g
-		generator.ensure_items_exist(self)
+		var generator: LevelItemGenerator = g
+		generator.run(self)
 
 	if is_destination_set:
 		$Player.turn_towards(destination)
@@ -162,6 +172,10 @@ func _on_Button_pressed() -> void:
 	get_tree().paused = false
 	$UI/PauseMenu.hide()
 
+func _on_Game_over_button_pressed() -> void:
+	get_tree().paused = false
+	$UI/GameFinishedMenu.hide()
+	get_tree().reload_current_scene()
 
 func _on_Player_shield_changed(shield_active: bool) -> void:
 	var message = "Shield Activated" if shield_active else "Shield Lost!"
diff --git a/World.tscn b/World.tscn
index a85e592..fc4bf60 100644
--- a/World.tscn
+++ b/World.tscn
@@ -80,19 +80,54 @@ margin_right = 132.0
 margin_bottom = 110.0
 
 [node name="Label" type="Label" parent="UI/PauseMenu/Panel/VBoxContainer"]
-margin_right = 114.0
+margin_right = 126.0
 margin_bottom = 35.0
 theme = ExtResource( 6 )
 text = "Paused"
 align = 1
 
 [node name="Button" type="Button" parent="UI/PauseMenu/Panel/VBoxContainer"]
-margin_top = 39.0
-margin_right = 114.0
-margin_bottom = 80.0
+margin_top = 43.0
+margin_right = 126.0
+margin_bottom = 90.0
 theme = ExtResource( 6 )
 text = "Resume"
 
+[node name="GameFinishedMenu" type="Control" parent="UI"]
+pause_mode = 2
+visible = false
+anchor_right = 1.0
+anchor_bottom = 1.0
+margin_right = 40.0
+margin_bottom = 40.0
+mouse_filter = 2
+
+[node name="Panel" type="Panel" parent="UI/GameFinishedMenu"]
+margin_left = 120.0
+margin_top = 233.0
+margin_right = 400.0
+margin_bottom = 483.0
+
+[node name="VBoxContainer" type="VBoxContainer" parent="UI/GameFinishedMenu/Panel"]
+margin_left = 68.0
+margin_top = 72.0
+margin_right = 132.0
+margin_bottom = 110.0
+
+[node name="Label" type="Label" parent="UI/GameFinishedMenu/Panel/VBoxContainer"]
+margin_right = 148.0
+margin_bottom = 35.0
+theme = ExtResource( 6 )
+text = "You've won!"
+align = 1
+
+[node name="Button" type="Button" parent="UI/GameFinishedMenu/Panel/VBoxContainer"]
+margin_top = 43.0
+margin_right = 148.0
+margin_bottom = 90.0
+theme = ExtResource( 6 )
+text = "Restart"
+
 [node name="ShootTimer" type="Timer" parent="."]
 process_mode = 0
 wait_time = 0.1
@@ -113,4 +148,5 @@ antialiased = true
 [connection signal="body_entered" from="Destination" to="." method="_on_Destination_body_entered"]
 [connection signal="shield_changed" from="Player" to="." method="_on_Player_shield_changed"]
 [connection signal="pressed" from="UI/PauseMenu/Panel/VBoxContainer/Button" to="." method="_on_Button_pressed"]
+[connection signal="pressed" from="UI/GameFinishedMenu/Panel/VBoxContainer/Button" to="." method="_on_Game_over_button_pressed"]
 [connection signal="timeout" from="ShootTimer" to="." method="_on_ShootTimer_timeout"]
diff --git a/project.godot b/project.godot
index fac0ddf..1dfe127 100644
--- a/project.godot
+++ b/project.godot
@@ -14,15 +14,20 @@ _global_script_classes=[ {
 "language": "GDScript",
 "path": "res://Bullet.gd"
 }, {
+"base": "Reference",
+"class": "ConstantItemGenerator",
+"language": "GDScript",
+"path": "res://ConstantItemGenerator.gd"
+}, {
 "base": "KinematicBody2D",
 "class": "Enemy",
 "language": "GDScript",
 "path": "res://Enemy.gd"
 }, {
 "base": "Reference",
-"class": "ItemGenerator",
+"class": "LevelItemGenerator",
 "language": "GDScript",
-"path": "res://ItemGenerator.gd"
+"path": "res://LevelItemGenerator.gd"
 }, {
 "base": "KinematicBody2D",
 "class": "Player",
@@ -41,8 +46,9 @@ _global_script_classes=[ {
 } ]
 _global_script_class_icons={
 "Bullet": "",
+"ConstantItemGenerator": "",
 "Enemy": "",
-"ItemGenerator": "",
+"LevelItemGenerator": "",
 "Player": "",
 "PowerUp": "",
 "Trails": ""