diff options
Diffstat (limited to 'client/scripts/controllable_player.gd')
-rw-r--r-- | client/scripts/controllable_player.gd | 107 |
1 files changed, 107 insertions, 0 deletions
diff --git a/client/scripts/controllable_player.gd b/client/scripts/controllable_player.gd new file mode 100644 index 00000000..adf3f2c0 --- /dev/null +++ b/client/scripts/controllable_player.gd @@ -0,0 +1,107 @@ +class_name ControllablePlayer +extends Player + +@export var map: Node3D +@export var camera: FollowCamera + +var facing = Vector2(1, 0) +var velocity = Vector2(0, 0) + +func _ready(): + var timer = Timer.new() + timer.one_shot = false + timer.wait_time = 1. / 25. + add_child(timer) + timer.start() + timer.connect("timeout", func(): + Multiplayer.send_position(Vector2(position.x, position.z), -rotation.y + .5 * PI) + ) + +func _process(delta): + var input = Vector2(Input.get_axis("left", "right"), Input.get_axis("forward", "backwards")).normalized() + input = input.rotated(-camera.angle_target) + + if input.length() > 0.1: + facing = lerp_vector2_exp(facing, input, delta * 10.) + + self.rotation.y = facing.angle() + + velocity.x += input.x * delta * SPEED + velocity.y += input.y * delta * SPEED + + position = Vector3( + position.x + (velocity.x * delta), + 0, + position.z + (velocity.y * delta) + ) + + # collide + collide(delta) + + velocity = lerp_vector2_exp(velocity, Vector2(0, 0), delta * 5.) + +func collide(_delta: float): + for i in map.get_children(): + if is_instance_of(i, FullTile): + var tile: FullTile = i + var d = aabb_circle_distance( + tile.position.x, + tile.position.z, + tile.position.x + 1, + tile.position.z + 1, + position.x, + position.z + ) + + if d > PLAYER_SIZE: + continue + + var h = 0.01 + var d_sample_x = aabb_circle_distance( + tile.position.x, + tile.position.z, + tile.position.x + 1, + tile.position.z + 1, + position.x + h, + position.z + ) + var d_sample_y = aabb_circle_distance( + tile.position.x, + tile.position.z, + tile.position.x + 1, + tile.position.z + 1, + position.x, + position.z + h + ) + var grad_x = (d_sample_x - d) / h + var grad_y = (d_sample_y - d) / h + + position.x += (PLAYER_SIZE - d) * grad_x + position.z += (PLAYER_SIZE - d) * grad_y + + var vdotn = (grad_x * velocity.x) + (grad_y * velocity.y) + + velocity.x -= grad_x * vdotn + velocity.y -= grad_y * vdotn + # TODO: Player collisions + +func lerp_vector2_exp(current: Vector2, target: Vector2, delta: float) -> Vector2: + return Vector2( + target.x + (current.x - target.x) * exp( - delta), + target.y + (current.y - target.y) * exp( - delta) + ) + +func aabb_circle_distance( + min_x: float, + min_y: float, + max_x: float, + max_y: float, + px: float, + py: float +) -> float: + var dx = px - max(min_x, min(max_x, px)) + var dy = py - max(min_y, min(max_y, py)) + return sqrt(dx * dx + dy * dy) + +func update_position(_new_position: Vector2, _new_rotation: float): + pass |