0 votes


I'm having difficulty changing the typical game mechanic I've seen in the majority of tutorials for platform game character movement with KinematicBody2D in Godot.

I'm trying to create a movement typical of 80's platform games, such as Super Mario. Where the player jumps and cannot reverse the direction of movement. Flip the sprite, yes, but not go against physics!

The desired outcome is to force the player to only jump in the direction they chose, so they are committed to it.

It's absolutely baffling how to implement it. I've attempted functions to split the controls up, but it just became too complicated as it then affected the jumping too. Plus I was creating the same code twice, which looked amateurish at best - it still didn't work though ;)

Anyway, here's my basic code before I attempted to alter it:

extends KinematicBody2D

var bear_velocity = Vector2()
var on_ground = false

const SPEED = 60
const GRAVITY = 10
const FLOOR = Vector2(0,-1)
const JUMP_POWER = -242

func _physics_process(delta):

    # Walking Left, Right or Idle
    if Input.is_action_pressed("ui_right"):
        $Sprite.flip_h = false      
        bear_velocity.x = SPEED

    elif Input.is_action_pressed("ui_left"):
        $Sprite.flip_h = true       
        bear_velocity.x = -SPEED
        bear_velocity.x = 0
        if on_ground == true:

    # Jumping
    if is_on_floor():
        on_ground = true        
        on_ground = false
        if bear_velocity.y < 0:

    if Input.is_action_pressed("ui_select"):
        if on_ground == true:
            bear_velocity.y = JUMP_POWER
            on_ground = false

    # Variable Height Jump      
    if Input.is_action_just_released("ui_up") && bear_velocity.y < -50:
        bear_velocity.y = -50

    # Add Gravity
    bear_velocity.y += GRAVITY

    # Add Movement from Vector2 
    bear_velocity = move_and_slide(bear_velocity, FLOOR)
asked Feb 24, 2019 in Engine by JayH (22 points)

1 Answer

+1 vote

A way to make the player unable to change direction when not on the ground is to prevent direction change when the player is not on the grund (as you see, the question gives an answer).

if Input.is_action_pressed("ui_right") && on_ground:

For this, you will have to do the is_on_floor() check before the input handling to get the correct grounded status.

answered Feb 24, 2019 by eons (7,764 points)

Thanks, but this causes a small issue. The character can no longer move left or right when jumping.

Someone else suggested I place the control inside the if on_floor, e.g.:

if is_on_floor():
    if Input.is_action_pressed("ui_right"): # move right if you press right-key
        bear_velocity.x = SPEED
    elif Input.is_action_pressed("ui_left"): # move left if you press left-key
        bear_velocity.x = -SPEED
    else: # don't move if you are grounded and neither left nor right key is pressed
        bear_velocity.x = 0

But that isn't right either, again the player has no control over the amount of distance traveled left or right. The player is locked to one big jump left, or one big jump right.

Here's a link to Super Mario for reference (forget the inertia, I have to tackle that next):


If you want SMB style then the ting is different, you need to apply inertia to add speed ( stop adding on release), and SMB probably applies similar drag to floor and air.

Welcome to Godot Engine Q&A, where you can ask questions and receive answers from other members of the community.

Please make sure to read How to use this Q&A? before posting your first questions.