79 lines
2.1 KiB
GDScript
79 lines
2.1 KiB
GDScript
extends Area2D
|
|
|
|
|
|
|
|
# Maximum radial turning speed of the player
|
|
@export var turning_speed = PI/4 # (rad/sec)
|
|
# Maximum speed added to player's velocity per push
|
|
@export var skate_speed = 100 # (pixels/sec)
|
|
# Maximum speed deceleration while stopping
|
|
@export var braking_speed = 200 # (pixels/sec^2)
|
|
# "Natural" deceleration
|
|
@export var decel_ratio = 0.15 # (decel applied per second)
|
|
|
|
var velocity: Vector2
|
|
|
|
func _ready():
|
|
velocity = Vector2.ZERO
|
|
|
|
|
|
func _physics_process(delta: float):
|
|
# Flip sprite
|
|
if velocity.length() > 0:
|
|
$AnimatedSprite2D.flip_h = velocity.x > 0
|
|
|
|
# Update position
|
|
position = clamp_position(position + (velocity * delta))
|
|
|
|
# Decelerate naturally
|
|
# TODO fix vector math, need to apply to hypotenuse, not the sides
|
|
# TODO fix decel math, think compounding interest, it doesn't work this way
|
|
# TODO brake harder when almost stopped
|
|
velocity = velocity * (1 - decel_ratio * delta)
|
|
|
|
|
|
func push(effort: float, angle: float):
|
|
var delta_v = effort * skate_speed
|
|
velocity += delta_v * Vector2.from_angle(angle)
|
|
|
|
|
|
# TODO how to do doc comments?
|
|
# TODO should applying delta come from the controller or the player? It doesn't
|
|
# matter too much because these objects are pretty tightly coupled anyways.
|
|
func turn(effort: float, delta: float):
|
|
# Continuosly call with the effort while turning
|
|
|
|
# effort is +ve right, -ve left? maybe, some orientation
|
|
velocity = velocity.rotated(effort * turning_speed * delta)
|
|
|
|
|
|
func brake(effort: float, delta: float):
|
|
var delta_v = effort * braking_speed * delta
|
|
delta_v = min(delta_v, velocity.length())
|
|
velocity -= delta_v * velocity.normalized()
|
|
|
|
|
|
# TODO setup collision from world, and edges of arena, not the window
|
|
func clamp_position(new_pos: Vector2) -> Vector2:
|
|
var size = Vector2(get_window().size)
|
|
if new_pos.x > size.x:
|
|
if velocity.x > 0:
|
|
velocity.x = 0
|
|
new_pos.x = size.x
|
|
if new_pos.x < 0:
|
|
if velocity.x < 0:
|
|
velocity.x = 0
|
|
|
|
new_pos.x = 0
|
|
|
|
if new_pos.y > size.y:
|
|
if velocity.y > 0:
|
|
velocity.y = 0
|
|
new_pos.y = size.y
|
|
if new_pos.y < 0:
|
|
if velocity.y < 0:
|
|
velocity.y = 0
|
|
new_pos.y = 0
|
|
|
|
return new_pos
|