admin管理员组

文章数量:1122846

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

本文标签: a star(GODOT 43) how to make enemy move to random tile using astargrid2dStack Overflow