mirror of
https://github.com/godotengine/godot-demo-projects.git
synced 2025-12-16 13:30:07 +01:00
[3.x] Add a 2D version of the dynamic split screen demo (#762)
* add a 2D version of the dynamic split screen demo * refactor the dynamic split screen demo - both 2D and 3D scenes have the exact same hierarchy - a single camera_controller.gd script instead of one per mode - the third viewport for 2D mode has been removed
This commit is contained in:
1
viewport/dynamic_split_screen/.gitignore
vendored
Normal file
1
viewport/dynamic_split_screen/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
export/
|
||||
531
viewport/dynamic_split_screen/2d/level.tscn
Normal file
531
viewport/dynamic_split_screen/2d/level.tscn
Normal file
@@ -0,0 +1,531 @@
|
||||
[gd_scene load_steps=8 format=2]
|
||||
|
||||
[ext_resource path="res://2d/player.gd" type="Script" id=1]
|
||||
[ext_resource path="res://2d/wall_coloring.gd" type="Script" id=2]
|
||||
[ext_resource path="res://2d/square.png" type="Texture" id=3]
|
||||
[ext_resource path="res://2d/player.png" type="Texture" id=4]
|
||||
|
||||
[sub_resource type="CircleShape2D" id=3]
|
||||
radius = 8.0
|
||||
|
||||
[sub_resource type="CircleShape2D" id=4]
|
||||
radius = 8.06226
|
||||
|
||||
[sub_resource type="RectangleShape2D" id=2]
|
||||
extents = Vector2( 8, 8 )
|
||||
|
||||
[node name="Level" type="Node2D"]
|
||||
|
||||
[node name="Player1" type="KinematicBody2D" parent="."]
|
||||
position = Vector2( -36, -16 )
|
||||
script = ExtResource( 1 )
|
||||
|
||||
[node name="CollisionShape2D" type="CollisionShape2D" parent="Player1"]
|
||||
shape = SubResource( 3 )
|
||||
|
||||
[node name="Sprite" type="Sprite" parent="Player1"]
|
||||
modulate = Color( 1, 0, 0, 1 )
|
||||
scale = Vector2( 0.25, 0.25 )
|
||||
texture = ExtResource( 4 )
|
||||
|
||||
[node name="Player2" type="KinematicBody2D" parent="."]
|
||||
position = Vector2( 25, 42 )
|
||||
script = ExtResource( 1 )
|
||||
player_id = 2
|
||||
|
||||
[node name="CollisionShape2D" type="CollisionShape2D" parent="Player2"]
|
||||
shape = SubResource( 4 )
|
||||
|
||||
[node name="Sprite" type="Sprite" parent="Player2"]
|
||||
modulate = Color( 0, 0.588235, 1, 1 )
|
||||
scale = Vector2( 0.25, 0.25 )
|
||||
texture = ExtResource( 4 )
|
||||
|
||||
[node name="Walls" type="Node2D" parent="."]
|
||||
script = ExtResource( 2 )
|
||||
|
||||
[node name="Group1" type="Node2D" parent="Walls"]
|
||||
position = Vector2( 342, -1.00002 )
|
||||
rotation = 0.707648
|
||||
|
||||
[node name="StaticBody2D" type="StaticBody2D" parent="Walls/Group1"]
|
||||
position = Vector2( -68, -17 )
|
||||
scale = Vector2( 2, 2 )
|
||||
|
||||
[node name="CollisionShape2D" type="CollisionShape2D" parent="Walls/Group1/StaticBody2D"]
|
||||
shape = SubResource( 2 )
|
||||
|
||||
[node name="Sprite" type="Sprite" parent="Walls/Group1/StaticBody2D" groups=["walls"]]
|
||||
modulate = Color( 0.607891, 0.046592, 0.00570985, 1 )
|
||||
texture = ExtResource( 3 )
|
||||
|
||||
[node name="StaticBody2D4" type="StaticBody2D" parent="Walls/Group1"]
|
||||
position = Vector2( 52, 29 )
|
||||
scale = Vector2( 2, 2 )
|
||||
|
||||
[node name="CollisionShape2D" type="CollisionShape2D" parent="Walls/Group1/StaticBody2D4"]
|
||||
shape = SubResource( 2 )
|
||||
|
||||
[node name="Sprite" type="Sprite" parent="Walls/Group1/StaticBody2D4" groups=["walls"]]
|
||||
modulate = Color( 0.404256, 0.898451, 0.937987, 1 )
|
||||
texture = ExtResource( 3 )
|
||||
|
||||
[node name="StaticBody2D2" type="StaticBody2D" parent="Walls/Group1"]
|
||||
position = Vector2( -20, 48 )
|
||||
scale = Vector2( 2, 2 )
|
||||
|
||||
[node name="CollisionShape2D" type="CollisionShape2D" parent="Walls/Group1/StaticBody2D2"]
|
||||
shape = SubResource( 2 )
|
||||
|
||||
[node name="Sprite" type="Sprite" parent="Walls/Group1/StaticBody2D2" groups=["walls"]]
|
||||
modulate = Color( 0.180765, 0.0852998, 0.0428303, 1 )
|
||||
texture = ExtResource( 3 )
|
||||
|
||||
[node name="StaticBody2D3" type="StaticBody2D" parent="Walls/Group1"]
|
||||
position = Vector2( 35, -38 )
|
||||
scale = Vector2( 2, 2 )
|
||||
|
||||
[node name="CollisionShape2D" type="CollisionShape2D" parent="Walls/Group1/StaticBody2D3"]
|
||||
shape = SubResource( 2 )
|
||||
|
||||
[node name="Sprite" type="Sprite" parent="Walls/Group1/StaticBody2D3" groups=["walls"]]
|
||||
modulate = Color( 0.0991764, 0.976524, 0.341112, 1 )
|
||||
texture = ExtResource( 3 )
|
||||
|
||||
[node name="Group8" type="Node2D" parent="Walls"]
|
||||
position = Vector2( -119, -69 )
|
||||
rotation = 0.707648
|
||||
|
||||
[node name="StaticBody2D" type="StaticBody2D" parent="Walls/Group8"]
|
||||
position = Vector2( -68, -17 )
|
||||
scale = Vector2( 2, 2 )
|
||||
|
||||
[node name="CollisionShape2D" type="CollisionShape2D" parent="Walls/Group8/StaticBody2D"]
|
||||
shape = SubResource( 2 )
|
||||
|
||||
[node name="Sprite" type="Sprite" parent="Walls/Group8/StaticBody2D" groups=["walls"]]
|
||||
modulate = Color( 0.607891, 0.046592, 0.00570985, 1 )
|
||||
texture = ExtResource( 3 )
|
||||
|
||||
[node name="StaticBody2D4" type="StaticBody2D" parent="Walls/Group8"]
|
||||
position = Vector2( 52, 29 )
|
||||
scale = Vector2( 2, 2 )
|
||||
|
||||
[node name="CollisionShape2D" type="CollisionShape2D" parent="Walls/Group8/StaticBody2D4"]
|
||||
shape = SubResource( 2 )
|
||||
|
||||
[node name="Sprite" type="Sprite" parent="Walls/Group8/StaticBody2D4" groups=["walls"]]
|
||||
modulate = Color( 0.404256, 0.898451, 0.937987, 1 )
|
||||
texture = ExtResource( 3 )
|
||||
|
||||
[node name="StaticBody2D2" type="StaticBody2D" parent="Walls/Group8"]
|
||||
position = Vector2( -20, 48 )
|
||||
scale = Vector2( 2, 2 )
|
||||
|
||||
[node name="CollisionShape2D" type="CollisionShape2D" parent="Walls/Group8/StaticBody2D2"]
|
||||
shape = SubResource( 2 )
|
||||
|
||||
[node name="Sprite" type="Sprite" parent="Walls/Group8/StaticBody2D2" groups=["walls"]]
|
||||
modulate = Color( 0.180765, 0.0852998, 0.0428303, 1 )
|
||||
texture = ExtResource( 3 )
|
||||
|
||||
[node name="StaticBody2D3" type="StaticBody2D" parent="Walls/Group8"]
|
||||
position = Vector2( 35, -38 )
|
||||
scale = Vector2( 2, 2 )
|
||||
|
||||
[node name="CollisionShape2D" type="CollisionShape2D" parent="Walls/Group8/StaticBody2D3"]
|
||||
shape = SubResource( 2 )
|
||||
|
||||
[node name="Sprite" type="Sprite" parent="Walls/Group8/StaticBody2D3" groups=["walls"]]
|
||||
modulate = Color( 0.0991764, 0.976524, 0.341112, 1 )
|
||||
texture = ExtResource( 3 )
|
||||
|
||||
[node name="Group6" type="Node2D" parent="Walls"]
|
||||
position = Vector2( -12, -162 )
|
||||
rotation = -0.472087
|
||||
|
||||
[node name="StaticBody2D" type="StaticBody2D" parent="Walls/Group6"]
|
||||
position = Vector2( -68, -17 )
|
||||
scale = Vector2( 2, 2 )
|
||||
|
||||
[node name="CollisionShape2D" type="CollisionShape2D" parent="Walls/Group6/StaticBody2D"]
|
||||
shape = SubResource( 2 )
|
||||
|
||||
[node name="Sprite" type="Sprite" parent="Walls/Group6/StaticBody2D" groups=["walls"]]
|
||||
modulate = Color( 0.830074, 0.71524, 0.115105, 1 )
|
||||
texture = ExtResource( 3 )
|
||||
|
||||
[node name="StaticBody2D4" type="StaticBody2D" parent="Walls/Group6"]
|
||||
position = Vector2( 52, 29 )
|
||||
scale = Vector2( 2, 2 )
|
||||
|
||||
[node name="CollisionShape2D" type="CollisionShape2D" parent="Walls/Group6/StaticBody2D4"]
|
||||
shape = SubResource( 2 )
|
||||
|
||||
[node name="Sprite" type="Sprite" parent="Walls/Group6/StaticBody2D4" groups=["walls"]]
|
||||
modulate = Color( 0.86402, 0.891686, 0.747119, 1 )
|
||||
texture = ExtResource( 3 )
|
||||
|
||||
[node name="StaticBody2D2" type="StaticBody2D" parent="Walls/Group6"]
|
||||
position = Vector2( -20, 48 )
|
||||
scale = Vector2( 2, 2 )
|
||||
|
||||
[node name="CollisionShape2D" type="CollisionShape2D" parent="Walls/Group6/StaticBody2D2"]
|
||||
shape = SubResource( 2 )
|
||||
|
||||
[node name="Sprite" type="Sprite" parent="Walls/Group6/StaticBody2D2" groups=["walls"]]
|
||||
modulate = Color( 0.176854, 0.187306, 0.991179, 1 )
|
||||
texture = ExtResource( 3 )
|
||||
|
||||
[node name="StaticBody2D3" type="StaticBody2D" parent="Walls/Group6"]
|
||||
position = Vector2( 35, -38 )
|
||||
scale = Vector2( 2, 2 )
|
||||
|
||||
[node name="CollisionShape2D" type="CollisionShape2D" parent="Walls/Group6/StaticBody2D3"]
|
||||
shape = SubResource( 2 )
|
||||
|
||||
[node name="Sprite" type="Sprite" parent="Walls/Group6/StaticBody2D3" groups=["walls"]]
|
||||
modulate = Color( 0.909202, 0.190021, 0.310404, 1 )
|
||||
texture = ExtResource( 3 )
|
||||
|
||||
[node name="Group9" type="Node2D" parent="Walls"]
|
||||
position = Vector2( 7, 268 )
|
||||
rotation = 1.44794
|
||||
|
||||
[node name="StaticBody2D" type="StaticBody2D" parent="Walls/Group9"]
|
||||
position = Vector2( -68, -17 )
|
||||
scale = Vector2( 2, 2 )
|
||||
|
||||
[node name="CollisionShape2D" type="CollisionShape2D" parent="Walls/Group9/StaticBody2D"]
|
||||
shape = SubResource( 2 )
|
||||
|
||||
[node name="Sprite" type="Sprite" parent="Walls/Group9/StaticBody2D" groups=["walls"]]
|
||||
modulate = Color( 0.830074, 0.71524, 0.115105, 1 )
|
||||
texture = ExtResource( 3 )
|
||||
|
||||
[node name="StaticBody2D4" type="StaticBody2D" parent="Walls/Group9"]
|
||||
position = Vector2( 52, 29 )
|
||||
scale = Vector2( 2, 2 )
|
||||
|
||||
[node name="CollisionShape2D" type="CollisionShape2D" parent="Walls/Group9/StaticBody2D4"]
|
||||
shape = SubResource( 2 )
|
||||
|
||||
[node name="Sprite" type="Sprite" parent="Walls/Group9/StaticBody2D4" groups=["walls"]]
|
||||
modulate = Color( 0.86402, 0.891686, 0.747119, 1 )
|
||||
texture = ExtResource( 3 )
|
||||
|
||||
[node name="StaticBody2D2" type="StaticBody2D" parent="Walls/Group9"]
|
||||
position = Vector2( -20, 48 )
|
||||
scale = Vector2( 2, 2 )
|
||||
|
||||
[node name="CollisionShape2D" type="CollisionShape2D" parent="Walls/Group9/StaticBody2D2"]
|
||||
shape = SubResource( 2 )
|
||||
|
||||
[node name="Sprite" type="Sprite" parent="Walls/Group9/StaticBody2D2" groups=["walls"]]
|
||||
modulate = Color( 0.176854, 0.187306, 0.991179, 1 )
|
||||
texture = ExtResource( 3 )
|
||||
|
||||
[node name="StaticBody2D3" type="StaticBody2D" parent="Walls/Group9"]
|
||||
position = Vector2( 35, -38 )
|
||||
scale = Vector2( 2, 2 )
|
||||
|
||||
[node name="CollisionShape2D" type="CollisionShape2D" parent="Walls/Group9/StaticBody2D3"]
|
||||
shape = SubResource( 2 )
|
||||
|
||||
[node name="Sprite" type="Sprite" parent="Walls/Group9/StaticBody2D3" groups=["walls"]]
|
||||
modulate = Color( 0.909202, 0.190021, 0.310404, 1 )
|
||||
texture = ExtResource( 3 )
|
||||
|
||||
[node name="Group2" type="Node2D" parent="Walls"]
|
||||
position = Vector2( 166, 1 )
|
||||
rotation = -2.65517
|
||||
scale = Vector2( 0.5, 0.5 )
|
||||
|
||||
[node name="StaticBody2D" type="StaticBody2D" parent="Walls/Group2"]
|
||||
position = Vector2( -68, -17 )
|
||||
scale = Vector2( 2, 2 )
|
||||
|
||||
[node name="CollisionShape2D" type="CollisionShape2D" parent="Walls/Group2/StaticBody2D"]
|
||||
shape = SubResource( 2 )
|
||||
|
||||
[node name="Sprite" type="Sprite" parent="Walls/Group2/StaticBody2D" groups=["walls"]]
|
||||
modulate = Color( 0.255383, 0.0261656, 0.866709, 1 )
|
||||
texture = ExtResource( 3 )
|
||||
|
||||
[node name="StaticBody2D4" type="StaticBody2D" parent="Walls/Group2"]
|
||||
position = Vector2( 52, 29 )
|
||||
scale = Vector2( 2, 2 )
|
||||
|
||||
[node name="CollisionShape2D" type="CollisionShape2D" parent="Walls/Group2/StaticBody2D4"]
|
||||
shape = SubResource( 2 )
|
||||
|
||||
[node name="Sprite" type="Sprite" parent="Walls/Group2/StaticBody2D4" groups=["walls"]]
|
||||
modulate = Color( 0.484218, 0.0260328, 0.657083, 1 )
|
||||
texture = ExtResource( 3 )
|
||||
|
||||
[node name="StaticBody2D2" type="StaticBody2D" parent="Walls/Group2"]
|
||||
position = Vector2( -20, 48 )
|
||||
scale = Vector2( 2, 2 )
|
||||
|
||||
[node name="CollisionShape2D" type="CollisionShape2D" parent="Walls/Group2/StaticBody2D2"]
|
||||
shape = SubResource( 2 )
|
||||
|
||||
[node name="Sprite" type="Sprite" parent="Walls/Group2/StaticBody2D2" groups=["walls"]]
|
||||
modulate = Color( 0.20515, 0.697483, 0.160248, 1 )
|
||||
texture = ExtResource( 3 )
|
||||
|
||||
[node name="StaticBody2D3" type="StaticBody2D" parent="Walls/Group2"]
|
||||
position = Vector2( 35, -38 )
|
||||
scale = Vector2( 2, 2 )
|
||||
|
||||
[node name="CollisionShape2D" type="CollisionShape2D" parent="Walls/Group2/StaticBody2D3"]
|
||||
shape = SubResource( 2 )
|
||||
|
||||
[node name="Sprite" type="Sprite" parent="Walls/Group2/StaticBody2D3" groups=["walls"]]
|
||||
modulate = Color( 0.641967, 0.583661, 0.16892, 1 )
|
||||
texture = ExtResource( 3 )
|
||||
|
||||
[node name="Group5" type="Node2D" parent="Walls"]
|
||||
position = Vector2( -31, 77 )
|
||||
rotation = -1.82393
|
||||
scale = Vector2( 0.5, 0.5 )
|
||||
|
||||
[node name="StaticBody2D" type="StaticBody2D" parent="Walls/Group5"]
|
||||
position = Vector2( -68, -17 )
|
||||
scale = Vector2( 2, 2 )
|
||||
|
||||
[node name="CollisionShape2D" type="CollisionShape2D" parent="Walls/Group5/StaticBody2D"]
|
||||
shape = SubResource( 2 )
|
||||
|
||||
[node name="Sprite" type="Sprite" parent="Walls/Group5/StaticBody2D" groups=["walls"]]
|
||||
modulate = Color( 0.394341, 0.0701354, 0.101846, 1 )
|
||||
texture = ExtResource( 3 )
|
||||
|
||||
[node name="StaticBody2D4" type="StaticBody2D" parent="Walls/Group5"]
|
||||
position = Vector2( 52, 29 )
|
||||
scale = Vector2( 2, 2 )
|
||||
|
||||
[node name="CollisionShape2D" type="CollisionShape2D" parent="Walls/Group5/StaticBody2D4"]
|
||||
shape = SubResource( 2 )
|
||||
|
||||
[node name="Sprite" type="Sprite" parent="Walls/Group5/StaticBody2D4" groups=["walls"]]
|
||||
modulate = Color( 0.94116, 0.566994, 0.606703, 1 )
|
||||
texture = ExtResource( 3 )
|
||||
|
||||
[node name="StaticBody2D2" type="StaticBody2D" parent="Walls/Group5"]
|
||||
position = Vector2( -20, 48 )
|
||||
scale = Vector2( 2, 2 )
|
||||
|
||||
[node name="CollisionShape2D" type="CollisionShape2D" parent="Walls/Group5/StaticBody2D2"]
|
||||
shape = SubResource( 2 )
|
||||
|
||||
[node name="Sprite" type="Sprite" parent="Walls/Group5/StaticBody2D2" groups=["walls"]]
|
||||
modulate = Color( 0.276915, 0.426239, 0.60367, 1 )
|
||||
texture = ExtResource( 3 )
|
||||
|
||||
[node name="StaticBody2D3" type="StaticBody2D" parent="Walls/Group5"]
|
||||
position = Vector2( 35, -38 )
|
||||
scale = Vector2( 2, 2 )
|
||||
|
||||
[node name="CollisionShape2D" type="CollisionShape2D" parent="Walls/Group5/StaticBody2D3"]
|
||||
shape = SubResource( 2 )
|
||||
|
||||
[node name="Sprite" type="Sprite" parent="Walls/Group5/StaticBody2D3" groups=["walls"]]
|
||||
modulate = Color( 0.673828, 0.857139, 0.0330471, 1 )
|
||||
texture = ExtResource( 3 )
|
||||
|
||||
[node name="Group10" type="Node2D" parent="Walls"]
|
||||
position = Vector2( -215, 133 )
|
||||
rotation = -2.80987
|
||||
scale = Vector2( 0.5, 0.5 )
|
||||
|
||||
[node name="StaticBody2D" type="StaticBody2D" parent="Walls/Group10"]
|
||||
position = Vector2( -68, -17 )
|
||||
scale = Vector2( 2, 2 )
|
||||
|
||||
[node name="CollisionShape2D" type="CollisionShape2D" parent="Walls/Group10/StaticBody2D"]
|
||||
shape = SubResource( 2 )
|
||||
|
||||
[node name="Sprite" type="Sprite" parent="Walls/Group10/StaticBody2D" groups=["walls"]]
|
||||
modulate = Color( 0.394341, 0.0701354, 0.101846, 1 )
|
||||
texture = ExtResource( 3 )
|
||||
|
||||
[node name="StaticBody2D4" type="StaticBody2D" parent="Walls/Group10"]
|
||||
position = Vector2( 52, 29 )
|
||||
scale = Vector2( 2, 2 )
|
||||
|
||||
[node name="CollisionShape2D" type="CollisionShape2D" parent="Walls/Group10/StaticBody2D4"]
|
||||
shape = SubResource( 2 )
|
||||
|
||||
[node name="Sprite" type="Sprite" parent="Walls/Group10/StaticBody2D4" groups=["walls"]]
|
||||
modulate = Color( 0.94116, 0.566994, 0.606703, 1 )
|
||||
texture = ExtResource( 3 )
|
||||
|
||||
[node name="StaticBody2D2" type="StaticBody2D" parent="Walls/Group10"]
|
||||
position = Vector2( -20, 48 )
|
||||
scale = Vector2( 2, 2 )
|
||||
|
||||
[node name="CollisionShape2D" type="CollisionShape2D" parent="Walls/Group10/StaticBody2D2"]
|
||||
shape = SubResource( 2 )
|
||||
|
||||
[node name="Sprite" type="Sprite" parent="Walls/Group10/StaticBody2D2" groups=["walls"]]
|
||||
modulate = Color( 0.276915, 0.426239, 0.60367, 1 )
|
||||
texture = ExtResource( 3 )
|
||||
|
||||
[node name="StaticBody2D3" type="StaticBody2D" parent="Walls/Group10"]
|
||||
position = Vector2( 35, -38 )
|
||||
scale = Vector2( 2, 2 )
|
||||
|
||||
[node name="CollisionShape2D" type="CollisionShape2D" parent="Walls/Group10/StaticBody2D3"]
|
||||
shape = SubResource( 2 )
|
||||
|
||||
[node name="Sprite" type="Sprite" parent="Walls/Group10/StaticBody2D3" groups=["walls"]]
|
||||
modulate = Color( 0.673828, 0.857139, 0.0330471, 1 )
|
||||
texture = ExtResource( 3 )
|
||||
|
||||
[node name="Group4" type="Node2D" parent="Walls"]
|
||||
position = Vector2( 162, 197 )
|
||||
rotation = -0.800594
|
||||
scale = Vector2( 0.5, 0.5 )
|
||||
|
||||
[node name="StaticBody2D" type="StaticBody2D" parent="Walls/Group4"]
|
||||
position = Vector2( -68, -17 )
|
||||
scale = Vector2( 2, 2 )
|
||||
|
||||
[node name="CollisionShape2D" type="CollisionShape2D" parent="Walls/Group4/StaticBody2D"]
|
||||
shape = SubResource( 2 )
|
||||
|
||||
[node name="Sprite" type="Sprite" parent="Walls/Group4/StaticBody2D" groups=["walls"]]
|
||||
modulate = Color( 0.334467, 0.798133, 0.45167, 1 )
|
||||
texture = ExtResource( 3 )
|
||||
|
||||
[node name="StaticBody2D4" type="StaticBody2D" parent="Walls/Group4"]
|
||||
position = Vector2( 52, 29 )
|
||||
scale = Vector2( 2, 2 )
|
||||
|
||||
[node name="CollisionShape2D" type="CollisionShape2D" parent="Walls/Group4/StaticBody2D4"]
|
||||
shape = SubResource( 2 )
|
||||
|
||||
[node name="Sprite" type="Sprite" parent="Walls/Group4/StaticBody2D4" groups=["walls"]]
|
||||
modulate = Color( 0.386136, 0.875769, 0.0833352, 1 )
|
||||
texture = ExtResource( 3 )
|
||||
|
||||
[node name="StaticBody2D2" type="StaticBody2D" parent="Walls/Group4"]
|
||||
position = Vector2( -20, 48 )
|
||||
scale = Vector2( 2, 2 )
|
||||
|
||||
[node name="CollisionShape2D" type="CollisionShape2D" parent="Walls/Group4/StaticBody2D2"]
|
||||
shape = SubResource( 2 )
|
||||
|
||||
[node name="Sprite" type="Sprite" parent="Walls/Group4/StaticBody2D2" groups=["walls"]]
|
||||
modulate = Color( 0.680544, 0.336621, 0.477674, 1 )
|
||||
texture = ExtResource( 3 )
|
||||
|
||||
[node name="StaticBody2D3" type="StaticBody2D" parent="Walls/Group4"]
|
||||
position = Vector2( 35, -38 )
|
||||
scale = Vector2( 2, 2 )
|
||||
|
||||
[node name="CollisionShape2D" type="CollisionShape2D" parent="Walls/Group4/StaticBody2D3"]
|
||||
shape = SubResource( 2 )
|
||||
|
||||
[node name="Sprite" type="Sprite" parent="Walls/Group4/StaticBody2D3" groups=["walls"]]
|
||||
modulate = Color( 0.810584, 0.863357, 0.582931, 1 )
|
||||
texture = ExtResource( 3 )
|
||||
|
||||
[node name="Group3" type="Node2D" parent="Walls"]
|
||||
position = Vector2( 142, 27 )
|
||||
rotation = 1.61359
|
||||
scale = Vector2( 2, 2 )
|
||||
|
||||
[node name="StaticBody2D" type="StaticBody2D" parent="Walls/Group3"]
|
||||
position = Vector2( -68, -17 )
|
||||
scale = Vector2( 2, 2 )
|
||||
|
||||
[node name="CollisionShape2D" type="CollisionShape2D" parent="Walls/Group3/StaticBody2D"]
|
||||
shape = SubResource( 2 )
|
||||
|
||||
[node name="Sprite" type="Sprite" parent="Walls/Group3/StaticBody2D" groups=["walls"]]
|
||||
modulate = Color( 0.0134517, 0.400895, 0.508833, 1 )
|
||||
texture = ExtResource( 3 )
|
||||
|
||||
[node name="StaticBody2D4" type="StaticBody2D" parent="Walls/Group3"]
|
||||
position = Vector2( 52, 29 )
|
||||
scale = Vector2( 2, 2 )
|
||||
|
||||
[node name="CollisionShape2D" type="CollisionShape2D" parent="Walls/Group3/StaticBody2D4"]
|
||||
shape = SubResource( 2 )
|
||||
|
||||
[node name="Sprite" type="Sprite" parent="Walls/Group3/StaticBody2D4" groups=["walls"]]
|
||||
modulate = Color( 0.280046, 0.408967, 0.911763, 1 )
|
||||
texture = ExtResource( 3 )
|
||||
|
||||
[node name="StaticBody2D2" type="StaticBody2D" parent="Walls/Group3"]
|
||||
position = Vector2( -20, 48 )
|
||||
scale = Vector2( 2, 2 )
|
||||
|
||||
[node name="CollisionShape2D" type="CollisionShape2D" parent="Walls/Group3/StaticBody2D2"]
|
||||
shape = SubResource( 2 )
|
||||
|
||||
[node name="Sprite" type="Sprite" parent="Walls/Group3/StaticBody2D2" groups=["walls"]]
|
||||
modulate = Color( 0.228981, 0.571434, 0.607728, 1 )
|
||||
texture = ExtResource( 3 )
|
||||
|
||||
[node name="StaticBody2D3" type="StaticBody2D" parent="Walls/Group3"]
|
||||
position = Vector2( 35, -38 )
|
||||
scale = Vector2( 2, 2 )
|
||||
|
||||
[node name="CollisionShape2D" type="CollisionShape2D" parent="Walls/Group3/StaticBody2D3"]
|
||||
shape = SubResource( 2 )
|
||||
|
||||
[node name="Sprite" type="Sprite" parent="Walls/Group3/StaticBody2D3" groups=["walls"]]
|
||||
modulate = Color( 0.398647, 0.433863, 0.423729, 1 )
|
||||
texture = ExtResource( 3 )
|
||||
|
||||
[node name="Group7" type="Node2D" parent="Walls"]
|
||||
position = Vector2( -228, 127 )
|
||||
rotation = 3.15427
|
||||
scale = Vector2( 2, 2 )
|
||||
|
||||
[node name="StaticBody2D" type="StaticBody2D" parent="Walls/Group7"]
|
||||
position = Vector2( -68, -17 )
|
||||
scale = Vector2( 2, 2 )
|
||||
|
||||
[node name="CollisionShape2D" type="CollisionShape2D" parent="Walls/Group7/StaticBody2D"]
|
||||
shape = SubResource( 2 )
|
||||
|
||||
[node name="Sprite" type="Sprite" parent="Walls/Group7/StaticBody2D" groups=["walls"]]
|
||||
modulate = Color( 0.0134517, 0.400895, 0.508833, 1 )
|
||||
texture = ExtResource( 3 )
|
||||
|
||||
[node name="StaticBody2D4" type="StaticBody2D" parent="Walls/Group7"]
|
||||
position = Vector2( 52, 29 )
|
||||
scale = Vector2( 2, 2 )
|
||||
|
||||
[node name="CollisionShape2D" type="CollisionShape2D" parent="Walls/Group7/StaticBody2D4"]
|
||||
shape = SubResource( 2 )
|
||||
|
||||
[node name="Sprite" type="Sprite" parent="Walls/Group7/StaticBody2D4" groups=["walls"]]
|
||||
modulate = Color( 0.280046, 0.408967, 0.911763, 1 )
|
||||
texture = ExtResource( 3 )
|
||||
|
||||
[node name="StaticBody2D2" type="StaticBody2D" parent="Walls/Group7"]
|
||||
position = Vector2( -20, 48 )
|
||||
scale = Vector2( 2, 2 )
|
||||
|
||||
[node name="CollisionShape2D" type="CollisionShape2D" parent="Walls/Group7/StaticBody2D2"]
|
||||
shape = SubResource( 2 )
|
||||
|
||||
[node name="Sprite" type="Sprite" parent="Walls/Group7/StaticBody2D2" groups=["walls"]]
|
||||
modulate = Color( 0.228981, 0.571434, 0.607728, 1 )
|
||||
texture = ExtResource( 3 )
|
||||
|
||||
[node name="StaticBody2D3" type="StaticBody2D" parent="Walls/Group7"]
|
||||
position = Vector2( 35, -38 )
|
||||
scale = Vector2( 2, 2 )
|
||||
|
||||
[node name="CollisionShape2D" type="CollisionShape2D" parent="Walls/Group7/StaticBody2D3"]
|
||||
shape = SubResource( 2 )
|
||||
|
||||
[node name="Sprite" type="Sprite" parent="Walls/Group7/StaticBody2D3" groups=["walls"]]
|
||||
modulate = Color( 0.398647, 0.433863, 0.423729, 1 )
|
||||
texture = ExtResource( 3 )
|
||||
17
viewport/dynamic_split_screen/2d/player.gd
Normal file
17
viewport/dynamic_split_screen/2d/player.gd
Normal file
@@ -0,0 +1,17 @@
|
||||
extends KinematicBody2D
|
||||
|
||||
|
||||
# Moves the player
|
||||
|
||||
export(int, 1, 2) var player_id = 1
|
||||
export(float) var walk_speed = 200.0
|
||||
|
||||
|
||||
func _physics_process(_delta):
|
||||
var velocity = Vector2.ZERO
|
||||
velocity.y = -Input.get_action_strength("move_up_player" + str(player_id))
|
||||
velocity.y += Input.get_action_strength("move_down_player" + str(player_id))
|
||||
velocity.x = -Input.get_action_strength("move_left_player" + str(player_id))
|
||||
velocity.x += Input.get_action_strength("move_right_player" + str(player_id))
|
||||
|
||||
move_and_slide(velocity.normalized() * walk_speed)
|
||||
BIN
viewport/dynamic_split_screen/2d/player.png
Normal file
BIN
viewport/dynamic_split_screen/2d/player.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.2 KiB |
35
viewport/dynamic_split_screen/2d/player.png.import
Normal file
35
viewport/dynamic_split_screen/2d/player.png.import
Normal file
@@ -0,0 +1,35 @@
|
||||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="StreamTexture"
|
||||
path="res://.import/player.png-efb1916a0d650384deb4448ddc0269fa.stex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://2d/player.png"
|
||||
dest_files=[ "res://.import/player.png-efb1916a0d650384deb4448ddc0269fa.stex" ]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/lossy_quality=0.7
|
||||
compress/hdr_mode=0
|
||||
compress/bptc_ldr=0
|
||||
compress/normal_map=0
|
||||
flags/repeat=0
|
||||
flags/filter=true
|
||||
flags/mipmaps=false
|
||||
flags/anisotropic=false
|
||||
flags/srgb=2
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/HDR_as_SRGB=false
|
||||
process/invert_color=false
|
||||
process/normal_map_invert_y=false
|
||||
stream=false
|
||||
size_limit=0
|
||||
detect_3d=true
|
||||
svg/scale=1.0
|
||||
56
viewport/dynamic_split_screen/2d/split_screen.tscn
Normal file
56
viewport/dynamic_split_screen/2d/split_screen.tscn
Normal file
@@ -0,0 +1,56 @@
|
||||
[gd_scene load_steps=7 format=2]
|
||||
|
||||
[ext_resource path="res://camera_controller.gd" type="Script" id=1]
|
||||
[ext_resource path="res://split_screen.shader" type="Shader" id=2]
|
||||
[ext_resource path="res://icon.png" type="Texture" id=3]
|
||||
[ext_resource path="res://exit_to_menu.gd" type="Script" id=4]
|
||||
[ext_resource path="res://2d/level.tscn" type="PackedScene" id=5]
|
||||
|
||||
[sub_resource type="ShaderMaterial" id=1]
|
||||
shader = ExtResource( 2 )
|
||||
shader_param/viewport_size = null
|
||||
shader_param/split_active = null
|
||||
shader_param/player1_position = null
|
||||
shader_param/player2_position = null
|
||||
shader_param/split_line_thickness = null
|
||||
shader_param/split_line_color = null
|
||||
|
||||
[node name="Game" type="Node2D"]
|
||||
script = ExtResource( 4 )
|
||||
|
||||
[node name="SplitScreen" type="Node" parent="."]
|
||||
script = ExtResource( 1 )
|
||||
max_separation = 100.0
|
||||
|
||||
[node name="View" type="TextureRect" parent="SplitScreen"]
|
||||
material = SubResource( 1 )
|
||||
margin_right = 1024.0
|
||||
margin_bottom = 600.0
|
||||
texture = ExtResource( 3 )
|
||||
expand = true
|
||||
|
||||
[node name="Main" type="Viewport" parent="SplitScreen"]
|
||||
size = Vector2( 1024, 600 )
|
||||
hdr = false
|
||||
disable_3d = true
|
||||
usage = 0
|
||||
render_target_v_flip = true
|
||||
render_target_update_mode = 3
|
||||
|
||||
[node name="Level" parent="SplitScreen/Main" instance=ExtResource( 5 )]
|
||||
|
||||
[node name="Camera" type="Camera2D" parent="SplitScreen/Main"]
|
||||
current = true
|
||||
zoom = Vector2( 0.2, 0.2 )
|
||||
|
||||
[node name="Secondary" type="Viewport" parent="SplitScreen"]
|
||||
size = Vector2( 100, 100 )
|
||||
hdr = false
|
||||
disable_3d = true
|
||||
usage = 0
|
||||
render_target_v_flip = true
|
||||
render_target_update_mode = 3
|
||||
|
||||
[node name="Camera" type="Camera2D" parent="SplitScreen/Secondary"]
|
||||
current = true
|
||||
zoom = Vector2( 0.2, 0.2 )
|
||||
BIN
viewport/dynamic_split_screen/2d/square.png
Normal file
BIN
viewport/dynamic_split_screen/2d/square.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 502 B |
35
viewport/dynamic_split_screen/2d/square.png.import
Normal file
35
viewport/dynamic_split_screen/2d/square.png.import
Normal file
@@ -0,0 +1,35 @@
|
||||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="StreamTexture"
|
||||
path="res://.import/square.png-78c70671391f71adc77019bdb5e7a73b.stex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://2d/square.png"
|
||||
dest_files=[ "res://.import/square.png-78c70671391f71adc77019bdb5e7a73b.stex" ]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/lossy_quality=0.7
|
||||
compress/hdr_mode=0
|
||||
compress/bptc_ldr=0
|
||||
compress/normal_map=0
|
||||
flags/repeat=0
|
||||
flags/filter=true
|
||||
flags/mipmaps=false
|
||||
flags/anisotropic=false
|
||||
flags/srgb=2
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/HDR_as_SRGB=false
|
||||
process/invert_color=false
|
||||
process/normal_map_invert_y=false
|
||||
stream=false
|
||||
size_limit=0
|
||||
detect_3d=true
|
||||
svg/scale=1.0
|
||||
11
viewport/dynamic_split_screen/2d/wall_coloring.gd
Normal file
11
viewport/dynamic_split_screen/2d/wall_coloring.gd
Normal file
@@ -0,0 +1,11 @@
|
||||
tool
|
||||
extends Node2D
|
||||
|
||||
# Set a random color to all objects in the "walls" group.
|
||||
# To use, attach this script to the "Walls" node.
|
||||
|
||||
func _ready():
|
||||
randomize()
|
||||
var walls = get_tree().get_nodes_in_group("walls")
|
||||
for wall in walls:
|
||||
wall.modulate = Color(randf(), randf(), randf())
|
||||
@@ -1,19 +1,7 @@
|
||||
[gd_scene load_steps=58 format=2]
|
||||
[gd_scene load_steps=54 format=2]
|
||||
|
||||
[ext_resource path="res://default_env.tres" type="Environment" id=1]
|
||||
[ext_resource path="res://camera_controller.gd" type="Script" id=2]
|
||||
[ext_resource path="res://split_screen.shader" type="Shader" id=3]
|
||||
[ext_resource path="res://icon.png" type="Texture" id=4]
|
||||
[ext_resource path="res://player.gd" type="Script" id=5]
|
||||
|
||||
[sub_resource type="ShaderMaterial" id=1]
|
||||
shader = ExtResource( 3 )
|
||||
shader_param/viewport_size = null
|
||||
shader_param/split_active = null
|
||||
shader_param/player1_position = null
|
||||
shader_param/player2_position = null
|
||||
shader_param/split_line_thickness = null
|
||||
shader_param/split_line_color = null
|
||||
[ext_resource path="res://3d/player.gd" type="Script" id=1]
|
||||
[ext_resource path="res://default_env.tres" type="Environment" id=2]
|
||||
|
||||
[sub_resource type="CapsuleMesh" id=2]
|
||||
|
||||
@@ -164,54 +152,19 @@ albedo_color = Color( 0.770645, 0.287346, 0.739309, 1 )
|
||||
[sub_resource type="SpatialMaterial" id=52]
|
||||
albedo_color = Color( 0.791675, 0.946163, 0.317723, 1 )
|
||||
|
||||
[node name="World" type="Spatial"]
|
||||
[node name="Level" type="Spatial"]
|
||||
|
||||
[node name="WorldEnvironment" type="WorldEnvironment" parent="."]
|
||||
environment = ExtResource( 1 )
|
||||
environment = ExtResource( 2 )
|
||||
|
||||
[node name="DirectionalLight" type="DirectionalLight" parent="WorldEnvironment"]
|
||||
transform = Transform( 1, 0, 0, 0, -0.818651, 0.574291, 0, -0.574291, -0.818651, 0, 70.567, -72.3668 )
|
||||
shadow_enabled = true
|
||||
shadow_color = Color( 0.6, 0.6, 0.6, 1 )
|
||||
|
||||
[node name="Cameras" type="Spatial" parent="."]
|
||||
script = ExtResource( 2 )
|
||||
|
||||
[node name="View" type="TextureRect" parent="Cameras"]
|
||||
material = SubResource( 1 )
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
texture = ExtResource( 4 )
|
||||
expand = true
|
||||
__meta__ = {
|
||||
"_edit_use_anchors_": false
|
||||
}
|
||||
|
||||
[node name="Viewport1" type="Viewport" parent="Cameras"]
|
||||
size = Vector2( 100, 100 )
|
||||
msaa = 2
|
||||
usage = 3
|
||||
render_target_v_flip = true
|
||||
render_target_update_mode = 3
|
||||
|
||||
[node name="Camera1" type="Camera" parent="Cameras/Viewport1"]
|
||||
transform = Transform( 1, 0, 0, 0, -4.37114e-08, 1, 0, -1, -4.37114e-08, 0, 20, 0 )
|
||||
current = true
|
||||
|
||||
[node name="Viewport2" type="Viewport" parent="Cameras"]
|
||||
size = Vector2( 100, 100 )
|
||||
msaa = 2
|
||||
usage = 3
|
||||
render_target_v_flip = true
|
||||
render_target_update_mode = 3
|
||||
|
||||
[node name="Camera2" type="Camera" parent="Cameras/Viewport2"]
|
||||
transform = Transform( 1, 0, 0, 0, -4.37114e-08, 1, 0, -1, -4.37114e-08, 0, 20, 0 )
|
||||
current = true
|
||||
|
||||
[node name="Player1" type="KinematicBody" parent="."]
|
||||
transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.25, 0 )
|
||||
script = ExtResource( 5 )
|
||||
script = ExtResource( 1 )
|
||||
|
||||
[node name="Mesh" type="MeshInstance" parent="Player1"]
|
||||
transform = Transform( 1, 0, 0, 0, -4.37114e-08, -1, 0, 1, -4.37114e-08, 0, 0, 0 )
|
||||
@@ -224,7 +177,7 @@ shape = SubResource( 4 )
|
||||
|
||||
[node name="Player2" type="KinematicBody" parent="."]
|
||||
transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 4.18358, 1.25, 3.01882 )
|
||||
script = ExtResource( 5 )
|
||||
script = ExtResource( 1 )
|
||||
player_id = 2
|
||||
|
||||
[node name="Mesh" type="MeshInstance" parent="Player2"]
|
||||
53
viewport/dynamic_split_screen/3d/split_screen.tscn
Normal file
53
viewport/dynamic_split_screen/3d/split_screen.tscn
Normal file
@@ -0,0 +1,53 @@
|
||||
[gd_scene load_steps=7 format=2]
|
||||
|
||||
[ext_resource path="res://3d/level.tscn" type="PackedScene" id=1]
|
||||
[ext_resource path="res://camera_controller.gd" type="Script" id=2]
|
||||
[ext_resource path="res://split_screen.shader" type="Shader" id=3]
|
||||
[ext_resource path="res://icon.png" type="Texture" id=4]
|
||||
[ext_resource path="res://exit_to_menu.gd" type="Script" id=6]
|
||||
|
||||
[sub_resource type="ShaderMaterial" id=1]
|
||||
shader = ExtResource( 3 )
|
||||
shader_param/viewport_size = null
|
||||
shader_param/split_active = null
|
||||
shader_param/player1_position = null
|
||||
shader_param/player2_position = null
|
||||
shader_param/split_line_thickness = null
|
||||
shader_param/split_line_color = null
|
||||
|
||||
[node name="Game" type="Spatial"]
|
||||
script = ExtResource( 6 )
|
||||
|
||||
[node name="SplitScreen" type="Node" parent="."]
|
||||
script = ExtResource( 2 )
|
||||
|
||||
[node name="View" type="TextureRect" parent="SplitScreen"]
|
||||
material = SubResource( 1 )
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
texture = ExtResource( 4 )
|
||||
expand = true
|
||||
|
||||
[node name="Main" type="Viewport" parent="SplitScreen"]
|
||||
size = Vector2( 100, 100 )
|
||||
msaa = 2
|
||||
usage = 3
|
||||
render_target_v_flip = true
|
||||
render_target_update_mode = 3
|
||||
|
||||
[node name="Level" parent="SplitScreen/Main" instance=ExtResource( 1 )]
|
||||
|
||||
[node name="Camera" type="Camera" parent="SplitScreen/Main"]
|
||||
transform = Transform( 1, 0, 0, 0, -4.37114e-08, 1, 0, -1, -4.37114e-08, 0, 20, 0 )
|
||||
current = true
|
||||
|
||||
[node name="Secondary" type="Viewport" parent="SplitScreen"]
|
||||
size = Vector2( 100, 100 )
|
||||
msaa = 2
|
||||
usage = 3
|
||||
render_target_v_flip = true
|
||||
render_target_update_mode = 3
|
||||
|
||||
[node name="Camera" type="Camera" parent="SplitScreen/Secondary"]
|
||||
transform = Transform( 1, 0, 0, 0, -4.37114e-08, 1, 0, -1, -4.37114e-08, 0, 20, 0 )
|
||||
current = true
|
||||
@@ -1,26 +1,25 @@
|
||||
# Dynamic Split Screen
|
||||
|
||||
This sample project showcases an implementation of dynamic
|
||||
split screen, also called Voronoi split screen.
|
||||
split screen, also called Voronoi split screen, for both 2D and 3D games.
|
||||
|
||||
Language: [GDSL](https://docs.godotengine.org/en/latest/tutorials/shaders/shader_reference/shading_language.html) and GDScript
|
||||
|
||||
Renderer: GLES 2
|
||||
|
||||
Note: An HTML5 export is testable
|
||||
[here](https://benjaminnavarro.github.io/godot_dynamic_split_screen/index.html).
|
||||
Note: An HTML5 export is testable on [itch.io](https://benjaminnavarro.itch.io/godot-dynamic-split-screen-demo).
|
||||
|
||||
Check out this demo on the asset library: https://godotengine.org/asset-library/asset/541
|
||||
|
||||
## Details
|
||||
|
||||
A dynamic split screen system displays a single screen when
|
||||
the two players are close but a splitted view when they move apart.
|
||||
the two players are close but a split view when they move apart.
|
||||
|
||||
The splitting line can take any angle depending on the players'
|
||||
position, so it won't be either vertical or horizontal.
|
||||
|
||||
This system was popularized by the Lego videogames.
|
||||
This system was popularized by the Lego video games.
|
||||
|
||||
## How it works
|
||||
|
||||
@@ -28,8 +27,8 @@ Two cameras are placed inside two separate viewports and their
|
||||
texture, as well as some other parameters, are passed to a
|
||||
shader attached to a TextureRect filling the whole screen.
|
||||
|
||||
The `SplitScreen` shader, with the help of the `CameraController`
|
||||
script, chooses wich texture to display on each pixel to
|
||||
The `split_screen` shader, with the help of the `camera_controller`
|
||||
script, chooses which texture to display on each pixel to
|
||||
achieve the effect.
|
||||
|
||||
The cameras are placed on the segment joining the two players,
|
||||
@@ -38,14 +37,26 @@ distance otherwise.
|
||||
|
||||
## How to use it
|
||||
|
||||
Open and launch the project inside the Godot engine and then
|
||||
you can use WASD keys to move the first player and IJKL keys
|
||||
to move the second one.
|
||||
Open and launch the project inside the Godot engine, select either the
|
||||
2D or the 3D demo from the menu and then use WASD/ZQSD keys
|
||||
to move the first player and IJKL/arrows keys to move the
|
||||
second one.
|
||||
|
||||
While a demo is running, you can press the escape key to get back
|
||||
to the menu.
|
||||
|
||||
The `Cameras` node has parameters to tune the distance at
|
||||
which the screen splits and also the width and color of
|
||||
the splitting line.
|
||||
the splitting line. The `Adaptive Split Line Thickness` parameter
|
||||
select whether the split line has a constant thickness or a dynamic
|
||||
one varying depending on the distance between the two players.
|
||||
|
||||
## Screenshots
|
||||
|
||||

|
||||
### 2D
|
||||
|
||||

|
||||
|
||||
### 3D
|
||||
|
||||

|
||||
|
||||
@@ -1,47 +1,56 @@
|
||||
extends Spatial
|
||||
extends Node
|
||||
|
||||
|
||||
# Handle the motion of both player cameras as well as communication with the
|
||||
# SplitScreen shader to achieve the dynamic split screen effet
|
||||
#
|
||||
# Cameras are place on the segment joining the two players, either in the middle
|
||||
# if players are close enough or at a fixed distance if they are not.
|
||||
# Cameras are placed on the segment joining the two players, either in the middle
|
||||
# if players are close enough or at a fixed distance from them if they are not.
|
||||
# In the first case, both cameras being at the same location, only the view of
|
||||
# the first one is used for the entire screen thus allowing the players to play
|
||||
# on a unsplit screen.
|
||||
# on an unsplit screen.
|
||||
# In the second case, the screen is split in two with a line perpendicular to the
|
||||
# segement joining the two players.
|
||||
# segment joining the two players.
|
||||
#
|
||||
# The points of customization are:
|
||||
# max_separation: the distance between players at which the view starts to split
|
||||
# split_line_thickness: the thickness of the split line in pixels
|
||||
# split_line_color: color of the split line
|
||||
# adaptive_split_line_thickness: if true, the split line thickness will vary
|
||||
# depending on the distance between players. If false, the thickness will
|
||||
# be constant and equal to split_line_thickness
|
||||
# depending on the distance between players, with a maximum of
|
||||
# split_line_thickness. If false, the thickness will be constant and equal
|
||||
# to split_line_thickness.
|
||||
|
||||
|
||||
enum Mode {
|
||||
Mode2D,
|
||||
Mode3D
|
||||
}
|
||||
|
||||
export(float) var max_separation = 20.0
|
||||
export(float) var split_line_thickness = 3.0
|
||||
export(Color, RGBA) var split_line_color = Color.black
|
||||
export(bool) var adaptive_split_line_thickness = true
|
||||
|
||||
onready var player1 = $"../Player1"
|
||||
onready var player2 = $"../Player2"
|
||||
onready var main_viewport = $Main
|
||||
onready var secondary_viewport = $Secondary
|
||||
onready var level = main_viewport.get_node(@"Level")
|
||||
onready var player1 = level.get_node(@"Player1")
|
||||
onready var player2 = level.get_node(@"Player2")
|
||||
onready var view = $View
|
||||
onready var viewport1 = $Viewport1
|
||||
onready var viewport2 = $Viewport2
|
||||
onready var camera1 = viewport1.get_node(@"Camera1")
|
||||
onready var camera2 = viewport2.get_node(@"Camera2")
|
||||
|
||||
onready var camera1 = main_viewport.get_node(@"Camera")
|
||||
onready var camera2 = secondary_viewport.get_node(@"Camera")
|
||||
onready var mode = Mode.Mode2D if camera1 is Camera2D else Mode.Mode3D
|
||||
|
||||
func _ready():
|
||||
secondary_viewport.world_2d = main_viewport.world_2d
|
||||
_on_size_changed()
|
||||
_update_splitscreen()
|
||||
|
||||
get_viewport().connect("size_changed", self, "_on_size_changed")
|
||||
|
||||
view.material.set_shader_param("viewport1", viewport1.get_texture())
|
||||
view.material.set_shader_param("viewport2", viewport2.get_texture())
|
||||
view.material.set_shader_param("viewport1", main_viewport.get_texture())
|
||||
view.material.set_shader_param("viewport2", secondary_viewport.get_texture())
|
||||
|
||||
|
||||
func _process(_delta):
|
||||
@@ -56,6 +65,11 @@ func _move_cameras():
|
||||
|
||||
position_difference = position_difference.normalized() * distance
|
||||
|
||||
match mode:
|
||||
Mode.Mode2D:
|
||||
camera1.position = player1.position + position_difference / 2.0
|
||||
camera2.position = player2.position - position_difference / 2.0
|
||||
Mode.Mode3D:
|
||||
camera1.translation.x = player1.translation.x + position_difference.x / 2.0
|
||||
camera1.translation.z = player1.translation.z + position_difference.z / 2.0
|
||||
|
||||
@@ -65,15 +79,24 @@ func _move_cameras():
|
||||
|
||||
func _update_splitscreen():
|
||||
var screen_size = get_viewport().get_visible_rect().size
|
||||
var player1_position = camera1.unproject_position(player1.translation) / screen_size
|
||||
var player2_position = camera2.unproject_position(player2.translation) / screen_size
|
||||
var player1_position
|
||||
var player2_position
|
||||
|
||||
match mode:
|
||||
Mode.Mode2D:
|
||||
player1_position = (player1.position - camera1.position) / (camera1.zoom * screen_size) + Vector2(0.5, 0.5)
|
||||
player2_position = (player2.position - camera2.position) / (camera2.zoom * screen_size) + Vector2(0.5, 0.5)
|
||||
Mode.Mode3D:
|
||||
player1_position = camera1.unproject_position(player1.translation) / screen_size
|
||||
player2_position = camera2.unproject_position(player2.translation) / screen_size
|
||||
|
||||
var thickness
|
||||
if adaptive_split_line_thickness:
|
||||
var position_difference = _compute_position_difference_in_world()
|
||||
var distance = _compute_horizontal_length(position_difference)
|
||||
thickness = lerp(0, split_line_thickness, (distance - max_separation) / max_separation)
|
||||
thickness = clamp(thickness, 0, split_line_thickness)
|
||||
if thickness > 0:
|
||||
thickness = clamp(thickness, 1, split_line_thickness)
|
||||
else:
|
||||
thickness = split_line_thickness
|
||||
|
||||
@@ -85,7 +108,7 @@ func _update_splitscreen():
|
||||
|
||||
|
||||
# Split screen is active if players are too far apart from each other.
|
||||
# Only the horizontal components (x, z) are used for distance computation
|
||||
# Only the horizontal components (x/z in 3D, x/y in 2D) are used for distance computation
|
||||
func _get_split_state():
|
||||
var position_difference = _compute_position_difference_in_world()
|
||||
var separation_distance = _compute_horizontal_length(position_difference)
|
||||
@@ -95,15 +118,15 @@ func _get_split_state():
|
||||
func _on_size_changed():
|
||||
var screen_size = get_viewport().get_visible_rect().size
|
||||
|
||||
$Viewport1.size = screen_size
|
||||
$Viewport2.size = screen_size
|
||||
main_viewport.size = screen_size
|
||||
secondary_viewport.size = screen_size
|
||||
|
||||
view.material.set_shader_param("viewport_size", screen_size)
|
||||
|
||||
|
||||
func _compute_position_difference_in_world():
|
||||
return player2.translation - player1.translation
|
||||
return player2.position - player1.position if mode == Mode.Mode2D else player2.translation - player1.translation
|
||||
|
||||
|
||||
func _compute_horizontal_length(vec):
|
||||
return Vector2(vec.x, vec.z).length()
|
||||
return Vector2(vec.x, vec.y).length() if mode == Mode.Mode2D else Vector2(vec.x, vec.z).length()
|
||||
|
||||
6
viewport/dynamic_split_screen/exit_to_menu.gd
Normal file
6
viewport/dynamic_split_screen/exit_to_menu.gd
Normal file
@@ -0,0 +1,6 @@
|
||||
extends Node
|
||||
|
||||
|
||||
func _process(_delta):
|
||||
if Input.is_action_just_pressed("ui_cancel"):
|
||||
get_tree().change_scene("res://menu.tscn")
|
||||
8
viewport/dynamic_split_screen/menu.gd
Normal file
8
viewport/dynamic_split_screen/menu.gd
Normal file
@@ -0,0 +1,8 @@
|
||||
extends Control
|
||||
|
||||
func _load_2d_demo():
|
||||
get_tree().change_scene("res://2d/split_screen.tscn")
|
||||
|
||||
|
||||
func _load_3d_demo():
|
||||
get_tree().change_scene("res://3d/split_screen.tscn")
|
||||
56
viewport/dynamic_split_screen/menu.tscn
Normal file
56
viewport/dynamic_split_screen/menu.tscn
Normal file
@@ -0,0 +1,56 @@
|
||||
[gd_scene load_steps=5 format=2]
|
||||
|
||||
[ext_resource path="res://noto_sans_ui_regular.ttf" type="DynamicFontData" id=1]
|
||||
[ext_resource path="res://menu.gd" type="Script" id=2]
|
||||
|
||||
[sub_resource type="DynamicFont" id=1]
|
||||
size = 45
|
||||
font_data = ExtResource( 1 )
|
||||
|
||||
[sub_resource type="Theme" id=2]
|
||||
default_font = SubResource( 1 )
|
||||
|
||||
[node name="Menu" type="Control"]
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
rect_rotation = -0.0105554
|
||||
theme = SubResource( 2 )
|
||||
script = ExtResource( 2 )
|
||||
|
||||
[node name="CenterContainer" type="CenterContainer" parent="."]
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
|
||||
[node name="VBoxContainer" type="VBoxContainer" parent="CenterContainer"]
|
||||
margin_left = 112.0
|
||||
margin_top = 152.0
|
||||
margin_right = 912.0
|
||||
margin_bottom = 448.0
|
||||
|
||||
[node name="Label" type="Label" parent="CenterContainer/VBoxContainer"]
|
||||
margin_right = 800.0
|
||||
margin_bottom = 150.0
|
||||
rect_min_size = Vector2( 800, 150 )
|
||||
custom_colors/font_color = Color( 0.290196, 0.290196, 0.290196, 1 )
|
||||
text = "Dynamic Split Screen"
|
||||
align = 1
|
||||
valign = 1
|
||||
|
||||
[node name="StartButtons" type="VBoxContainer" parent="CenterContainer/VBoxContainer"]
|
||||
margin_top = 154.0
|
||||
margin_right = 800.0
|
||||
margin_bottom = 296.0
|
||||
|
||||
[node name="Start2D" type="Button" parent="CenterContainer/VBoxContainer/StartButtons"]
|
||||
margin_right = 800.0
|
||||
margin_bottom = 69.0
|
||||
text = "Start 2D demo"
|
||||
|
||||
[node name="Start3D" type="Button" parent="CenterContainer/VBoxContainer/StartButtons"]
|
||||
margin_top = 73.0
|
||||
margin_right = 800.0
|
||||
margin_bottom = 142.0
|
||||
text = "Start 3D demo"
|
||||
|
||||
[connection signal="pressed" from="CenterContainer/VBoxContainer/StartButtons/Start2D" to="." method="_load_2d_demo"]
|
||||
[connection signal="pressed" from="CenterContainer/VBoxContainer/StartButtons/Start3D" to="." method="_load_3d_demo"]
|
||||
BIN
viewport/dynamic_split_screen/noto_sans_ui_regular.ttf
Normal file
BIN
viewport/dynamic_split_screen/noto_sans_ui_regular.ttf
Normal file
Binary file not shown.
@@ -13,7 +13,7 @@ config_version=4
|
||||
config/name="Dynamic Split Screen"
|
||||
config/description="This sample project showcases an implementation of dynamic
|
||||
split screen, also called Voronoi split screen, using GDSL."
|
||||
run/main_scene="res://split_screen.tscn"
|
||||
run/main_scene="res://menu.tscn"
|
||||
config/icon="res://icon.png"
|
||||
|
||||
[debug]
|
||||
|
||||
BIN
viewport/dynamic_split_screen/screenshots/splitscreen_2d.png
Normal file
BIN
viewport/dynamic_split_screen/screenshots/splitscreen_2d.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 54 KiB |
|
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 13 KiB |
Reference in New Issue
Block a user