Making Platformer Player Movement 2D

platformer mechanics godot 4

You want to create a character & move it with code. For 2D platformers.

This recipe aims to solve this problem.

Making a character

In Godot, create a scene with CharacterBody2D as its root. Add a Sprite2D (or AnimatedSprite2D) nodes as its child. Also add collision shape. Overall setup should look like this:

platformer character godot

Motion mechanics

Add a script to the character and add code to move left, right, jump, or stay idle like this (I used AnimatedSprite2D for these animations) if you use Sprite2D, just remove lines dealing with AnimatedSprite2D:


extends CharacterBody2D

@export var speed = 232
@export var jump_speed = -800
@export var gravity = 300 *  9.8

@export_range(0.0, 1.0) var friction = 0.32
@export_range(0.0 , 1.0) var acceleration = 0.32

var is_jumping :bool= false


func _physics_process(delta):
	velocity.y += gravity * delta
	var dir = Input.get_axis("ui_left", "ui_right")
	if dir != 0:
		if is_on_floor():
			velocity.x = lerp(velocity.x, dir * speed, acceleration)
		else:
			velocity.x = lerp(velocity.x, dir * speed * 1.4, acceleration)
		if dir > 0:
			# flip the sprite
			$AnimatedSprite2D.flip_h = false
		else:
			$AnimatedSprite2D.flip_h = true
		$AnimatedSprite2D.play("run")
	else:
		velocity.x = lerp(velocity.x, 0.0, friction)
		$AnimatedSprite2D.play("idle")
	
	if Input.is_action_just_pressed("ui_up") and is_on_floor():
		velocity.y = jump_speed
		is_jumping = true
	
	if is_jumping:
		if is_on_floor():
			is_jumping = false
		$AnimatedSprite2D.play("fall")
	
	move_and_slide()

Adding attack mechanics

Attack adds a bit of complexity. While attacking, we complete the animation even if another animation such as jump or run is triggered. Otherwise, attack animation will be cut abruptly. For this we add some more checks.

sword attack animation platformer game

Code:



extends CharacterBody2D

@export var speed = 232
@export var jump_speed = -800
@export var gravity = 300 *  9.8

@export_range(0.0, 1.0) var friction = 0.32
@export_range(0.0 , 1.0) var acceleration = 0.32

var is_jumping: bool= false
var is_attacking: bool = false


func _physics_process(delta):
	velocity.y += gravity * delta
	var dir = Input.get_axis("ui_left", "ui_right")
	if dir != 0:
		if is_on_floor():
			velocity.x = lerp(velocity.x, dir * speed, acceleration)
		else:
			velocity.x = lerp(velocity.x, dir * speed * 1.4, acceleration)
		if dir > 0:
			# flip the sprite
			$AnimatedSprite2D.flip_h = false
		else:
			$AnimatedSprite2D.flip_h = true
		if not is_attacking: $AnimatedSprite2D.play("run")
	else:
		velocity.x = lerp(velocity.x, 0.0, friction)
		if not is_attacking: $AnimatedSprite2D.play("idle")
	
	if Input.is_action_just_pressed("ui_up") and is_on_floor():
		velocity.y = jump_speed
		is_jumping = true
	
	if is_jumping:
		if is_on_floor():
			is_jumping = false
		if not is_attacking: $AnimatedSprite2D.play("fall")
	
	if Input.is_action_just_pressed("ui_home"):
		is_attacking = true
	
	if is_attacking:
		$AnimatedSprite2D.play("attack")
	
	move_and_slide()


func _on_animated_sprite_2d_animation_finished():
	if is_attacking:
		is_attacking = false
		print("ff")
	


func _on_animated_sprite_2d_animation_looped():
	if is_attacking:
		is_attacking = false
		print("ff")


Thank you for reading <3

Leave a Reply

Your email address will not be published. Required fields are marked *