i have made an enemy that uses astargrid2d to move and chase the player, however i wanted to make the enemy move to a random tile when it goes to a certain state
what i tried to do is to make an if statement that says if the enemy goes into that state, a statement called path.pick_random() is called, but that didnt work
is there a way to do this feature? here is the code:
extends Node2D
class_name Ghost
enum GhostState {CHASE, RUN_AWAY, EATEN}
signal frightened_timeout
@onready var player: Sprite2D = $"../Player" as PacMan
@onready var tile_map: TileMap = $"../TileMap"
@onready var body = $Sprite2D as BodySprite
@onready var target: Sprite2D = $Target
@onready var eyes = $Sprite2D/eyes as EyesSprite
@onready var ghostsiren: AudioStreamPlayer2D = $"../SFX/ghostsiren"
var current_state: GhostState
@onready var frightened_timer: Timer = $"../Frightened_Timer"
@export var color: Color
@onready var area_2d: Area2D = $Sprite2D/Area2D
@onready var frightenedghost: AudioStreamPlayer2D = $"../SFX/frightenedghost"
@onready var gate_tile = $"../homePosition"
@onready var ghosteaten: AudioStreamPlayer2D = $"../SFX/ghosteaten"
@onready var points_animation_player: AnimationPlayer = $"200Points/AnimationPlayer"
var is_blinking = false
@export var move_speed: float = 1
var direction = null
var astar_grid: AStarGrid2D
var is_moving: bool
func _ready() -> void:
move_speed = 0.9
ghostsiren.play()
is_blinking = false
area_2d.set_collision_mask_value(1, true)
body.normal()
eyes.show()
astar_grid = AStarGrid2D.new()
astar_grid.region = tile_map.get_used_rect()
astar_grid.cell_size = Vector2(8, 8)
astar_grid.diagonal_mode = AStarGrid2D.DIAGONAL_MODE_NEVER
astar_grid.update()
var region_size = astar_grid.region.size
var region_position = astar_grid.region.position
for x in range(region_size.x):
for y in range(region_size.y):
var tile_position = Vector2i(x + region_position.x, y + region_position.y)
var tile_data = tile_map.get_cell_tile_data(0, tile_position)
if tile_data == null or not tile_data.get_custom_data("walk_tiles") or tile_data.get_custom_data("gate"):
astar_grid.set_point_solid(tile_position)
func _process(_delta: float) -> void:
if is_moving:
return
states()
if !frightened_timer.is_stopped() && frightened_timer.time_left < frightened_timer.wait_time / 5 && !is_blinking:
start_flashing()
func chase():
print("CHASE")
is_moving = true
var path = astar_grid.get_id_path(
tile_map.local_to_map(global_position),
tile_map.local_to_map(player.global_position)
)
path.pop_front()
if path.size() == 0:
print("arrived at pacman")
return
if path.is_empty():
print("cant find path")
return
var original_position = Vector2(global_position)
global_position = tile_map.map_to_local(path[0])
body.global_position = original_position
var movement_direction = global_position - body.global_position
update_direction(movement_direction)
is_moving = true
target.global_position
current_state = GhostState.CHASE
func _physics_process(_delta: float) -> void:
if is_moving:
body.global_position = body.global_position.move_toward(global_position, move_speed)
if body.global_position == global_position:
is_moving = false
func update_direction(movement: Vector2) -> void:
if movement.x > 0:
direction = Vector2.RIGHT
elif movement.x < 0:
direction = Vector2.LEFT
elif movement.y > 0:
direction = Vector2.DOWN
elif movement.y < 0:
direction = Vector2.UP
# Now, update the sprite texture based on the direction
eyes.change_texture_based_on_direction(direction)
func _on_area_2d_body_entered(_body = player) -> void:
if current_state == GhostState.RUN_AWAY:
print("EATEN")
get_eaten()
elif current_state == GhostState.CHASE:
print("DEATH")
area_2d.set_collision_mask_value(1, false)
get_tree().quit()
func frightened_mode():
print("FRIGHTENED")
if frightened_timer.is_stopped():
ghostsiren.stop()
body.frightened()
eyes.hide_eyes()
frightened_timer.start()
is_blinking = false
move_speed = 0.6
current_state = GhostState.RUN_AWAY
# random tile movement
func _on_frightened_timer_timeout():
print("BACK TO CHASE")
frightened_timeout.emit()
is_blinking = false
eyes.show_eyes()
body.normal()
chase()
ghostsiren.play()
frightenedghost.stop()
move_speed = 0.9
current_state = GhostState.CHASE
func get_eaten():
if current_state != GhostState.EATEN:
print("EATEN")
ghosteaten.play()
body.eaten()
eyes.show_eyes()
Global.score += 200
frightened_timer.stop()
frightenedghost.stop()
frightened_timeout.emit()
current_state = GhostState.EATEN
$"200Points".show()
points_animation_player.play("200points")
await get_tree().create_timer(1).timeout
$"200Points".hide()
is_moving = true
move_speed = 5
func start_flashing():
body.flashing()
func states():
if current_state == GhostState.CHASE:
chase()
elif current_state == GhostState.RUN_AWAY:
frightened_mode()
elif current_state == GhostState.EATEN:
get_eaten()
func start_chase_after_eaten():
chase()
body.normal()
body.show()
move_speed = 0.9