Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Projectile Enemy Tweaks #241

Merged
merged 6 commits into from
Jan 11, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 20 additions & 15 deletions enemy/enemy.gd
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ var time_since_last_seen_player : float = 0.0
@export var agressive_target_distance_max: int = 300

@export var enemy_state : EnemyState = EnemyState.ROAMING
var navigation_target: Vector2 = self.position
var navigation_target: Vector2 = self.global_position

@onready var original_position : Vector2 = position
@onready var target_position: Vector2 = _get_roaming_target()
Expand Down Expand Up @@ -127,7 +127,7 @@ func on_death() -> void:
# pick an eligible item and get the scene path
var chosen: String = eligible_pickup_paths.pick_random()
var dropped_item: Node2D = load(chosen).instantiate()
dropped_item.position = position
dropped_item.global_position = global_position
add_sibling.call_deferred(dropped_item)
print("Item '", dropped_item.name, "' was dropped by ", get_path())

Expand Down Expand Up @@ -160,25 +160,29 @@ func _get_roaming_target() -> Vector2:

func _process_agressive(delta: float) -> void:
#Note that these variables are the square distance
var enemy_distance: float = self.position.distance_to(Player.instance.position)
var navigation_target_distance: float = navigation_target.distance_to(Player.instance.position)
var player_location: Vector2 = Player.instance.position
var enemy_distance: float = self.global_position.distance_to(Player.instance.global_position)
var player_location: Vector2 = Player.instance.global_position
var navigation_target_distance: float = navigation_target.distance_to(player_location)
var target_distance: float = agressive_target_distance_min+(agressive_target_distance_max-agressive_target_distance_min)/2
var target_direction: Vector2

var target : Vector2
#When the enemy is inside of the valid target region

if (enemy_distance > agressive_target_distance_min) && (enemy_distance < agressive_target_distance_max):
if(self.position.distance_squared_to(navigation_target)>10):
pass
const angle_variance := deg_to_rad(10)
target_direction = player_location.direction_to(self.position).rotated(randf_range(-1, 1) * angle_variance)
target = player_location+target_direction*target_distance;
else:
target_direction = player_location.direction_to(self.position)
target = player_location+target_direction*target_distance;
approach(target)
if (enemy_distance < agressive_target_distance_min) || (enemy_distance > agressive_target_distance_max):

target_direction = player_location.direction_to(self.global_position)
target = player_location+target_direction*target_distance
approach(target)
#else:
##print(self.global_position.distance_squared_to(navigation_target))
#if(self.global_position.distance_squared_to(navigation_target)>100):
#return
#const angle_variance := deg_to_rad(90)
#target_direction = player_location.direction_to(self.global_position).rotated(randf_range(-1, 1) * angle_variance)
#target = player_location+target_direction*target_distance



func _process_stunned(_delta: float) -> void:
pass
Expand All @@ -189,6 +193,7 @@ func barked() -> void:

func approach(target: Vector2) -> void:
if navigation_agent:
navigation_target = target
navigation_agent.set_target_position(target)

## Helper function for derived Enemy types to check whether or not they have
Expand Down
126 changes: 118 additions & 8 deletions enemy/projectile_enemy/projectile_enemy.gd
Original file line number Diff line number Diff line change
@@ -1,15 +1,125 @@
extends Enemy

@export var attack_speed: float = 1.0
@export var attack_range: float = 2.0
@export_range(0, 90) var attack_spread: float = 0
@export var animation_length: float = 1
#Attack speed (time between shots)
@export var attack_speed : float = 1.0
#Standstill time (time after an attack before the enemy can move again)
@export var standstill_time : float = 0.5
#How close the enemy must be to start shooting.
@export var attack_range : float = 1.3
#Accuracy
@export_range(0, 90) var attack_spread : float = 0
#Shoot animation length
@export var animation_length : float = 1


var can_shoot : bool = true
var can_move : bool = true


static var projectile :PackedScene = preload("res://enemy/projectile_enemy/projectile/projectile.tscn")

func _ready() -> void:
super._ready()
$ShootProjectileBehavior.attack_speed = attack_speed
$ShootProjectileBehavior.attack_range = attack_range
$ShootProjectileBehavior.attack_spread = attack_spread
$ShootProjectileBehavior.animation_length = animation_length
$AnimatedSprite2D.animation="fire_right"

assert(projectile != null)
$Shooter/CooldownTimer.wait_time = attack_speed
$Shooter/AttackRange/CollisionShape2D.scale *= attack_range


func _process(delta: float) -> void:
super._process(delta)
if can_shoot:
for body: Node2D in $"Shooter/AttackRange".get_overlapping_bodies():
if body is Player:
print("Found Player")
shoot()

func _physics_process(delta: float) -> void:
if can_move:
super._physics_process(delta)
animateWalk()



#
#func _enter_tree() -> void:
## apparently, taking a timer out of and back into a tree breaks it, since autostart is disabled after entering the tree
## since enemies are unloaded and reloaded by taking them out of the tree, we need to work around this
#$Shooter/CooldownTimer.start.call_deferred()




func shoot() -> void:
var proj : Node2D = projectile.instantiate()
proj.global_position = self.global_position
# Finds the player and rotates the bullet to be pointing towards their position
proj.look_at(get_tree().get_first_node_in_group("Player").position)
# Adds some spread
proj.global_rotation_degrees += randf()*attack_spread *2 - attack_spread
get_parent().add_sibling(proj)
can_shoot = false
can_move = false
$Shooter/StandStillTimer.start(standstill_time)
$Shooter/CooldownTimer.start(attack_speed)

animateShooting()

func enable_movement() -> void:
can_move = true

func end_cooldown() -> void:
can_shoot = true
pass

func animateWalk() -> void:
if velocity == Vector2.ZERO: return
var best: Vector2
var best_dot := -INF

for v: Vector2 in [Vector2.LEFT, Vector2.RIGHT, Vector2.UP, Vector2.DOWN]:
if velocity.dot(v) > best_dot:
best_dot = velocity.dot(v)
best = v

var anim: String
match best:
Vector2.LEFT:
anim = "walk_left"
Vector2.RIGHT:
anim = "walk_right"
Vector2.UP:
anim = "shoot_up"
Vector2.DOWN:
anim = "shoot_down"

if $AnimatedSprite2D.animation != anim or not $AnimatedSprite2D.is_playing():
$AnimatedSprite2D.play(anim)

func animateShooting() -> void:

# We have animations for shooting in the 4 cardinal directions.
# We need to decide which of those directions to the enemy the player is MOSTLY in.

var playerPos : Vector2 = Player.instance.global_position
# We get the difference from the player separately on each axis.
var xposDifference : float = abs(self.global_position.x-playerPos.x)
var yposDifference : float = abs(self.global_position.y-playerPos.y)
# We decide which axis the player is farther from. Greater X difference means "mostly horizontal", greater Y difference means "mostly vertical"
# A second if statement kicks in to decide which of the two directions along the given axis we're dealing in.
if xposDifference>=yposDifference:
# HORIZONTAL SHOOTING
#if i'm to the right of the player, fire to my left. otherwise, to the right
if self.global_position.x>=playerPos.x:
enemy_sprite.animation="fire_left"
else:
enemy_sprite.animation="fire_right"
else:
#VERTICAL SHOOTING
#if i'm below the player, fire "up" (animation tbd). otherwise, fire down
if self.global_position.y>=playerPos.y:
enemy_sprite.animation="fire_up"
else:
enemy_sprite.animation="fire_down"
enemy_sprite.play()
26 changes: 14 additions & 12 deletions enemy/projectile_enemy/projectile_enemy.tscn
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
[gd_scene load_steps=8 format=3 uid="uid://bs6o5glcfe2as"]
[gd_scene load_steps=7 format=3 uid="uid://bs6o5glcfe2as"]

[ext_resource type="PackedScene" uid="uid://blpi4x6if673v" path="res://enemy/base_enemy.tscn" id="1_27jju"]
[ext_resource type="Texture2D" uid="uid://bf0rs7x60qf5e" path="res://enemy/projectile_enemy/octorok.png" id="2_8e4mk"]
[ext_resource type="Script" path="res://enemy/projectile_enemy/projectile_enemy.gd" id="2_rirh3"]
[ext_resource type="Script" path="res://enemy/projectile_enemy/shoot_projectile_behavior.gd" id="3_qdk2l"]
[ext_resource type="SpriteFrames" uid="uid://b3tys1ggbpdvu" path="res://enemy/projectile_enemy/sprites/projectile_sprite_frames.tres" id="5_ivjup"]

[sub_resource type="CircleShape2D" id="CircleShape2D_qplrn"]
Expand All @@ -15,7 +14,8 @@ size = Vector2(79.3333, 80)
[node name="ProjectileEnemy" node_paths=PackedStringArray("enemy_sprite") instance=ExtResource("1_27jju")]
script = ExtResource("2_rirh3")
attack_speed = 1.0
attack_range = 2.0
standstill_time = 0.5
attack_range = 1.3
attack_spread = 0.0
animation_length = 1.0
enemy_sprite = NodePath("AnimatedSprite2D")
Expand All @@ -38,18 +38,19 @@ rotation = -1.5708
scale = Vector2(3.68048, 3.58954)
texture = ExtResource("2_8e4mk")

[node name="ShootProjectileBehavior" type="Node2D" parent="." index="4" node_paths=PackedStringArray("sprite")]
script = ExtResource("3_qdk2l")
sprite = NodePath("../AnimatedSprite2D")
[node name="Shooter" type="Node2D" parent="." index="4"]

[node name="CooldownTimer" type="Timer" parent="ShootProjectileBehavior" index="0"]
autostart = true
[node name="StandStillTimer" type="Timer" parent="Shooter" index="0"]
one_shot = true

[node name="AttackRange" type="Area2D" parent="ShootProjectileBehavior" index="1"]
[node name="CooldownTimer" type="Timer" parent="Shooter" index="1"]
one_shot = true

[node name="AttackRange" type="Area2D" parent="Shooter" index="2"]
collision_layer = 0
collision_mask = 2

[node name="CollisionShape2D" type="CollisionShape2D" parent="ShootProjectileBehavior/AttackRange" index="0"]
[node name="CollisionShape2D" type="CollisionShape2D" parent="Shooter/AttackRange" index="0"]
shape = SubResource("CircleShape2D_qplrn")

[node name="Hurtbox" type="CollisionShape2D" parent="." index="5"]
Expand All @@ -59,7 +60,8 @@ shape = SubResource("RectangleShape2D_3wk5l")
[node name="AnimatedSprite2D" type="AnimatedSprite2D" parent="." index="7"]
scale = Vector2(0.7, 0.7)
sprite_frames = ExtResource("5_ivjup")
animation = &"fire_right"
animation = &"walk_left"
metadata/_edit_lock_ = true

[connection signal="timeout" from="ShootProjectileBehavior/CooldownTimer" to="ShootProjectileBehavior" method="timeout"]
[connection signal="timeout" from="Shooter/StandStillTimer" to="." method="enable_movement"]
[connection signal="timeout" from="Shooter/CooldownTimer" to="." method="end_cooldown"]
72 changes: 0 additions & 72 deletions enemy/projectile_enemy/shoot_projectile_behavior.gd

This file was deleted.

Loading