How can I lessen the X velocity while in mid air?

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

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!

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.

kidscancode | 2019-01-05 19:09

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

MysteryGM | 2019-01-05 19:17

:bust_in_silhouette: Reply From: MysteryGM

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.

:bust_in_silhouette: Reply From: pospathos

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)