117 lines
4.6 KiB
C#
117 lines
4.6 KiB
C#
using System;
|
|
|
|
using Microsoft.Xna.Framework.Input;
|
|
|
|
using Syntriax.Engine.Core;
|
|
using Syntriax.Engine.Network;
|
|
using Syntriax.Engine.Physics2D;
|
|
using Syntriax.Engine.Systems.Input;
|
|
|
|
namespace Pong.Behaviours;
|
|
|
|
public class PaddleBehaviour(Keys Up, Keys Down, float High, float Low, float Speed) : Behaviour2D, IFirstFrameUpdate, IPostPhysicsUpdate,
|
|
IPacketListenerServer<PaddleBehaviour.PaddleKeyStatePacket>, IPacketListenerClient<PaddleBehaviour.PaddleKeyStatePacket>
|
|
{
|
|
private Keys Up { get; } = Up;
|
|
private Keys Down { get; } = Down;
|
|
public float High { get; } = High;
|
|
public float Low { get; } = Low;
|
|
public float Speed { get; set; } = Speed;
|
|
|
|
private bool isUpPressed = false;
|
|
private bool isDownPressed = false;
|
|
|
|
private IButtonInputs<Keys> inputs = null!;
|
|
private INetworkCommunicatorClient? networkClient = null!;
|
|
private INetworkCommunicatorServer? networkServer = null;
|
|
private IRigidBody2D rigidBody = null!;
|
|
private IPhysicsEngine2D physicsEngine2D = null!;
|
|
|
|
public void PostPhysicsUpdate(float delta)
|
|
{
|
|
Transform.Position = new Vector2D(Transform.Position.X, MathF.Max(MathF.Min(Transform.Position.Y, High), Low));
|
|
}
|
|
|
|
public void FirstActiveFrame()
|
|
{
|
|
physicsEngine2D = Universe.GetRequiredUniverseObject<IPhysicsEngine2D>();
|
|
inputs = Universe.FindRequired<IButtonInputs<Keys>>();
|
|
networkClient = Universe.Find<INetworkCommunicatorClient>();
|
|
networkServer = Universe.Find<INetworkCommunicatorServer>();
|
|
rigidBody = BehaviourController.GetRequiredBehaviour<IRigidBody2D>();
|
|
|
|
inputs.RegisterOnPress(Up, OnUpPressed);
|
|
inputs.RegisterOnRelease(Up, OnUpReleased);
|
|
|
|
inputs.RegisterOnPress(Down, OnDownPressed);
|
|
inputs.RegisterOnRelease(Down, OnDownReleased);
|
|
}
|
|
|
|
protected override void OnFinalize()
|
|
{
|
|
inputs.UnregisterOnPress(Up, OnUpPressed);
|
|
inputs.UnregisterOnRelease(Up, OnUpReleased);
|
|
|
|
inputs.UnregisterOnPress(Down, OnDownPressed);
|
|
inputs.UnregisterOnRelease(Down, OnDownReleased);
|
|
}
|
|
|
|
private void OnUpPressed(IButtonInputs<Keys> sender, IButtonInputs<Keys>.ButtonCallbackArguments args) { isUpPressed = true; UpdateVelocity(); networkClient?.SendToServer(new PaddleKeyStatePacket(this)); }
|
|
private void OnUpReleased(IButtonInputs<Keys> sender, IButtonInputs<Keys>.ButtonCallbackArguments args) { isUpPressed = false; UpdateVelocity(); networkClient?.SendToServer(new PaddleKeyStatePacket(this)); }
|
|
private void OnDownPressed(IButtonInputs<Keys> sender, IButtonInputs<Keys>.ButtonCallbackArguments args) { isDownPressed = true; UpdateVelocity(); networkClient?.SendToServer(new PaddleKeyStatePacket(this)); }
|
|
private void OnDownReleased(IButtonInputs<Keys> sender, IButtonInputs<Keys>.ButtonCallbackArguments args) { isDownPressed = false; UpdateVelocity(); networkClient?.SendToServer(new PaddleKeyStatePacket(this)); }
|
|
|
|
private void UpdateVelocity()
|
|
{
|
|
if (isUpPressed)
|
|
rigidBody.Velocity = Vector2D.Up * Speed;
|
|
else if (isDownPressed)
|
|
rigidBody.Velocity = -Vector2D.Up * Speed;
|
|
else
|
|
rigidBody.Velocity = Vector2D.Zero;
|
|
}
|
|
|
|
public void OnServerPacketArrived(string sender, PaddleKeyStatePacket packet)
|
|
{
|
|
isUpPressed = packet.IsUpPressed;
|
|
isDownPressed = packet.IsDownPressed;
|
|
UpdateVelocity();
|
|
|
|
networkServer?.SendToClient("*", new PaddleKeyStatePacket(this));
|
|
}
|
|
|
|
public void OnClientPacketArrived(PaddleKeyStatePacket packet)
|
|
{
|
|
isUpPressed = packet.IsUpPressed;
|
|
isDownPressed = packet.IsDownPressed;
|
|
Transform.Position = packet.Position;
|
|
|
|
UpdateVelocity();
|
|
|
|
physicsEngine2D.StepIndividual(rigidBody, new DateTime(DateTime.UtcNow.Ticks - packet.Timestamp).Second);
|
|
}
|
|
|
|
public class PaddleKeyStatePacket : IEntityNetworkPacket
|
|
{
|
|
public string EntityId { get; set; } = default!;
|
|
public Vector2D Position { get; set; } = default!;
|
|
public bool IsUpPressed { get; set; } = default!;
|
|
public bool IsDownPressed { get; set; } = default!;
|
|
public long Timestamp { get; set; } = 0;
|
|
|
|
public PaddleKeyStatePacket Set(PaddleBehaviour paddleBehaviour)
|
|
{
|
|
EntityId = paddleBehaviour.Id;
|
|
Position = paddleBehaviour.Transform.Position;
|
|
IsUpPressed = paddleBehaviour.isUpPressed;
|
|
IsDownPressed = paddleBehaviour.isDownPressed;
|
|
Timestamp = DateTime.UtcNow.Ticks;
|
|
|
|
return this;
|
|
}
|
|
|
|
public PaddleKeyStatePacket() { }
|
|
public PaddleKeyStatePacket(PaddleBehaviour paddleBehaviour) => Set(paddleBehaviour);
|
|
}
|
|
}
|