godotgdscriptgodot4

(GODOT 4.3) how to make it so that the player that moves via tilemap move forever when an arrow key is pressed?


(ik i made a post similar to this, its just that i decided to switch to godot so i can make games more easier than in flash since its outdated)

i made a character that the player can control and it moves via tiles and tilemap, i wanna make it so that the player can move forever when an arrow key is pressed (and moving to the direction of said arrow key) until it goes into a walkable tile thats touching a non-walkable tile

you can give me any hints on how to do so, heres the code:

extends Sprite2D

class_name PacMan

@export var move_speed: float = 1



@onready var tile_map: TileMap = $"../TileMap"

@onready var sprite_2d: Sprite2D = $Sprite2D

@onready var animation_player: AnimationPlayer = $Sprite2D/AnimationPlayer


var is_moving = false

func _physics_process(delta: float) -> void:
    if is_moving == false:
        return
    if global_position == sprite_2d.global_position:
        is_moving = false
        return
    sprite_2d.global_position = sprite_2d.global_position.move_toward(global_position, move_speed)

func _ready() -> void:
    animation_player.play("chomping")

func _process(delta: float) -> void:
    if is_moving:
        return
    if Input.is_action_pressed("up"):
        rotation_degrees = 90
        move(Vector2.UP)
        is_moving = true
    elif Input.is_action_pressed("down"):
        rotation_degrees = 270
        move(Vector2.DOWN)
        is_moving = true
    elif Input.is_action_pressed("left"):
        rotation_degrees = 0
        move(Vector2.LEFT)
        is_moving = true
    elif Input.is_action_pressed("right"):
        rotation_degrees = 180
        move(Vector2.RIGHT)
        is_moving = true

func move(direction: Vector2):
    var current_tile: Vector2i = tile_map.local_to_map(global_position)
    var target_tile: Vector2i = Vector2i(
        current_tile.x + direction.x,
        current_tile.y + direction.y,
    )
    var tile_data: TileData = tile_map.get_cell_tile_data(0, target_tile)
    if tile_data.get_custom_data("walk_tiles") == false:
        return
    #Player movement
    is_moving = true
    global_position = tile_map.map_to_local(target_tile)
    sprite_2d.global_position = tile_map.map_to_local(current_tile)

Solution

  • Multiple possible solutions. My recommendation would be to create a global variable to store the current direction of the player. Then, instead of calling move(direction), change the player_direction variable and make a call to a direction-agnostic move() function.

    Example semi-pseudocode:

    var player_direction = Vector2.ZERO
    func process(delta):
        if Input.is_action_pressed("up"):
            player_direction = Vector2.UP
        #etc. for the other directions
        
        move()
    
    func move():
        #exactly as you have it, but using player_direction instead of direction