fuzzyworld

godot-shooter / commit

Starting to implement navigation logic using the NavigationAgend2D.

023ec2fb81f2d615113942768d85ee74eb55dbc9 · Pavel Safronov · 2023-11-29 13:16:31 -0800 · parents 62151b90dd17

Starting to implement navigation logic using the NavigationAgend2D.
Current state: works fine if there's just one enemy, but only navigates one enemy if there are multiple enemies. It's also not clear if the enemy collision bounds are being respected.
 actors/Enemy.gd    | 43 ++++++++++++++++++++++++++++++++++++-------
 actors/Enemy.tscn  | 24 +++++++++++++++++-------
 actors/Player.gd   |  6 +++---
 actors/Player.tscn |  1 -
 scenes/World.gd    |  8 ++++----
 weapons/Weapons.gd |  2 +-
 6 files changed, 61 insertions(+), 23 deletions(-)

diff --git a/actors/Enemy.gd b/actors/Enemy.gd
index cbf76fe..7a8b60c 100644
--- a/actors/Enemy.gd
+++ b/actors/Enemy.gd
@@ -3,6 +3,7 @@ class_name Enemy
 
 onready var ray_cast_2d: RayCast2D = $RayCast2D
 onready var damage_points = $DamagePoints
+onready var navigation_agent: NavigationAgent2D = $NavigationAgent2D
 const Utils = preload("res://utils/Utils.gd")
 const Explosion = preload("res://effects/Explosion.tscn")
 const Smoke = preload("res://effects/Smoke.tscn")
@@ -23,6 +24,11 @@ var health_ratio
 var health_percentage
 
 func _ready() -> void:
+	var _err = navigation_agent.connect("path_changed", self, "path_changed")
+	_err = navigation_agent.connect("velocity_computed", self, "velocity_computed")
+	_err = navigation_agent.connect("target_reached", self, "target_reached")
+#	navigation_agent.set_navigation_map()
+	
 	$AnimationPlayer.play("fade_in")
 	if health < 0 or health > max_health:
 		health = max_health
@@ -32,6 +38,15 @@ func _ready() -> void:
 		for i in hurt_points:
 			hurt()
 
+func path_changed() -> void:
+	Utils.log("path changed", navigation_agent.get_nav_path())
+
+func velocity_computed(new_vel: Vector2) -> void:
+	Utils.log("velocity computed", new_vel)
+
+func target_reached() -> void:
+	Utils.log("target reached")
+
 func _process(_delta: float) -> void:
 	var pb: ProgressBar = $Graphics/Alive/Container/ProgressBar
 	health_ratio = float(health) / float(max_health)
@@ -51,7 +66,17 @@ func _process(_delta: float) -> void:
 func _physics_process(_delta: float) -> void:
 	if dead:
 		return
-		
+	
+	# navigate to the next position
+	var current_pos = global_position
+	var next_pos = navigation_agent.get_next_location()
+	var path = navigation_agent.get_nav_path()
+	Utils.log("next nav pos", next_pos, "current pos", current_pos, "nav finished", navigation_agent.is_navigation_finished(), "path", path)
+	var new_vel: Vector2 = next_pos - current_pos
+	new_vel = new_vel.normalized()
+	new_vel = new_vel * move_speed
+	velocity = new_vel
+	
 	velocity = move_and_slide(velocity)
 	global_rotation = velocity.angle() + PI/2.0
 
@@ -67,12 +92,16 @@ func _physics_process(_delta: float) -> void:
 			get_parent().add_child(explosion)
 			kill()
 
-func turn_towards(pos: Vector2):
-	var to_dir = (pos - global_position).normalized()
-	var curr_dir = velocity.normalized()
-	var dir_diff = to_dir - curr_dir
-	var change = dir_diff * turn_rate * move_speed
-	velocity = (velocity + change).normalized() * move_speed
+func set_target(pos: Vector2):
+#	var to_dir = (pos - global_position).normalized()
+#	var curr_dir = velocity.normalized()
+#	var dir_diff = to_dir - curr_dir
+#	var change = dir_diff * turn_rate * move_speed
+#	velocity = (velocity + change).normalized() * move_speed
+	var nav_map = navigation_agent.get_navigation_map()
+	Utils.log("setting target location", pos, "map", nav_map)
+	navigation_agent.set_target_location(pos)
+	
 
 func _ensure_smoke_exists() -> void:
 	var max_smoke_count = $DamagePoints.get_child_count()
diff --git a/actors/Enemy.tscn b/actors/Enemy.tscn
index f887843..c39e83f 100644
--- a/actors/Enemy.tscn
+++ b/actors/Enemy.tscn
@@ -1,4 +1,4 @@
-[gd_scene load_steps=11 format=2]
+[gd_scene load_steps=12 format=2]
 
 [ext_resource path="res://effects/Trails.tscn" type="PackedScene" id=2]
 [ext_resource path="res://actors/Enemy.gd" type="Script" id=3]
@@ -19,7 +19,6 @@ length = 3.0
 
 [sub_resource type="Animation" id=3]
 resource_name = "fade_in"
-length = 3.0
 tracks/0/type = "value"
 tracks/0/path = NodePath(".:modulate")
 tracks/0/interp = 1
@@ -27,7 +26,7 @@ tracks/0/loop_wrap = true
 tracks/0/imported = false
 tracks/0/enabled = true
 tracks/0/keys = {
-"times": PoolRealArray( 0, 3 ),
+"times": PoolRealArray( 0, 1 ),
 "transitions": PoolRealArray( 1, 1 ),
 "update": 0,
 "values": [ Color( 1, 1, 1, 0 ), Color( 1, 1, 1, 1 ) ]
@@ -39,7 +38,7 @@ tracks/1/loop_wrap = true
 tracks/1/imported = false
 tracks/1/enabled = true
 tracks/1/keys = {
-"times": PoolRealArray( -0.2, 3 ),
+"times": PoolRealArray( -0.2, 1 ),
 "transitions": PoolRealArray( 1, 1 ),
 "update": 0,
 "values": [ Vector2( 0.01, 0.01 ), Vector2( 1, 1 ) ]
@@ -87,10 +86,15 @@ tracks/2/keys = {
 "values": [ 1.0, 0.0 ]
 }
 
+[sub_resource type="NavigationPolygon" id=7]
+vertices = PoolVector2Array( -39, -40, 41, -41, 41, 41, -41, 39 )
+polygons = [ PoolIntArray( 0, 1, 2, 3 ) ]
+outlines = [ PoolVector2Array( -39, -40, 41, -41, 41, 41, -41, 39 ) ]
+
 [node name="Enemy" type="KinematicBody2D"]
 z_index = 10
 collision_layer = 2
-collision_mask = 9
+collision_mask = 11
 script = ExtResource( 3 )
 
 [node name="Graphics" type="Node2D" parent="."]
@@ -102,12 +106,10 @@ modulate = Color( 1, 0.470588, 0, 1 )
 texture = ExtResource( 4 )
 
 [node name="Target" type="Sprite" parent="Graphics/Alive/Sprite"]
-visible = false
 modulate = Color( 1, 0, 0, 1 )
 texture = ExtResource( 5 )
 
 [node name="Trails" parent="Graphics/Alive/Sprite" instance=ExtResource( 2 )]
-visible = false
 gradient = SubResource( 4 )
 
 [node name="Container" type="Node2D" parent="Graphics/Alive"]
@@ -150,3 +152,11 @@ visible = false
 polygon = PoolVector2Array( 0, -23, -7, 5, -12, 9, -19, 9, -23, 14, -23, 19, -19, 23, -14, 23, -9, 19, -9, 14, -10, 12, -6, 9, 0, 15, 6, 9, 10, 12, 9, 14, 9, 19, 13, 23, 18, 23, 23, 18, 23, 14, 19, 10, 13, 10, 7, 5 )
 
 [node name="DamageObjects" type="Node2D" parent="."]
+
+[node name="NavigationPolygonInstance" type="NavigationPolygonInstance" parent="."]
+navpoly = SubResource( 7 )
+
+[node name="NavigationAgent2D" type="NavigationAgent2D" parent="."]
+max_speed = 100.0
+
+[node name="NavigationObstacle2D" type="NavigationObstacle2D" parent="."]
diff --git a/actors/Player.gd b/actors/Player.gd
index 99cf0cf..ab16946 100644
--- a/actors/Player.gd
+++ b/actors/Player.gd
@@ -9,7 +9,7 @@ export var score = 0
 export var move_speed = Constants.SPEED
 export var health = 50
 export var max_health = 100
-export var is_invincible = false
+export var is_invincible = true
 export var turn_rate = 0.03
 export var accel_rate = 1
 export var radar_min_radius = 350
@@ -40,7 +40,7 @@ const Utils = preload("res://utils/Utils.gd")
 const PopupControl = preload("res://utils/Popup.tscn")
 
 var weapon: Weapon
-var default_weapon: Weapon = Weapons.create_basic_gun()
+var default_weapon: Weapon = Weapons.create_smg_gun()
 var dead = false
 var velocity: Vector2
 var can_fire = true
@@ -184,7 +184,7 @@ func shoot_at(pos: Vector2):
 	can_fire = false
 	if weapon.ammo != INF:
 		if weapon.ammo <= 0:
-			weapon = default_weapon
+			weapon = Weapons.create_basic_gun()
 		weapon.ammo -= 1
 	shot_timer.wait_time = weapon.cooldown_seconds
 	shot_timer.start()
diff --git a/actors/Player.tscn b/actors/Player.tscn
index a8bea0d..9319310 100644
--- a/actors/Player.tscn
+++ b/actors/Player.tscn
@@ -373,7 +373,6 @@ current = true
 
 [node name="ShotTimer" type="Timer" parent="."]
 wait_time = 0.5
-autostart = true
 
 [node name="Barrel" type="Position2D" parent="."]
 position = Vector2( 0, -20 )
diff --git a/scenes/World.gd b/scenes/World.gd
index 3ccf6fe..44eeb39 100644
--- a/scenes/World.gd
+++ b/scenes/World.gd
@@ -11,7 +11,7 @@ onready var player: Player = $Player
 onready var update_timer = $UpdateTimer
 
 var generators = [
-	ConstantItemGenerator.new("create_enemy", self, "enemies", 4),
+	ConstantItemGenerator.new("create_enemy", self, "enemies", 2),
 	ConstantItemGenerator.new("create_health", self, "health", 10),
 	ConstantItemGenerator.new("create_weapon", self, "weapon", 10),
 	ConstantItemGenerator.new("create_bomb", self, "bombs", 10),
@@ -48,7 +48,7 @@ func bomb_consumed(data):
 
 func create_enemy() -> Enemy:
 	var enemy = Enemy.instance()
-	enemy.position = get_new_environment_position()
+	enemy.position = get_new_environment_position(.5)
 	enemy.connect("enemy_killed", self, "enemy_killed")
 	return enemy
 func create_health() -> PowerUp:
@@ -84,7 +84,7 @@ func create_weapon() -> PowerUp:
 		weapon.label = "ROC"
 		weapon.color = Color.red
 	elif r < .9:
-		weapon.data = Weapons.create_gattling_gun()
+		weapon.data = Weapons.create_smg_gun()
 		weapon.label = "SMG"
 		weapon.color = Color.orange
 	else:
@@ -208,7 +208,7 @@ func _on_Player_debug() -> void:
 #	player.kill()
 #	completed_objectives = max_objectives
 #	player.debug()
-	weapon_consumed(Weapons.create_rocket_gun())
+	weapon_consumed(Weapons.create_smg_gun())
 	pass # Replace with function body.
 
 func _on_Player_destination_set() -> void:
diff --git a/weapons/Weapons.gd b/weapons/Weapons.gd
index d191331..15589e1 100644
--- a/weapons/Weapons.gd
+++ b/weapons/Weapons.gd
@@ -15,7 +15,7 @@ static func create_basic_gun() -> Weapon:
 	weapon.reload_size = 1
 	return weapon
 
-static func create_gattling_gun() -> Weapon:
+static func create_smg_gun() -> Weapon:
 	var weapon = Weapon.new()
 	weapon.particle = preload("res://weapons/Bullet.tscn")
 	weapon.shooting_range = 400