Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Updated Multiplayer Pong C# to Godot 4.2 #1045

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 6 additions & 3 deletions mono/multiplayer_pong/Pong Multiplayer with C#.csproj
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
<Project Sdk="Godot.NET.Sdk/4.0.0-dev5">
<Project Sdk="Godot.NET.Sdk/4.2.0">
<PropertyGroup>
<TargetFramework>net472</TargetFramework>
<RootNamespace>PongMultiplayer</RootNamespace>
<TargetFramework>net6.0</TargetFramework>
<TargetFramework Condition=" '$(GodotTargetPlatform)' == 'android' ">net7.0</TargetFramework>
<TargetFramework Condition=" '$(GodotTargetPlatform)' == 'ios' ">net8.0</TargetFramework>
<EnableDynamicLoading>true</EnableDynamicLoading>
<RootNamespace>PongMultiplayerwithC</RootNamespace>
</PropertyGroup>
</Project>
14 changes: 7 additions & 7 deletions mono/multiplayer_pong/Pong Multiplayer with C#.sln
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# 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
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Expand All @@ -9,11 +9,11 @@ Global
ExportRelease|Any CPU = ExportRelease|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{4BB6C2D0-FC11-466E-8C73-8DAD689F135A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{4BB6C2D0-FC11-466E-8C73-8DAD689F135A}.Debug|Any CPU.Build.0 = Debug|Any CPU
{4BB6C2D0-FC11-466E-8C73-8DAD689F135A}.ExportDebug|Any CPU.ActiveCfg = ExportDebug|Any CPU
{4BB6C2D0-FC11-466E-8C73-8DAD689F135A}.ExportDebug|Any CPU.Build.0 = ExportDebug|Any CPU
{4BB6C2D0-FC11-466E-8C73-8DAD689F135A}.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}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{58FECEC2-0618-4042-81F2-4EDD7982C229}.Debug|Any CPU.Build.0 = Debug|Any CPU
{58FECEC2-0618-4042-81F2-4EDD7982C229}.ExportDebug|Any CPU.ActiveCfg = ExportDebug|Any CPU
{58FECEC2-0618-4042-81F2-4EDD7982C229}.ExportDebug|Any CPU.Build.0 = ExportDebug|Any CPU
{58FECEC2-0618-4042-81F2-4EDD7982C229}.ExportRelease|Any CPU.ActiveCfg = ExportRelease|Any CPU
{58FECEC2-0618-4042-81F2-4EDD7982C229}.ExportRelease|Any CPU.Build.0 = ExportRelease|Any CPU
EndGlobalSection
EndGlobal
33 changes: 15 additions & 18 deletions mono/multiplayer_pong/lobby.tscn
Original file line number Diff line number Diff line change
@@ -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"]
layout_mode = 3
anchors_preset = 8
anchor_left = 0.5
anchor_top = 0.5
anchor_right = 0.5
Expand All @@ -11,36 +13,33 @@ offset_left = -320.0
offset_top = -200.0
offset_right = 320.0
offset_bottom = 200.0
grow_horizontal = 2
grow_vertical = 2
size_flags_horizontal = 2
size_flags_vertical = 2
__meta__ = {
"_edit_use_anchors_": false
}

[node name="Title" type="Label" parent="."]
layout_mode = 0
offset_left = 210.0
offset_top = 40.0
offset_right = 430.0
offset_bottom = 80.0
size_flags_horizontal = 2
size_flags_vertical = 0
text = "Multiplayer Pong"
align = 1
valign = 1

[node name="LobbyPanel" type="Panel" parent="."]
layout_mode = 0
offset_left = 210.0
offset_top = 160.0
offset_right = 430.0
offset_bottom = 270.0
size_flags_horizontal = 2
size_flags_vertical = 2
script = ExtResource( 1 )
__meta__ = {
"_edit_use_anchors_": false
}
script = ExtResource("1")

[node name="AddressLabel" type="Label" parent="LobbyPanel"]
layout_mode = 0
offset_left = 10.0
offset_top = 10.0
offset_right = 62.0
Expand All @@ -50,6 +49,7 @@ size_flags_vertical = 0
text = "Address"

[node name="Address" type="LineEdit" parent="LobbyPanel"]
layout_mode = 0
offset_left = 10.0
offset_top = 30.0
offset_right = 210.0
Expand All @@ -59,6 +59,7 @@ size_flags_vertical = 2
text = "127.0.0.1"

[node name="HostButton" type="Button" parent="LobbyPanel"]
layout_mode = 0
offset_left = 10.0
offset_top = 60.0
offset_right = 90.0
Expand All @@ -68,36 +69,32 @@ size_flags_vertical = 2
text = "Host"

[node name="JoinButton" type="Button" parent="LobbyPanel"]
layout_mode = 0
offset_left = 130.0
offset_top = 60.0
offset_right = 210.0
offset_bottom = 80.0
size_flags_horizontal = 2
size_flags_vertical = 2
text = "Join"
__meta__ = {
"_edit_use_anchors_": false
}

[node name="StatusOk" type="Label" parent="LobbyPanel"]
layout_mode = 0
offset_left = 10.0
offset_top = 90.0
offset_right = 210.0
offset_bottom = 104.0
size_flags_horizontal = 2
size_flags_vertical = 0
custom_colors/font_color = Color(0, 1, 0.015625, 1)
align = 1

[node name="StatusFail" type="Label" parent="LobbyPanel"]
layout_mode = 0
offset_left = 10.0
offset_top = 90.0
offset_right = 210.0
offset_bottom = 104.0
size_flags_horizontal = 2
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/JoinButton" to="LobbyPanel" method="OnJoinPressed"]
38 changes: 19 additions & 19 deletions mono/multiplayer_pong/logic/Ball.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ public partial class Ball : Area2D

private Vector2 _direction = Vector2.Left;
private bool _stopped = false;
private float _speed = DefaultSpeed;
private double _speed = DefaultSpeed;
private Vector2 _screenSize;

// Called when the node enters the scene tree for the first time.
Expand All @@ -17,44 +17,44 @@ public override void _Ready()
}

// 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;
// Ball will move normally for both players,
// even if it's slightly out of sync between them,
// so each player sees the motion as smooth and not jerky.
if (!_stopped)
{
Translate(_speed * delta * _direction);
Translate((float)(_speed * delta) * _direction);
}

// Check screen bounds to make ball bounce.
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
// the left side (it's own side). This makes the game
// playable even if latency is high and ball is going
// fast. Otherwise ball might be out in the other
// Only the server (Multiplayer Authority) will decide
// when the ball is out in the left side (it's own side).
// This makes the game playable even if latency is high and
// ball is going fast. Otherwise ball might be out in the other
// player's screen but not this one.
if (ballPosition.x < 0)
if (ballPosition.X < 0)
{
GetParent().Rpc("UpdateScore", false);
Rpc("ResetBall", false);
}
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 game playable even if latency is high and ball
// is going fast. Otherwise ball might be out in the
// other player's screen but not this one.
if (ballPosition.x > _screenSize.x)
if (ballPosition.X > _screenSize.X)
{
GetParent().Rpc("UpdateScore", true);
Rpc("ResetBall", true);
Expand All @@ -63,31 +63,31 @@ public override void _Process(float delta)
}
}

[Sync]
[Rpc(mode: MultiplayerApi.RpcMode.AnyPeer, CallLocal = true)]
private void Bounce(bool left, float random)
{
// Using sync because both players can make it bounce.
if (left)
{
_direction.x = Mathf.Abs(_direction.x);
_direction.X = Mathf.Abs(_direction.X);
}
else
{
_direction.x = -Mathf.Abs(_direction.x);
_direction.X = -Mathf.Abs(_direction.X);
}

_speed *= 1.1f;
_direction.y = random * 2.0f - 1;
_direction.Y = random * 2.0f - 1;
_direction = _direction.Normalized();
}

[Sync]
[Rpc(mode: MultiplayerApi.RpcMode.AnyPeer, CallLocal = true)]
private void Stop()
{
_stopped = true;
}

[Sync]
[Rpc(mode: MultiplayerApi.RpcMode.AnyPeer, CallLocal = true)]
private void ResetBall(bool forLeft)
{
Position = _screenSize / 2;
Expand Down
34 changes: 18 additions & 16 deletions mono/multiplayer_pong/logic/Lobby.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ public partial class Lobby : Control
private Button _joinButton;
private Label _statusOk;
private Label _statusFail;
private NetworkedMultiplayerENet _peer;
private ENetMultiplayerPeer _peer;

public override void _Ready()
{
Expand All @@ -25,11 +25,11 @@ public override void _Ready()

// Connect all callbacks related to networking.
// Note: Use snake_case when talking to engine API.
GetTree().Connect("network_peer_connected", this, nameof(PlayerConnected));
GetTree().Connect("network_peer_disconnected", this, nameof(PlayerDisconnected));
GetTree().Connect("connected_to_server", this, nameof(ConnectedOk));
GetTree().Connect("connection_failed", this, nameof(ConnectedFail));
GetTree().Connect("server_disconnected", this, nameof(ServerDisconnected));
GetTree().GetMultiplayer().Connect("peer_connected", new Callable(this, nameof(PlayerConnected)));
GetTree().GetMultiplayer().Connect("peer_disconnected", new Callable(this, nameof(PlayerDisconnected)));
GetTree().GetMultiplayer().Connect("connected_to_server", new Callable(this, nameof(ConnectedOk)));
GetTree().GetMultiplayer().Connect("connection_failed", new Callable(this, nameof(ConnectedFail)));
GetTree().GetMultiplayer().Connect("server_disconnected", new Callable(this, nameof(ServerDisconnected)));
}

// Network callbacks from SceneTree
Expand All @@ -41,15 +41,15 @@ private void PlayerConnected(int id)
var pong = ResourceLoader.Load<PackedScene>("res://pong.tscn").Instantiate();

// 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);
Hide();
}

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).
Expand All @@ -63,7 +63,7 @@ private void ConnectedFail()
{
SetStatus("Couldn't connect", false);

GetTree().NetworkPeer = null; // Remove peer.
GetTree().GetMultiplayer().MultiplayerPeer = null; // Remove peer.
_hostButton.Disabled = false;
_joinButton.Disabled = false;
}
Expand All @@ -85,7 +85,7 @@ private void EndGame(string withError = "")
Show();
}

GetTree().NetworkPeer = null; // Remove peer.
GetTree().GetMultiplayer().MultiplayerPeer = null; // Remove peer.
_hostButton.Disabled = false;
_joinButton.Disabled = false;

Expand All @@ -109,8 +109,7 @@ private void SetStatus(string text, bool isOk)

private void OnHostPressed()
{
_peer = new NetworkedMultiplayerENet();
_peer.CompressionMode = NetworkedMultiplayerENet.CompressionModeEnum.RangeCoder;
_peer = new ENetMultiplayerPeer();
Error err = _peer.CreateServer(DefaultPort, MaxNumberOfPeers);
if (err != Error.Ok)
{
Expand All @@ -119,7 +118,9 @@ private void OnHostPressed()
return;
}

GetTree().NetworkPeer = _peer;
_peer.Host.Compress(ENetConnection.CompressionMode.RangeCoder);

GetTree().GetMultiplayer().MultiplayerPeer = _peer;
_hostButton.Disabled = true;
_joinButton.Disabled = true;
SetStatus("Waiting for player...", true);
Expand All @@ -134,10 +135,11 @@ private void OnJoinPressed()
return;
}

_peer = new NetworkedMultiplayerENet();
_peer.CompressionMode = NetworkedMultiplayerENet.CompressionModeEnum.RangeCoder;
_peer = new ENetMultiplayerPeer();
_peer.CreateClient(ip, DefaultPort);
GetTree().NetworkPeer = _peer;
_peer.Host.Compress(ENetConnection.CompressionMode.RangeCoder);

GetTree().GetMultiplayer().MultiplayerPeer = _peer;
SetStatus("Connecting...", true);
}
}
Loading