From fe5a08840c6ff747fe23907e03bc9ed97e8e3006 Mon Sep 17 00:00:00 2001 From: Syntriax Date: Fri, 2 Feb 2024 12:53:25 +0300 Subject: [PATCH] feat: Test Network --- Engine | 2 +- Game/Behaviours/BallBehaviour.cs | 30 ++++++++++++++++++-- Game/Behaviours/PaddleBehaviour.cs | 30 ++++++++++++++++++-- Game/Behaviours/PongManagerBehaviour.cs | 37 +++++++++++++++++++++++++ Game/Behaviours/TextScoreBehaviour.cs | 1 + Game/GamePong.cs | 25 +++++++++++++---- 6 files changed, 115 insertions(+), 10 deletions(-) diff --git a/Engine b/Engine index 5d897f2..dbb263e 160000 --- a/Engine +++ b/Engine @@ -1 +1 @@ -Subproject commit 5d897f2f56c711629f8cbf915d0ed112cf21680f +Subproject commit dbb263ebed24a1658d5d18d27182c8749cc8ee06 diff --git a/Game/Behaviours/BallBehaviour.cs b/Game/Behaviours/BallBehaviour.cs index 2e6ff53..3e5b6df 100644 --- a/Game/Behaviours/BallBehaviour.cs +++ b/Game/Behaviours/BallBehaviour.cs @@ -1,5 +1,6 @@ using System; - +using LiteNetLib; +using Pong.Network; using Syntriax.Engine.Core; using Syntriax.Engine.Physics2D; using Syntriax.Engine.Physics2D.Abstract; @@ -14,6 +15,7 @@ public class BallBehaviour : BehaviourOverride private readonly Random random = new(); private IRigidBody2D rigidBody = null!; + private INetworkCommunicator communicator = null!; protected override void OnFirstActiveFrame() { @@ -21,11 +23,14 @@ public class BallBehaviour : BehaviourOverride throw new Exception($"{nameof(IRigidBody2D)} is missing on {GameObject.Name}."); if (!BehaviourController.TryGetBehaviour(out ICollider2D? foundCollider)) throw new Exception($"{nameof(ICollider2D)} is missing on {GameObject.Name}."); + if (!GameObject.GameManager.TryFindBehaviour(out INetworkCommunicator? foundCommunicator)) + throw new Exception($"{nameof(INetworkCommunicator)} is missing on GameManager."); foundCollider.OnCollisionDetected += OnCollisionDetected; rigidBody = foundRigidBody; - + communicator = foundCommunicator; + communicator.RegisterEntityListener(this, OnDataReceived); if (GameObject.GameManager.TryFindBehaviour(out PongManagerBehaviour? pongManager)) { pongManager.OnReset += ResetBall; @@ -34,6 +39,12 @@ public class BallBehaviour : BehaviourOverride } } + private void OnDataReceived(NetPacketReader reader) + { + rigidBody.Transform.Position = reader.GetVector2D(); + rigidBody.Velocity = reader.GetVector2D(); + } + private void DisableBall(PongManagerBehaviour pongManager) { BehaviourController.GameObject.Transform.Position = Vector2D.Zero; @@ -45,6 +56,8 @@ public class BallBehaviour : BehaviourOverride StateEnable.Enabled = true; BehaviourController.GameObject.Transform.Position = Vector2D.Zero; rigidBody.Velocity = GetRandomDirection() * Speed; + + SendBallData(); } private Vector2D GetRandomDirection() @@ -70,6 +83,19 @@ public class BallBehaviour : BehaviourOverride rigidBody.Velocity = information.Left.Transform.Position.FromTo(information.Right.Transform.Position).Normalized * rigidBody.Velocity.Magnitude; else rigidBody.Velocity = rigidBody.Velocity.Reflect(information.Normal); + + SendBallData(); + } + + private void SendBallData() + { + if (communicator is not INetworkServer server) + return; + + LiteNetLib.Utils.NetDataWriter dataWriter = communicator.GetEntityWriter(this); + dataWriter.Put(rigidBody.Transform.Position); + dataWriter.Put(rigidBody.Velocity); + server.Manager.SendToAll(dataWriter, LiteNetLib.DeliveryMethod.ReliableOrdered); } public BallBehaviour() { } diff --git a/Game/Behaviours/PaddleBehaviour.cs b/Game/Behaviours/PaddleBehaviour.cs index d944847..684aa9f 100644 --- a/Game/Behaviours/PaddleBehaviour.cs +++ b/Game/Behaviours/PaddleBehaviour.cs @@ -2,6 +2,11 @@ using System; using Microsoft.Xna.Framework.Input; +using LiteNetLib; +using LiteNetLib.Utils; + +using Pong.Network; + using Syntriax.Engine.Core; using Syntriax.Engine.Input; @@ -19,6 +24,7 @@ public class PaddleBehaviour(Keys Up, Keys Down, float High, float Low, float Sp private bool isDownPressed = false; private IButtonInputs inputs = null!; + private INetworkCommunicator communicator = null!; protected override void OnUpdate() { @@ -26,23 +32,43 @@ public class PaddleBehaviour(Keys Up, Keys Down, float High, float Low, float Sp return; if (isUpPressed) - GameObject.Transform.Position = GameObject.Transform.Position + Vector2D.Up * (float)Time.Elapsed.TotalSeconds * Speed; + MovePaddle(Vector2D.Up * (float)Time.Elapsed.TotalSeconds * Speed); else if (isDownPressed) - GameObject.Transform.Position = GameObject.Transform.Position + -Vector2D.Up * (float)Time.Elapsed.TotalSeconds * Speed; + MovePaddle(-Vector2D.Up * (float)Time.Elapsed.TotalSeconds * Speed); GameObject.Transform.Position = new Vector2D(GameObject.Transform.Position.X, MathF.Max(MathF.Min(GameObject.Transform.Position.Y, High), Low)); } + private void MovePaddle(Vector2D vectorToAdd) + { + GameObject.Transform.Position += vectorToAdd; + + NetDataWriter dataWriter = communicator.GetEntityWriter(this); + dataWriter.Put(Transform.Position); + communicator.Manager.SendToAll(dataWriter, LiteNetLib.DeliveryMethod.Unreliable); + } + protected override void OnFirstActiveFrame() { if (!BehaviourController.TryGetBehaviour>(out var behaviourResult)) inputs = behaviourResult ?? BehaviourController.AddBehaviour(); + if (!GameObject.GameManager.TryFindBehaviour(out INetworkCommunicator? foundCommunicator)) + throw new Exception($"{nameof(INetworkCommunicator)} is missing on GameManager."); + inputs.RegisterOnPress(Up, OnUpPressed); inputs.RegisterOnRelease(Up, OnUpReleased); inputs.RegisterOnPress(Down, OnDownPressed); inputs.RegisterOnRelease(Down, OnDownReleased); + + communicator = foundCommunicator; + communicator.RegisterEntityListener(this, OnDataReceived); + } + + private void OnDataReceived(NetPacketReader reader) + { + Transform.Position = reader.GetVector2D(); } protected override void OnFinalize() diff --git a/Game/Behaviours/PongManagerBehaviour.cs b/Game/Behaviours/PongManagerBehaviour.cs index dbdb3d7..2aeb03e 100644 --- a/Game/Behaviours/PongManagerBehaviour.cs +++ b/Game/Behaviours/PongManagerBehaviour.cs @@ -2,6 +2,10 @@ using System; using Microsoft.Xna.Framework.Input; +using LiteNetLib; + +using Pong.Network; + using Syntriax.Engine.Core; namespace Pong.Behaviours; @@ -12,6 +16,8 @@ public class PongManagerBehaviour : BehaviourOverride public Action? OnFinished { get; set; } = null; public Action? OnScored { get; set; } = null; + private INetworkCommunicator communicator = null!; + public int ScoreLeft { get; private set; } = 0; public int ScoreRight { get; private set; } = 0; public int ScoreSum => ScoreLeft + ScoreRight; @@ -28,15 +34,31 @@ public class PongManagerBehaviour : BehaviourOverride if (!BehaviourController.TryGetBehaviour(out buttonInputs)) buttonInputs = BehaviourController.AddBehaviour(); + if (!GameObject.GameManager.TryFindBehaviour(out INetworkCommunicator? foundCommunicator)) + throw new Exception($"{nameof(INetworkCommunicator)} is missing on GameManager."); + buttonInputs.RegisterOnRelease(Keys.Space, (_, _1) => Reset()); + + communicator = foundCommunicator; + communicator.RegisterEntityListener(this, OnMessageReceived); } + private void OnMessageReceived(NetPacketReader reader) + { + ScoreLeft = reader.GetInt(); + ScoreRight = reader.GetInt(); + OnScored?.Invoke(this); + + CheckFinish(); + } public void ScoreToLeft() { ScoreLeft++; OnScored?.Invoke(this); + SendData(); + CheckFinish(); } @@ -45,6 +67,8 @@ public class PongManagerBehaviour : BehaviourOverride ScoreRight++; OnScored?.Invoke(this); + SendData(); + CheckFinish(); } @@ -52,6 +76,8 @@ public class PongManagerBehaviour : BehaviourOverride { ScoreLeft = ScoreRight = 0; OnReset?.Invoke(this); + + SendData(); } private void CheckFinish() @@ -61,4 +87,15 @@ public class PongManagerBehaviour : BehaviourOverride if (ScoreLeft > halfwayScore || ScoreRight > halfwayScore) OnFinished?.Invoke(this); } + + private void SendData() + { + if (communicator is not INetworkServer server) + return; + + LiteNetLib.Utils.NetDataWriter dataWriter = communicator.GetEntityWriter(this); + dataWriter.Put(ScoreLeft); + dataWriter.Put(ScoreRight); + server.Manager.SendToAll(dataWriter, LiteNetLib.DeliveryMethod.ReliableOrdered); + } } diff --git a/Game/Behaviours/TextScoreBehaviour.cs b/Game/Behaviours/TextScoreBehaviour.cs index 452f660..bdb5a45 100644 --- a/Game/Behaviours/TextScoreBehaviour.cs +++ b/Game/Behaviours/TextScoreBehaviour.cs @@ -14,6 +14,7 @@ public class TextScoreBehaviour : TextBehaviour if (!GameObject.GameManager.TryFindBehaviour(out pongManager)) return; + pongManager.OnFinished += UpdateScores; pongManager.OnScored += UpdateScores; pongManager.OnReset += UpdateScores; diff --git a/Game/GamePong.cs b/Game/GamePong.cs index bb883eb..4ab3184 100644 --- a/Game/GamePong.cs +++ b/Game/GamePong.cs @@ -1,16 +1,19 @@ using System; + using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; using Microsoft.Xna.Framework.Input; -using Pong.Behaviours; using Apos.Shapes; +using Pong.Behaviours; +using Pong.Network; + using Syntriax.Engine.Core; using Syntriax.Engine.Core.Abstract; using Syntriax.Engine.Physics2D; -using Syntriax.Engine.Physics2D.Primitives; using Syntriax.Engine.Physics2D.Abstract; +using Syntriax.Engine.Physics2D.Primitives; namespace Pong; @@ -79,7 +82,7 @@ public class GamePong : Game gameObjectBall.Transform.SetTransform(position: new Vector2D(0, 0f), scale: new Vector2D(10f, 10f)); gameObjectBall.BehaviourController.AddBehaviour(new Circle(Vector2D.Zero, 1f)); - gameObjectBall.BehaviourController.AddBehaviour(); + gameObjectBall.BehaviourController.AddBehaviour().Id = "ball"; gameObjectBall.BehaviourController.AddBehaviour(); //////////////////////////////////////////////////////////////////////////////////// @@ -87,13 +90,13 @@ public class GamePong : Game IGameObject gameObjectLeftPaddle = gameManager.InstantiateGameObject().SetGameObject("Left Paddle"); gameObjectLeftPaddle.Transform.SetTransform(position: new Vector2D(-468f, 0f), scale: new Vector2D(15f, 60f)); - gameObjectLeftPaddle.BehaviourController.AddBehaviour(Keys.W, Keys.S, 228f, -228f, 400f); + gameObjectLeftPaddle.BehaviourController.AddBehaviour(Keys.W, Keys.S, 228f, -228f, 400f).Id = "leftPaddle"; ; gameObjectLeftPaddle.BehaviourController.AddBehaviour(Shape.Box); gameObjectLeftPaddle.BehaviourController.AddBehaviour().IsStatic = true; IGameObject gameObjectRightPaddle = gameManager.InstantiateGameObject().SetGameObject("Right Paddle"); gameObjectRightPaddle.Transform.SetTransform(position: new Vector2D(468f, 0f), scale: new Vector2D(15f, 60f)); - gameObjectRightPaddle.BehaviourController.AddBehaviour(Keys.Up, Keys.Down, 228f, -228f, 400f); + gameObjectRightPaddle.BehaviourController.AddBehaviour(Keys.Up, Keys.Down, 228f, -228f, 400f).Id = "rightPaddle"; ; gameObjectRightPaddle.BehaviourController.AddBehaviour(Shape.Box); gameObjectRightPaddle.BehaviourController.AddBehaviour().IsStatic = true; @@ -130,6 +133,18 @@ public class GamePong : Game IGameObject gameObjectRightScoreText = gameManager.InstantiateGameObject().SetGameObject("Score Right"); gameObjectRightScoreText.Transform.SetTransform(position: new Vector2D(250f, 250f), scale: Vector2D.One * .25f); gameObjectRightScoreText.BehaviourController.AddBehaviour(false, spriteFont); + + string[] commandLineArguments = Environment.GetCommandLineArgs(); + if (commandLineArguments.Length != 1) + { + if (commandLineArguments[1].Equals("server", StringComparison.OrdinalIgnoreCase)) + pongManager.BehaviourController.AddBehaviour().Start(8888, 2); + else + pongManager.BehaviourController.AddBehaviour().Connect(commandLineArguments[1], 8888); + + } + else + pongManager.BehaviourController.AddBehaviour().Connect("127.0.0.1", 8888); } protected override void Update(GameTime gameTime)