1

I'm new to coding and the game developing scene, so for my first project, I'm trying to make a Mario esc platformer in Godot. Using multiple YouTube tutorials as well as ChatGPT, I came up with code for the movement. However, I've run into an issue where whenever I don't stop moving. This occurred after asking GPT to help me add friction. This is what the code looks like now:

extends CharacterBody2D

@export var speed: float = 200.0

# Jumping physics
@export var jump_height: float
@export var jump_time_to_peak: float
@export var jump_time_to_descend: float

var jump_velocity: float
var jump_gravity: float
var fall_gravity: float

var previous_direction: int = 0

var friction: float = 0.01

var gravity: float = ProjectSettings.get_setting("physics/2d/default_gravity")

func _ready():
    jump_velocity = ((2.0 * jump_height) / jump_time_to_peak) * -1.0
    jump_gravity = ((-2.0 * jump_height) / jump_time_to_peak * jump_time_to_peak) * -1.0
    fall_gravity = ((-2.0 * jump_height) / jump_time_to_descend * jump_time_to_descend) * -1.0

func _physics_process(delta: float) -> void:
    velocity.y += _get_gravity() * delta
    
    var direction: float = Input.get_action_strength("move_right") - Input.get_action_strength("move_left")
    
    if direction != 0.0:
        if direction > 0.0:
            previous_direction = 1
        else:
            previous_direction = -1
        velocity.x = previous_direction * speed
    else:
        if is_on_floor():
            velocity.x = move_toward(velocity.x, 0, friction * delta)
        else:
            if velocity.x != 0.0:
                var sign: float
                if velocity.x > 0.0:
                    sign = 1.0
                else:
                    sign = -1.0
                velocity.x = move_toward(velocity.x, 0, friction * delta) + sign * speed * delta
    
    velocity.x = previous_direction * speed
    
    if Input.is_action_just_pressed("jump") and is_on_floor():
        _jump()
    
    if Input.is_action_just_pressed("jump") and is_on_floor():
        _jump()

    move_and_slide()

func _get_gravity() -> float:
    return jump_gravity if velocity.y < 0.0 else fall_gravity

func _jump() -> void:
    velocity.y = jump_velocity

I've tried if else blocks, syntax errors, and asking ChatGPT to help multiple times. Nothing has worked.

Theraot
  • 31,890
  • 5
  • 57
  • 86

1 Answers1

0

This are the issues I notice on the code:

  • You are comparing floats with 0.0, which sometimes it is fine, but in general we cannot rely on a float that is steadily incremented or decremented each frame to hit exactly 0.0 due to possible rounding issues. So, instead we use the method is_zero_approx. You might also be interested in is_equal_approx.

  • Your friction seems to be too small. The method move_toward takes as third parameter the maximum amount it can change, and you are passing friction * delta, where delta is a time in seconds from the last frame (so it is usually a value less than 1.0 or you have bigger problems) and friction is set to 0.01... And since you are working in 2D, your distance units are pixels. So we are talking of a maximum change rate of a fraction of a pixel per second, which won't be noticeable.

  • I fail to understand the logic for the movement in the air which both applies a friction that reduces the speed, but you are also adding a speed in the same direction.

  • And the friction won't do anything anyway, because you overwrite the changes to velocity.x with velocity.x = previous_direction * speed after the conditional (so this happens regardless of input). Since that is the problem you are asking about (it does not stop moving) start by removing this line.

  • The conditional where you call _jump is needlessly duplicated.

In fact, I believe you don't need to keep previous_direction at all, instead you could use signf(direction) - or better yet: use direction directly, which would give you support for analog input (which is the point of using get_action_strength instead of is_action_pressed).

The variable previous_direction might be useful in the future depending on what do you plan to implement, but removing it might simplify your code, and you might reintroduce it later if you need it.

Theraot
  • 31,890
  • 5
  • 57
  • 86