108 lines
3.7 KiB
C#
108 lines
3.7 KiB
C#
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;
|
|
}
|