Why is the movement super sticky in this code??

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

I’m new to coding and I am trying to create a top-down movement script. When I used this code I wrote, the controls end up being really sticky and the movement is incredibly fast.

Help!

extends KinematicBody2D

var velocity: = Vector2()
export var speed: = 100

func _process(delta: float) → void:
move_and_slide(velocity)
if Input.is_action_pressed(“Up”):
velocity.y -= speed
if Input.is_action_pressed(“Down”):
velocity.y += speed
if Input.is_action_pressed(“Left”):
velocity.x -= speed
if Input.is_action_pressed(“Right”):
velocity.x += speed
if Input.is_action_just_released(“Up”):
velocity.y = 0
if Input.is_action_just_released(“Down”):
velocity.y = 0
if Input. is_action_just_released(“Left”):
velocity.x = 0
if Input.is_action_just_released(“Right”):
velocity.x = 0

do you have an example of how you would like it to move?

Eric Ellingson | 2019-10-25 03:40

Have you seen the video game Stardew Valley? The movement in that game is what I am going for (there are plenty of videos on youtube on the game) The movement is quite snappy and responsive. I would like to be able to do diagonals at the same speed as the walking and have snappy direction changes.

Thanks!

therealconnorroberts | 2019-10-25 04:46

One this that will help you, change how you are adding your speed.

Try this instead:

var velocity = Vector2()
export var speed = 500

func _process(delta: float) -> void:
if Input.is_action_pressed("Left") and not Input.is_action_pressed("Right"):
	velocity.x = -speed
elif Input.is_action_pressed("Right") and not Input.is_action_pressed("Left"):
	velocity.x = speed
else:
	 velocity.x = 0
	
if Input.is_action_pressed("Up") and not Input.is_action_pressed("Down"):
	velocity.y = -speed
elif Input.is_action_pressed("Down") and not Input.is_action_pressed("Up"):
	velocity.y = speed
else:
	 velocity.y = 0
	
move_and_slide(velocity)

This will make your movement significantly slower so you will need to bump up your speed variable.

Notice how I am doing speed or - speed instead of adding or subtracting speed

I have never played Stardew Valley, but it may well use a grid based movement system

llama | 2019-10-25 05:10

Thank you so much! I had no idea you could do “and” and “not” statements,
This is much appreciated!

therealconnorroberts | 2019-10-25 05:26

:bust_in_silhouette: Reply From: Eric Ellingson

If you want the diagonals to be the same speed, you will need to normalize your velocity vector.

Modifying @llama’s code:

var velocity = Vector2()
export var speed = 500

func _process(delta: float) -> void:
    if Input.is_action_pressed("Left") and not Input.is_action_pressed("Right"):
        velocity.x = -speed
    elif Input.is_action_pressed("Right") and not Input.is_action_pressed("Left"):
        velocity.x = speed
    else:
        velocity.x = 0

if Input.is_action_pressed("Up") and not Input.is_action_pressed("Down"):
    velocity.y = -speed
elif Input.is_action_pressed("Down") and not Input.is_action_pressed("Up"):
    velocity.y = speed
else:
     velocity.y = 0

move_and_slide(velocity.normalized() * speed)

But since we are normalizing velocity, there is no need to use the speed value until the the vector is normalized. You can also simplify your movement code by defining your directions in a Dictionary and just looping through the keys (which are just your defined input actions)

var velocity = Vector2()
export var speed = 500

const MOVEMENTS : Dictionary = {
	'Left': Vector2.LEFT, # (-1, 0)
	'Right': Vector2.RIGHT, # (1, 0)
	'Up': Vector2.UP, # (0, -1)
	'Down': Vector2.DOWN, # (0, 1)
}

func _process(delta: float) -> void:
    # this is the default case. if none of the checks
    # for `Input.is_action_pressed()`below are true,
    # then we have no movement
	velocity = Vector2(0, 0)
	
	for direction in MOVEMENTS.keys():
		if Input.is_action_pressed(direction):
                    # just add each direction that is pressed to the total, final velocity.
                    # if `Left` and `Right` are both pressed, we will be 
                    # adding (-1, 0) to (1, 0), which will just give us (0, 0),
                    # so they cancel
			velocity += MOVEMENTS[direction]
	
    # normalizing the vector is what gives us the same speed on the diagonals
	velocity = velocity.normalized() * speed
	
	body.move_and_slide(velocity)