Expanded Movement

Godot Version

3.5.3.stable

Question

Hello!

So last week I was expanding my movement system to add some depth. My goal was to have 3 different speed settings and a boost with i-frames.

And I did it!

Though, I feel as if the code is a bit sloppy and there is some repeated code.

Anyways, here is what I have done (WARNING: WALL OF CODE):

For my player:

extends KinematicBody2D

export (int) var FRICTION = 100
export (int) var SLOW_MOVEMENT = 200
export (int) var MEDIUM_MOVEMENT = 300
export (int) var FAST_MOVEMENT = 400
export (int) var BOOST_MOVEMENT = 500
export (int) var ROTATION_SPEED = 2
export (int) var FORWARD_SPEED = 200
export (int) var BACKWARD_SPEED = 110

var moveState = SLOWMOVE
var velocity = Vector2.ZERO
var rotation_dir = 0


onready var boostLengthTimer = $BoostLengthTimer
onready var cooldownTimer = $Hurtbox/CooldownTimer
onready var animationTree = $AnimationTree
onready var animationState = animationTree.get("parameters/playback")

enum {
	SLOWMOVE,
	MEDIUMMOVE,
	FASTMOVE,
	BOOSTMOVE1,
	BOOSTMOVE2,
	BOOSTMOVE3
}

func rotateCheck():
	
	rotation_dir = 0
	
	if Input.is_action_pressed("Rotate_Clockwise"):
		rotation_dir += 1
		
	if Input.is_action_pressed("Rotate_CounterClockwise"):
		rotation_dir -= 1

func slowMove(delta):
	if Input.is_action_pressed("Reverse"):
		velocity += Vector2(0, BACKWARD_SPEED).rotated(rotation) * delta
		velocity = velocity.limit_length(SLOW_MOVEMENT)
		
	if Input.is_action_pressed("Thrust"):
		velocity += Vector2(0, -FORWARD_SPEED).rotated(rotation) * delta
		velocity = velocity.limit_length(SLOW_MOVEMENT)
		animationState.travel("SlowMovement")

	else:
		animationState.travel("Idle")
		velocity = velocity.move_toward(Vector2.ZERO, FRICTION * delta)
		
	if Input.is_action_just_pressed("Speed_Up"):
		moveState = MEDIUMMOVE

	if Input.is_action_just_pressed("Boost") && cooldownTimer.is_stopped():
		moveState = BOOSTMOVE1

func mediumMove(delta):
	if Input.is_action_pressed("Reverse"):
		velocity += Vector2(0, BACKWARD_SPEED).rotated(rotation) * delta
		velocity = velocity.limit_length(SLOW_MOVEMENT)

	if Input.is_action_pressed("Thrust"):
		velocity += Vector2(0, -FORWARD_SPEED).rotated(rotation) * delta
		velocity = velocity.limit_length(MEDIUM_MOVEMENT)
		animationState.travel("MediumMovement")

	else:
		animationState.travel("Idle")
		velocity = velocity.move_toward(Vector2.ZERO, FRICTION * delta)

	if Input.is_action_just_pressed("Speed_Up"):
		moveState = FASTMOVE

	if Input.is_action_just_pressed("Speed_Down"):
		moveState = SLOWMOVE

	if Input.is_action_just_pressed("Boost") && cooldownTimer.is_stopped():
		moveState = BOOSTMOVE2

func fastMove(delta):
	if Input.is_action_pressed("Reverse"):
		velocity += Vector2(0, BACKWARD_SPEED).rotated(rotation) * delta
		velocity = velocity.limit_length(SLOW_MOVEMENT)

	if Input.is_action_pressed("Thrust"):
		velocity += Vector2(0, -FORWARD_SPEED).rotated(rotation) * delta
		velocity = velocity.limit_length(FAST_MOVEMENT)
		animationState.travel("FastMovement")

	else:
		animationState.travel("Idle")
		velocity = velocity.move_toward(Vector2.ZERO, FRICTION * delta)

	if Input.is_action_just_pressed("Speed_Down"):
		moveState = MEDIUMMOVE

	if Input.is_action_just_pressed("Boost") && cooldownTimer.is_stopped():
		moveState = BOOSTMOVE3

func boostMove1(delta):
	velocity += Vector2(0, -BOOST_MOVEMENT).rotated(rotation) * delta
	velocity = velocity.limit_length(BOOST_MOVEMENT)
	animationState.travel("Boost")
	if boostLengthTimer.is_stopped():
		moveState = SLOWMOVE

func boostMove2(delta):
	velocity += Vector2(0, -BOOST_MOVEMENT).rotated(rotation) * delta
	velocity = velocity.limit_length(BOOST_MOVEMENT)
	animationState.travel("Boost")
	if boostLengthTimer.is_stopped():
		moveState = MEDIUMMOVE

func boostMove3(delta):
	velocity += Vector2(0, -BOOST_MOVEMENT).rotated(rotation) * delta
	velocity = velocity.limit_length(BOOST_MOVEMENT)
	animationState.travel("Boost")
	if boostLengthTimer.is_stopped():
		moveState = FASTMOVE

func rotation(delta):
	rotation += rotation_dir * ROTATION_SPEED * delta

func move():
	velocity = move_and_slide(velocity)

func boostTimerStart():
	if Input.is_action_just_pressed("Boost") && cooldownTimer.is_stopped():
		boostLengthTimer.start()

func _ready():
	animationTree.active = true

func _physics_process(delta):
	match moveState:
		
		SLOWMOVE:
			slowMove(delta)
			
		MEDIUMMOVE:
			mediumMove(delta)
			
		FASTMOVE:
			fastMove(delta)
			
		BOOSTMOVE1:
			boostMove1(delta)
			
		BOOSTMOVE2:
			boostMove2(delta)
			
		BOOSTMOVE3:
			boostMove3(delta)
	
	boostTimerStart()
	rotateCheck()
	rotation(delta)
	move()

For my Hurtbox:

extends Area2D

onready var cooldownTimer = $CooldownTimer
onready var iFrameTimer = $IFrameTimer
onready var hurtbox = $Hurtbox

func _ready():
	hurtbox.disabled = false

func boost_iframes():
	if Input.is_action_just_pressed("Boost") && cooldownTimer.is_stopped():
		hurtbox.disabled = true
		iFrameTimer.start()
		cooldownTimer.start()

func _on_IFrameTimer_timeout():
	hurtbox.disabled = false

func _physics_process(_delta):
	boost_iframes()

This does work, but I am wondering if there is a way to condense and/or restructure it. Or do I stick with “If it works don’t fix it.”

I also hope that this can serve as, some sort of, a guide to help people along (however niche this movement system may be).


(Off topic)

Next I think I will try to get my projectile to add my player speed to the base projectile speed to have a, sort of, “conservation of momentum.”