feat: basic pong manager networking added
This commit is contained in:
		@@ -1,5 +1,3 @@
 | 
				
			|||||||
using System;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
using Syntriax.Engine.Core;
 | 
					using Syntriax.Engine.Core;
 | 
				
			||||||
using Syntriax.Engine.Physics2D;
 | 
					using Syntriax.Engine.Physics2D;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -7,47 +5,28 @@ namespace Pong.Behaviours;
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
public class BallBehaviour : Behaviour2D
 | 
					public class BallBehaviour : Behaviour2D
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    public Vector2D StartDirection { get; private set; } = Vector2D.Zero;
 | 
					 | 
				
			||||||
    public float Speed { get; set; } = 500f;
 | 
					    public float Speed { get; set; } = 500f;
 | 
				
			||||||
    public float SpeedUpMultiplier { get; set; } = .0125f;
 | 
					    public float SpeedUpMultiplier { get; set; } = .0125f;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private readonly Random random = new();
 | 
					    public IRigidBody2D rigidBody = null!;
 | 
				
			||||||
    private IRigidBody2D rigidBody = null!;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    protected override void OnFirstActiveFrame()
 | 
					    protected override void OnFirstActiveFrame()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        BehaviourController.GetRequiredBehaviour<ICollider2D>().OnCollisionDetected += OnCollisionDetected;
 | 
					        BehaviourController.GetRequiredBehaviour<ICollider2D>().OnCollisionDetected += OnCollisionDetected;
 | 
				
			||||||
        rigidBody = BehaviourController.GetRequiredBehaviour<IRigidBody2D>();
 | 
					        rigidBody = BehaviourController.GetRequiredBehaviour<IRigidBody2D>();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (UniverseObject.Universe.TryFindBehaviour(out PongManagerBehaviour? pongManager))
 | 
					    public void LaunchBall(Vector2D launchDirection)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
            pongManager.OnReset += ResetBall;
 | 
					        rigidBody.Velocity = launchDirection * Speed;
 | 
				
			||||||
            pongManager.OnScored += ResetBall;
 | 
					 | 
				
			||||||
            pongManager.OnFinished += DisableBall;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private void DisableBall(PongManagerBehaviour pongManager)
 | 
					    public void ResetBall()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        Transform.Position = Vector2D.Zero;
 | 
					        Transform.Position = Vector2D.Zero;
 | 
				
			||||||
        rigidBody.Velocity = Vector2D.Zero;
 | 
					        rigidBody.Velocity = Vector2D.Zero;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private void ResetBall(PongManagerBehaviour pongManager)
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        StateEnable.Enabled = true;
 | 
					 | 
				
			||||||
        Transform.Position = Vector2D.Zero;
 | 
					 | 
				
			||||||
        rigidBody.Velocity = GetRandomDirection() * Speed;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    private Vector2D GetRandomDirection()
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        const float AllowedRadians = 45f * Syntriax.Engine.Core.Math.DegreeToRadian;
 | 
					 | 
				
			||||||
        float rotation = (float)random.NextDouble() * 2f * AllowedRadians - AllowedRadians;
 | 
					 | 
				
			||||||
        bool isBackwards = (random.Next() % 2) == 1;
 | 
					 | 
				
			||||||
        return Vector2D.Right.Rotate(isBackwards ? rotation + Syntriax.Engine.Core.Math.PI : rotation);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    protected override void OnUpdate()
 | 
					    protected override void OnUpdate()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        if (rigidBody.Velocity.MagnitudeSquared <= 0.01f)
 | 
					        if (rigidBody.Velocity.MagnitudeSquared <= 0.01f)
 | 
				
			||||||
@@ -59,16 +38,12 @@ public class BallBehaviour : Behaviour2D
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    private void OnCollisionDetected(ICollider2D collider2D, CollisionDetectionInformation information)
 | 
					    private void OnCollisionDetected(ICollider2D collider2D, CollisionDetectionInformation information)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        if (Syntriax.Engine.Core.Math.Abs(information.Normal.Dot(Vector2D.Right)) > .25)
 | 
					        if (Math.Abs(information.Normal.Dot(Vector2D.Right)) > .25)
 | 
				
			||||||
            rigidBody.Velocity = information.Detected.Transform.Position.FromTo(information.Detector.Transform.Position).Normalized * rigidBody.Velocity.Magnitude;
 | 
					            rigidBody.Velocity = information.Detected.Transform.Position.FromTo(information.Detector.Transform.Position).Normalized * rigidBody.Velocity.Magnitude;
 | 
				
			||||||
        else
 | 
					        else
 | 
				
			||||||
            rigidBody.Velocity = rigidBody.Velocity.Reflect(information.Normal);
 | 
					            rigidBody.Velocity = rigidBody.Velocity.Reflect(information.Normal);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public BallBehaviour() { }
 | 
					    public BallBehaviour() { }
 | 
				
			||||||
    public BallBehaviour(Vector2D startDirection, float speed)
 | 
					    public BallBehaviour(float speed) => Speed = speed;
 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        StartDirection = Vector2D.Normalize(startDirection);
 | 
					 | 
				
			||||||
        Speed = speed;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -3,16 +3,28 @@ using System;
 | 
				
			|||||||
using Microsoft.Xna.Framework.Input;
 | 
					using Microsoft.Xna.Framework.Input;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
using Syntriax.Engine.Core;
 | 
					using Syntriax.Engine.Core;
 | 
				
			||||||
 | 
					using Syntriax.Engine.Network;
 | 
				
			||||||
using Syntriax.Engine.Systems.Input;
 | 
					using Syntriax.Engine.Systems.Input;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Pong.Behaviours;
 | 
					namespace Pong.Behaviours;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
public class PongManagerBehaviour : Behaviour
 | 
					public class PongManagerBehaviour : Behaviour,
 | 
				
			||||||
 | 
					    IPacketListenerServer<PongManagerBehaviour.PongStartPacket>,
 | 
				
			||||||
 | 
					    IPacketListenerServer<PongManagerBehaviour.PongResetPacket>,
 | 
				
			||||||
 | 
					    IPacketListenerClient<PongManagerBehaviour.PongStartPacket>,
 | 
				
			||||||
 | 
					    IPacketListenerClient<PongManagerBehaviour.PongResetPacket>,
 | 
				
			||||||
 | 
					    IPacketListenerClient<PongManagerBehaviour.PongScoreUpdatePacket>
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    public Action<PongManagerBehaviour>? OnReset { get; set; } = null;
 | 
					    public Action<PongManagerBehaviour>? OnReset { get; set; } = null;
 | 
				
			||||||
    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 readonly Random random = new();
 | 
				
			||||||
 | 
					    private BallBehaviour ball = null!;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private INetworkCommunicatorClient networkClient = null!;
 | 
				
			||||||
 | 
					    private INetworkCommunicatorServer? networkServer = 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;
 | 
				
			||||||
@@ -25,22 +37,31 @@ public class PongManagerBehaviour : Behaviour
 | 
				
			|||||||
    protected override void OnFirstActiveFrame()
 | 
					    protected override void OnFirstActiveFrame()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        var buttonInputs = Universe.FindRequiredBehaviour<IButtonInputs<Keys>>();
 | 
					        var buttonInputs = Universe.FindRequiredBehaviour<IButtonInputs<Keys>>();
 | 
				
			||||||
        buttonInputs.RegisterOnRelease(Keys.Space, (_, _1) => Reset());
 | 
					        buttonInputs.RegisterOnRelease(Keys.Space, (_, _1) => networkClient.SendToServer(new PongResetPacket()));
 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        networkClient = Universe.FindRequiredBehaviour<INetworkCommunicatorClient>();
 | 
				
			||||||
 | 
					        ball = Universe.FindRequiredBehaviour<BallBehaviour>();
 | 
				
			||||||
 | 
					        networkServer = Universe.FindBehaviour<INetworkCommunicatorServer>();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public void ScoreToLeft()
 | 
					    public void ScoreToLeft()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if (networkServer is not null)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            ScoreLeft++;
 | 
					            ScoreLeft++;
 | 
				
			||||||
            OnScored?.InvokeSafe(this);
 | 
					            OnScored?.InvokeSafe(this);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        CheckFinish();
 | 
					        CheckFinish();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public void ScoreToRight()
 | 
					    public void ScoreToRight()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if (networkServer is not null)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            ScoreRight++;
 | 
					            ScoreRight++;
 | 
				
			||||||
            OnScored?.InvokeSafe(this);
 | 
					            OnScored?.InvokeSafe(this);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        CheckFinish();
 | 
					        CheckFinish();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@@ -54,8 +75,66 @@ public class PongManagerBehaviour : Behaviour
 | 
				
			|||||||
    private void CheckFinish()
 | 
					    private void CheckFinish()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        int halfwayScore = (int)(WinScore * .5f);
 | 
					        int halfwayScore = (int)(WinScore * .5f);
 | 
				
			||||||
 | 
					        ball.ResetBall();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        networkServer?.SendToClient("*", new PongScoreUpdatePacket(this));
 | 
				
			||||||
        if (ScoreLeft > halfwayScore || ScoreRight > halfwayScore)
 | 
					        if (ScoreLeft > halfwayScore || ScoreRight > halfwayScore)
 | 
				
			||||||
            OnFinished?.InvokeSafe(this);
 | 
					            OnFinished?.InvokeSafe(this);
 | 
				
			||||||
 | 
					        else
 | 
				
			||||||
 | 
					            networkServer?.SendToClient("*", new PongStartPacket() { BallVelocity = GetBallLaunchDirection() });
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private Vector2D GetBallLaunchDirection()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        const float AllowedRadians = 45f * Syntriax.Engine.Core.Math.DegreeToRadian;
 | 
				
			||||||
 | 
					        float rotation = (float)random.NextDouble() * 2f * AllowedRadians - AllowedRadians;
 | 
				
			||||||
 | 
					        bool isBackwards = (random.Next() % 2) == 1;
 | 
				
			||||||
 | 
					        return Vector2D.Right.Rotate(isBackwards ? rotation + Syntriax.Engine.Core.Math.PI : rotation);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public void OnClientPacketArrived(PongResetPacket packet) => Reset();
 | 
				
			||||||
 | 
					    public void OnClientPacketArrived(PongScoreUpdatePacket packet)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        ScoreLeft = packet.Left;
 | 
				
			||||||
 | 
					        ScoreRight = packet.Right;
 | 
				
			||||||
 | 
					        OnScored?.InvokeSafe(this);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public void OnServerPacketArrived(PongResetPacket packet, string from)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        Reset();
 | 
				
			||||||
 | 
					        networkServer?.SendToClient("*", new PongResetPacket());
 | 
				
			||||||
 | 
					        networkServer?.SendToClient("*", new PongStartPacket() { BallVelocity = GetBallLaunchDirection() });
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public void OnServerPacketArrived(PongStartPacket packet, string from)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        packet = new() { BallVelocity = GetBallLaunchDirection() };
 | 
				
			||||||
 | 
					        networkServer?.SendToClient("*", packet);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public void OnClientPacketArrived(PongStartPacket packet)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        ball.LaunchBall(packet.BallVelocity);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public class PongStartPacket : INetworkPacket
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        public Vector2D BallVelocity { get; set; } = Vector2D.Zero;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public class PongResetPacket : INetworkPacket;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public class PongScoreUpdatePacket : INetworkPacket
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        public int Left { get; set; } = 0;
 | 
				
			||||||
 | 
					        public int Right { get; set; } = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public PongScoreUpdatePacket() { }
 | 
				
			||||||
 | 
					        public PongScoreUpdatePacket(PongManagerBehaviour pongManagerBehaviour)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            Left = pongManagerBehaviour.ScoreLeft;
 | 
				
			||||||
 | 
					            Right = pongManagerBehaviour.ScoreRight;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -16,18 +16,6 @@ using Syntriax.Engine.Physics2D;
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
namespace Pong;
 | 
					namespace Pong;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[System.Serializable]
 | 
					 | 
				
			||||||
public class TestMessagePacket : INetworkPacket, LiteNetLib.Utils.INetSerializable
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    public string Message { get; set; }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public void Deserialize(LiteNetLib.Utils.NetDataReader reader) => Message = reader.GetString();
 | 
					 | 
				
			||||||
    public void Serialize(LiteNetLib.Utils.NetDataWriter writer) => writer.Put(Message);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public TestMessagePacket() => Message = "Default Message";
 | 
					 | 
				
			||||||
    public TestMessagePacket(string Message) => this.Message = Message;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
public class GamePong : Game
 | 
					public class GamePong : Game
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    private readonly IUniverseObject platformSpecificUniverseObject = null!;
 | 
					    private readonly IUniverseObject platformSpecificUniverseObject = null!;
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user