More enemy AI added

This commit is contained in:
2025-11-29 16:15:42 +03:00
parent 371ded7d06
commit 16ba892f74
15 changed files with 106 additions and 26 deletions
+62 -4
View File
@@ -11,6 +11,15 @@ const HEAVY_ENEMY = preload("res://game/entities/ships/enemies/heavy/heavy_enemy
const ENEMY_TYPES := [ SMALL_ENEMY, MEDIUM_ENEMY, HEAVY_ENEMY ] const ENEMY_TYPES := [ SMALL_ENEMY, MEDIUM_ENEMY, HEAVY_ENEMY ]
const SHORT_DISTANCE = 75
const MEDIUM_DISTANCE = 150
const LONG_DISTANCE = 300
const INDIRECT_OFFSET = 75
const MIN_POSITION = Vector2(300, 30)
const MAX_POSITION = Vector2(600, 330)
@onready var enemy_update_timer : Timer = $EnemyUpdateTimer @onready var enemy_update_timer : Timer = $EnemyUpdateTimer
@@ -23,9 +32,7 @@ func create_enemy() -> void:
_update_enemy.call_deferred(enemy) _update_enemy.call_deferred(enemy)
func _on_enemy_update_timer_timeout() -> void: func _on_enemy_update_timer_timeout() -> void:
enemy_update_timer.start(randi_range(3, 9))
var enemies := get_tree().get_nodes_in_group("enemies") var enemies := get_tree().get_nodes_in_group("enemies")
if enemies.is_empty(): return if enemies.is_empty(): return
@@ -36,4 +43,55 @@ func _on_enemy_update_timer_timeout() -> void:
func _update_enemy(enemy: AbstractEnemyShip) -> void: func _update_enemy(enemy: AbstractEnemyShip) -> void:
enemy.controller.target_position = Vector2(randi_range(300, 600), randi_range(30, 330)) var players := get_tree().get_nodes_in_group("players")
if players.is_empty():
_random_move_enemy(enemy)
return
var player : Node = players.pick_random()
if not player is PlayerShip:
_random_move_enemy(enemy)
return
_target_enemy_to_player(enemy, player)
func _target_enemy_to_player(enemy: AbstractEnemyShip, player: PlayerShip) -> void:
match enemy.weapon_type:
AbstractWeapon.Type.NONE:
_random_move_enemy(enemy)
AbstractWeapon.Type.SHORT_RANGE:
_update_enemy_target_position(enemy, player, SHORT_DISTANCE)
AbstractWeapon.Type.MEDIUM_RANGE:
_update_enemy_target_position(enemy, player, MEDIUM_DISTANCE)
AbstractWeapon.Type.LONG_RANGE:
_update_enemy_target_position(enemy, player, LONG_DISTANCE)
AbstractWeapon.Type.HOMING:
_update_enemy_target_position(enemy, player, LONG_DISTANCE, INDIRECT_OFFSET)
AbstractWeapon.Type.MINES:
_update_enemy_target_position(enemy, player, SHORT_DISTANCE, INDIRECT_OFFSET)
func _update_enemy_target_position(
enemy: AbstractEnemyShip,
player: PlayerShip,
distance: int,
offset: int = 0
) -> void:
var new_position := player.position
new_position.x += distance
if offset != 0:
if randi_range(0, 1) == 0:
new_position.y += offset
else:
new_position.y -= offset
enemy.controller.target_position = new_position.clamp(MIN_POSITION, MAX_POSITION)
func _random_move_enemy(enemy: AbstractEnemyShip) -> void:
enemy.controller.target_position = Vector2(
randf_range(MIN_POSITION.x, MAX_POSITION.x),
randf_range(MIN_POSITION.y, MAX_POSITION.y)
)
+2 -1
View File
@@ -6,7 +6,8 @@
script = ExtResource("1_ol8cy") script = ExtResource("1_ol8cy")
[node name="EnemyUpdateTimer" type="Timer" parent="."] [node name="EnemyUpdateTimer" type="Timer" parent="."]
one_shot = true process_callback = 0
wait_time = 0.5
autostart = true autostart = true
[connection signal="timeout" from="EnemyUpdateTimer" to="." method="_on_enemy_update_timer_timeout"] [connection signal="timeout" from="EnemyUpdateTimer" to="." method="_on_enemy_update_timer_timeout"]
+7 -7
View File
@@ -43,13 +43,6 @@ func _ready() -> void:
for slot in $WeaponSlots.get_children(): for slot in $WeaponSlots.get_children():
if slot is Node2D: if slot is Node2D:
weapon_positions.append(slot.global_position - global_position) weapon_positions.append(slot.global_position - global_position)
for pos in weapon_positions:
var weapon : AbstractWeapon = WEAPONS.pick_random().instantiate()
weapon.position = pos
weapon.rotation_degrees = weapon_rotation
add_child(weapon)
_weapons.append(weapon)
func _physics_process(_delta: float) -> void: func _physics_process(_delta: float) -> void:
@@ -94,3 +87,10 @@ func _get_new_speed(accel: float, decel: float, current_speed: float) -> float:
func _on_health_depleted() -> void: func _on_health_depleted() -> void:
queue_free() queue_free()
destroyed.emit() destroyed.emit()
func _add_weapon(weapon: AbstractWeapon, weapon_position: Vector2) -> void:
weapon.position = weapon_position
weapon.rotation_degrees = weapon_rotation
add_child(weapon)
_weapons.append(weapon)
@@ -6,12 +6,22 @@ extends AbstractShip
var is_on_screen : bool = false var is_on_screen : bool = false
var weapon_type : AbstractWeapon.Type = AbstractWeapon.Type.NONE
func _ready() -> void: func _ready() -> void:
super._ready() super._ready()
for weapon in _weapons:
weapon.set_belonging(AbstractWeapon.Belonging.ENEMY) var weapon_scene : PackedScene = WEAPONS.pick_random()
for weapon_position in weapon_positions:
var weapon : AbstractWeapon = weapon_scene.instantiate()
weapon_type = weapon.type
_add_weapon(weapon, weapon_position)
func _add_weapon(weapon: AbstractWeapon, weapon_position: Vector2) -> void:
super._add_weapon(weapon, weapon_position)
weapon.set_belonging(AbstractWeapon.Belonging.ENEMY)
func _on_enemy_controller_shoot() -> void: func _on_enemy_controller_shoot() -> void:
+9 -2
View File
@@ -11,8 +11,15 @@ extends AbstractShip
func _ready() -> void: func _ready() -> void:
super._ready() super._ready()
for weapon in _weapons:
weapon.set_belonging(AbstractWeapon.Belonging.PLAYER) for weapon_position in weapon_positions:
var weapon : AbstractWeapon = WEAPONS.pick_random().instantiate()
_add_weapon(weapon, weapon_position)
func _add_weapon(weapon: AbstractWeapon, weapon_position: Vector2) -> void:
super._add_weapon(weapon, weapon_position)
weapon.set_belonging(AbstractWeapon.Belonging.PLAYER)
func _on_player_controller_shoot(weapon_index: int) -> void: func _on_player_controller_shoot(weapon_index: int) -> void:
+2 -2
View File
@@ -3,14 +3,14 @@ extends Node2D
enum Belonging { PLAYER, ENEMY } enum Belonging { PLAYER, ENEMY }
enum Type { SHORT_RANGE, MEDIUM_RANGE, LONG_RANGE, HOMING, MINES } enum Type { NONE, SHORT_RANGE, MEDIUM_RANGE, LONG_RANGE, HOMING, MINES }
@export_range(1, 100) var bullet_per_shot : int = 1 @export_range(1, 100) var bullet_per_shot : int = 1
@export_range(0, 360) var sector_angle : int = 0 @export_range(0, 360) var sector_angle : int = 0
@export var Projectile : PackedScene @export var Projectile : PackedScene
@export var type := Type.MEDIUM_RANGE @export var type := Type.NONE
@onready var muzzle : Node2D = $Muzzle @onready var muzzle : Node2D = $Muzzle
@@ -158,7 +158,7 @@ gravity = Vector3(0, 0, 0)
script = ExtResource("2_ew5um") script = ExtResource("2_ew5um")
sector_angle = 1 sector_angle = 1
Projectile = ExtResource("2_2bjeu") Projectile = ExtResource("2_2bjeu")
type = 2 type = 3
[node name="ShotParticles" type="Node2D" parent="." index="0"] [node name="ShotParticles" type="Node2D" parent="." index="0"]
@@ -44,6 +44,7 @@ script = ExtResource("1_kg6du")
reloader = SubResource("Resource_oppha") reloader = SubResource("Resource_oppha")
sector_angle = 5 sector_angle = 5
Projectile = ExtResource("2_ylc0n") Projectile = ExtResource("2_ylc0n")
type = 1
[node name="AnimatedSprite2D" type="AnimatedSprite2D" parent="." index="0"] [node name="AnimatedSprite2D" type="AnimatedSprite2D" parent="." index="0"]
position = Vector2(6, 0) position = Vector2(6, 0)
@@ -46,7 +46,7 @@ region = Rect2(224, 144, 32, 16)
script = ExtResource("2_mxjpe") script = ExtResource("2_mxjpe")
sector_angle = 5 sector_angle = 5
Projectile = ExtResource("3_fsoo2") Projectile = ExtResource("3_fsoo2")
type = 3 type = 4
[node name="LeftParticles" type="GPUParticles2D" parent="." index="0"] [node name="LeftParticles" type="GPUParticles2D" parent="." index="0"]
position = Vector2(-4, -3) position = Vector2(-4, -3)
@@ -130,7 +130,7 @@ animations = [{
script = ExtResource("2_mmhtn") script = ExtResource("2_mmhtn")
sector_angle = 10 sector_angle = 10
Projectile = ExtResource("2_7y446") Projectile = ExtResource("2_7y446")
type = 4 type = 5
[node name="AnimatedSprite2D" type="AnimatedSprite2D" parent="." index="0"] [node name="AnimatedSprite2D" type="AnimatedSprite2D" parent="." index="0"]
position = Vector2(-7, 0) position = Vector2(-7, 0)
@@ -99,6 +99,7 @@ animations = [{
script = ExtResource("2_fnsb7") script = ExtResource("2_fnsb7")
sector_angle = 2 sector_angle = 2
Projectile = ExtResource("2_yluvp") Projectile = ExtResource("2_yluvp")
type = 2
[node name="AnimatedSprite2D" type="AnimatedSprite2D" parent="." index="0"] [node name="AnimatedSprite2D" type="AnimatedSprite2D" parent="." index="0"]
position = Vector2(8, 0) position = Vector2(8, 0)
@@ -154,7 +154,7 @@ animations = [{
[node name="RailgunWeapon" instance=ExtResource("1_0nxvu")] [node name="RailgunWeapon" instance=ExtResource("1_0nxvu")]
script = ExtResource("1_5nhwg") script = ExtResource("1_5nhwg")
Projectile = ExtResource("2_cbsia") Projectile = ExtResource("2_cbsia")
type = 2 type = 3
[node name="AnimatedSprite2D" type="AnimatedSprite2D" parent="." index="0"] [node name="AnimatedSprite2D" type="AnimatedSprite2D" parent="." index="0"]
position = Vector2(5, 0) position = Vector2(5, 0)
@@ -115,7 +115,7 @@ script = ExtResource("2_1bd18")
bullet_per_shot = 20 bullet_per_shot = 20
sector_angle = 30 sector_angle = 30
Projectile = ExtResource("2_xvd4y") Projectile = ExtResource("2_xvd4y")
type = 0 type = 1
[node name="ShotParticles" type="GPUParticles2D" parent="." index="0"] [node name="ShotParticles" type="GPUParticles2D" parent="." index="0"]
position = Vector2(17, 0) position = Vector2(17, 0)
@@ -146,7 +146,7 @@ gravity = Vector3(0, 0, 0)
script = ExtResource("2_08si3") script = ExtResource("2_08si3")
sector_angle = 10 sector_angle = 10
Projectile = ExtResource("2_1rrdy") Projectile = ExtResource("2_1rrdy")
type = 3 type = 4
[node name="AnimatedSprite2D" type="AnimatedSprite2D" parent="." index="0"] [node name="AnimatedSprite2D" type="AnimatedSprite2D" parent="." index="0"]
sprite_frames = SubResource("SpriteFrames_ckvhw") sprite_frames = SubResource("SpriteFrames_ckvhw")
+4 -2
View File
@@ -14,10 +14,12 @@ const PLAYER := preload("res://game/entities/ships/player/player_ship.tscn")
func _on_enemy_timer_timeout() -> void: func _on_enemy_timer_timeout() -> void:
var enemies := get_tree().get_nodes_in_group("enemies") var enemies := get_tree().get_nodes_in_group("enemies")
if enemies.size() < 25: if enemies.size() < 1:
enemy_swamp_controller.create_enemy() enemy_swamp_controller.create_enemy()
enemy_timer.start(randi_range(1, 3)) var factor := maxi(enemies.size(), 1)
enemy_timer.start(randi_range(1 * factor, 3 * factor))
func _on_player_ship_destroyed() -> void: func _on_player_ship_destroyed() -> void: