How collide with a TileMap while using exact movement?

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By Et_Tenumbra

Currently I have my player character set up to move exactly 32 pixles every time the arrow key is pressed. The problem is that I can’t collide with any of the walls, static bodies, or anything else i am supposed to. I know my walls are collide-able because when using the “8-way movement” on the Godot Docs movement page, i can collide with my tiles just fine. Sadly using the speed var and Vector2() movement doesn’t let me move exactly 32 pixels.

What I have for movement at the moment:

func get_input():
if Input.is_action_just_pressed('ui_right'): 
	position.x += 32
if Input.is_action_just_pressed('ui_left'):
	position.x -= 32
if Input.is_action_just_pressed('ui_down'):
	position.y += 32
if Input.is_action_just_pressed('ui_up'):
	position.y -= 32

Now I figure this is kind of like teleportation, which might be why I can’t run into walls, i have yet to figure out an alternative way of getting this kind of exact movement.
Please let me know your thoughts and ideas.

In the end I need my character to run into walls and move exactly one ‘Square’ every time my arrow key are pressed. Thank you all for your help.

You could use 4 RayCast2D which check the space in the direction you want to move, and disable movement in that direction if it’s colliding with the TileMap. Probably not the best solution, but that’s how I’d do it.

Afely | 2020-10-29 16:56

Thank you, I was thinking about that, but I do worry that it will take to much processing power. I will probably need four different ray-cast on my player’s character, and each NPC that moves. I Will go ahead and try it though maybe I am over estimating the amount of processing that would take.

Et_Tenumbra | 2020-10-30 14:05

you can disable all raycasts and only enable the ones you need to check when you need to check

so if presed “up” you turn on the up_raycast, check it, and disable it again

you can also have multiple raycasts being turned on, checked, and off in a for loop to check multiple collisions

Surtarso | 2020-11-05 18:22

That is, a really good idea thank you, and with all of that it should work great.

Et_Tenumbra | 2020-11-05 18:43

:bust_in_silhouette: Reply From: Et_Tenumbra

Alright this ,may be the most simplest and dumbest way to do this but i figured it out.

basing it of the 8-way movement given at 2D movement overview — Godot Engine (stable) documentation in English

And this is how I ended up getting it to work:

extends KinematicBody2D

export (int) var speed = 32

var velocity = Vector2(int(0), int(0))

func get_input():
    velocity = Vector2()
    if Input.is_action_just_pressed("right"):
        velocity.x += 1
    if Input.is_action_just_pressed("left"):
        velocity.x -= 1
    if Input.is_action_just_pressed("down"):
        velocity.y += 1
    if Input.is_action_just_pressed("up"):
        velocity.y -= 1
    velocity = velocity.normalized() * speed

func _physics_process(delta):
    get_input()
    velocity = move_and_colide(velocity)

All I had to change was the speed and the values for Vector2 to be used as an integer instead of a float, move and collides instead of move and side and naturally action just pressed. It collides interacts and works wonderfully. hope this helped someone else out.