offside/player_controller.gd

86 lines
2.2 KiB
GDScript

extends Node
# Variables used by controller
@export var skate_push_start_len = 0.2
@export var skate_push_end_len = 0.9
@export var skate_min_time = 0.02
@export var skate_max_time = 0.1
@export var skate_max_turn_radius = PI / 8
@export var brake_deadzone = 0.3
var skate_occurred: bool
var time_for_push: float
var player_node: Node = null
# Called when the node enters the scene tree for the first time.
func _ready():
skate_occurred = false
time_for_push = 0
# Called every physics processing step
func _physics_process(delta):
if player_node == null:
# Don't call the processing functions if the player node isn't set
return
var joy = Input.get_vector("move_left", "move_right", "move_up", "move_down", 0)
handle_skate_push(joy, delta)
handle_turning(joy, delta)
handle_braking(joy, delta)
func set_player_node(node: Node):
player_node = node
func handle_skate_push(joy: Vector2, delta: float):
var pos = joy.length()
if pos >= skate_push_start_len and !skate_occurred:
time_for_push += delta
if pos >= skate_push_end_len and !skate_occurred:
if time_for_push >= skate_min_time and time_for_push <= skate_max_time:
var effort = 1 - time_for_push / skate_max_time
player_node.push(effort, joy.angle())
skate_occurred = true
elif pos < skate_push_start_len:
skate_occurred = false
time_for_push = 0
func handle_turning(joy: Vector2, delta: float):
if joy.length() < 0.95:
# Only turn if the stick is at the edge
return
# TODO this doesn't work well when you hit a wall
var radial_diff = player_node.velocity.angle_to(joy)
if (radial_diff >= PI/3):
# Only turn for roughlyone "half" of the stick. The other half is used for braking
return
var is_negative: bool = radial_diff < 0
var turn_effort = min(abs(radial_diff), skate_max_turn_radius) / skate_max_turn_radius
if is_negative:
turn_effort = -turn_effort
player_node.turn(turn_effort, delta)
func handle_braking(joy: Vector2, delta: float):
if joy.length() < brake_deadzone:
# Only brake past a certain amount
return
var radial_diff = player_node.velocity.angle_to(joy)
if (radial_diff < 3 * PI / 4):
# Only brake if controller is mostly facing away from velocity
return
player_node.brake(joy.length(), delta)