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