aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--client/scenes/game.tscn11
-rw-r--r--client/scenes/player.tscn5
-rw-r--r--client/scripts/controllable_player.gd107
-rw-r--r--client/scripts/game.gd32
-rw-r--r--client/scripts/multiplayer.gd18
-rw-r--r--client/scripts/player.gd98
6 files changed, 168 insertions, 103 deletions
diff --git a/client/scenes/game.tscn b/client/scenes/game.tscn
index bf93d4d7..998329cb 100644
--- a/client/scenes/game.tscn
+++ b/client/scenes/game.tscn
@@ -1,7 +1,7 @@
[gd_scene load_steps=7 format=3 uid="uid://clsylbmw7jc0s"]
+[ext_resource type="Script" path="res://scripts/game.gd" id="1_qnslj"]
[ext_resource type="PackedScene" uid="uid://bnqujofthaa4h" path="res://scenes/map.tscn" id="1_qt88a"]
-[ext_resource type="PackedScene" uid="uid://d30bj2cp1m7gd" path="res://scenes/player.tscn" id="2_cdwnc"]
[ext_resource type="PackedScene" uid="uid://b31mlnao6ybt8" path="res://scenes/follow_camera.tscn" id="3_6ot70"]
[sub_resource type="PhysicalSkyMaterial" id="PhysicalSkyMaterial_ko0bu"]
@@ -19,6 +19,7 @@ sdfgi_enabled = true
glow_enabled = true
[node name="Game" type="Node3D"]
+script = ExtResource("1_qnslj")
[node name="Map" parent="." instance=ExtResource("1_qt88a")]
@@ -29,10 +30,6 @@ shadow_enabled = true
[node name="WorldEnvironment" type="WorldEnvironment" parent="."]
environment = SubResource("Environment_h880f")
-[node name="Player" parent="." node_paths=PackedStringArray("map", "camera") instance=ExtResource("2_cdwnc")]
-transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 2, 0, 2)
-map = NodePath("../Map")
-camera = NodePath("../FollowCamera")
-
[node name="FollowCamera" parent="." node_paths=PackedStringArray("target") instance=ExtResource("3_6ot70")]
-target = NodePath("../Player")
+transform = Transform3D(0.894934, 0.084374, -0.438148, 0, 0.981959, 0.189095, 0.446198, -0.169228, 0.878789, 0, 3.65756, 11.0189)
+target = NodePath("../Map")
diff --git a/client/scenes/player.tscn b/client/scenes/player.tscn
index f746e0ec..d0ebfa75 100644
--- a/client/scenes/player.tscn
+++ b/client/scenes/player.tscn
@@ -1,11 +1,8 @@
-[gd_scene load_steps=3 format=3 uid="uid://d30bj2cp1m7gd"]
-
-[ext_resource type="Script" path="res://scripts/player.gd" id="1_yh3ku"]
+[gd_scene load_steps=2 format=3 uid="uid://d30bj2cp1m7gd"]
[sub_resource type="CapsuleMesh" id="CapsuleMesh_4w71x"]
[node name="Player" type="Node3D"]
-script = ExtResource("1_yh3ku")
[node name="MeshInstance3D" type="MeshInstance3D" parent="."]
transform = Transform3D(0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5, 0, 0.5, 0)
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
diff --git a/client/scripts/game.gd b/client/scripts/game.gd
new file mode 100644
index 00000000..7c9b4bc2
--- /dev/null
+++ b/client/scripts/game.gd
@@ -0,0 +1,32 @@
+extends Node3D
+
+@onready var camera: FollowCamera = $FollowCamera
+@onready var map: Node3D = $Map
+
+var players := {}
+# Called when the node enters the scene tree for the first time.
+func _ready():
+ await Multiplayer.init
+ if Multiplayer.player_id == -1:
+ push_error("multiplayer has not been initialized")
+ Multiplayer.connect("add_player",
+ 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
+ camera.target = player_instance
+ else:
+ player_instance = Player.new(player, name, pos, character)
+ players[player] = player_instance
+ add_child(player_instance)
+ )
+
+ Multiplayer.connect("position",
+ func(player: int, position: Vector2, rotation: float):
+ var player_instance: Player = players[player]
+ player_instance.update_position(position, rotation)
+ )
+
+ Multiplayer.send_join("Blub", 1)
diff --git a/client/scripts/multiplayer.gd b/client/scripts/multiplayer.gd
index d7dd9d1b..79c5df76 100644
--- a/client/scripts/multiplayer.gd
+++ b/client/scripts/multiplayer.gd
@@ -1,9 +1,13 @@
extends Node
+signal init(player_id: int)
signal update_map(tile: int, pos: Array, neighbors: Array)
signal clear_message(player: int)
signal text_message(player: int, text: String)
signal item_message(player: int, item: int)
+signal add_player(player: int, name: String, pos: Vector2, character: int)
+signal remove_player(player: int)
+signal position(player: int, position: Vector2, rotation: float)
var connected := false
var socket := WebSocketPeer.new()
@@ -48,20 +52,24 @@ func handle_packet(bytes: PackedByteArray):
player_id = decoded["id"]
item_names = decoded["data"]["item_names"]
tile_names = decoded["data"]["tile_names"]
+ emit_signal("init", player_id)
"add_player":
var id = decoded["id"]
var player_name = decoded["name"]
- #var item = decoded["item"]
var pos = decoded["position"]
var char = decoded["character"]
+
other_players[id] = [player_name, char]
+ emit_signal("add_player", id, player_name, pos_to_vec2(pos), char)
"remove_player":
var id = decoded["id"]
other_players.erase(id)
+ emit_signal("remove_player", id)
"position":
var id = decoded["player"]
var pos = decoded["pos"]
var rot = decoded["rot"]
+ emit_signal("position", id, pos_to_vec2(pos), rot)
"take_item":
var tile = decoded["tile"]
var player_id = decoded["player"]
@@ -94,10 +102,11 @@ func handle_packet(bytes: PackedByteArray):
_:
push_error("Unrecognized packet type: %s" % packet_type)
-func send_join(player_name: String):
+func send_join(player_name: String, character: int):
send_packet({
"type": "join",
- "name": player_name
+ "name": player_name,
+ "character": character
})
func send_position(pos: Vector2, rotation: float):
@@ -127,3 +136,6 @@ func decode_packet(bytes: PackedByteArray):
else:
print("Decode of packet failed: %s in %s" % [json.get_error_message(), in_str])
return null
+
+func pos_to_vec2(pos: Array) -> Vector2:
+ return Vector2(pos[0], pos[1])
diff --git a/client/scripts/player.gd b/client/scripts/player.gd
index c4cec300..3ad77322 100644
--- a/client/scripts/player.gd
+++ b/client/scripts/player.gd
@@ -1,96 +1,16 @@
+class_name Player
extends Node3D
const PLAYER_SIZE: float = 0.4
const SPEED: float = 25.
-@export var map: Node3D
-@export var camera: FollowCamera
+var mesh = preload("res://scenes/player.tscn").instantiate()
-var facing = Vector2(1, 0)
-var velocity = Vector2(0, 0)
+func _init(id: int, new_name: String, pos: Vector2, _character: int):
+ add_child(mesh)
+ position = Vector3(pos.x, 0, pos.y)
+ name = new_name
-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 * 0.5
- velocity.y += input.y * delta * 0.5
-
- position = Vector3(
- position.x + (velocity.x * delta * SPEED),
- 0,
- position.z + (velocity.y * delta * SPEED)
- )
-
- # 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):
+ position = Vector3(new_position.x, 0, new_position.y)
+ rotation.y = new_rotation