How to make a KinematicBody2D move?

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By Francesco Cicala
:warning: Old Version Published before Godot 3 was released.

Hello guys, I started few days ago with GDScript and I love it. Now I’m facing this problem: I want my paddle to move in 8 directions (north, east, west, south and their combinations). As you can see I used variables to memorize the velocity components, and the new position is got by doing the normalized vector sum with these components.

Here is the behavior:
LEFT+RIGHT = paddle doesn’t move = UP + DOWN
LEFT+DOWN+RIGHT = paddle goes down (horizontals components reciprocally nullify)
RIGHT+DOWN+LEFT = paddle goes down (same)
DOWN+RIGHT+UP = paddle goes right

But here the unexpected behaviours:
LEFT+UP+RIGHT = paddle goes to the North-West, not only North, as if the RIGHT key wasn’t being pressed.
RIGHT+UP+LEFT: paddle goes to the North-East, as if the third key wasn’t being pressed.
DOWN+LEFT+UP: paddle goes to the South-East

I can’t explain why, I would say that the third key pressed isn’t registered but it’s false, it seems it isn’t only in some cases. Could you help me to figure out this problem?

#
extends KinematicBody2D

const SPEED = 150
var hor_speed = 0
var ver_speed = 0
var norm = 1

func _ready():
    set_process_input(true)
    set_process(true)

func _input(event):
    if event.is_action_released("ui_down") or event.is_action_pressed("ui_up"):
	    ver_speed += -SPEED
    if event.is_action_released("ui_up") or event.is_action_pressed("ui_down"):
	    ver_speed += SPEED
    if event.is_action_released("ui_left") or event.is_action_pressed("ui_right"):
	    hor_speed += SPEED
    if event.is_action_released("ui_right") or event.is_action_pressed("ui_left"):
	    hor_speed += -SPEED

	
func _process(delta):
    norm = sqrt(hor_speed*hor_speed + ver_speed*ver_speed) 
    if (norm == 0):
	    norm = 1
    else:
	    pass
	set_pos(Vector2(get_pos().x + (hor_speed*delta)*abs(hor_speed)/norm, get_pos().y + (ver_speed*delta)*abs(ver_speed)/norm))
:bust_in_silhouette: Reply From: Zylann

First note: in 2D, Godot uses an Y-down axis convention, so going up actually means having a negative vertical speed (which is positive in your code).

Second, you can simplify your code by using Vector2 from the start. Also you can do input checks in _fixed_process because in that case it’s easier, and motion-related stuff that could interact with physics should better be done here.

Finally, when doing that you don’t need to write 8 direction checks, you can remove all the or and directions will combinate naturally because you have no else.

#
extends KinematicBody2D

const SPEED = 150

func _ready():
    set_fixed_process(true)

func _fixed_process(delta):
	var direction = Vector2()

    if Input.is_action_pressed("ui_down"):
        direction.y += 1
    if Input.is_action_pressed("ui_up"):
        direction.y += -1
    if Input.is_action_pressed("ui_left"):
        direction.x += -1
    if Input.is_action_pressed("ui_right"):
        direction.x += 1

	set_pos(get_pos() + direction.normalized() * SPEED * delta)

First of all, thank you! Now the code is very shorter and more elegant.
I’ve upgraded exactly you code (changing two signs for left and right) and it’s everything going well, except the problem I mentioned in my question :frowning:
Still, if I press RIGHT + UP + LEFT, the “LEFT” seems not to be executed, while with RIGHT + DOWN + LEFT the “LEFT” is executed, nullifying the “RIGHT” movement, so that the paddle moves to the south direction :frowning:
Do you have any hypothesis for what could be the problem?

Francesco Cicala | 2016-12-25 16:37

The code I proposed doesn’t depend on keypress order, opposite directions should cancel each other correctly.
I just tested my code, and I did a mistake, the signs of left and right have to be reversed (I fixed them on my post above). But other than that, holding RIGHT + DOWN + LEFT makes my sprite go down and RIGHT + UP + LEFT makes it go up :expressionless:

Zylann | 2016-12-25 16:46

That’s quite curious :expressionless:
I’m using the linux version, maybe the two things are correlated. The behaviour persists exporting the file in linux… Well, I’ll try other ways to implement the movement

Francesco Cicala | 2016-12-25 16:58

Do you actually enter the if blocks? Maybe there is a bug to be reported.

Zylann | 2016-12-25 17:34

I copied and pasted the code you wrote to be sure… I’m going to report it on github - issues!
Thank you for the help! :slight_smile:

Francesco Cicala | 2016-12-25 17:51

The weird key problems could be a keyboard issue too, if you can, try with another keyboard to discard that possibility.

eons | 2016-12-25 19:11

Good idea! I’m going to try that

Francesco Cicala | 2016-12-25 21:28

(i know i am necromanting this question, but it is very high in the google results)

Umm… Why are you adding SPEED to direction vector before you call normalize()? Why not add just direction.y += 1 for clarity? Its not true vector (as in “displacement”, “force”, “speed”, “momentum”, “drag”, “thrust” etc), its only direction… You made it “true” vector when you direction.normalize() * SPEED * delta

splite | 2020-04-02 07:50

True, I could have used 1.

Zylann | 2020-04-02 12:31