+1 vote

Hello!

I'm completely new in coding and I'm making a platformer game I watched a lot of platformer tutorials on youtube which helped me in starting my game but I'm not quite satisfied with common platformer's physics. How can I lessen my X velocity while in mid-air using Kinematicbody2D as the controller? Also if you can recommend me a good platformer tutorial with mid-air dash, and wall jumps that will be more appreciated!

Thanks, everyone!

in Engine by (16 points)
recategorized by

A bit of advice, since you said you're new to coding: you're not going to find a tutorial with every particular feature you want to make - it's just impossible. Instead of trying to find tutorials for the game you want to make, you should be focusing on learning to code. When you know how to code, you'll find these kinds of things easy to add because you'll understand the logic behind it.

That said, if you want to get into the inner workings of a platformer, there is one in the Godot demo projects you can look at. It includes a friction parameter to slow the character when on the ground - you could use that instead while in the air.

Here is a sample from one of Prototype projects. This formula also collides properly on slopes, but it doesn't have character code yet.

extends KinematicBody

var Velocity = Vector3.ZERO
var OldVelocity = Vector3.ZERO
var Friction = 0.05

var PrintLoop = 0

func PrintEveryX(ThingToPrint, loops):
    if PrintLoop < 1:
        print(ThingToPrint)
        PrintLoop = loops
    else:
        PrintLoop -= 1

func _process(delta):

    if Input.is_action_just_released("ui_up") :
        PrintLoop = 0
        Velocity += Vector3.UP * 60

    if Input.is_action_pressed("ui_right") :
        PrintLoop = 0
        Velocity = Vector3.RIGHT *4

    if Input.is_action_pressed("ui_left") :
        PrintLoop = 0
        Velocity = Vector3.LEFT *4

    Velocity = OldVelocity.linear_interpolate(Velocity+ Vector3(0,-1, 0), 0.4)

    #PrintEveryX(Velocity,30)
    var Collision = move_and_collide(Velocity *delta)

    if Collision != null:
        Velocity += Velocity * (-Collision.normal * Collision.normal)

        #PrintEveryX(Collision.normal,30)
        var FrictionVec = -Velocity * Friction
        Velocity += FrictionVec

    PrintEveryX(Velocity,120)
    OldVelocity = Velocity

2 Answers

+1 vote
Best answer

If you haven't tried it yet try lerp-ing the velocity. This is a trick that comes from old games like Supper Mario, cheap way to simulate friction.

Velocity = OldVelocity.linear_interpolate(Velocity, SmoothValue)

At the end of the physics step you need this, it keeps the old velocity value for the next pass:

OldVelocity = Velocity

Then to prevent it from breaking terminal velocity do something like this:

var TerminalV  = 10

if Velocity.length() < TerminalV  :
   Velocity = OldVelocity.linear_interpolate(Velocity, SmoothValue)

   OldVelocity = Velocity

Play around with this. I recommend you do some research on the old games. Look at Gamasutra for game development advice and research on old games.

by (1,445 points)
selected by
0 votes

Use two variables for acceleration when Player is on ground and in air:

var targetSpeed
targetSpeed = int(Input.is_action_pressed( "move_right" )) - int(Input.is_action_pressed( "move_left" ))
targetSpeed *= WALK_SPEED
velocity.x = lerp( velocity.x, targetSpeed, accelerationTimeGrounded if is_on_floor() else accelerationTimeAirborne)
by (243 points)
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.
Social login is currently unavailable. If you've previously logged in with a Facebook or GitHub account, use the I forgot my password link in the login box to set a password for your account. If you still can't access your account, send an email to webmaster@godotengine.org with your username.