fuzzyworld

godot-shooter / commit

Got most of a game working!

fc5de8ee27c41c625ea372e6d14cddc5125dd5db · Pavel Safronov · 2023-11-09 15:49:24 -0800 · parents 4ac09ada620b

Got most of a game working!
- changed the constant item generator to generate a constant stream of characters
- added a teleport method to Enemy, which change the position of an Enemy and resets its trail history
- reworked the update_radar method to handle any Node and represent it on the radar with a notch of a given color
- gold power ups are now treated as objectives, there are 5 of them
 ConstantItemGenerator.gd | 27 ++++++++++++++-------------
 Enemy.gd                 |  4 ++++
 Player.gd                | 16 ++++++++--------
 Player.tscn              |  5 ++---
 Trails.gd                |  3 +++
 World.gd                 | 20 ++++++++++++++++----
 6 files changed, 47 insertions(+), 28 deletions(-)

diff --git a/ConstantItemGenerator.gd b/ConstantItemGenerator.gd
index 360f741..cbb7137 100644
--- a/ConstantItemGenerator.gd
+++ b/ConstantItemGenerator.gd
@@ -1,24 +1,25 @@
 class_name ConstantItemGenerator
 
 const Utils = preload("res://Utils.gd")
+var generated_count: int = 0
 var item_count: int
 var creator_name: String
 var instance_object: Object
 var group_name: String
+var simultaneous_count
 
-func _init(count, creator, instance, group) -> void:
-	item_count = count
+func _init(creator, instance, group, sim_count = 1) -> void:
 	creator_name = creator
-	group_name = group
 	instance_object = instance
+	group_name = group
+	simultaneous_count = sim_count
 
-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
+func run(node: Node) -> bool:
+	var items = node.get_tree().get_nodes_in_group(group_name)
+	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)
+		generated_count += 1
+	return false
diff --git a/Enemy.gd b/Enemy.gd
index a55f423..1333e94 100644
--- a/Enemy.gd
+++ b/Enemy.gd
@@ -84,6 +84,10 @@ func kill():
 	z_index = -1
 	emit_signal("enemy_killed", global_position)
 
+func teleport(dest: Vector2) -> void:
+	$Graphics/Alive/Trails.clear()
+	position = dest
+
 func _on_death_explosion_finished():
 	$AnimationPlayer.play("fade_out")
 
diff --git a/Player.gd b/Player.gd
index a21a110..b0b79b9 100644
--- a/Player.gd
+++ b/Player.gd
@@ -53,19 +53,19 @@ func clear_radar():
 	for child in children:
 		radar_container.remove_child(child)
 
-func update_radar(enemies: Array, color: Color):
-	for e in enemies:
-		var enemy: Enemy = e
-		var diff = enemy.global_position - global_position
+func update_radar(items: Array, color: Color):
+	for i in items:
+		var item: Node = i
+		var diff = item.global_position - global_position
 		var dist = diff.length()
 		var ratio = Utils.dist_to_ratio(dist, radar_min_radius, radar_max_radius)
 		if dist < radar_min_radius:
 			ratio = 0
 		var angle_to = Vector2.UP.angle_to(diff)
-		var item: Sprite = radar_sprite.duplicate()
-		item.rotate(angle_to)
-		item.modulate = Color(color.r,color.g,color.b,ratio * .5)
-		radar_container.add_child(item)
+		var sprite: Sprite = radar_sprite.duplicate()
+		sprite.rotate(angle_to)
+		sprite.modulate = Color(color.r,color.g,color.b,ratio * .5)
+		radar_container.add_child(sprite)
 
 func restart():
 	var _error = get_tree().reload_current_scene()
diff --git a/Player.tscn b/Player.tscn
index db6d667..22fc62c 100644
--- a/Player.tscn
+++ b/Player.tscn
@@ -3,10 +3,10 @@
 [ext_resource path="res://assets/kenney_simple-space/PNG/Default/ship_sidesA.png" type="Texture" id=1]
 [ext_resource path="res://Explosion.tscn" type="PackedScene" id=2]
 [ext_resource path="res://Player.gd" type="Script" id=3]
+[ext_resource path="res://assets/kenney_simple-space/PNG/Retina/ship_B.png" type="Texture" id=4]
 [ext_resource path="res://CharacterTheme.tres" type="Theme" id=5]
 [ext_resource path="res://Trails.tscn" type="PackedScene" id=6]
 [ext_resource path="res://assets/kenney_crosshair-pack/PNG/White Retina/crosshair120.png" type="Texture" id=7]
-[ext_resource path="res://assets/kenney_simple-space/PNG/Retina/ship_A.png" type="Texture" id=8]
 
 [sub_resource type="CircleShape2D" id=7]
 radius = 36.0
@@ -196,9 +196,8 @@ align = 1
 uppercase = true
 
 [node name="RadarSprite" type="Sprite" parent="Graphics/Alive/StaticControls"]
-modulate = Color( 1, 0, 0, 0.517647 )
 scale = Vector2( 0.4, 0.4 )
-texture = ExtResource( 8 )
+texture = ExtResource( 4 )
 offset = Vector2( 0, -300 )
 
 [node name="Radar" type="Node2D" parent="Graphics/Alive/StaticControls"]
diff --git a/Trails.gd b/Trails.gd
index eecf198..7b3c934 100644
--- a/Trails.gd
+++ b/Trails.gd
@@ -25,3 +25,6 @@ func add_position(pos: Vector2) -> void:
 	while points.size() > trails_length:
 		points.remove(0)
 	trails.points = points
+
+func clear() -> void:
+	trails.points = []
diff --git a/World.gd b/World.gd
index e675ad9..a17ea76 100644
--- a/World.gd
+++ b/World.gd
@@ -12,7 +12,7 @@ onready var player = $Player
 var destination: Vector2
 var is_destination_set = false
 var generators = [
-	LevelItemGenerator.new(5, "create_enemy", self, "enemies", 2),
+	ConstantItemGenerator.new("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),
@@ -20,17 +20,18 @@ var generators = [
 ]
 var completed_objectives = 0
 var max_objectives = 5
+var item_replacement_distance = 3000
 
 func enemy_killed(_position: Vector2):
 	$UI/HUD.score += 1
 	$UI/HUD.show_message("Enemy killed!", 1)
-	completed_objectives += 1
 func health_consumed():
 	$Player.heal()
 func shield_consumed():
 	Utils.log("consuming a shield and sending a message")
 	$Player.enable_shield()
 func gold_consumed():
+	completed_objectives += 1
 	$UI/HUD.score += 5
 func weapon_consumed():
 	$Player.weapon = Weapons.create_rocket_gun()
@@ -61,7 +62,7 @@ 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.label = ""
 	gold.color = Color.gold
 	return gold
 
@@ -105,11 +106,14 @@ func _process(_delta: float) -> void:
 	var all_done = completed_objectives == max_objectives
 	if all_done:
 		get_tree().paused = true
+		var score = $UI/HUD.score
+		var final_message = "You won with %s points!" % score
+		$UI/GameFinishedMenu/Panel/VBoxContainer/Label.text = final_message
 		$UI/GameFinishedMenu.show()
 		return
 
 	for g in generators:
-		var generator: LevelItemGenerator = g
+		var generator = g
 		var _is_done = generator.run(self)
 
 	if is_destination_set:
@@ -123,8 +127,16 @@ func _process(_delta: float) -> void:
 	for e in filteredEnemies:
 		var enemy: Enemy = e
 		enemy.turn_towards($Player.position)
+		var diff = enemy.global_position - player.global_position
+		var dist = diff.length()
+		var is_too_far = dist > item_replacement_distance
+		if is_too_far:
+			var new_pos = get_new_item_pos(1 + randf())
+			Utils.log("moving distant enemy from", enemy.position, "to", new_pos)
+			enemy.teleport(new_pos)
 
 	player.clear_radar()
+	player.update_radar(get_tree().get_nodes_in_group("gold"), Color.gray)
 	player.update_radar(filteredEnemies, Color.red)
 
 func pause():