aboutsummaryrefslogtreecommitdiff
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.gd122
1 files changed, 41 insertions, 81 deletions
diff --git a/client/scripts/controllable_player.gd b/client/scripts/controllable_player.gd
index 58ac4401..34ef5859 100644
--- a/client/scripts/controllable_player.gd
+++ b/client/scripts/controllable_player.gd
@@ -1,11 +1,11 @@
class_name ControllablePlayer
extends Player
-@export var map: Node3D
-@export var camera: FollowCamera
+
+const PLAYER_SPEED: float = 25.;
var facing = Vector2(1, 0)
-var velocity = Vector2(0, 0)
+var velocity_ = Vector2(0, 0)
func _ready():
var timer = Timer.new()
@@ -19,89 +19,49 @@ func _ready():
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)
- )
+ input = input.rotated(-game.camera.angle_target)
+ update(delta, input)
+ super(delta)
- # collide
- collide(delta)
- velocity = lerp_vector2_exp(velocity, Vector2(0, 0), delta * 5.)
+func update(dt: float, input: Vector2):
+ var direction = input.limit_length(1.);
+ rotation.y = atan2(self.facing.x, self.facing.y);
+ if direction.length() > 0.1:
+ self.facing = direction + (self.facing - direction) * exp(-dt * 10.);
+ self.velocity_ += direction * dt * PLAYER_SPEED;
+ self.position_ += self.velocity_ * dt;
+ self.velocity_ = self.velocity_ * exp(-dt * 5.);
+ collide(dt);
-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
- )
+func collide(dt: float):
+ for xo in range(-1,2):
+ for yo in range(-1,2):
+ var tile = Vector2i(xo, yo) + Vector2i(self.position_);
+ if not is_instance_of(game.map.tile_by_pos.get(str(tile)), FullTile): continue
+ tile = Vector2(tile)
+ var d = aabb_point_distance(tile, tile + Vector2.ONE, self.position_);
+ if d > PLAYER_SIZE: continue
+ var h = 0.01;
+ var d_sample_x = aabb_point_distance(tile, tile + Vector2.ONE, self.position_ + Vector2(h, 0));
+ var d_sample_y = aabb_point_distance(tile, tile + Vector2.ONE, self.position_ + Vector2(0, h));
+ var grad = (Vector2(d_sample_x - d, d_sample_y - d)) / h;
- 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)
- )
+ self.position_ += (PLAYER_SIZE - d) * grad;
+ self.velocity_ -= grad * grad.dot(self.velocity_)
+
+ for player: Player in game.players.values():
+ var diff = self.position_ - player.position_
+ var d = diff.length()
+ if d < 0.01: continue
+ if d >= PLAYER_SIZE * 2: continue
+ var norm = diff.normalized();
+ var f = 100 / (1 + d)
+ self.velocity_.x += norm.x * f * dt
+ self.velocity_.y += norm.y * f * dt
-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 aabb_point_distance(min: Vector2, max: Vector2, p: Vector2) -> float:
+ return (p - p.clamp(min, max)).length()
func update_position(_new_position: Vector2, _new_rotation: float):
pass