Compare commits
No commits in common. "main" and "feat/litenetlib" have entirely different histories.
main
...
feat/liten
2
.vscode/launch.json
vendored
2
.vscode/launch.json
vendored
@ -6,7 +6,7 @@
|
|||||||
"type": "coreclr",
|
"type": "coreclr",
|
||||||
"request": "launch",
|
"request": "launch",
|
||||||
"preLaunchTask": "build-client",
|
"preLaunchTask": "build-client",
|
||||||
"program": "${workspaceFolder}/Platforms/Desktop/bin/Debug/net9.0/Pong.dll",
|
"program": "${workspaceFolder}/Platforms/Desktop/bin/Debug/net9.0/Desktop.dll",
|
||||||
"args": [],
|
"args": [],
|
||||||
"cwd": "${workspaceFolder}",
|
"cwd": "${workspaceFolder}",
|
||||||
"stopAtEntry": false,
|
"stopAtEntry": false,
|
||||||
|
2
Engine
2
Engine
@ -1 +1 @@
|
|||||||
Subproject commit 03232f72e8f045fa3b5731a2b3839425f8ea9721
|
Subproject commit 83b155fc5e8fd1892278876cb90e10dcb64e2154
|
@ -19,10 +19,22 @@ ILogger logger = new FileLogger($"Logs/{DateTime.UtcNow:yyyy-MM-dd_HH-mm-ss-ffff
|
|||||||
logger = new LoggerWrapper(logger, new ConsoleLogger());
|
logger = new LoggerWrapper(logger, new ConsoleLogger());
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
universe.InstantiateUniverseObject().SetUniverseObject("Logger").BehaviourController.AddBehaviour<LoggerContainer>().Logger = ILogger.Shared = logger;
|
universe.InstantiateUniverseObject().SetUniverseObject("Logger").BehaviourController.AddBehaviour<LoggerContainer>().Logger = logger;
|
||||||
|
|
||||||
string settingsPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "settings.yaml");
|
string settingsPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "settings.yaml");
|
||||||
ClientConfiguration clientConfiguration = GetOrCreateConfiguration(serializer, logger, settingsPath);
|
ClientConfiguration clientConfiguration;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
clientConfiguration = serializer.Deserialize<ClientConfiguration>(File.ReadAllText(settingsPath));
|
||||||
|
logger.Log(clientConfiguration, $"{settingsPath} read");
|
||||||
|
}
|
||||||
|
catch (Exception exception)
|
||||||
|
{
|
||||||
|
clientConfiguration = new();
|
||||||
|
logger.LogError(serializer, $"Error loading {settingsPath}. Creating new settings file");
|
||||||
|
logger.LogException(serializer, exception);
|
||||||
|
File.WriteAllText(settingsPath, serializer.Serialize(clientConfiguration));
|
||||||
|
}
|
||||||
|
|
||||||
if (clientConfiguration.Host)
|
if (clientConfiguration.Host)
|
||||||
Pong.PongUniverse.ApplyPongServer(universe, clientConfiguration.HostPort);
|
Pong.PongUniverse.ApplyPongServer(universe, clientConfiguration.HostPort);
|
||||||
@ -45,30 +57,3 @@ universe.FindBehaviour<Syntriax.Engine.Network.INetworkCommunicatorClient>()?
|
|||||||
);
|
);
|
||||||
|
|
||||||
monoGameWindow.Run();
|
monoGameWindow.Run();
|
||||||
|
|
||||||
static ClientConfiguration GetOrCreateConfiguration(ISerializer serializer, ILogger logger, string settingsPath)
|
|
||||||
{
|
|
||||||
ClientConfiguration clientConfiguration;
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
clientConfiguration = serializer.Deserialize<ClientConfiguration>(File.ReadAllText(settingsPath));
|
|
||||||
logger.Log(clientConfiguration, $"Configuration is successfully read");
|
|
||||||
}
|
|
||||||
catch (FileNotFoundException)
|
|
||||||
{
|
|
||||||
clientConfiguration = new();
|
|
||||||
logger.Log(clientConfiguration, $"Configuration does not exist");
|
|
||||||
File.WriteAllText(settingsPath, serializer.Serialize(clientConfiguration));
|
|
||||||
}
|
|
||||||
catch (Exception exception)
|
|
||||||
{
|
|
||||||
clientConfiguration = new();
|
|
||||||
logger.LogError(clientConfiguration, $"Error loading configuration");
|
|
||||||
logger.LogException(clientConfiguration, exception);
|
|
||||||
File.WriteAllText(settingsPath, serializer.Serialize(clientConfiguration));
|
|
||||||
}
|
|
||||||
|
|
||||||
logger.Log(clientConfiguration, $"Creating new configuration file at {settingsPath}");
|
|
||||||
return clientConfiguration;
|
|
||||||
}
|
|
||||||
|
@ -8,7 +8,7 @@ Universe universe = new();
|
|||||||
|
|
||||||
FileLogger fileLogger = new($"Logs/{DateTime.UtcNow:yyyy-MM-dd_HH-mm-ss-ffffff}.log");
|
FileLogger fileLogger = new($"Logs/{DateTime.UtcNow:yyyy-MM-dd_HH-mm-ss-ffffff}.log");
|
||||||
universe.InstantiateUniverseObject().SetUniverseObject("Logger").BehaviourController
|
universe.InstantiateUniverseObject().SetUniverseObject("Logger").BehaviourController
|
||||||
.AddBehaviour<LoggerContainer>().Logger = ILogger.Shared = new LoggerWrapper(fileLogger, new ConsoleLogger());
|
.AddBehaviour<LoggerContainer>().Logger = new LoggerWrapper(fileLogger, new ConsoleLogger());
|
||||||
|
|
||||||
Pong.PongUniverse.ApplyPongServer(universe, int.Parse(Environment.GetEnvironmentVariable("PORT") ?? "8888"));
|
Pong.PongUniverse.ApplyPongServer(universe, int.Parse(Environment.GetEnvironmentVariable("PORT") ?? "8888"));
|
||||||
Pong.PongUniverse.ApplyPongUniverse(universe);
|
Pong.PongUniverse.ApplyPongUniverse(universe);
|
||||||
|
@ -1,15 +1,11 @@
|
|||||||
using Microsoft.Xna.Framework.Audio;
|
|
||||||
using Microsoft.Xna.Framework.Content;
|
|
||||||
|
|
||||||
using Syntriax.Engine.Core;
|
using Syntriax.Engine.Core;
|
||||||
using Syntriax.Engine.Integration.MonoGame;
|
|
||||||
using Syntriax.Engine.Network;
|
using Syntriax.Engine.Network;
|
||||||
using Syntriax.Engine.Physics2D;
|
using Syntriax.Engine.Physics2D;
|
||||||
using Syntriax.Engine.Systems.Tween;
|
using Syntriax.Engine.Systems.Tween;
|
||||||
|
|
||||||
namespace Pong.Behaviours;
|
namespace Pong.Behaviours;
|
||||||
|
|
||||||
public class Ball : Behaviour2D, IFirstFrameUpdate, ILoadContent, IPhysicsUpdate, INetworkEntity,
|
public class Ball : Behaviour2D, IFirstFrameUpdate, IPhysicsUpdate, INetworkEntity,
|
||||||
IPacketListenerClient<Ball.BallUpdatePacket>,
|
IPacketListenerClient<Ball.BallUpdatePacket>,
|
||||||
IPacketListenerClient<Ball.BallResetPacket>
|
IPacketListenerClient<Ball.BallResetPacket>
|
||||||
{
|
{
|
||||||
@ -23,8 +19,6 @@ public class Ball : Behaviour2D, IFirstFrameUpdate, ILoadContent, IPhysicsUpdate
|
|||||||
private INetworkCommunicatorServer? networkServer = null;
|
private INetworkCommunicatorServer? networkServer = null;
|
||||||
private ITween? networkTween = null;
|
private ITween? networkTween = null;
|
||||||
|
|
||||||
private SoundEffect? bounceSoundEffect = null;
|
|
||||||
|
|
||||||
public void FirstActiveFrame()
|
public void FirstActiveFrame()
|
||||||
{
|
{
|
||||||
BehaviourController.GetRequiredBehaviour<ICollider2D>().OnCollisionDetected.AddListener(OnCollisionDetected);
|
BehaviourController.GetRequiredBehaviour<ICollider2D>().OnCollisionDetected.AddListener(OnCollisionDetected);
|
||||||
@ -34,11 +28,6 @@ public class Ball : Behaviour2D, IFirstFrameUpdate, ILoadContent, IPhysicsUpdate
|
|||||||
networkServer = Universe.FindBehaviour<INetworkCommunicatorServer>();
|
networkServer = Universe.FindBehaviour<INetworkCommunicatorServer>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void LoadContent(ContentManager content)
|
|
||||||
{
|
|
||||||
bounceSoundEffect = content.Load<SoundEffect>("Audio/Bounce");
|
|
||||||
}
|
|
||||||
|
|
||||||
public void LaunchBall(Vector2D launchDirection)
|
public void LaunchBall(Vector2D launchDirection)
|
||||||
{
|
{
|
||||||
ResetBall();
|
ResetBall();
|
||||||
@ -70,9 +59,7 @@ public class Ball : Behaviour2D, IFirstFrameUpdate, ILoadContent, IPhysicsUpdate
|
|||||||
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);
|
||||||
|
networkServer?.SendToAll(new BallUpdatePacket(this));
|
||||||
if (information.Detected.Transform.BehaviourController.GetBehaviour<ScoreWall>() is null)
|
|
||||||
networkServer?.SendToAll(new BallUpdatePacket(this));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Ball() { }
|
public Ball() { }
|
||||||
@ -87,9 +74,6 @@ public class Ball : Behaviour2D, IFirstFrameUpdate, ILoadContent, IPhysicsUpdate
|
|||||||
else
|
else
|
||||||
Transform.Position = packet.Position;
|
Transform.Position = packet.Position;
|
||||||
|
|
||||||
if (RigidBody.Velocity.MagnitudeSquared >= .01f)
|
|
||||||
bounceSoundEffect?.Play();
|
|
||||||
|
|
||||||
RigidBody.Velocity = packet.Velocity;
|
RigidBody.Velocity = packet.Velocity;
|
||||||
physicsEngine2D.StepIndividual(RigidBody, sender.Ping);
|
physicsEngine2D.StepIndividual(RigidBody, sender.Ping);
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
using Microsoft.Xna.Framework.Content;
|
using Microsoft.Xna.Framework;
|
||||||
using Microsoft.Xna.Framework.Graphics;
|
using Microsoft.Xna.Framework.Graphics;
|
||||||
|
|
||||||
using Syntriax.Engine.Core;
|
using Syntriax.Engine.Core;
|
||||||
@ -6,10 +6,9 @@ using Syntriax.Engine.Integration.MonoGame;
|
|||||||
|
|
||||||
namespace Pong.Behaviours;
|
namespace Pong.Behaviours;
|
||||||
|
|
||||||
public class Label : Behaviour2D, IDrawableSprite, ILoadContent
|
public class Label : Behaviour2D, IDrawableSprite
|
||||||
{
|
{
|
||||||
public SpriteFont? Font { get; set; } = null;
|
public SpriteFont? Font { get; set; } = null;
|
||||||
public ColorRGBA Color { get; set; } = new ColorRGBA(255, 255, 255, 255);
|
|
||||||
public int Size { get; set; } = 16;
|
public int Size { get; set; } = 16;
|
||||||
public string Text { get; set; } = string.Empty;
|
public string Text { get; set; } = string.Empty;
|
||||||
|
|
||||||
@ -18,12 +17,7 @@ public class Label : Behaviour2D, IDrawableSprite, ILoadContent
|
|||||||
if (Font is null)
|
if (Font is null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
spriteBatch.DrawString(Font, Text, Transform.Position, Color.ToPreMultipliedColor(), Transform.Rotation, Vector2D.One * .5f, Transform.Scale.Magnitude, SpriteEffects.None, 0f);
|
spriteBatch.DrawString(Font, Text, Transform.Position, Color.White, Transform.Rotation, Vector2D.One * .5f, Transform.Scale.Magnitude, SpriteEffects.None, 0f);
|
||||||
}
|
|
||||||
|
|
||||||
public void LoadContent(ContentManager content)
|
|
||||||
{
|
|
||||||
Font ??= content.Load<SpriteFont>("UbuntuMono");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Label() { }
|
public Label() { }
|
||||||
|
@ -1,107 +0,0 @@
|
|||||||
using Microsoft.Xna.Framework.Audio;
|
|
||||||
using Microsoft.Xna.Framework.Content;
|
|
||||||
using Microsoft.Xna.Framework.Input;
|
|
||||||
|
|
||||||
using Syntriax.Engine.Core;
|
|
||||||
using Syntriax.Engine.Core.Debug;
|
|
||||||
using Syntriax.Engine.Integration.MonoGame;
|
|
||||||
using Syntriax.Engine.Network;
|
|
||||||
using Syntriax.Engine.Systems.Input;
|
|
||||||
using Syntriax.Engine.Systems.Time;
|
|
||||||
using Syntriax.Engine.Systems.Tween;
|
|
||||||
|
|
||||||
namespace Pong.Behaviours;
|
|
||||||
|
|
||||||
public class PongGameStarter : Behaviour, INetworkEntity, IFirstFrameUpdate, ILoadContent,
|
|
||||||
IPacketListenerServer<PongGameStarter.RequestStartPacket>,
|
|
||||||
IPacketListenerClient<PongGameStarter.RequestStartPacket>
|
|
||||||
{
|
|
||||||
private const float START_COUNTDOWN = 3f;
|
|
||||||
|
|
||||||
private INetworkCommunicatorServer? networkServer = null;
|
|
||||||
private INetworkCommunicatorClient? networkClient = null;
|
|
||||||
private ITweenManager? tweenManager = null;
|
|
||||||
private PongManager pongManager = null!;
|
|
||||||
|
|
||||||
private ILogger? logger = null;
|
|
||||||
|
|
||||||
private Label? label = null;
|
|
||||||
private TickerTimer timer = null!;
|
|
||||||
|
|
||||||
private SoundEffectInstance? tickSoundEffect = null;
|
|
||||||
private SoundEffectInstance? startSoundEffect = null;
|
|
||||||
|
|
||||||
public void FirstActiveFrame()
|
|
||||||
{
|
|
||||||
IButtonInputs<Keys>? buttonInputs = Universe.FindBehaviour<IButtonInputs<Keys>>();
|
|
||||||
buttonInputs?.RegisterOnRelease(Keys.Space, (_, _1) => networkClient?.SendToServer(new RequestStartPacket()));
|
|
||||||
|
|
||||||
networkClient = Universe.FindBehaviour<INetworkCommunicatorClient>();
|
|
||||||
networkServer = Universe.FindBehaviour<INetworkCommunicatorServer>();
|
|
||||||
tweenManager = Universe.FindBehaviour<ITweenManager>();
|
|
||||||
pongManager = BehaviourController.GetRequiredBehaviourInParent<PongManager>();
|
|
||||||
label = BehaviourController.GetRequiredBehaviour<Label>();
|
|
||||||
logger = Universe.FindBehaviour<ILogger>();
|
|
||||||
|
|
||||||
if (!BehaviourController.TryGetBehaviour(out timer!))
|
|
||||||
{
|
|
||||||
timer = BehaviourController.AddBehaviour<TickerTimer>();
|
|
||||||
timer.OnStarted.AddListener(OnCountdownStart);
|
|
||||||
timer.OnTick.AddListener(DisplayCountdown);
|
|
||||||
timer.OnStopped.AddListener(StartPong);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void LoadContent(ContentManager content)
|
|
||||||
{
|
|
||||||
tickSoundEffect = content.Load<SoundEffect>("Audio/TimerTick").CreateInstance();
|
|
||||||
startSoundEffect = content.Load<SoundEffect>("Audio/TimerEnd").CreateInstance();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void OnCountdownStart(IReadOnlyTimer sender)
|
|
||||||
{
|
|
||||||
pongManager.Reset();
|
|
||||||
DisplayCountdown(timer);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void DisplayCountdown(ITicker sender)
|
|
||||||
{
|
|
||||||
tickSoundEffect?.Play();
|
|
||||||
|
|
||||||
if (label != null)
|
|
||||||
{
|
|
||||||
label.Text = $"{START_COUNTDOWN - timer.TickCounter}";
|
|
||||||
label.Color = new ColorRGBA(255, 255, 255, 255);
|
|
||||||
if (tweenManager is not null)
|
|
||||||
label.Color.TweenColor(tweenManager, 1f, new ColorRGBA(255, 255, 255, 0), (x) => label.Color = x);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void StartPong(IReadOnlyTimer sender)
|
|
||||||
{
|
|
||||||
startSoundEffect?.Play();
|
|
||||||
pongManager.Start();
|
|
||||||
}
|
|
||||||
|
|
||||||
void IPacketListenerServer<RequestStartPacket>.OnServerPacketArrived(IConnection sender, RequestStartPacket packet)
|
|
||||||
{
|
|
||||||
logger?.Log(this, $"{sender} requested start");
|
|
||||||
|
|
||||||
if (pongManager.IsGameInProgress)
|
|
||||||
{
|
|
||||||
logger?.Log(this, $"The game is already in progress");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
timer.Start(START_COUNTDOWN);
|
|
||||||
networkServer?.SendToAll(packet);
|
|
||||||
}
|
|
||||||
|
|
||||||
void IPacketListenerClient<RequestStartPacket>.OnClientPacketArrived(IConnection sender, RequestStartPacket packet)
|
|
||||||
{
|
|
||||||
logger?.Log(this, $"Server is starting the game");
|
|
||||||
timer.Start(START_COUNTDOWN - sender.Ping);
|
|
||||||
}
|
|
||||||
|
|
||||||
private class RequestStartPacket : INetworkPacket;
|
|
||||||
}
|
|
@ -1,17 +1,16 @@
|
|||||||
using System;
|
using System;
|
||||||
|
|
||||||
using Microsoft.Xna.Framework.Audio;
|
using Microsoft.Xna.Framework.Input;
|
||||||
using Microsoft.Xna.Framework.Content;
|
|
||||||
|
|
||||||
using Syntriax.Engine.Core;
|
using Syntriax.Engine.Core;
|
||||||
using Syntriax.Engine.Core.Debug;
|
using Syntriax.Engine.Core.Debug;
|
||||||
using Syntriax.Engine.Integration.MonoGame;
|
|
||||||
using Syntriax.Engine.Network;
|
using Syntriax.Engine.Network;
|
||||||
|
using Syntriax.Engine.Systems.Input;
|
||||||
|
|
||||||
namespace Pong.Behaviours;
|
namespace Pong.Behaviours;
|
||||||
|
|
||||||
public class PongManager : Behaviour, INetworkEntity, IFirstFrameUpdate, ILoadContent,
|
public class PongManager : Behaviour, INetworkEntity, IFirstFrameUpdate,
|
||||||
IPacketListenerClient<PongManager.StartPacket>,
|
IPacketListenerServer<PongManager.RequestStartPacket>,
|
||||||
IPacketListenerClient<PongManager.ScorePacket>
|
IPacketListenerClient<PongManager.ScorePacket>
|
||||||
{
|
{
|
||||||
public Action<PongManager>? OnReset { get; set; } = null;
|
public Action<PongManager>? OnReset { get; set; } = null;
|
||||||
@ -19,78 +18,60 @@ public class PongManager : Behaviour, INetworkEntity, IFirstFrameUpdate, ILoadCo
|
|||||||
public Action<PongManager>? OnScoreUpdated { get; set; } = null;
|
public Action<PongManager>? OnScoreUpdated { get; set; } = null;
|
||||||
|
|
||||||
private Random random = new();
|
private Random random = new();
|
||||||
|
private Ball ball = null!;
|
||||||
|
|
||||||
|
private INetworkCommunicatorClient? networkClient = null!;
|
||||||
private INetworkCommunicatorServer? networkServer = null;
|
private INetworkCommunicatorServer? networkServer = null;
|
||||||
private ILogger? logger = null;
|
private ILogger? logger = null;
|
||||||
private SoundEffectInstance? scoreSoundEffect = null;
|
|
||||||
private SoundEffectInstance? gameEndSoundEffect = 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;
|
||||||
|
|
||||||
public int WinScore { get; } = 5;
|
public int WinScore { get; } = 5;
|
||||||
public Ball Ball { get; private set; } = null!;
|
|
||||||
public bool IsGameInProgress { get; private set; } = false;
|
|
||||||
|
|
||||||
public PongManager() => WinScore = 5;
|
public PongManager() => WinScore = 5;
|
||||||
public PongManager(int winScore) => WinScore = winScore;
|
public PongManager(int winScore) => WinScore = winScore;
|
||||||
|
|
||||||
public void FirstActiveFrame()
|
public void FirstActiveFrame()
|
||||||
{
|
{
|
||||||
Ball = Universe.FindRequiredBehaviour<Ball>();
|
IButtonInputs<Keys>? buttonInputs = Universe.FindBehaviour<IButtonInputs<Keys>>();
|
||||||
|
buttonInputs?.RegisterOnRelease(Keys.Space, (_, _1) => networkClient?.SendToServer(new RequestStartPacket()));
|
||||||
|
|
||||||
|
ball = Universe.FindRequiredBehaviour<Ball>();
|
||||||
|
networkClient = Universe.FindBehaviour<INetworkCommunicatorClient>();
|
||||||
networkServer = Universe.FindBehaviour<INetworkCommunicatorServer>();
|
networkServer = Universe.FindBehaviour<INetworkCommunicatorServer>();
|
||||||
logger = Universe.FindBehaviour<ILogger>();
|
logger = Universe.FindBehaviour<ILogger>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void LoadContent(ContentManager content)
|
|
||||||
{
|
|
||||||
gameEndSoundEffect = content.Load<SoundEffect>("Audio/Win").CreateInstance();
|
|
||||||
scoreSoundEffect = content.Load<SoundEffect>("Audio/Score").CreateInstance();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void ScoreToLeft()
|
public void ScoreToLeft()
|
||||||
{
|
{
|
||||||
ScoreLeft++;
|
ScoreLeft++;
|
||||||
|
OnScoreUpdated?.Invoke(this);
|
||||||
|
|
||||||
PostScoreUpdate();
|
PostScoreUpdate();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ScoreToRight()
|
public void ScoreToRight()
|
||||||
{
|
{
|
||||||
ScoreRight++;
|
ScoreRight++;
|
||||||
|
OnScoreUpdated?.Invoke(this);
|
||||||
|
|
||||||
PostScoreUpdate();
|
PostScoreUpdate();
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool Start()
|
|
||||||
{
|
|
||||||
if (networkServer is null)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (Ball.RigidBody.Velocity.MagnitudeSquared > 0.01f)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
Reset();
|
|
||||||
IsGameInProgress = true;
|
|
||||||
PostScoreUpdate();
|
|
||||||
networkServer.SendToAll(new StartPacket());
|
|
||||||
logger?.Log(this, $"Game started");
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Reset()
|
public void Reset()
|
||||||
{
|
{
|
||||||
ScoreLeft = ScoreRight = 0;
|
ScoreLeft = ScoreRight = 0;
|
||||||
IsGameInProgress = false;
|
|
||||||
|
|
||||||
Ball.ResetBall();
|
PostScoreUpdate();
|
||||||
|
|
||||||
OnReset?.Invoke(this);
|
OnReset?.Invoke(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void PostScoreUpdate()
|
private void PostScoreUpdate()
|
||||||
{
|
{
|
||||||
OnScoreUpdated?.Invoke(this);
|
ball.ResetBall();
|
||||||
Ball.ResetBall();
|
|
||||||
|
|
||||||
if (networkServer is not null)
|
if (networkServer is not null)
|
||||||
{
|
{
|
||||||
@ -101,14 +82,12 @@ public class PongManager : Behaviour, INetworkEntity, IFirstFrameUpdate, ILoadCo
|
|||||||
int halfwayScore = (int)(WinScore * .5f);
|
int halfwayScore = (int)(WinScore * .5f);
|
||||||
if (ScoreLeft > halfwayScore || ScoreRight > halfwayScore)
|
if (ScoreLeft > halfwayScore || ScoreRight > halfwayScore)
|
||||||
{
|
{
|
||||||
IsGameInProgress = false;
|
|
||||||
gameEndSoundEffect?.Play();
|
|
||||||
OnFinished?.Invoke(this);
|
OnFinished?.Invoke(this);
|
||||||
logger?.Log(this, $"Game finished: {ScoreLeft} - {ScoreRight}");
|
logger?.Log(this, $"Game finished");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ball.LaunchBall(GetBallLaunchDirection());
|
ball.LaunchBall(GetBallLaunchDirection());
|
||||||
}
|
}
|
||||||
|
|
||||||
private Vector2D GetBallLaunchDirection()
|
private Vector2D GetBallLaunchDirection()
|
||||||
@ -124,21 +103,22 @@ public class PongManager : Behaviour, INetworkEntity, IFirstFrameUpdate, ILoadCo
|
|||||||
ScoreLeft = packet.Left;
|
ScoreLeft = packet.Left;
|
||||||
ScoreRight = packet.Right;
|
ScoreRight = packet.Right;
|
||||||
|
|
||||||
PostScoreUpdate();
|
OnScoreUpdated?.Invoke(this);
|
||||||
|
|
||||||
if (IsGameInProgress && (ScoreLeft != 0 || ScoreRight != 0))
|
|
||||||
scoreSoundEffect?.Play();
|
|
||||||
|
|
||||||
logger?.Log(this, $"Client score update packet arrived: {packet.Left} - {packet.Right}");
|
logger?.Log(this, $"Client score update packet arrived: {packet.Left} - {packet.Right}");
|
||||||
}
|
}
|
||||||
|
|
||||||
void IPacketListenerClient<StartPacket>.OnClientPacketArrived(IConnection sender, StartPacket packet)
|
void IPacketListenerServer<RequestStartPacket>.OnServerPacketArrived(IConnection sender, RequestStartPacket packet)
|
||||||
{
|
{
|
||||||
IsGameInProgress = true;
|
logger?.Log(this, $"{sender} requested start");
|
||||||
|
if (ball.RigidBody.Velocity.MagnitudeSquared > 0.01f)
|
||||||
|
return;
|
||||||
|
|
||||||
|
Reset();
|
||||||
|
ball.LaunchBall(GetBallLaunchDirection());
|
||||||
logger?.Log(this, $"Game started");
|
logger?.Log(this, $"Game started");
|
||||||
}
|
}
|
||||||
|
|
||||||
private class StartPacket : INetworkPacket;
|
private class RequestStartPacket : INetworkPacket;
|
||||||
private class ScorePacket : INetworkPacket
|
private class ScorePacket : INetworkPacket
|
||||||
{
|
{
|
||||||
public int Left { get; set; }
|
public int Left { get; set; }
|
||||||
|
@ -1,4 +1,7 @@
|
|||||||
|
using Microsoft.Xna.Framework.Graphics;
|
||||||
|
|
||||||
using Syntriax.Engine.Core;
|
using Syntriax.Engine.Core;
|
||||||
|
using Syntriax.Engine.Integration.MonoGame;
|
||||||
|
|
||||||
namespace Pong.Behaviours;
|
namespace Pong.Behaviours;
|
||||||
|
|
||||||
@ -10,6 +13,9 @@ public class ScoreLabel(bool IsLeft) : Label, IFirstFrameUpdate
|
|||||||
|
|
||||||
public void FirstActiveFrame()
|
public void FirstActiveFrame()
|
||||||
{
|
{
|
||||||
|
MonoGameWindow monoGameWindow = Universe.FindRequiredBehaviour<MonoGameWindowContainer>().Window;
|
||||||
|
Font = monoGameWindow.Content.Load<SpriteFont>("UbuntuMono");
|
||||||
|
|
||||||
pongManager = Universe.FindRequiredBehaviour<PongManager>();
|
pongManager = Universe.FindRequiredBehaviour<PongManager>();
|
||||||
|
|
||||||
pongManager.OnScoreUpdated += UpdateScores;
|
pongManager.OnScoreUpdated += UpdateScores;
|
||||||
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -13,36 +13,6 @@
|
|||||||
|
|
||||||
#---------------------------------- Content ---------------------------------#
|
#---------------------------------- Content ---------------------------------#
|
||||||
|
|
||||||
#begin Audio/Bounce.wav
|
|
||||||
/importer:WavImporter
|
|
||||||
/processor:SoundEffectProcessor
|
|
||||||
/processorParam:Quality=Best
|
|
||||||
/build:Audio/Bounce.wav
|
|
||||||
|
|
||||||
#begin Audio/Score.wav
|
|
||||||
/importer:WavImporter
|
|
||||||
/processor:SoundEffectProcessor
|
|
||||||
/processorParam:Quality=Best
|
|
||||||
/build:Audio/Score.wav
|
|
||||||
|
|
||||||
#begin Audio/Win.wav
|
|
||||||
/importer:WavImporter
|
|
||||||
/processor:SoundEffectProcessor
|
|
||||||
/processorParam:Quality=Best
|
|
||||||
/build:Audio/Win.wav
|
|
||||||
|
|
||||||
#begin Audio/TimerTick.wav
|
|
||||||
/importer:WavImporter
|
|
||||||
/processor:SoundEffectProcessor
|
|
||||||
/processorParam:Quality=Best
|
|
||||||
/build:Audio/TimerTick.wav
|
|
||||||
|
|
||||||
#begin Audio/TimerEnd.wav
|
|
||||||
/importer:WavImporter
|
|
||||||
/processor:SoundEffectProcessor
|
|
||||||
/processorParam:Quality=Best
|
|
||||||
/build:Audio/TimerEnd.wav
|
|
||||||
|
|
||||||
#begin UbuntuMono.spritefont
|
#begin UbuntuMono.spritefont
|
||||||
/importer:FontDescriptionImporter
|
/importer:FontDescriptionImporter
|
||||||
/processor:FontDescriptionProcessor
|
/processor:FontDescriptionProcessor
|
||||||
|
@ -66,11 +66,6 @@ public static class PongUniverse
|
|||||||
PongManager pongManager = universe.InstantiateUniverseObject().SetUniverseObject("Pong Game Manager")
|
PongManager pongManager = universe.InstantiateUniverseObject().SetUniverseObject("Pong Game Manager")
|
||||||
.BehaviourController.AddBehaviour<PongManager>(5);
|
.BehaviourController.AddBehaviour<PongManager>(5);
|
||||||
|
|
||||||
universe.InstantiateUniverseObject().SetUniverseObject("Pong Game Starter", parent: pongManager.UniverseObject)
|
|
||||||
.BehaviourController.AddBehaviour<PongGameStarter>()
|
|
||||||
.BehaviourController.AddBehaviour<Transform2D>().SetTransform(position: new Vector2D(-24, 250f), scale: Vector2D.One * .5f)
|
|
||||||
.BehaviourController.AddBehaviour<Label>();
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
universe.InstantiateUniverseObject().SetUniverseObject("Ball")
|
universe.InstantiateUniverseObject().SetUniverseObject("Ball")
|
||||||
|
Loading…
x
Reference in New Issue
Block a user