86 lines
2.2 KiB
GDScript
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)
|
|
|