Basic multiplayer working?
This commit is contained in:
parent
202c44cabf
commit
384d7bac31
10 changed files with 166 additions and 64 deletions
|
@ -24,11 +24,6 @@ flags = 4
|
|||
atlas = ExtResource( 1 )
|
||||
region = Rect2( 54, 468, 18, 36 )
|
||||
|
||||
[sub_resource type="AtlasTexture" id=9]
|
||||
flags = 4
|
||||
atlas = ExtResource( 1 )
|
||||
region = Rect2( 144, 468, 18, 36 )
|
||||
|
||||
[sub_resource type="AtlasTexture" id=5]
|
||||
flags = 4
|
||||
atlas = ExtResource( 1 )
|
||||
|
@ -49,6 +44,11 @@ flags = 4
|
|||
atlas = ExtResource( 1 )
|
||||
region = Rect2( 126, 468, 18, 36 )
|
||||
|
||||
[sub_resource type="AtlasTexture" id=9]
|
||||
flags = 4
|
||||
atlas = ExtResource( 1 )
|
||||
region = Rect2( 144, 468, 18, 36 )
|
||||
|
||||
[sub_resource type="SpriteFrames" id=10]
|
||||
animations = [ {
|
||||
"frames": [ SubResource( 1 ), SubResource( 2 ), SubResource( 3 ), SubResource( 4 ) ],
|
||||
|
@ -56,15 +56,15 @@ animations = [ {
|
|||
"name": "idle",
|
||||
"speed": 6.0
|
||||
}, {
|
||||
"frames": [ SubResource( 9 ) ],
|
||||
"loop": true,
|
||||
"name": "hurt",
|
||||
"speed": 5.0
|
||||
}, {
|
||||
"frames": [ SubResource( 5 ), SubResource( 6 ), SubResource( 7 ), SubResource( 8 ) ],
|
||||
"loop": true,
|
||||
"name": "run",
|
||||
"speed": 12.0
|
||||
}, {
|
||||
"frames": [ SubResource( 9 ) ],
|
||||
"loop": true,
|
||||
"name": "hurt",
|
||||
"speed": 5.0
|
||||
} ]
|
||||
|
||||
[sub_resource type="ConvexPolygonShape2D" id=11]
|
||||
|
@ -81,7 +81,7 @@ modulate = Color( 0.384314, 0.796078, 1, 1 )
|
|||
position = Vector2( 0, -18 )
|
||||
frames = SubResource( 10 )
|
||||
animation = "idle"
|
||||
frame = 1
|
||||
frame = 2
|
||||
playing = true
|
||||
|
||||
[node name="collider" type="CollisionShape2D" parent="."]
|
||||
|
|
|
@ -38,6 +38,40 @@ Global="*res://scripts/global/global.gd"
|
|||
|
||||
singletons=[ "res://webrtc/webrtc.tres" ]
|
||||
|
||||
[input]
|
||||
|
||||
ui_cancel={
|
||||
"deadzone": 0.5,
|
||||
"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":16777217,"physical_scancode":0,"unicode":0,"echo":false,"script":null)
|
||||
, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":1,"pressure":0.0,"pressed":false,"script":null)
|
||||
, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":16777220,"physical_scancode":0,"unicode":0,"echo":false,"script":null)
|
||||
]
|
||||
}
|
||||
up={
|
||||
"deadzone": 0.5,
|
||||
"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":87,"physical_scancode":0,"unicode":0,"echo":false,"script":null)
|
||||
, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":16777232,"physical_scancode":0,"unicode":0,"echo":false,"script":null)
|
||||
]
|
||||
}
|
||||
down={
|
||||
"deadzone": 0.5,
|
||||
"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":83,"physical_scancode":0,"unicode":0,"echo":false,"script":null)
|
||||
, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":16777234,"physical_scancode":0,"unicode":0,"echo":false,"script":null)
|
||||
]
|
||||
}
|
||||
left={
|
||||
"deadzone": 0.5,
|
||||
"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":65,"physical_scancode":0,"unicode":0,"echo":false,"script":null)
|
||||
, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":16777231,"physical_scancode":0,"unicode":0,"echo":false,"script":null)
|
||||
]
|
||||
}
|
||||
right={
|
||||
"deadzone": 0.5,
|
||||
"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":68,"physical_scancode":0,"unicode":0,"echo":false,"script":null)
|
||||
, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":16777233,"physical_scancode":0,"unicode":0,"echo":false,"script":null)
|
||||
]
|
||||
}
|
||||
|
||||
[physics]
|
||||
|
||||
common/enable_pause_aware_picking=true
|
||||
|
|
|
@ -1,32 +1,49 @@
|
|||
[gd_scene load_steps=2 format=2]
|
||||
[gd_scene load_steps=3 format=2]
|
||||
|
||||
[ext_resource path="res://scripts/screens/game.gd" type="Script" id=1]
|
||||
[ext_resource path="res://assets/theme.tres" type="Theme" id=2]
|
||||
|
||||
[node name="game" type="Node2D"]
|
||||
script = ExtResource( 1 )
|
||||
|
||||
[node name="camera" type="Camera2D" parent="."]
|
||||
offset = Vector2( 100, 0 )
|
||||
current = true
|
||||
zoom = Vector2( 0.5, 0.5 )
|
||||
drag_margin_left = 0.0
|
||||
drag_margin_top = 0.0
|
||||
drag_margin_right = 0.0
|
||||
drag_margin_bottom = 0.0
|
||||
editor_draw_limits = true
|
||||
|
||||
[node name="Label" type="Label" parent="."]
|
||||
margin_left = 93.0
|
||||
margin_top = 109.0
|
||||
margin_right = 253.0
|
||||
margin_bottom = 123.0
|
||||
[node name="CanvasLayer" type="CanvasLayer" parent="."]
|
||||
|
||||
[node name="ui" type="MarginContainer" parent="CanvasLayer"]
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
theme = ExtResource( 2 )
|
||||
__meta__ = {
|
||||
"_edit_use_anchors_": false
|
||||
}
|
||||
|
||||
[node name="v" type="VBoxContainer" parent="CanvasLayer/ui"]
|
||||
margin_right = 1024.0
|
||||
margin_bottom = 600.0
|
||||
|
||||
[node name="Label" type="Label" parent="CanvasLayer/ui/v"]
|
||||
margin_right = 1024.0
|
||||
margin_bottom = 21.0
|
||||
text = "You are playing the game"
|
||||
__meta__ = {
|
||||
"_edit_use_anchors_": false
|
||||
}
|
||||
|
||||
[node name="Button" type="Button" parent="Label"]
|
||||
margin_left = 29.0
|
||||
margin_top = 177.0
|
||||
margin_right = 120.0
|
||||
margin_bottom = 197.0
|
||||
[node name="Button" type="Button" parent="CanvasLayer/ui/v"]
|
||||
margin_top = 25.0
|
||||
margin_right = 1024.0
|
||||
margin_bottom = 52.0
|
||||
text = "Leave Game"
|
||||
__meta__ = {
|
||||
"_edit_use_anchors_": false
|
||||
}
|
||||
|
||||
[connection signal="pressed" from="Label/Button" to="." method="_on_Button_pressed"]
|
||||
[connection signal="pressed" from="CanvasLayer/ui/v/Button" to="." method="_on_Button_pressed"]
|
||||
|
|
|
@ -1,20 +1,22 @@
|
|||
[gd_scene load_steps=5 format=2]
|
||||
[gd_scene load_steps=6 format=2]
|
||||
|
||||
[ext_resource path="res://assets/fonts/iosevkalyte/iosevkalyte-regular.ttf" type="DynamicFontData" id=1]
|
||||
[ext_resource path="res://assets/img/cross.png" type="Texture" id=2]
|
||||
[ext_resource path="res://scripts/screens/main_menu.gd" type="Script" id=3]
|
||||
[ext_resource path="res://assets/theme.tres" type="Theme" id=4]
|
||||
|
||||
[sub_resource type="DynamicFont" id=1]
|
||||
size = 70
|
||||
font_data = ExtResource( 1 )
|
||||
|
||||
[node name="Control" type="MarginContainer"]
|
||||
[node name="main_menu" type="MarginContainer"]
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
margin_left = 20.0
|
||||
margin_top = 20.0
|
||||
margin_right = -20.0
|
||||
margin_bottom = -20.0
|
||||
theme = ExtResource( 4 )
|
||||
script = ExtResource( 3 )
|
||||
__meta__ = {
|
||||
"_edit_use_anchors_": false
|
||||
|
@ -77,9 +79,9 @@ size_flags_vertical = 3
|
|||
|
||||
[node name="v" type="VBoxContainer" parent="v/c"]
|
||||
margin_left = 124.0
|
||||
margin_top = 153.0
|
||||
margin_top = 150.0
|
||||
margin_right = 859.0
|
||||
margin_bottom = 352.0
|
||||
margin_bottom = 356.0
|
||||
|
||||
[node name="title" type="Label" parent="v/c/v"]
|
||||
margin_right = 735.0
|
||||
|
@ -93,19 +95,19 @@ valign = 1
|
|||
[node name="h" type="HBoxContainer" parent="v/c/v"]
|
||||
margin_top = 185.0
|
||||
margin_right = 735.0
|
||||
margin_bottom = 199.0
|
||||
margin_bottom = 206.0
|
||||
alignment = 1
|
||||
|
||||
[node name="made_by" type="Label" parent="v/c/v/h"]
|
||||
margin_left = 312.0
|
||||
margin_right = 371.0
|
||||
margin_bottom = 14.0
|
||||
margin_left = 305.0
|
||||
margin_right = 369.0
|
||||
margin_bottom = 21.0
|
||||
text = "made by "
|
||||
|
||||
[node name="link" type="LinkButton" parent="v/c/v/h"]
|
||||
margin_left = 375.0
|
||||
margin_right = 422.0
|
||||
margin_bottom = 14.0
|
||||
margin_left = 373.0
|
||||
margin_right = 429.0
|
||||
margin_bottom = 21.0
|
||||
hint_tooltip = "Open https://lyte.dev"
|
||||
text = "lytedev"
|
||||
|
||||
|
|
|
@ -5,12 +5,14 @@ const SignalledWebRTCMultiplayer = preload("./signalled_webrtc_multiplayer.gd")
|
|||
onready var client = SignalledWebRTCMultiplayer.new()
|
||||
|
||||
onready var onetime_cmd_flags = {
|
||||
"--singleplayer": false,
|
||||
"--multiplayer": false,
|
||||
"--create-lobby": false,
|
||||
"--join-first-available-lobby": false,
|
||||
}
|
||||
|
||||
func _ready():
|
||||
get_tree().use_font_oversampling = true
|
||||
add_child(client)
|
||||
for flag in onetime_cmd_flags.keys():
|
||||
if flag in OS.get_cmdline_args():
|
||||
|
@ -29,7 +31,7 @@ func main_menu():
|
|||
goto_scene("main_menu")
|
||||
|
||||
func start_singleplayer_game():
|
||||
client.close()
|
||||
client.singleplayer()
|
||||
goto_game()
|
||||
|
||||
func goto_game():
|
||||
|
|
|
@ -78,9 +78,17 @@ func connect_to_signaller(url = signaller_url):
|
|||
if result != OK:
|
||||
print("Failed to connect to WebSocket signalling server at %s: %s" % [signaller_url, result])
|
||||
|
||||
func singleplayer():
|
||||
close()
|
||||
webrtc = WebRTCMultiplayer.new()
|
||||
webrtc.initialize(1, false)
|
||||
get_tree().network_peer = webrtc
|
||||
_create_peer({id = 1})
|
||||
|
||||
func close():
|
||||
if webrtc != null: webrtc.close()
|
||||
websocket.disconnect_from_host()
|
||||
get_tree().network_peer = null
|
||||
|
||||
func set_display_name(new_display_name: String):
|
||||
display_name = new_display_name
|
||||
|
@ -125,9 +133,11 @@ func send_answer(id, answer) -> int:
|
|||
return _send_json({"id": id, "answer": answer }, "answer")
|
||||
|
||||
func _webrtc_peer_connected(id):
|
||||
peers[id].connected = true
|
||||
emit_signal("webrtc_peer_connected", id)
|
||||
|
||||
func _webrtc_peer_disconnected(id):
|
||||
peers[id].connected = false
|
||||
emit_signal("webrtc_peer_disconnected", id)
|
||||
|
||||
func _webrtc_connection_succeeded():
|
||||
|
@ -222,8 +232,17 @@ func _create_peer(data):
|
|||
# this guarantees only one peer sends the offer and that offers are never
|
||||
# sent to ourselves?
|
||||
if int(id) > webrtc.get_unique_id(): peer.create_offer()
|
||||
peers[int(id)] = {
|
||||
connected = false,
|
||||
ready = false,
|
||||
name = "",
|
||||
}
|
||||
emit_signal("peer_created", data)
|
||||
|
||||
func _delete_peer(id):
|
||||
if webrtc.has_peer(id): webrtc.remove_peer(id)
|
||||
if peers.has(id): peers.erase(id)
|
||||
|
||||
func _webrtc_offer_created(type, data, id):
|
||||
print("WebRTC %s created for peer %s" % [type, id])
|
||||
if not webrtc.has_peer(int(id)): return
|
||||
|
@ -237,7 +256,8 @@ func _new_ice_candidate(mid, index, sdp, id):
|
|||
print("New ICE candidate for peer %s" % id)
|
||||
send_candidate(id, mid, index, sdp)
|
||||
|
||||
func _signaller_peer_left(id): if peers.has(id): peers.delete(id)
|
||||
func _signaller_peer_left(id):
|
||||
_delete_peer(id)
|
||||
|
||||
func _signaller_peer_data(peers):
|
||||
for peer in peers:
|
||||
|
@ -262,7 +282,7 @@ func _webrtc_answer_received(data):
|
|||
func _webrtc_candidate_received(data):
|
||||
if webrtc.has_peer(data.id):
|
||||
print("Adding ice candidate for peer %s" % data.id)
|
||||
print("--> Candidate: %s" % JSON.print(data.candidate))
|
||||
print("--> Candidate: %s" % JSON.print(data))
|
||||
webrtc.get_peer(data.id).connection.add_ice_candidate(data.mid, data.index, data.sdp)
|
||||
else:
|
||||
print("Received candidate for non-existant peer %s" % data.id)
|
||||
|
|
|
@ -77,18 +77,21 @@ func maybe_hide_health_bar():
|
|||
func _ready():
|
||||
# rset_config("acceleration", MultiplayerAPI.RPC_MODE_REMOTESYNC)
|
||||
# rset_config("velocity", MultiplayerAPI.RPC_MODE_REMOTESYNC)
|
||||
rset_config("position", MultiplayerAPI.RPC_MODE_SLAVE)
|
||||
# rset_config("position", MultiplayerAPI.RPC_MODE_SLAVE)
|
||||
set_display_name(name)
|
||||
|
||||
func set_display_name(i_name):
|
||||
display_name = i_name
|
||||
if len(get_tree().get_network_connected_peers()) > 1:
|
||||
name_displayer.text = display_name
|
||||
else:
|
||||
name_displayer.text = ""
|
||||
name_displayer.text = display_name
|
||||
|
||||
static func int_input_action(action):
|
||||
return int(Input.is_action_pressed(action))
|
||||
static func int_input_action(actions) -> int:
|
||||
if typeof(actions) == TYPE_ARRAY:
|
||||
var result = false
|
||||
for action in actions:
|
||||
result = result or Input.is_action_pressed(action)
|
||||
return int(result)
|
||||
else:
|
||||
return int(Input.is_action_pressed(actions))
|
||||
|
||||
func _physics_process(delta):
|
||||
self.mana += (10*delta)
|
||||
|
@ -101,8 +104,8 @@ func _physics_process(delta):
|
|||
if collision.collider is RigidBody2D:
|
||||
collision.collider.apply_central_impulse(-collision.normal * weight)
|
||||
|
||||
if is_network_master():
|
||||
rset_unreliable("position", position)
|
||||
# if is_network_master():
|
||||
# rset_unreliable("position", position)
|
||||
|
||||
func _process_input():
|
||||
if is_network_master():
|
||||
|
@ -110,8 +113,8 @@ func _process_input():
|
|||
# probably want to implement a "whichever one was pressed last" so that
|
||||
# players move as fast as possible without having to worry about switching
|
||||
# key frame perfectly
|
||||
iv.x = int_input_action("ui_right") - int_input_action("ui_left")
|
||||
iv.y = int_input_action("ui_down") - int_input_action("ui_up")
|
||||
iv.x = int_input_action(["ui_right", "right"]) - int_input_action(["ui_left", "left"])
|
||||
iv.y = int_input_action(["ui_down", "down"]) - int_input_action(["ui_up", "up"])
|
||||
rset("acceleration", iv.normalized() * speed)
|
||||
|
||||
func _process_animation():
|
||||
|
|
|
@ -1,26 +1,48 @@
|
|||
extends Node2D
|
||||
|
||||
onready var player = preload("res://objects/player.tscn")
|
||||
onready var player_obj = preload("res://objects/player.tscn")
|
||||
|
||||
onready var camera = $camera
|
||||
onready var camera_target = null
|
||||
onready var zoom_levels = [0.25, 0.5, 1, 1.5, 2, 2.5, 3]
|
||||
onready var current_zoom_level_index = 2
|
||||
onready var player = null
|
||||
onready var players = null
|
||||
|
||||
func _ready():
|
||||
# TODO: probably have to wait for all peers to be ready before we add players
|
||||
rpc("add_player", get_tree().get_network_unique_id())
|
||||
if Global.client.is_host():
|
||||
for id in get_tree().get_network_connected_peers():
|
||||
Global.client.peers[id].ready = false
|
||||
ready(1)
|
||||
else:
|
||||
rpc("ready", get_tree().get_network_unique_id())
|
||||
|
||||
func _process(delta):
|
||||
pass
|
||||
remotesync func ready(id):
|
||||
print("Ready %d" % id)
|
||||
Global.client.peers[id].ready = true
|
||||
var all_ready = true
|
||||
for id in Global.client.peers: all_ready = all_ready and Global.client.peers[id].ready
|
||||
if all_ready: start()
|
||||
|
||||
remotesync func add_player(peer_id):
|
||||
var new_player = player.instance()
|
||||
new_player.name = Global.negotiator.peer_by_peer_id(peer_id).name
|
||||
new_player.set_network_master(peer_id)
|
||||
func start():
|
||||
print("Starting Game...")
|
||||
# for each peer
|
||||
for id in get_tree().get_network_connected_peers():
|
||||
print("Creating player for peer %d" % id)
|
||||
rpc("add_player", id)
|
||||
rpc("add_player", 1)
|
||||
|
||||
func _process(_delta):
|
||||
if player: camera.offset = player.position
|
||||
|
||||
remotesync func add_player(id):
|
||||
var new_player = player_obj.instance()
|
||||
if id == get_tree().get_network_unique_id(): player = new_player
|
||||
new_player.name = Global.client.peers[id].name
|
||||
new_player.set_network_master(id)
|
||||
add_child(new_player)
|
||||
new_player.global_position = Vector2(100, 100)
|
||||
print("Added player: %s for peer %s" % [new_player, peer_id])
|
||||
new_player.global_position = Vector2(-100 + (id % 200), -100 + (id % 200))
|
||||
print("Added player: %s for peer %s" % [new_player, id])
|
||||
|
||||
func _on_Button_pressed():
|
||||
Global.main_menu()
|
||||
|
|
|
@ -6,6 +6,8 @@ func _ready():
|
|||
$v/h/singleplayer.shortcut = Global.key_shortcut(KEY_S)
|
||||
if Global.check_onetime_flag("multiplayer"):
|
||||
_on_multiplayer_pressed()
|
||||
if Global.check_onetime_flag("singleplayer"):
|
||||
_on_Singleplayer_pressed()
|
||||
|
||||
func _on_Singleplayer_pressed():
|
||||
Global.start_singleplayer_game()
|
||||
|
|
|
@ -61,7 +61,7 @@ func _add_peer(id, p):
|
|||
if p.id == 1: p.ready = true
|
||||
new_peer.set_with_dict(p)
|
||||
peers_grid.add_child(new_peer)
|
||||
peers[id] = new_peer
|
||||
peers[int(id)] = new_peer
|
||||
add_chat("> %s joined the lobby" % new_peer.display_name)
|
||||
|
||||
func _update_peer(id, peer_data):
|
||||
|
@ -123,14 +123,14 @@ func _on_start_pressed():
|
|||
if is_host: rpc("start_game")
|
||||
|
||||
remotesync func start_game():
|
||||
Global.negotiator.peers = peers
|
||||
Global.negotiator.peers_id_mappings = peers_id_mappings
|
||||
# TODO: seal lobby
|
||||
get_tree().refuse_new_network_connections = true
|
||||
Global.goto_game()
|
||||
|
||||
remotesync func set_ready(ready):
|
||||
var from = get_tree().get_rpc_sender_id()
|
||||
print("Set Ready: %s %s" % [from, ready])
|
||||
Global.client.peers[from].ready = ready
|
||||
peers[from].ready = ready
|
||||
if is_host: update_can_start()
|
||||
|
||||
func _on_TextEdit_text_entered(_new_text):
|
||||
|
|
Loading…
Reference in a new issue