Player cant move through tilemap/sometimes, player cant move through the tilemap properly

Godot Version

4.1

Question

hi, im making a player that can only move through a tilemap and only through tiles whose data layer is “walkable”

however, after i finished programming the player (via a tutorial), it doesnt work like how it works in the tutorial

the player cant move through the tiles that are walkable, only the target tile image can, but however when i press up, its still on the current tile (like it should), but when i press either left or right keys, the target tile image does move, but the character’s sprite goes on top of it

is there anything i programmed in the code that is inaccurate from the tutorial? here is the code:

the code

extends Sprite2D

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

@onready var sprite_2d = $Sprite2D

@onready var animation_player = $Sprite2D/AnimationPlayer




var is_moving = false

func physics_process(_delta):
	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, 1)

func _ready():
	animation_player.play("chomping")
	


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

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("walkable") == 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)

the tutorial i followed

update to 4.3 version. The new TileMapLayer node is implemented, making it easer to manage layers.
To make it easer to check if you can enter tile is to call where player is going to
var tile=TileMapLayer.get_neighbor_cell()
where player is a child node to ^^^ tile map layer node
and then check if that tile is present in different TileMapLayer node used to define walkable tiles
TileMapLayer.get_used_cells() list
player shouldn’t be a child of that
then check

if tile not in TileMapLayer.get_used_cells(): #code related to movement

but personally I prefer not to use at all TileMap related nodes. There many ways to achieve similar behavior

ok i upgraded to 4.3, but i see a warning sign next to tilemap


does it mean i should like replace tilemap with tilemaplayer or something? im a bit confused

try to look a game in debug remote. It generates TileMapLayer for every internal tilemap layer. It still will work with old TileMap type.

i enabled debug remote

but the player seem to still have the problem
@solver10

here I made simple project to demonstrate mechanic

may use or may ignore if you don’t trust

looks nice but doesnt use arrow keys for movement nor actually like glide into another tile like shown in the tutorial i linked

well it for show how to check if it can be walked in, you can adapt that check

if tile in w.get_used_cells() and player_tile in w.get_surrounding_cells(tile):

after that conditional that filtered tiles do your movement. Just check after you pushed left arrow key if player_tile+Vector2.LEFT in walkable.get_used_cells()

im confused
@solver10

i managed to fix it, i just had to rewrite the code

1 Like