0

I'm new to both Stackoverflow and Godot. I have a script for my player which allows me to switch from momentum-based movement (winged) to traditional 8-direction movement (running). However, when I disable (winged) whilst I'm moving, and toggle back to (winged), it remembers the momentum I had and shoots me in that direction. I want my player to reset its speed to zero every time I toggle. I think I'm only missing one or two lines Here's my code

extends KinematicBody2D
export var speed = 300
var velocity = Vector2()
var wings = false

export var MAX_SPEED = 1000
export var ACCELERATION = 1800
var motion = Vector2.ZERO


func _physics_process(delta):
    if (!wings):
        velocity = Vector2()
        if Input.is_action_pressed("right"):
            velocity.x += speed
        if Input.is_action_pressed("left"):
            velocity.x -= speed
        if Input.is_action_pressed("down"):
            velocity.y += speed
        if Input.is_action_pressed("up"):
            velocity.y -= speed
        if Input.is_action_pressed("shift"):
            speed = 70
        else:
            speed = 300
        move_and_slide(velocity)
    if (wings):
        var axis = get_input_axis()
        if axis == Vector2.ZERO:
            apply_friction(ACCELERATION * delta)
        else:
            apply_movement(axis * ACCELERATION * delta)
        motion = move_and_slide(motion)

func _process(delta):
    if Input.is_action_just_pressed("toggle"):
        wings = !wings



func get_input_axis():
    if (wings):
        var axis = Vector2.ZERO
        axis.x = int(Input.is_action_pressed("right")) - int(Input.is_action_pressed("left"))
        axis.y = int(Input.is_action_pressed("down")) - int(Input.is_action_pressed("up"))
        return axis.normalized()

func apply_friction(amount):
    if (wings):
        if motion.length() > amount:
            motion -= motion.normalized() * amount
        else:
            motion = Vector2.ZERO

func apply_movement(acceleration):
    if (wings):
        motion += acceleration
        motion = motion.clamped(MAX_SPEED)
  • Hi. Well, you solved it. As you said, " it remembers the momentum " and if your code _remembers_, than it stored knowledge in a variable. Voilà. Now, regarding your code; after the test if(wings), you call get_input_axis(), apply_friction() and apply_movement(). Watch out, all three test again: if(wings). An observation, I like your code better than hola's, because the extra-code in the pattern-thing supports design and not functionality. It goes a bit in the direction of "forbidden global variables". Besides, CPUs and batteries are happier with less call/return sequences. – A Koscianski Oct 11 '21 at 21:33

2 Answers2

0

I figured it out.

I added this in the toggle press function:

OLD:

func _process(delta):
if Input.is_action_just_pressed("toggle"):
    wings = !wings

NEW:

func _process(delta):
if Input.is_action_just_pressed("toggle"):
    motion = Vector2.ZERO
    wings = !wings
Makyen
  • 31,849
  • 12
  • 86
  • 121
0

I see you fixed your issue and I wanted to offer up an alternative.

The following encapsulates your different movement code. This a mix of a State pattern and a little bit of Strategy pattern.

When encapsulated like this it obviates the need for if state: checks in each method, each object can maintain it's own state such as speed and velocity, and you have a clear point of entry and exit to have cleanup such as resetting velocity to zero.

This is unsolicited, but I hope it helps.

extends KinematicBody2D

class _Movement:
    var body = null
    var velocity = Vector2()

    func enter(body):
        self.body = body

    func exit():
        body = null

    func physics_process(delta):
        pass

class Walk extends _Movement:

    var speed = 0

    func enter(body):
        .enter(body)
        speed = body.FAST_SPEED

    func physics_process(delta):
        velocity = Vector2()
        if Input.is_action_pressed("right"):
            velocity.x += speed
        if Input.is_action_pressed("left"):
            velocity.x -= speed
        if Input.is_action_pressed("down"):
            velocity.y += speed
        if Input.is_action_pressed("up"):
            velocity.y -= speed
        if Input.is_action_pressed("shift"):
            speed = body.SLOW_SPEED
        else:
            speed = body.FAST_SPEED
        move_and_slide(velocity)

class Fly extends _Movement:

    func enter(body):
        .enter(body)
        velocity = Vector2()

    func physics_process(delta):
        var axis = get_input_axis()
        if axs == Vector2.ZERO:
            apply_friction(body.ACCELERATION * delta)
        else:
            apply_movement(axis * body.ACCELERATION * delta)
        velocity = body.move_and_slide(velocity)

    func apply_friction(amount):
        if velocity.length() > amount:
            velocity -= velocity.normalized() * amount
        else:
            velocity = Vector2.ZERO

    func apply_movement(acceleration):
        velocity += acceleration
        velocity = velocity.clamped(body.MAX_SPEED)

    func get_input_axis():
        var axis = Vector2.ZERO
        axis.x = int(Input.is_action_pressed("right")) - int(Input.is_action_pressed("left"))
        axis.y = int(Input.is_action_pressed("down")) - int(Input.is_action_pressed("up"))
        return axis.normalized()

export var MAX_SPEED = 1000
export var ACCELERATION = 1800
export var SLOW_SPEED = 70
export var FAST_SPEED = 300

var FLY = Fly.new()
var WALK = Walk.new()

var wings = false
var movement = WALK

func _ready():
    movement.enter(self)

func _unhandled_input(event):
    if Input.is_action_just_pressed("toggle"):
        wings = !wings
        movement.exit()
        movement = FLY if wings else WALK
        movement.enter(self)

func _physics_process(delta):
    movement.physics_process(delta)
hola
  • 3,150
  • 13
  • 21