godot-shooter / commit
Making enemies fire a weak gun at the player.
actors/Enemy.gd | 15 +++++++++++++++ actors/Player.gd | 2 +- weapons/Bullet.gd | 17 +++++++++++++---- weapons/Bullet.tscn | 5 ++++- weapons/Weapon.gd | 3 ++- weapons/Weapons.gd | 12 ++++++++++++ 6 files changed, 47 insertions(+), 7 deletions(-) diff --git a/actors/Enemy.gd b/actors/Enemy.gd index d4aa41a..2403822 100644 --- a/actors/Enemy.gd +++ b/actors/Enemy.gd @@ -8,6 +8,7 @@ const Explosion = preload("res://effects/Explosion.tscn") const Smoke = preload("res://effects/Smoke.tscn") const Damage = preload("res://effects/Damage.tscn") const Constants = preload("res://utils/Constants.gd") +const Weapons = preload("res://weapons/Weapons.gd") export var move_speed = Constants.SPEED * 1.05 export var turn_rate = 0.03 @@ -19,12 +20,14 @@ export var target: Vector2 export var follow_target = false signal enemy_killed(position) +var weapon: Weapon var velocity = Vector2.ZERO var dead = false var health_ratio var health_percentage func _ready() -> void: + weapon = Weapons.create_basic_enemy_gun() navigation_agent.max_speed = move_speed var _err = navigation_agent.connect("path_changed", self, "path_changed") _err = navigation_agent.connect("velocity_computed", self, "velocity_computed") @@ -72,6 +75,18 @@ func _process(_delta: float) -> void: $Graphics/Alive/Sprite/Target.visible = is_targeted $Graphics/Alive/Sprite/Target.global_rotation = 0 $Graphics/Alive/Sprite/Trails.add_position(global_position) + + var players = get_tree().get_nodes_in_group("player") + var player = players[0] + var dist_to_player = global_position.distance_to(player.global_position) + + var should_shoot = dist_to_player < weapon.shooting_range + if should_shoot: + var space_state = get_world_2d().direct_space_state + var intersections = space_state.intersect_ray(global_position, player.global_position, [self]) + var hits_player = intersections and intersections.collider == player + if hits_player: + weapon.try_shoot(self, player.global_position) func _physics_process(delta: float) -> void: if dead: diff --git a/actors/Player.gd b/actors/Player.gd index b3aa23b..1734638 100644 --- a/actors/Player.gd +++ b/actors/Player.gd @@ -5,7 +5,7 @@ const Damage = preload("res://effects/Damage.tscn") const Weapons = preload("res://weapons/Weapons.gd") const Constants = preload("res://utils/Constants.gd") -export var is_invincible = true +export var is_invincible = false export var score = 0 export var move_speed = Constants.SPEED export var health = 50 diff --git a/weapons/Bullet.gd b/weapons/Bullet.gd index e14f34e..99f0a44 100644 --- a/weapons/Bullet.gd +++ b/weapons/Bullet.gd @@ -8,10 +8,15 @@ const Constants = preload("res://utils/Constants.gd") export var lifetime_seconds = 1.5 export var speed = Constants.SPEED * 5 export var damage_amount = 1 +export var arm_period_seconds = .25 + +var is_armed = false func _ready() -> void: $Timer.wait_time = lifetime_seconds $Timer.start() + $ArmTimer.wait_time = arm_period_seconds + $ArmTimer.start() func _physics_process(delta: float) -> void: position += transform.y * speed * delta @@ -20,12 +25,16 @@ func on_expiration(): queue_free() func on_bullet_body_entered(body): - var tree = get_tree() - var players = tree.get_nodes_in_group("player") - var player = players[0] - if body.has_method("hurt") && body != player: + if not is_armed: + return + if body.has_method("hurt"): body.hurt(damage_amount) var se = SmallExplosion.instance() get_parent().add_child(se) se.transform = transform queue_free() + + +func _on_ArmTimer_timeout() -> void: + is_armed = true + pass # Replace with function body. diff --git a/weapons/Bullet.tscn b/weapons/Bullet.tscn index 8164058..bd15d68 100644 --- a/weapons/Bullet.tscn +++ b/weapons/Bullet.tscn @@ -10,7 +10,7 @@ extents = Vector2( 4.50004, 16 ) modulate = Color( 1, 0, 0, 1 ) position = Vector2( 0, -1 ) collision_layer = 8 -collision_mask = 2 +collision_mask = 3 script = ExtResource( 1 ) [node name="Sprite" type="Sprite" parent="."] @@ -28,5 +28,8 @@ shape = SubResource( 1 ) one_shot = true autostart = true +[node name="ArmTimer" type="Timer" parent="."] + [connection signal="body_entered" from="." to="." method="on_bullet_body_entered"] [connection signal="timeout" from="Timer" to="." method="on_expiration"] +[connection signal="timeout" from="ArmTimer" to="." method="_on_ArmTimer_timeout"] diff --git a/weapons/Weapon.gd b/weapons/Weapon.gd index c7aa55a..f94ad0c 100644 --- a/weapons/Weapon.gd +++ b/weapons/Weapon.gd @@ -31,8 +31,9 @@ func try_shoot(shooter: Node2D, target: Vector2) -> void: if ammo != INF: ammo = ammo - 1 + var parent = shooter.get_parent() var particle_instance = particle.instance() - shooter.owner.add_child(particle_instance) + parent.add_child(particle_instance) particle_instance.transform = shooter.global_transform particle_instance.damage_amount = self.damage_amount particle_instance.global_rotation = shooter.global_position.angle_to_point(target) + PI / 2.0 diff --git a/weapons/Weapons.gd b/weapons/Weapons.gd index fc4981f..b1d5193 100644 --- a/weapons/Weapons.gd +++ b/weapons/Weapons.gd @@ -26,6 +26,18 @@ static func create_basic_gun() -> Weapon: weapon.reload_size = 1 return weapon +static func create_basic_enemy_gun() -> Weapon: + var weapon = Weapon.new() + weapon.particle = preload("res://weapons/Bullet.tscn") + weapon.shooting_range = 400 + weapon.particle_lifetime_secs = 1 + weapon.particle_speed = Constants.SPEED * 5 + weapon.cooldown_seconds = 1 + weapon.damage_amount = 1 + weapon.ammo = INF + weapon.reload_size = 1 + return weapon + static func create_smg_gun() -> Weapon: var weapon = Weapon.new() weapon.particle = preload("res://weapons/Bullet.tscn")