summaryrefslogtreecommitdiff
path: root/client/scripts/controllable_player.gd
diff options
context:
space:
mode:
Diffstat (limited to 'client/scripts/controllable_player.gd')
-rw-r--r--client/scripts/controllable_player.gd107
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