fuzzyworld

godot-shooter / commit

Reworked how messages are shown.

44475e041fca700dd6b74a78e9cbb8da549e0b17 · Pavel Safronov · 2023-11-08 02:38:32 -0800 · parents c37b0e755c51

Reworked how messages are shown.
Implemented an item generator pattern for recreating various items.
Player now reports shield changes.
 HUD.gd           | 29 +++++++++++++------
 HUD.tscn         | 22 +++++++++++----
 ItemGenerator.gd | 24 ++++++++++++++++
 Player.gd        |  3 ++
 PowerUp.gd       |  1 +
 World.gd         | 86 +++++++++++++++++++++++++++-----------------------------
 World.tscn       |  1 +
 project.godot    | 12 ++++++++
 8 files changed, 121 insertions(+), 57 deletions(-)

diff --git a/HUD.gd b/HUD.gd
index a7d57f2..46fcafd 100644
--- a/HUD.gd
+++ b/HUD.gd
@@ -1,8 +1,10 @@
 extends Control
 
+const Utils = preload("res://Utils.gd")
 export var score = 0
 onready var label = $CanvasLayer/Label
 onready var animation_player = $AnimationPlayer
+var message_count = 0
 
 func _process(_delta: float) -> void:
 	$VBoxContainer/HBoxContainer/Score.text = "%s" % score
@@ -19,12 +21,23 @@ func restart():
 	get_tree().paused = false
 
 func show_message(message: String, duration_seconds: int = 2) -> void:
-	label.text = message
-	var animation_name = "message fade out"
-	var animation = animation_player.get_animation(animation_name)
-	animation.track_set_key_time(0, 1, duration_seconds)
-	animation_player.remove_animation(animation_name)
-	animation_player.add_animation(animation_name, animation)
+	message_count += 1
+
+	var fade_in = animation_player.get_animation("message fade in")
+	fade_in.track_set_key_value(1, 0, message)
+	var fade_out = animation_player.get_animation("message fade out")
+	fade_out.track_set_key_time(0, 1, duration_seconds)
+
+	var new_fade_in = "fade in %s" % message_count
+	animation_player.add_animation(new_fade_in, fade_in)
+	var new_fade_out = "fade out %s" % message_count
+	animation_player.add_animation(new_fade_out, fade_out)
+	
+	if animation_player.is_playing():
+		animation_player.queue(new_fade_in)
+	else:
+		animation_player.play(new_fade_in)
+	animation_player.queue(new_fade_out)
 	
-	animation_player.queue("message fade in")
-	animation_player.queue(animation_name)
+func set_label_text(new_text: String) -> void:
+	$CanvasLayer/Label.text = new_text
diff --git a/HUD.tscn b/HUD.tscn
index 83be37e..b98556e 100644
--- a/HUD.tscn
+++ b/HUD.tscn
@@ -5,7 +5,6 @@
 
 [sub_resource type="Animation" id=2]
 resource_name = "message fade in"
-length = 0.75
 tracks/0/type = "value"
 tracks/0/path = NodePath("CanvasLayer/Label:modulate")
 tracks/0/interp = 1
@@ -13,15 +12,27 @@ tracks/0/loop_wrap = true
 tracks/0/imported = false
 tracks/0/enabled = true
 tracks/0/keys = {
-"times": PoolRealArray( 0, 0.5 ),
+"times": PoolRealArray( 0, 1 ),
 "transitions": PoolRealArray( 1, 5.65685 ),
 "update": 0,
 "values": [ Color( 1, 1, 1, 0 ), Color( 1, 1, 1, 1 ) ]
 }
+tracks/1/type = "value"
+tracks/1/path = NodePath("CanvasLayer/Label:text")
+tracks/1/interp = 1
+tracks/1/loop_wrap = true
+tracks/1/imported = false
+tracks/1/enabled = true
+tracks/1/keys = {
+"times": PoolRealArray( 0 ),
+"transitions": PoolRealArray( 1 ),
+"update": 1,
+"values": [ "Tap to move???" ]
+}
 
 [sub_resource type="Animation" id=1]
 resource_name = "message fade out"
-length = 5.0
+length = 2.0
 tracks/0/type = "value"
 tracks/0/path = NodePath("CanvasLayer/Label:modulate")
 tracks/0/interp = 1
@@ -29,7 +40,7 @@ tracks/0/loop_wrap = true
 tracks/0/imported = false
 tracks/0/enabled = true
 tracks/0/keys = {
-"times": PoolRealArray( 0, 5 ),
+"times": PoolRealArray( 0, 2 ),
 "transitions": PoolRealArray( 1, 5.65685 ),
 "update": 0,
 "values": [ Color( 1, 1, 1, 1 ), Color( 1, 1, 1, 0 ) ]
@@ -64,6 +75,7 @@ uppercase = true
 [node name="CanvasLayer" type="CanvasLayer" parent="."]
 
 [node name="Label" type="Label" parent="CanvasLayer"]
+modulate = Color( 1, 1, 1, 0 )
 anchor_left = 0.1
 anchor_top = 0.6
 anchor_right = 0.8
@@ -71,7 +83,7 @@ anchor_bottom = 0.8
 margin_right = 40.0
 margin_bottom = 14.0
 theme = ExtResource( 1 )
-text = "Tap to move"
+text = "Tap to move???"
 align = 1
 valign = 1
 autowrap = true
diff --git a/ItemGenerator.gd b/ItemGenerator.gd
new file mode 100644
index 0000000..2c369f7
--- /dev/null
+++ b/ItemGenerator.gd
@@ -0,0 +1,24 @@
+class_name ItemGenerator
+
+const Utils = preload("res://Utils.gd")
+var item_count: int
+var creator_name: String
+var instance_object: Object
+var group_name: String
+
+func _init(count, creator, instance, group) -> void:
+	item_count = count
+	creator_name = creator
+	group_name = group
+	instance_object = instance
+
+func ensure_items_exist(node: Node) -> void:
+	while true:
+		var items = node.get_tree().get_nodes_in_group(group_name)
+		var should_add = items.size() < item_count
+		if should_add:
+			var item: Node = funcref(instance_object, creator_name).call_func()
+			item.add_to_group(group_name)
+			node.add_child(item)
+		else:
+			break
diff --git a/Player.gd b/Player.gd
index b32788d..95bce87 100644
--- a/Player.gd
+++ b/Player.gd
@@ -11,6 +11,7 @@ export var turn_rate = 0.03
 export var shooting_range = 500
 export var shield_active = true
 export var shield_restart_period_seconds = 5
+signal shield_changed
 
 var PopupControl = preload("res://Popup.tscn")
 
@@ -63,6 +64,7 @@ func speed_up(delta: int = 10):
 func enable_shield() -> void:
 	shield_active = true
 	$Graphics/Alive/Shield/Sprite/AnimationPlayer.play("fade in")
+	emit_signal("shield_changed", shield_active)
 
 func hurt(damage_amount: int = 1):
 	if dead or is_invincible:
@@ -70,6 +72,7 @@ func hurt(damage_amount: int = 1):
 	if shield_active:
 		shield_active = false
 		$Graphics/Alive/Shield/Sprite/AnimationPlayer.play("fade out")
+		emit_signal("shield_changed", shield_active)
 		var timer = Timer.new()
 		add_child(timer)
 		timer.wait_time = shield_restart_period_seconds
diff --git a/PowerUp.gd b/PowerUp.gd
index 64628f5..93e98f1 100644
--- a/PowerUp.gd
+++ b/PowerUp.gd
@@ -1,4 +1,5 @@
 extends Node2D
+class_name PowerUp
 
 export var label = "+SP"
 export var color = Color.gold
diff --git a/World.gd b/World.gd
index af99a2c..da851b3 100644
--- a/World.gd
+++ b/World.gd
@@ -8,69 +8,57 @@ var height = ProjectSettings.get("display/window/size/height")
 
 var destination: Vector2
 var is_destination_set = false
-var min_items_dict = {
-	"create_enemy": 10,
-	"create_health": 5,
-#	"create_speed": 2,
-	"create_gold": 5,
-}
-
-func enemy_killed(position: Vector2):
+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"),
+]
+
+func enemy_killed(_position: Vector2):
 	$UI/HUD.score += 1
-	$UI/HUD.show_message("Enemy killed!", .5)
-	create_gold(position)
+	$UI/HUD.show_message("Enemy killed!", 1)
 func health_consumed():
 	$Player.heal()
 	$UI/HUD.show_message("+1 health", 1)
-func speed_consumed():
-	$Player.speed_up()
-	$UI/HUD.show_message("+10 speed", 1)
+func shield_consumed():
+	$Player.enable_shield()
+	$UI/HUD.show_message("Shield!", 1)
 func gold_consumed():
 	$UI/HUD.score += 5
 	$UI/HUD.show_message("+5 points", 1)
 	
-func create_enemy():
+func create_enemy() -> Enemy:
 	var enemy = Enemy.instance()
 	enemy.position = get_new_item_pos()
-	enemy.add_to_group("enemies")
 	enemy.connect("enemy_killed", self, "enemy_killed")
-	enemy.connect("tree_exiting", self, "create_enemy")
-	$Environment.call_deferred("add_child", enemy)
+	return enemy
 
-func create_health():
+func create_health() -> PowerUp:
 	var health = PowerUp.instance()
 	health.position = get_new_item_pos(1 + randf())
-	health.connect("tree_exiting", self, "create_health")
 	health.connect("consumed", self, "health_consumed")
 	health.label = "+HP"
 	health.color = Color.green
-	$Environment.call_deferred("add_child", health)
-
-func create_speed():
-	var speed = PowerUp.instance()
-	speed.position = get_new_item_pos(1 + randf())
-	speed.connect("tree_exiting", self, "create_speed")
-	speed.connect("consumed", self, "speed_consumed")
-	speed.label = "+SP"
-	speed.color = Color.blue
-	$Environment.call_deferred("add_child", speed)
-
-func create_gold(pos: Vector2 = get_new_item_pos(1 + randf())):
-	var speed = PowerUp.instance()
-	speed.position = pos
-	speed.connect("tree_exiting", self, "create_gold")
-	speed.connect("consumed", self, "gold_consumed")
-	speed.label = "+5"
-	speed.color = Color.gold
-	$Environment.call_deferred("add_child", speed)
+	return health
+
+func create_shield() -> PowerUp:
+	var shield = PowerUp.instance()
+	shield.position = get_new_item_pos(1 + randf())
+	shield.connect("consumed", self, "shield_consumed")
+	shield.label = "Shield"
+	shield.color = Color.blue
+	return shield
+
+func create_gold(pos: Vector2 = get_new_item_pos(1 + randf())) -> PowerUp:
+	var gold = PowerUp.instance()
+	gold.position = pos
+	gold.connect("consumed", self, "gold_consumed")
+	gold.label = "+5"
+	gold.color = Color.gold
+	return gold
 
 func _ready() -> void:
-	# create items
-	for creator in min_items_dict:
-		var count = min_items_dict[creator]
-		for n in count:
-			var function = funcref(self, creator)
-			function.call_func()
 	$UI/HUD.show_message("Tap/drag to move")
 
 func get_new_item_pos(dist_ratio: float = 1.0) -> Vector2:
@@ -97,6 +85,11 @@ func _process(_delta: float) -> void:
 	if Input.is_action_just_pressed("pause"):
 		get_tree().paused = true
 		$UI/PauseMenu.show()
+		return
+
+	for g in generators:
+		var generator: ItemGenerator = g
+		generator.ensure_items_exist(self)
 
 	if is_destination_set:
 		$Player.turn_towards(destination)
@@ -168,3 +161,8 @@ func _on_ShootTimer_timeout() -> void:
 func _on_Button_pressed() -> void:
 	get_tree().paused = false
 	$UI/PauseMenu.hide()
+
+
+func _on_Player_shield_changed(shield_active: bool) -> void:
+	var message = "Shield Activated" if shield_active else "Shield Lost!"
+	$UI/HUD.show_message(message)
diff --git a/World.tscn b/World.tscn
index e15ce44..a85e592 100644
--- a/World.tscn
+++ b/World.tscn
@@ -111,5 +111,6 @@ round_precision = 13
 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="timeout" from="ShootTimer" to="." method="_on_ShootTimer_timeout"]
diff --git a/project.godot b/project.godot
index 6b360f6..fac0ddf 100644
--- a/project.godot
+++ b/project.godot
@@ -19,12 +19,22 @@ _global_script_classes=[ {
 "language": "GDScript",
 "path": "res://Enemy.gd"
 }, {
+"base": "Reference",
+"class": "ItemGenerator",
+"language": "GDScript",
+"path": "res://ItemGenerator.gd"
+}, {
 "base": "KinematicBody2D",
 "class": "Player",
 "language": "GDScript",
 "path": "res://Player.gd"
 }, {
 "base": "Node2D",
+"class": "PowerUp",
+"language": "GDScript",
+"path": "res://PowerUp.gd"
+}, {
+"base": "Node2D",
 "class": "Trails",
 "language": "GDScript",
 "path": "res://Trails.gd"
@@ -32,7 +42,9 @@ _global_script_classes=[ {
 _global_script_class_icons={
 "Bullet": "",
 "Enemy": "",
+"ItemGenerator": "",
 "Player": "",
+"PowerUp": "",
 "Trails": ""
 }