I'm not much of a coder so I apologize if this is a relatively simple thing to do.

I'm making a 2D action platformer with control similar to the Kirby games, like automatically being at max speed when moving, start and stop on a dime, that sort of thing. No acceleration. I need the player to be able to switch from their walking speed to a faster run speed when another key is pressed while they're moving (like pressing shift while holding left or right). I've tried a few solutions already, but nothing has worked so far and there doesn't seem to be any tutorials that have it for some reason.

Here's my code currently:

extends KinematicBody2D

const WALK_SPEED : = 1200;
const RUN_SPEED : = 1000;
const JUMP : = 1800;
const GRAVITY : = 3500;
const MAXFALLSPEED : = 80;

var velocity : = Vector2();

func input():
	if Input.is_action_pressed("right"):
		velocity.x = WALK_SPEED;
	elif Input.is_action_pressed("left"):
		velocity.x = -WALK_SPEED;
	elif Input.is_action_pressed("right") and Input.is_action_pressed("run"):
		velocity.x = RUN_SPEED;
	elif Input.is_action_pressed("left") and Input.is_action_pressed("run"):
		velocity.x = -RUN_SPEED;
	else:
		velocity.x = 0;
		
	if Input.is_action_just_pressed("jump") and is_on_floor():
		velocity.y = -JUMP;

func _physics_process(delta):
	input();
	velocity.y += GRAVITY * delta;
	move_and_slide(velocity, Vector2.UP);

I've also tried doing it this way:

    if Input.is_action_pressed("right"):
    	if Input.is_action_pressed("run"):
    		velocity.x = RUN_SPEED;
    	else:
    		velocity.x = WALK_SPEED;
    elif Input.is_action_pressed("left"):
    	if Input.is_action_pressed("run"):
    		velocity.x = -RUN_SPEED;
    	else:
    		velocity.x = -WALK_SPEED;

I've tried a couple of other methods similar to above ones, but nothing so far.

It looks like RUN_SPEED should be a larger number than WALK_SPEED, maybe 2400 if you want running to be twice as fast as walking.

Also, in your first code example, I think the big if/elif block needs to be rearranged. If the player is pressing both right and run, then line 12's if Input.is_action_pressed("right"): since the player is indeed pressing right. That makes the character walk, and skips the rest of the if/elif block.

You can rearrange it like this, so that the run conditions are checked before the walk conditions:

    if Input.is_action_pressed("right") and Input.is_action_pressed("run"):
        velocity.x = RUN_SPEED;
    elif Input.is_action_pressed("left") and Input.is_action_pressed("run"):
        velocity.x = -RUN_SPEED;
    elif Input.is_action_pressed("right"):
        velocity.x = WALK_SPEED;
    elif Input.is_action_pressed("left"):
        velocity.x = -WALK_SPEED;
    else:
        velocity.x = 0;

Your second code example looks correct as you wrote it.

8 months later

That way it won't work, one will cancel out the other instead of overlapping. The best way is as follows:

    extends KinematicBody2D
    
    var SPEED
    const WALK_SPEED : = 1000;
    const RUN_SPEED : = 1500;
    const JUMP : = 1800;
    const GRAVITY : = 3500;
    const MAXFALLSPEED : = 80;
    
    var velocity : = Vector2();
    
    func input():
        SPEED = WALK_SPEED;

        if Input.is_action_pressed("run"):
          SPEED = RUN_SPEED;
        else:
          SPEED = WALK_SPEED;
          
        if Input.is_action_pressed("right"):
            velocity.x = SPEED;
        elif Input.is_action_pressed("left"):
            velocity.x = -SPEED;
        else:
            velocity.x = 0;
        if Input.is_action_just_pressed("jump") and is_on_floor():
            velocity.y = -JUMP;
            
    func _physics_process(delta):
        input();
        velocity.y += GRAVITY * delta;
        move_and_slide(velocity, Vector2.UP);

In short, just declare the SPEED variable without defining it, and it will be toggled when pressing SHIFT:

    var SPEED;
    const WALK_SPEED = 1000;
    const RUN_SPEED = 1500;

func _physics_process(delta):
        SPEED = WALK_SPEED;
        if Input.is_action_pressed("run"):
          SPEED = RUN_SPEED;
        else:
          SPEED = WALK_SPEED;

Sorry for the repetition, I did this just so that the next ones to see it understand the concept a little better. I didn't mean to be wordy.

10 months later