1-6 player splitscreen multiplayer addon
base functionality
bendn 2023-01-30
parent 5e83af6 · commit f6e26e3
-rw-r--r--.github/image.pngbin0 -> 353002 bytes
-rw-r--r--.gitignore1
-rw-r--r--Main.tscn29
-rw-r--r--README.md16
-rw-r--r--addons/splitter/screen.gd37
-rw-r--r--addons/splitter/viewport.gd22
-rw-r--r--project.godot1
-rw-r--r--test.gd9
8 files changed, 112 insertions, 3 deletions
diff --git a/.github/image.png b/.github/image.png
new file mode 100644
index 0000000..2e26865
--- /dev/null
+++ b/.github/image.png
Binary files differ
diff --git a/.gitignore b/.gitignore
index 7136bed..5e86342 100644
--- a/.gitignore
+++ b/.gitignore
@@ -6,4 +6,3 @@ logs/
.vscode/
exports/
*.x86_64
-addons/
diff --git a/Main.tscn b/Main.tscn
index 70a653e..d3383a1 100644
--- a/Main.tscn
+++ b/Main.tscn
@@ -1,3 +1,28 @@
-[gd_scene format=2]
+[gd_scene load_steps=2 format=3 uid="uid://862orftxq81e"]
-[node name="Main" type="Node2D"]
+[ext_resource type="Script" path="res://test.gd" id="1_ncs1l"]
+
+[node name="Main" type="Node3D"]
+
+[node name="CSGBox3D" type="CSGBox3D" parent="."]
+transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 1.86143, 0, -5.02182)
+
+[node name="CSGBox3D2" type="CSGBox3D" parent="."]
+transform = Transform3D(0.755853, 0.654741, 0, -0.654741, 0.755853, 0, 0, 0, 1, 0, 1.42561, -6.12958)
+
+[node name="CSGBox3D5" type="CSGBox3D" parent="."]
+transform = Transform3D(0.334084, 0.768755, -0.545348, 0.0288089, -0.58665, -0.809328, -0.942103, 0.254672, -0.218137, -0.595417, 0.115944, -3.48055)
+
+[node name="CSGBox3D3" type="CSGBox3D" parent="."]
+transform = Transform3D(0.755853, 0.654741, 0, -0.362328, 0.418283, -0.832921, -0.545348, 0.629566, 0.553392, 1.30623, 0.992493, -8.65402)
+
+[node name="CSGBox3D4" type="CSGBox3D" parent="."]
+transform = Transform3D(0.337242, 0.185292, -0.923003, -0.678851, -0.631421, -0.374793, -0.652249, 0.752977, -0.0871558, -2.09498, 0.478853, -6.66823)
+
+[node name="Node" type="Node" parent="."]
+script = ExtResource("1_ncs1l")
+
+[node name="OmniLight3D" type="OmniLight3D" parent="."]
+transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 5.78558, 0)
+light_energy = 16.0
+omni_range = 13.704
diff --git a/README.md b/README.md
index 746aaaa..0bc0ae8 100644
--- a/README.md
+++ b/README.md
@@ -4,3 +4,19 @@
<a href='https://ko-fi.com/bendn' title='Buy me a coffee' target='_blank'><img height='28' src='https://storage.ko-fi.com/cdn/brandasset/kofi_button_red.png' alt='Buy me a coffee'> </a>
Small addon for multiplayer splitscreen
+
+[![image](https://raw.githubusercontent.com/bend-n/splitter/main/.github/image.png)](_blank "Picture!")
+
+## Usage
+
+```GDScript
+extends Splitscreen
+
+func _ready() -> void:
+ super()
+ var cam := Camera3D.new()
+ join().add_child(cam)
+ await get_tree().create_timer(1).timeout
+ cam = Camera3D.new()
+ join().add_child(cam)
+```
diff --git a/addons/splitter/screen.gd b/addons/splitter/screen.gd
new file mode 100644
index 0000000..343b6a0
--- /dev/null
+++ b/addons/splitter/screen.gd
@@ -0,0 +1,37 @@
+extends Node
+class_name Splitscreen
+
+var players: Array[PlayerViewport] = []
+
+func _ready() -> void:
+ get_window().size_changed.connect(resize_players)
+
+func resize_players():
+ # plan:
+ #┌----┐
+ #├────┤
+ #└────┘
+ var size := Vector2(get_window().size) if len(players) == 1 else Vector2(get_window().size.x, get_window().size.y / 2.0)
+ for p in players:
+ p.player_count = len(players)
+ p.size_port(size)
+
+func join() -> Viewport:
+ if len(players) > 1:
+ push_error("no slots")
+ return
+
+ var player := PlayerViewport.new(len(players) + 1)
+ player.name = "player %d" % (len(players) + 1)
+ players.append(player)
+ add_child(player)
+ resize_players()
+ return player.viewport # so you can add a camera
+
+func leave(id: int) -> void:
+ var p := players.pop_at(id)
+ if p == null:
+ push_error("no player")
+ return
+ p.kill()
+ resize_players()
diff --git a/addons/splitter/viewport.gd b/addons/splitter/viewport.gd
new file mode 100644
index 0000000..6e73d4c
--- /dev/null
+++ b/addons/splitter/viewport.gd
@@ -0,0 +1,22 @@
+extends TextureRect
+class_name PlayerViewport
+
+var player_count: int
+var viewport: Viewport
+var id: int
+
+func _init(_id: int) -> void:
+ viewport = SubViewport.new()
+ add_child(viewport)
+ texture = viewport.get_texture()
+ id = _id
+ player_count = _id # id should be count + 1
+
+func size_port(to: Vector2) -> void:
+ viewport.size = to
+ size = to
+ global_position = Vector2.ZERO if id == 1 else Vector2(0, size.y)
+
+func kill() -> void:
+ viewport.queue_free()
+ queue_free() \ No newline at end of file
diff --git a/project.godot b/project.godot
index 325907f..f3809b5 100644
--- a/project.godot
+++ b/project.godot
@@ -12,6 +12,7 @@ config_version=5
config/name="splitter"
config/description="smol addon to simplify creation of multiplayer splitscreen"
+run/main_scene="res://Main.tscn"
config/features=PackedStringArray("4.0")
[rendering]
diff --git a/test.gd b/test.gd
new file mode 100644
index 0000000..c00de5a
--- /dev/null
+++ b/test.gd
@@ -0,0 +1,9 @@
+extends Splitscreen
+
+func _ready() -> void:
+ super()
+ var cam := Camera3D.new()
+ join().add_child(cam)
+ await get_tree().create_timer(1).timeout
+ cam = Camera3D.new()
+ join().add_child(cam) \ No newline at end of file