aboutsummaryrefslogtreecommitdiff
path: root/client/scripts
diff options
context:
space:
mode:
authormetamuffin <metamuffin@disroot.org>2024-06-22 18:10:07 +0200
committermetamuffin <metamuffin@disroot.org>2024-06-23 19:28:39 +0200
commite366cfdf9133c0da798352c474580d329c6a0f33 (patch)
tree1cb97c585cd7c457f3205cacc36cdd183883ac5f /client/scripts
parent512ea1fce397549e2dd2f2b24adde5bc074b4ad2 (diff)
downloadhurrycurry-e366cfdf9133c0da798352c474580d329c6a0f33.tar
hurrycurry-e366cfdf9133c0da798352c474580d329c6a0f33.tar.bz2
hurrycurry-e366cfdf9133c0da798352c474580d329c6a0f33.tar.zst
player collisions and better movement code
Diffstat (limited to 'client/scripts')
-rw-r--r--client/scripts/controllable_player.gd122
-rw-r--r--client/scripts/game.gd7
-rw-r--r--client/scripts/map.gd4
-rw-r--r--client/scripts/multiplayer.gd4
-rw-r--r--client/scripts/player.gd14
5 files changed, 63 insertions, 88 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
diff --git a/client/scripts/game.gd b/client/scripts/game.gd
index 9e02e7c0..48457f9c 100644
--- a/client/scripts/game.gd
+++ b/client/scripts/game.gd
@@ -1,3 +1,4 @@
+class_name Game
extends Node3D
@onready var camera: FollowCamera = $FollowCamera
@@ -13,12 +14,10 @@ func _ready():
func(player: int, name: String, pos: Vector2, character: int):
var player_instance: Player
if player == Multiplayer.player_id:
- player_instance = ControllablePlayer.new(player, name, pos, character)
- player_instance.camera = camera
- player_instance.map = map
+ player_instance = ControllablePlayer.new(player, name, pos, character, self)
camera.target = player_instance
else:
- player_instance = Player.new(player, name, pos, character)
+ player_instance = Player.new(player, name, pos, character, self)
players[player] = player_instance
add_child(player_instance)
)
diff --git a/client/scripts/map.gd b/client/scripts/map.gd
index 9d9453e4..01c7b66e 100644
--- a/client/scripts/map.gd
+++ b/client/scripts/map.gd
@@ -1,5 +1,8 @@
+class_name Map
extends Node3D
+var tile_by_pos: Dictionary = {}
+
func _ready():
Multiplayer.connect("update_map", update)
@@ -48,6 +51,7 @@ func update(pos, tile_name, neighbors):
instance = Floor.new(node_name, neighbors)
instance.position = Vector3(pos[0], 0, pos[1])
+ tile_by_pos[str(Vector2i(pos[0],pos[1]))] = instance
add_child(instance)
func queue_free_rename(node: Node) -> void:
diff --git a/client/scripts/multiplayer.gd b/client/scripts/multiplayer.gd
index f3f16387..6ac05699 100644
--- a/client/scripts/multiplayer.gd
+++ b/client/scripts/multiplayer.gd
@@ -14,6 +14,8 @@ var socket := WebSocketPeer.new()
var item_names = []
var tile_names = []
+var tile_collide = []
+var tile_interact = []
var item_idx_from_name: Dictionary = {}
var player_id = -1
@@ -53,6 +55,8 @@ func handle_packet(bytes: PackedByteArray):
player_id = decoded["id"]
item_names = decoded["data"]["item_names"]
tile_names = decoded["data"]["tile_names"]
+ tile_collide = decoded["data"]["tile_collide"]
+ tile_interact = decoded["data"]["tile_interact"]
for i in range(item_names.size()):
item_idx_from_name[item_names[i]] = i
emit_signal("init", player_id)
diff --git a/client/scripts/player.gd b/client/scripts/player.gd
index 3ad77322..8f53b790 100644
--- a/client/scripts/player.gd
+++ b/client/scripts/player.gd
@@ -4,13 +4,21 @@ extends Node3D
const PLAYER_SIZE: float = 0.4
const SPEED: float = 25.
+var game: Game
+var position_ = Vector2(0, 0)
+
var mesh = preload("res://scenes/player.tscn").instantiate()
-func _init(id: int, new_name: String, pos: Vector2, _character: int):
+func _init(id: int, new_name: String, pos: Vector2, _character: int, new_game: Game):
add_child(mesh)
- position = Vector3(pos.x, 0, pos.y)
+ position_ = pos
name = new_name
+ game = new_game
func update_position(new_position: Vector2, new_rotation: float):
- position = Vector3(new_position.x, 0, new_position.y)
+ position_ = new_position
rotation.y = new_rotation
+
+func _process(delta):
+ position.x = position_.x
+ position.z = position_.y