feat: basic pong manager networking added
This commit is contained in:
parent
8f9c9f77f0
commit
2853a6130b
@ -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!;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user