feat: Test Network

This commit is contained in:
Syntriax 2024-02-02 12:53:25 +03:00
parent 1c7b1cb78a
commit fe5a08840c
6 changed files with 115 additions and 10 deletions

2
Engine

@ -1 +1 @@
Subproject commit 5d897f2f56c711629f8cbf915d0ed112cf21680f Subproject commit dbb263ebed24a1658d5d18d27182c8749cc8ee06

View File

@ -1,5 +1,6 @@
using System; using System;
using LiteNetLib;
using Pong.Network;
using Syntriax.Engine.Core; using Syntriax.Engine.Core;
using Syntriax.Engine.Physics2D; using Syntriax.Engine.Physics2D;
using Syntriax.Engine.Physics2D.Abstract; using Syntriax.Engine.Physics2D.Abstract;
@ -14,6 +15,7 @@ public class BallBehaviour : BehaviourOverride
private readonly Random random = new(); private readonly Random random = new();
private IRigidBody2D rigidBody = null!; private IRigidBody2D rigidBody = null!;
private INetworkCommunicator communicator = null!;
protected override void OnFirstActiveFrame() protected override void OnFirstActiveFrame()
{ {
@ -21,11 +23,14 @@ public class BallBehaviour : BehaviourOverride
throw new Exception($"{nameof(IRigidBody2D)} is missing on {GameObject.Name}."); throw new Exception($"{nameof(IRigidBody2D)} is missing on {GameObject.Name}.");
if (!BehaviourController.TryGetBehaviour(out ICollider2D? foundCollider)) if (!BehaviourController.TryGetBehaviour(out ICollider2D? foundCollider))
throw new Exception($"{nameof(ICollider2D)} is missing on {GameObject.Name}."); 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; foundCollider.OnCollisionDetected += OnCollisionDetected;
rigidBody = foundRigidBody; rigidBody = foundRigidBody;
communicator = foundCommunicator;
communicator.RegisterEntityListener(this, OnDataReceived);
if (GameObject.GameManager.TryFindBehaviour(out PongManagerBehaviour? pongManager)) if (GameObject.GameManager.TryFindBehaviour(out PongManagerBehaviour? pongManager))
{ {
pongManager.OnReset += ResetBall; 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) private void DisableBall(PongManagerBehaviour pongManager)
{ {
BehaviourController.GameObject.Transform.Position = Vector2D.Zero; BehaviourController.GameObject.Transform.Position = Vector2D.Zero;
@ -45,6 +56,8 @@ public class BallBehaviour : BehaviourOverride
StateEnable.Enabled = true; StateEnable.Enabled = true;
BehaviourController.GameObject.Transform.Position = Vector2D.Zero; BehaviourController.GameObject.Transform.Position = Vector2D.Zero;
rigidBody.Velocity = GetRandomDirection() * Speed; rigidBody.Velocity = GetRandomDirection() * Speed;
SendBallData();
} }
private Vector2D GetRandomDirection() 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; rigidBody.Velocity = information.Left.Transform.Position.FromTo(information.Right.Transform.Position).Normalized * rigidBody.Velocity.Magnitude;
else else
rigidBody.Velocity = rigidBody.Velocity.Reflect(information.Normal); 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() { } public BallBehaviour() { }

View File

@ -2,6 +2,11 @@ using System;
using Microsoft.Xna.Framework.Input; using Microsoft.Xna.Framework.Input;
using LiteNetLib;
using LiteNetLib.Utils;
using Pong.Network;
using Syntriax.Engine.Core; using Syntriax.Engine.Core;
using Syntriax.Engine.Input; 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 bool isDownPressed = false;
private IButtonInputs<Keys> inputs = null!; private IButtonInputs<Keys> inputs = null!;
private INetworkCommunicator communicator = null!;
protected override void OnUpdate() protected override void OnUpdate()
{ {
@ -26,23 +32,43 @@ public class PaddleBehaviour(Keys Up, Keys Down, float High, float Low, float Sp
return; return;
if (isUpPressed) 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) 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)); 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() protected override void OnFirstActiveFrame()
{ {
if (!BehaviourController.TryGetBehaviour<IButtonInputs<Keys>>(out var behaviourResult)) if (!BehaviourController.TryGetBehaviour<IButtonInputs<Keys>>(out var behaviourResult))
inputs = behaviourResult ?? BehaviourController.AddBehaviour<KeyboardInputsBehaviour>(); inputs = behaviourResult ?? BehaviourController.AddBehaviour<KeyboardInputsBehaviour>();
if (!GameObject.GameManager.TryFindBehaviour(out INetworkCommunicator? foundCommunicator))
throw new Exception($"{nameof(INetworkCommunicator)} is missing on GameManager.");
inputs.RegisterOnPress(Up, OnUpPressed); inputs.RegisterOnPress(Up, OnUpPressed);
inputs.RegisterOnRelease(Up, OnUpReleased); inputs.RegisterOnRelease(Up, OnUpReleased);
inputs.RegisterOnPress(Down, OnDownPressed); inputs.RegisterOnPress(Down, OnDownPressed);
inputs.RegisterOnRelease(Down, OnDownReleased); inputs.RegisterOnRelease(Down, OnDownReleased);
communicator = foundCommunicator;
communicator.RegisterEntityListener(this, OnDataReceived);
}
private void OnDataReceived(NetPacketReader reader)
{
Transform.Position = reader.GetVector2D();
} }
protected override void OnFinalize() protected override void OnFinalize()

View File

@ -2,6 +2,10 @@ using System;
using Microsoft.Xna.Framework.Input; using Microsoft.Xna.Framework.Input;
using LiteNetLib;
using Pong.Network;
using Syntriax.Engine.Core; using Syntriax.Engine.Core;
namespace Pong.Behaviours; namespace Pong.Behaviours;
@ -12,6 +16,8 @@ public class PongManagerBehaviour : BehaviourOverride
public Action<PongManagerBehaviour>? OnFinished { get; set; } = null; public Action<PongManagerBehaviour>? OnFinished { get; set; } = null;
public Action<PongManagerBehaviour>? OnScored { get; set; } = null; public Action<PongManagerBehaviour>? OnScored { get; set; } = null;
private INetworkCommunicator communicator = null!;
public int ScoreLeft { get; private set; } = 0; public int ScoreLeft { get; private set; } = 0;
public int ScoreRight { get; private set; } = 0; public int ScoreRight { get; private set; } = 0;
public int ScoreSum => ScoreLeft + ScoreRight; public int ScoreSum => ScoreLeft + ScoreRight;
@ -28,15 +34,31 @@ public class PongManagerBehaviour : BehaviourOverride
if (!BehaviourController.TryGetBehaviour(out buttonInputs)) if (!BehaviourController.TryGetBehaviour(out buttonInputs))
buttonInputs = BehaviourController.AddBehaviour<KeyboardInputsBehaviour>(); buttonInputs = BehaviourController.AddBehaviour<KeyboardInputsBehaviour>();
if (!GameObject.GameManager.TryFindBehaviour(out INetworkCommunicator? foundCommunicator))
throw new Exception($"{nameof(INetworkCommunicator)} is missing on GameManager.");
buttonInputs.RegisterOnRelease(Keys.Space, (_, _1) => Reset()); 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() public void ScoreToLeft()
{ {
ScoreLeft++; ScoreLeft++;
OnScored?.Invoke(this); OnScored?.Invoke(this);
SendData();
CheckFinish(); CheckFinish();
} }
@ -45,6 +67,8 @@ public class PongManagerBehaviour : BehaviourOverride
ScoreRight++; ScoreRight++;
OnScored?.Invoke(this); OnScored?.Invoke(this);
SendData();
CheckFinish(); CheckFinish();
} }
@ -52,6 +76,8 @@ public class PongManagerBehaviour : BehaviourOverride
{ {
ScoreLeft = ScoreRight = 0; ScoreLeft = ScoreRight = 0;
OnReset?.Invoke(this); OnReset?.Invoke(this);
SendData();
} }
private void CheckFinish() private void CheckFinish()
@ -61,4 +87,15 @@ public class PongManagerBehaviour : BehaviourOverride
if (ScoreLeft > halfwayScore || ScoreRight > halfwayScore) if (ScoreLeft > halfwayScore || ScoreRight > halfwayScore)
OnFinished?.Invoke(this); 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);
}
} }

View File

@ -14,6 +14,7 @@ public class TextScoreBehaviour : TextBehaviour
if (!GameObject.GameManager.TryFindBehaviour(out pongManager)) if (!GameObject.GameManager.TryFindBehaviour(out pongManager))
return; return;
pongManager.OnFinished += UpdateScores;
pongManager.OnScored += UpdateScores; pongManager.OnScored += UpdateScores;
pongManager.OnReset += UpdateScores; pongManager.OnReset += UpdateScores;

View File

@ -1,16 +1,19 @@
using System; using System;
using Microsoft.Xna.Framework; using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics; using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input; using Microsoft.Xna.Framework.Input;
using Pong.Behaviours;
using Apos.Shapes; using Apos.Shapes;
using Pong.Behaviours;
using Pong.Network;
using Syntriax.Engine.Core; using Syntriax.Engine.Core;
using Syntriax.Engine.Core.Abstract; using Syntriax.Engine.Core.Abstract;
using Syntriax.Engine.Physics2D; using Syntriax.Engine.Physics2D;
using Syntriax.Engine.Physics2D.Primitives;
using Syntriax.Engine.Physics2D.Abstract; using Syntriax.Engine.Physics2D.Abstract;
using Syntriax.Engine.Physics2D.Primitives;
namespace Pong; namespace Pong;
@ -79,7 +82,7 @@ public class GamePong : Game
gameObjectBall.Transform.SetTransform(position: new Vector2D(0, 0f), scale: new Vector2D(10f, 10f)); gameObjectBall.Transform.SetTransform(position: new Vector2D(0, 0f), scale: new Vector2D(10f, 10f));
gameObjectBall.BehaviourController.AddBehaviour<CircleBehaviour>(new Circle(Vector2D.Zero, 1f)); gameObjectBall.BehaviourController.AddBehaviour<CircleBehaviour>(new Circle(Vector2D.Zero, 1f));
gameObjectBall.BehaviourController.AddBehaviour<BallBehaviour>(); gameObjectBall.BehaviourController.AddBehaviour<BallBehaviour>().Id = "ball";
gameObjectBall.BehaviourController.AddBehaviour<RigidBody2D>(); gameObjectBall.BehaviourController.AddBehaviour<RigidBody2D>();
//////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////
@ -87,13 +90,13 @@ public class GamePong : Game
IGameObject gameObjectLeftPaddle = gameManager.InstantiateGameObject<GameObject>().SetGameObject("Left Paddle"); IGameObject gameObjectLeftPaddle = gameManager.InstantiateGameObject<GameObject>().SetGameObject("Left Paddle");
gameObjectLeftPaddle.Transform.SetTransform(position: new Vector2D(-468f, 0f), scale: new Vector2D(15f, 60f)); gameObjectLeftPaddle.Transform.SetTransform(position: new Vector2D(-468f, 0f), scale: new Vector2D(15f, 60f));
gameObjectLeftPaddle.BehaviourController.AddBehaviour<PaddleBehaviour>(Keys.W, Keys.S, 228f, -228f, 400f); gameObjectLeftPaddle.BehaviourController.AddBehaviour<PaddleBehaviour>(Keys.W, Keys.S, 228f, -228f, 400f).Id = "leftPaddle"; ;
gameObjectLeftPaddle.BehaviourController.AddBehaviour<ShapeBehaviour>(Shape.Box); gameObjectLeftPaddle.BehaviourController.AddBehaviour<ShapeBehaviour>(Shape.Box);
gameObjectLeftPaddle.BehaviourController.AddBehaviour<RigidBody2D>().IsStatic = true; gameObjectLeftPaddle.BehaviourController.AddBehaviour<RigidBody2D>().IsStatic = true;
IGameObject gameObjectRightPaddle = gameManager.InstantiateGameObject<GameObject>().SetGameObject("Right Paddle"); IGameObject gameObjectRightPaddle = gameManager.InstantiateGameObject<GameObject>().SetGameObject("Right Paddle");
gameObjectRightPaddle.Transform.SetTransform(position: new Vector2D(468f, 0f), scale: new Vector2D(15f, 60f)); gameObjectRightPaddle.Transform.SetTransform(position: new Vector2D(468f, 0f), scale: new Vector2D(15f, 60f));
gameObjectRightPaddle.BehaviourController.AddBehaviour<PaddleBehaviour>(Keys.Up, Keys.Down, 228f, -228f, 400f); gameObjectRightPaddle.BehaviourController.AddBehaviour<PaddleBehaviour>(Keys.Up, Keys.Down, 228f, -228f, 400f).Id = "rightPaddle"; ;
gameObjectRightPaddle.BehaviourController.AddBehaviour<ShapeBehaviour>(Shape.Box); gameObjectRightPaddle.BehaviourController.AddBehaviour<ShapeBehaviour>(Shape.Box);
gameObjectRightPaddle.BehaviourController.AddBehaviour<RigidBody2D>().IsStatic = true; gameObjectRightPaddle.BehaviourController.AddBehaviour<RigidBody2D>().IsStatic = true;
@ -130,6 +133,18 @@ public class GamePong : Game
IGameObject gameObjectRightScoreText = gameManager.InstantiateGameObject<GameObject>().SetGameObject("Score Right"); IGameObject gameObjectRightScoreText = gameManager.InstantiateGameObject<GameObject>().SetGameObject("Score Right");
gameObjectRightScoreText.Transform.SetTransform(position: new Vector2D(250f, 250f), scale: Vector2D.One * .25f); gameObjectRightScoreText.Transform.SetTransform(position: new Vector2D(250f, 250f), scale: Vector2D.One * .25f);
gameObjectRightScoreText.BehaviourController.AddBehaviour<TextScoreBehaviour>(false, spriteFont); gameObjectRightScoreText.BehaviourController.AddBehaviour<TextScoreBehaviour>(false, spriteFont);
string[] commandLineArguments = Environment.GetCommandLineArgs();
if (commandLineArguments.Length != 1)
{
if (commandLineArguments[1].Equals("server", StringComparison.OrdinalIgnoreCase))
pongManager.BehaviourController.AddBehaviour<NetworkServer>().Start(8888, 2);
else
pongManager.BehaviourController.AddBehaviour<NetworkClient>().Connect(commandLineArguments[1], 8888);
}
else
pongManager.BehaviourController.AddBehaviour<NetworkClient>().Connect("127.0.0.1", 8888);
} }
protected override void Update(GameTime gameTime) protected override void Update(GameTime gameTime)