diff options
Diffstat (limited to 'client/scripts/controllable_player.gd')
-rw-r--r-- | client/scripts/controllable_player.gd | 122 |
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 |