mirror of
https://github.com/godotengine/godot-demo-projects.git
synced 2026-09-03 23:39:26 +03:00
Updated Multiplayer Pong C# to Godot 4.2 (#1045)
This commit is contained in:
@@ -1,6 +1,9 @@
|
|||||||
<Project Sdk="Godot.NET.Sdk/4.0.0-dev5">
|
<Project Sdk="Godot.NET.Sdk/4.2.0">
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>net472</TargetFramework>
|
<TargetFramework>net6.0</TargetFramework>
|
||||||
<RootNamespace>PongMultiplayer</RootNamespace>
|
<TargetFramework Condition=" '$(GodotTargetPlatform)' == 'android' ">net7.0</TargetFramework>
|
||||||
|
<TargetFramework Condition=" '$(GodotTargetPlatform)' == 'ios' ">net8.0</TargetFramework>
|
||||||
|
<EnableDynamicLoading>true</EnableDynamicLoading>
|
||||||
|
<RootNamespace>PongMultiplayerwithC</RootNamespace>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
</Project>
|
</Project>
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||||
# Visual Studio 2012
|
# Visual Studio 2012
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Pong Multiplayer with C#", "Pong Multiplayer with C#.csproj", "{4BB6C2D0-FC11-466E-8C73-8DAD689F135A}"
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Pong Multiplayer with C#", "Pong Multiplayer with C#.csproj", "{58FECEC2-0618-4042-81F2-4EDD7982C229}"
|
||||||
EndProject
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
@@ -9,11 +9,11 @@ Global
|
|||||||
ExportRelease|Any CPU = ExportRelease|Any CPU
|
ExportRelease|Any CPU = ExportRelease|Any CPU
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||||
{4BB6C2D0-FC11-466E-8C73-8DAD689F135A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
{58FECEC2-0618-4042-81F2-4EDD7982C229}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
{4BB6C2D0-FC11-466E-8C73-8DAD689F135A}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{58FECEC2-0618-4042-81F2-4EDD7982C229}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{4BB6C2D0-FC11-466E-8C73-8DAD689F135A}.ExportDebug|Any CPU.ActiveCfg = ExportDebug|Any CPU
|
{58FECEC2-0618-4042-81F2-4EDD7982C229}.ExportDebug|Any CPU.ActiveCfg = ExportDebug|Any CPU
|
||||||
{4BB6C2D0-FC11-466E-8C73-8DAD689F135A}.ExportDebug|Any CPU.Build.0 = ExportDebug|Any CPU
|
{58FECEC2-0618-4042-81F2-4EDD7982C229}.ExportDebug|Any CPU.Build.0 = ExportDebug|Any CPU
|
||||||
{4BB6C2D0-FC11-466E-8C73-8DAD689F135A}.ExportRelease|Any CPU.ActiveCfg = ExportRelease|Any CPU
|
{58FECEC2-0618-4042-81F2-4EDD7982C229}.ExportRelease|Any CPU.ActiveCfg = ExportRelease|Any CPU
|
||||||
{4BB6C2D0-FC11-466E-8C73-8DAD689F135A}.ExportRelease|Any CPU.Build.0 = ExportRelease|Any CPU
|
{58FECEC2-0618-4042-81F2-4EDD7982C229}.ExportRelease|Any CPU.Build.0 = ExportRelease|Any CPU
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
EndGlobal
|
EndGlobal
|
||||||
|
|||||||
@@ -1,8 +1,10 @@
|
|||||||
[gd_scene load_steps=2 format=2]
|
[gd_scene load_steps=2 format=3 uid="uid://bxj0km4t28u17"]
|
||||||
|
|
||||||
[ext_resource path="res://logic/Lobby.cs" type="Script" id=1]
|
[ext_resource type="Script" path="res://logic/Lobby.cs" id="1"]
|
||||||
|
|
||||||
[node name="Lobby" type="Control"]
|
[node name="Lobby" type="Control"]
|
||||||
|
layout_mode = 3
|
||||||
|
anchors_preset = 8
|
||||||
anchor_left = 0.5
|
anchor_left = 0.5
|
||||||
anchor_top = 0.5
|
anchor_top = 0.5
|
||||||
anchor_right = 0.5
|
anchor_right = 0.5
|
||||||
@@ -11,13 +13,13 @@ offset_left = -320.0
|
|||||||
offset_top = -200.0
|
offset_top = -200.0
|
||||||
offset_right = 320.0
|
offset_right = 320.0
|
||||||
offset_bottom = 200.0
|
offset_bottom = 200.0
|
||||||
|
grow_horizontal = 2
|
||||||
|
grow_vertical = 2
|
||||||
size_flags_horizontal = 2
|
size_flags_horizontal = 2
|
||||||
size_flags_vertical = 2
|
size_flags_vertical = 2
|
||||||
__meta__ = {
|
|
||||||
"_edit_use_anchors_": false
|
|
||||||
}
|
|
||||||
|
|
||||||
[node name="Title" type="Label" parent="."]
|
[node name="Title" type="Label" parent="."]
|
||||||
|
layout_mode = 0
|
||||||
offset_left = 210.0
|
offset_left = 210.0
|
||||||
offset_top = 40.0
|
offset_top = 40.0
|
||||||
offset_right = 430.0
|
offset_right = 430.0
|
||||||
@@ -25,22 +27,19 @@ offset_bottom = 80.0
|
|||||||
size_flags_horizontal = 2
|
size_flags_horizontal = 2
|
||||||
size_flags_vertical = 0
|
size_flags_vertical = 0
|
||||||
text = "Multiplayer Pong"
|
text = "Multiplayer Pong"
|
||||||
align = 1
|
|
||||||
valign = 1
|
|
||||||
|
|
||||||
[node name="LobbyPanel" type="Panel" parent="."]
|
[node name="LobbyPanel" type="Panel" parent="."]
|
||||||
|
layout_mode = 0
|
||||||
offset_left = 210.0
|
offset_left = 210.0
|
||||||
offset_top = 160.0
|
offset_top = 160.0
|
||||||
offset_right = 430.0
|
offset_right = 430.0
|
||||||
offset_bottom = 270.0
|
offset_bottom = 270.0
|
||||||
size_flags_horizontal = 2
|
size_flags_horizontal = 2
|
||||||
size_flags_vertical = 2
|
size_flags_vertical = 2
|
||||||
script = ExtResource( 1 )
|
script = ExtResource("1")
|
||||||
__meta__ = {
|
|
||||||
"_edit_use_anchors_": false
|
|
||||||
}
|
|
||||||
|
|
||||||
[node name="AddressLabel" type="Label" parent="LobbyPanel"]
|
[node name="AddressLabel" type="Label" parent="LobbyPanel"]
|
||||||
|
layout_mode = 0
|
||||||
offset_left = 10.0
|
offset_left = 10.0
|
||||||
offset_top = 10.0
|
offset_top = 10.0
|
||||||
offset_right = 62.0
|
offset_right = 62.0
|
||||||
@@ -50,6 +49,7 @@ size_flags_vertical = 0
|
|||||||
text = "Address"
|
text = "Address"
|
||||||
|
|
||||||
[node name="Address" type="LineEdit" parent="LobbyPanel"]
|
[node name="Address" type="LineEdit" parent="LobbyPanel"]
|
||||||
|
layout_mode = 0
|
||||||
offset_left = 10.0
|
offset_left = 10.0
|
||||||
offset_top = 30.0
|
offset_top = 30.0
|
||||||
offset_right = 210.0
|
offset_right = 210.0
|
||||||
@@ -59,6 +59,7 @@ size_flags_vertical = 2
|
|||||||
text = "127.0.0.1"
|
text = "127.0.0.1"
|
||||||
|
|
||||||
[node name="HostButton" type="Button" parent="LobbyPanel"]
|
[node name="HostButton" type="Button" parent="LobbyPanel"]
|
||||||
|
layout_mode = 0
|
||||||
offset_left = 10.0
|
offset_left = 10.0
|
||||||
offset_top = 60.0
|
offset_top = 60.0
|
||||||
offset_right = 90.0
|
offset_right = 90.0
|
||||||
@@ -68,6 +69,7 @@ size_flags_vertical = 2
|
|||||||
text = "Host"
|
text = "Host"
|
||||||
|
|
||||||
[node name="JoinButton" type="Button" parent="LobbyPanel"]
|
[node name="JoinButton" type="Button" parent="LobbyPanel"]
|
||||||
|
layout_mode = 0
|
||||||
offset_left = 130.0
|
offset_left = 130.0
|
||||||
offset_top = 60.0
|
offset_top = 60.0
|
||||||
offset_right = 210.0
|
offset_right = 210.0
|
||||||
@@ -75,29 +77,24 @@ offset_bottom = 80.0
|
|||||||
size_flags_horizontal = 2
|
size_flags_horizontal = 2
|
||||||
size_flags_vertical = 2
|
size_flags_vertical = 2
|
||||||
text = "Join"
|
text = "Join"
|
||||||
__meta__ = {
|
|
||||||
"_edit_use_anchors_": false
|
|
||||||
}
|
|
||||||
|
|
||||||
[node name="StatusOk" type="Label" parent="LobbyPanel"]
|
[node name="StatusOk" type="Label" parent="LobbyPanel"]
|
||||||
|
layout_mode = 0
|
||||||
offset_left = 10.0
|
offset_left = 10.0
|
||||||
offset_top = 90.0
|
offset_top = 90.0
|
||||||
offset_right = 210.0
|
offset_right = 210.0
|
||||||
offset_bottom = 104.0
|
offset_bottom = 104.0
|
||||||
size_flags_horizontal = 2
|
size_flags_horizontal = 2
|
||||||
size_flags_vertical = 0
|
size_flags_vertical = 0
|
||||||
custom_colors/font_color = Color(0, 1, 0.015625, 1)
|
|
||||||
align = 1
|
|
||||||
|
|
||||||
[node name="StatusFail" type="Label" parent="LobbyPanel"]
|
[node name="StatusFail" type="Label" parent="LobbyPanel"]
|
||||||
|
layout_mode = 0
|
||||||
offset_left = 10.0
|
offset_left = 10.0
|
||||||
offset_top = 90.0
|
offset_top = 90.0
|
||||||
offset_right = 210.0
|
offset_right = 210.0
|
||||||
offset_bottom = 104.0
|
offset_bottom = 104.0
|
||||||
size_flags_horizontal = 2
|
size_flags_horizontal = 2
|
||||||
size_flags_vertical = 0
|
size_flags_vertical = 0
|
||||||
custom_colors/font_color = Color(1, 0, 0, 1)
|
|
||||||
align = 1
|
|
||||||
|
|
||||||
[connection signal="pressed" from="LobbyPanel/HostButton" to="LobbyPanel" method="OnHostPressed"]
|
[connection signal="pressed" from="LobbyPanel/HostButton" to="LobbyPanel" method="OnHostPressed"]
|
||||||
[connection signal="pressed" from="LobbyPanel/JoinButton" to="LobbyPanel" method="OnJoinPressed"]
|
[connection signal="pressed" from="LobbyPanel/JoinButton" to="LobbyPanel" method="OnJoinPressed"]
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ public partial class Ball : Area2D
|
|||||||
|
|
||||||
private Vector2 _direction = Vector2.Left;
|
private Vector2 _direction = Vector2.Left;
|
||||||
private bool _stopped = false;
|
private bool _stopped = false;
|
||||||
private float _speed = DefaultSpeed;
|
private double _speed = DefaultSpeed;
|
||||||
private Vector2 _screenSize;
|
private Vector2 _screenSize;
|
||||||
|
|
||||||
// Called when the node enters the scene tree for the first time.
|
// Called when the node enters the scene tree for the first time.
|
||||||
@@ -17,7 +17,7 @@ public partial class Ball : Area2D
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Called every frame. 'delta' is the elapsed time since the previous frame.
|
// Called every frame. 'delta' is the elapsed time since the previous frame.
|
||||||
public override void _Process(float delta)
|
public override void _Process(double delta)
|
||||||
{
|
{
|
||||||
_speed += delta;
|
_speed += delta;
|
||||||
// Ball will move normally for both players,
|
// Ball will move normally for both players,
|
||||||
@@ -25,36 +25,36 @@ public partial class Ball : Area2D
|
|||||||
// so each player sees the motion as smooth and not jerky.
|
// so each player sees the motion as smooth and not jerky.
|
||||||
if (!_stopped)
|
if (!_stopped)
|
||||||
{
|
{
|
||||||
Translate(_speed * delta * _direction);
|
Translate((float)(_speed * delta) * _direction);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check screen bounds to make ball bounce.
|
// Check screen bounds to make ball bounce.
|
||||||
var ballPosition = Position;
|
var ballPosition = Position;
|
||||||
if ((ballPosition.y < 0 && _direction.y < 0) || (ballPosition.y > _screenSize.y && _direction.y > 0))
|
if ((ballPosition.Y < 0 && _direction.Y < 0) || (ballPosition.Y > _screenSize.Y && _direction.Y > 0))
|
||||||
{
|
{
|
||||||
_direction.y = -_direction.y;
|
_direction.Y = -_direction.Y;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IsNetworkMaster())
|
if (IsMultiplayerAuthority())
|
||||||
{
|
{
|
||||||
// Only the master will decide when the ball is out in
|
// Only the server (Multiplayer Authority) will decide
|
||||||
// the left side (it's own side). This makes the game
|
// when the ball is out in the left side (it's own side).
|
||||||
// playable even if latency is high and ball is going
|
// This makes the game playable even if latency is high and
|
||||||
// fast. Otherwise ball might be out in the other
|
// ball is going fast. Otherwise ball might be out in the other
|
||||||
// player's screen but not this one.
|
// player's screen but not this one.
|
||||||
if (ballPosition.x < 0)
|
if (ballPosition.X < 0)
|
||||||
{
|
{
|
||||||
GetParent().Rpc("UpdateScore", false);
|
GetParent().Rpc("UpdateScore", false);
|
||||||
Rpc("ResetBall", false);
|
Rpc("ResetBall", false);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Only the puppet will decide when the ball is out in
|
// Only the peer will decide when the ball is out in
|
||||||
// the right side, which is it's own side. This makes
|
// the right side, which is it's own side. This makes
|
||||||
// the game playable even if latency is high and ball
|
// the game playable even if latency is high and ball
|
||||||
// is going fast. Otherwise ball might be out in the
|
// is going fast. Otherwise ball might be out in the
|
||||||
// other player's screen but not this one.
|
// other player's screen but not this one.
|
||||||
if (ballPosition.x > _screenSize.x)
|
if (ballPosition.X > _screenSize.X)
|
||||||
{
|
{
|
||||||
GetParent().Rpc("UpdateScore", true);
|
GetParent().Rpc("UpdateScore", true);
|
||||||
Rpc("ResetBall", true);
|
Rpc("ResetBall", true);
|
||||||
@@ -63,31 +63,31 @@ public partial class Ball : Area2D
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[Sync]
|
[Rpc(mode: MultiplayerApi.RpcMode.AnyPeer, CallLocal = true)]
|
||||||
private void Bounce(bool left, float random)
|
private void Bounce(bool left, float random)
|
||||||
{
|
{
|
||||||
// Using sync because both players can make it bounce.
|
// Using sync because both players can make it bounce.
|
||||||
if (left)
|
if (left)
|
||||||
{
|
{
|
||||||
_direction.x = Mathf.Abs(_direction.x);
|
_direction.X = Mathf.Abs(_direction.X);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_direction.x = -Mathf.Abs(_direction.x);
|
_direction.X = -Mathf.Abs(_direction.X);
|
||||||
}
|
}
|
||||||
|
|
||||||
_speed *= 1.1f;
|
_speed *= 1.1f;
|
||||||
_direction.y = random * 2.0f - 1;
|
_direction.Y = random * 2.0f - 1;
|
||||||
_direction = _direction.Normalized();
|
_direction = _direction.Normalized();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Sync]
|
[Rpc(mode: MultiplayerApi.RpcMode.AnyPeer, CallLocal = true)]
|
||||||
private void Stop()
|
private void Stop()
|
||||||
{
|
{
|
||||||
_stopped = true;
|
_stopped = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
[Sync]
|
[Rpc(mode: MultiplayerApi.RpcMode.AnyPeer, CallLocal = true)]
|
||||||
private void ResetBall(bool forLeft)
|
private void ResetBall(bool forLeft)
|
||||||
{
|
{
|
||||||
Position = _screenSize / 2;
|
Position = _screenSize / 2;
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ public partial class Lobby : Control
|
|||||||
private Button _joinButton;
|
private Button _joinButton;
|
||||||
private Label _statusOk;
|
private Label _statusOk;
|
||||||
private Label _statusFail;
|
private Label _statusFail;
|
||||||
private NetworkedMultiplayerENet _peer;
|
private ENetMultiplayerPeer _peer;
|
||||||
|
|
||||||
public override void _Ready()
|
public override void _Ready()
|
||||||
{
|
{
|
||||||
@@ -25,11 +25,11 @@ public partial class Lobby : Control
|
|||||||
|
|
||||||
// Connect all callbacks related to networking.
|
// Connect all callbacks related to networking.
|
||||||
// Note: Use snake_case when talking to engine API.
|
// Note: Use snake_case when talking to engine API.
|
||||||
GetTree().Connect("network_peer_connected", this, nameof(PlayerConnected));
|
GetTree().GetMultiplayer().Connect("peer_connected", new Callable(this, nameof(PlayerConnected)));
|
||||||
GetTree().Connect("network_peer_disconnected", this, nameof(PlayerDisconnected));
|
GetTree().GetMultiplayer().Connect("peer_disconnected", new Callable(this, nameof(PlayerDisconnected)));
|
||||||
GetTree().Connect("connected_to_server", this, nameof(ConnectedOk));
|
GetTree().GetMultiplayer().Connect("connected_to_server", new Callable(this, nameof(ConnectedOk)));
|
||||||
GetTree().Connect("connection_failed", this, nameof(ConnectedFail));
|
GetTree().GetMultiplayer().Connect("connection_failed", new Callable(this, nameof(ConnectedFail)));
|
||||||
GetTree().Connect("server_disconnected", this, nameof(ServerDisconnected));
|
GetTree().GetMultiplayer().Connect("server_disconnected", new Callable(this, nameof(ServerDisconnected)));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Network callbacks from SceneTree
|
// Network callbacks from SceneTree
|
||||||
@@ -41,7 +41,7 @@ public partial class Lobby : Control
|
|||||||
var pong = ResourceLoader.Load<PackedScene>("res://pong.tscn").Instantiate();
|
var pong = ResourceLoader.Load<PackedScene>("res://pong.tscn").Instantiate();
|
||||||
|
|
||||||
// Connect deferred so we can safely erase it from the callback.
|
// Connect deferred so we can safely erase it from the callback.
|
||||||
pong.Connect("GameFinished", this, nameof(EndGame), new Godot.Collections.Array(), (int) ConnectFlags.Deferred);
|
pong.Connect("GameFinished", new Callable(this, nameof(EndGame)), (int) ConnectFlags.Deferred);
|
||||||
|
|
||||||
GetTree().Root.AddChild(pong);
|
GetTree().Root.AddChild(pong);
|
||||||
Hide();
|
Hide();
|
||||||
@@ -49,7 +49,7 @@ public partial class Lobby : Control
|
|||||||
|
|
||||||
private void PlayerDisconnected(int id)
|
private void PlayerDisconnected(int id)
|
||||||
{
|
{
|
||||||
EndGame(GetTree().IsNetworkServer() ? "Client disconnected" : "Server disconnected");
|
EndGame(GetTree().GetMultiplayer().IsServer() ? "Client disconnected" : "Server disconnected");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Callback from SceneTree, only for clients (not server).
|
// Callback from SceneTree, only for clients (not server).
|
||||||
@@ -63,7 +63,7 @@ public partial class Lobby : Control
|
|||||||
{
|
{
|
||||||
SetStatus("Couldn't connect", false);
|
SetStatus("Couldn't connect", false);
|
||||||
|
|
||||||
GetTree().NetworkPeer = null; // Remove peer.
|
GetTree().GetMultiplayer().MultiplayerPeer = null; // Remove peer.
|
||||||
_hostButton.Disabled = false;
|
_hostButton.Disabled = false;
|
||||||
_joinButton.Disabled = false;
|
_joinButton.Disabled = false;
|
||||||
}
|
}
|
||||||
@@ -85,7 +85,7 @@ public partial class Lobby : Control
|
|||||||
Show();
|
Show();
|
||||||
}
|
}
|
||||||
|
|
||||||
GetTree().NetworkPeer = null; // Remove peer.
|
GetTree().GetMultiplayer().MultiplayerPeer = null; // Remove peer.
|
||||||
_hostButton.Disabled = false;
|
_hostButton.Disabled = false;
|
||||||
_joinButton.Disabled = false;
|
_joinButton.Disabled = false;
|
||||||
|
|
||||||
@@ -109,8 +109,7 @@ public partial class Lobby : Control
|
|||||||
|
|
||||||
private void OnHostPressed()
|
private void OnHostPressed()
|
||||||
{
|
{
|
||||||
_peer = new NetworkedMultiplayerENet();
|
_peer = new ENetMultiplayerPeer();
|
||||||
_peer.CompressionMode = NetworkedMultiplayerENet.CompressionModeEnum.RangeCoder;
|
|
||||||
Error err = _peer.CreateServer(DefaultPort, MaxNumberOfPeers);
|
Error err = _peer.CreateServer(DefaultPort, MaxNumberOfPeers);
|
||||||
if (err != Error.Ok)
|
if (err != Error.Ok)
|
||||||
{
|
{
|
||||||
@@ -119,7 +118,9 @@ public partial class Lobby : Control
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
GetTree().NetworkPeer = _peer;
|
_peer.Host.Compress(ENetConnection.CompressionMode.RangeCoder);
|
||||||
|
|
||||||
|
GetTree().GetMultiplayer().MultiplayerPeer = _peer;
|
||||||
_hostButton.Disabled = true;
|
_hostButton.Disabled = true;
|
||||||
_joinButton.Disabled = true;
|
_joinButton.Disabled = true;
|
||||||
SetStatus("Waiting for player...", true);
|
SetStatus("Waiting for player...", true);
|
||||||
@@ -134,10 +135,11 @@ public partial class Lobby : Control
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
_peer = new NetworkedMultiplayerENet();
|
_peer = new ENetMultiplayerPeer();
|
||||||
_peer.CompressionMode = NetworkedMultiplayerENet.CompressionModeEnum.RangeCoder;
|
|
||||||
_peer.CreateClient(ip, DefaultPort);
|
_peer.CreateClient(ip, DefaultPort);
|
||||||
GetTree().NetworkPeer = _peer;
|
_peer.Host.Compress(ENetConnection.CompressionMode.RangeCoder);
|
||||||
|
|
||||||
|
GetTree().GetMultiplayer().MultiplayerPeer = _peer;
|
||||||
SetStatus("Connecting...", true);
|
SetStatus("Connecting...", true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,16 +13,15 @@ public partial class Paddle : Area2D
|
|||||||
|
|
||||||
public override void _Ready()
|
public override void _Ready()
|
||||||
{
|
{
|
||||||
_screenSizeY = GetViewportRect().Size.y;
|
_screenSizeY = GetViewportRect().Size.Y;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void _Process(float delta)
|
public override void _Process(double delta)
|
||||||
{
|
{
|
||||||
// Is the master of the paddle.
|
// Is the master of the paddle.
|
||||||
if (IsNetworkMaster())
|
if (IsMultiplayerAuthority())
|
||||||
{
|
{
|
||||||
_motion = Input.GetActionStrength("move_down") - Input.GetActionStrength("move_up");
|
_motion = Input.GetActionStrength("move_down") - Input.GetActionStrength("move_up");
|
||||||
|
|
||||||
if (!_youHidden && _motion != 0)
|
if (!_youHidden && _motion != 0)
|
||||||
{
|
{
|
||||||
HideYouLabel();
|
HideYouLabel();
|
||||||
@@ -32,7 +31,7 @@ public partial class Paddle : Area2D
|
|||||||
|
|
||||||
// Using unreliable to make sure position is updated as fast as possible,
|
// Using unreliable to make sure position is updated as fast as possible,
|
||||||
// even if one of the calls is dropped
|
// even if one of the calls is dropped
|
||||||
RpcUnreliable(nameof(SetPosAndMotion), Position, _motion);
|
Rpc(nameof(SetPosAndMotion), Position, _motion);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -41,13 +40,13 @@ public partial class Paddle : Area2D
|
|||||||
HideYouLabel();
|
HideYouLabel();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Translate(new Vector2(0, _motion * delta));
|
Translate(new Vector2(0, _motion * (float)delta));
|
||||||
|
|
||||||
// Set screen limits. Can't modify structs directly, so we create a new one.
|
// Set screen limits. Can't modify structs directly, so we create a new one.
|
||||||
Position = new Vector2(Position.x, Mathf.Clamp(Position.y, 16, _screenSizeY - 16));
|
Position = new Vector2(Position.X, Mathf.Clamp(Position.Y, 16, _screenSizeY - 16));
|
||||||
}
|
}
|
||||||
|
|
||||||
[Puppet]
|
[Rpc(TransferMode = MultiplayerPeer.TransferModeEnum.Unreliable)]
|
||||||
private void SetPosAndMotion(Vector2 pos, float motion)
|
private void SetPosAndMotion(Vector2 pos, float motion)
|
||||||
{
|
{
|
||||||
Position = pos;
|
Position = pos;
|
||||||
@@ -62,7 +61,7 @@ public partial class Paddle : Area2D
|
|||||||
|
|
||||||
private void OnPaddleAreaEnter(Area2D area)
|
private void OnPaddleAreaEnter(Area2D area)
|
||||||
{
|
{
|
||||||
if (IsNetworkMaster())
|
if (IsMultiplayerAuthority())
|
||||||
{
|
{
|
||||||
area.Rpc("Bounce", _left, GD.Randf());
|
area.Rpc("Bounce", _left, GD.Randf());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,9 +4,9 @@ using System;
|
|||||||
public partial class Pong : Node2D
|
public partial class Pong : Node2D
|
||||||
{
|
{
|
||||||
[Signal]
|
[Signal]
|
||||||
private delegate void GameFinished(string withError);
|
public delegate void GameFinishedEventHandler(string withError);
|
||||||
|
|
||||||
private const int ScoreToWin = 10;
|
private const int ScoreToWin = 3;
|
||||||
|
|
||||||
private int _scoreLeft = 0;
|
private int _scoreLeft = 0;
|
||||||
private int _scoreRight = 0;
|
private int _scoreRight = 0;
|
||||||
@@ -28,19 +28,19 @@ public partial class Pong : Node2D
|
|||||||
// By default, all nodes in server inherit from master,
|
// By default, all nodes in server inherit from master,
|
||||||
// while all nodes in clients inherit from puppet.
|
// while all nodes in clients inherit from puppet.
|
||||||
// SetNetworkMaster is tree-recursive by default.
|
// SetNetworkMaster is tree-recursive by default.
|
||||||
if (GetTree().IsNetworkServer())
|
if (GetTree().GetMultiplayer().IsServer())
|
||||||
{
|
{
|
||||||
_playerTwo.SetNetworkMaster(GetTree().GetNetworkConnectedPeers()[0]);
|
_playerTwo.SetMultiplayerAuthority(GetTree().GetMultiplayer().GetPeers()[0]);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_playerTwo.SetNetworkMaster(GetTree().GetNetworkUniqueId());
|
_playerTwo.SetMultiplayerAuthority(GetTree().GetMultiplayer().GetUniqueId());
|
||||||
}
|
}
|
||||||
|
|
||||||
GD.Print("Unique id: ", GetTree().GetNetworkUniqueId());
|
GD.Print("Unique id: ", GetTree().GetMultiplayer().GetUniqueId());
|
||||||
}
|
}
|
||||||
|
|
||||||
[Sync]
|
[Rpc(CallLocal = true)]
|
||||||
private void UpdateScore(bool addToLeft)
|
private void UpdateScore(bool addToLeft)
|
||||||
{
|
{
|
||||||
if (addToLeft)
|
if (addToLeft)
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ One of the players should press 'host', while the
|
|||||||
other should select the address and press 'join'."
|
other should select the address and press 'join'."
|
||||||
config/tags=PackedStringArray("2d", "demo", "network", "official")
|
config/tags=PackedStringArray("2d", "demo", "network", "official")
|
||||||
run/main_scene="res://lobby.tscn"
|
run/main_scene="res://lobby.tscn"
|
||||||
config/features=PackedStringArray("4.4")
|
config/features=PackedStringArray("4.4", "C#")
|
||||||
config/icon="res://icon.webp"
|
config/icon="res://icon.webp"
|
||||||
|
|
||||||
[display]
|
[display]
|
||||||
@@ -26,6 +26,10 @@ window/size/viewport_height=400
|
|||||||
window/stretch/mode="canvas_items"
|
window/stretch/mode="canvas_items"
|
||||||
window/stretch/aspect="expand"
|
window/stretch/aspect="expand"
|
||||||
|
|
||||||
|
[dotnet]
|
||||||
|
|
||||||
|
project/assembly_name="Pong Multiplayer with C#"
|
||||||
|
|
||||||
[input]
|
[input]
|
||||||
|
|
||||||
move_down={
|
move_down={
|
||||||
|
|||||||
Reference in New Issue
Block a user