feat: ball networking
This commit is contained in:
parent
f20aabcacf
commit
cbda44c2d5
2
Engine
2
Engine
@ -1 +1 @@
|
||||
Subproject commit 8f8558a262a20d584afd38369b02c4c50d86b20f
|
||||
Subproject commit feb2a05aa3e0683b62f7a306ab73df0def060dda
|
@ -1,49 +1,84 @@
|
||||
using Syntriax.Engine.Core;
|
||||
using Syntriax.Engine.Network;
|
||||
using Syntriax.Engine.Physics2D;
|
||||
using Syntriax.Engine.Systems.Tween;
|
||||
|
||||
namespace Pong.Behaviours;
|
||||
|
||||
public class BallBehaviour : Behaviour2D
|
||||
public class BallBehaviour : Behaviour2D, IPhysicsUpdate, INetworkEntity,
|
||||
IPacketListenerClient<BallBehaviour.BallUpdatePacket>
|
||||
{
|
||||
public float Speed { get; set; } = 500f;
|
||||
public float SpeedUpMultiplier { get; set; } = .0125f;
|
||||
|
||||
public IRigidBody2D rigidBody = null!;
|
||||
public IRigidBody2D RigidBody { get; private set; } = null!;
|
||||
|
||||
private IPhysicsEngine2D physicsEngine2D = null!;
|
||||
private ITweenManager tweenManager = null!;
|
||||
private INetworkCommunicatorServer? networkServer = null;
|
||||
|
||||
protected override void OnFirstActiveFrame()
|
||||
{
|
||||
BehaviourController.GetRequiredBehaviour<ICollider2D>().OnCollisionDetected += OnCollisionDetected;
|
||||
rigidBody = BehaviourController.GetRequiredBehaviour<IRigidBody2D>();
|
||||
physicsEngine2D = Universe.GetRequiredUniverseObject<IPhysicsEngine2D>();
|
||||
tweenManager = Universe.GetRequiredUniverseObject<ITweenManager>();
|
||||
RigidBody = BehaviourController.GetRequiredBehaviour<IRigidBody2D>();
|
||||
networkServer = Universe.Find<INetworkCommunicatorServer>();
|
||||
}
|
||||
|
||||
public void LaunchBall(Vector2D launchDirection)
|
||||
{
|
||||
rigidBody.Velocity = launchDirection * Speed;
|
||||
ResetBall();
|
||||
RigidBody.Velocity = launchDirection * Speed;
|
||||
networkServer?.SendToClient("*", new BallUpdatePacket(this));
|
||||
}
|
||||
|
||||
public void ResetBall()
|
||||
{
|
||||
Transform.Position = Vector2D.Zero;
|
||||
rigidBody.Velocity = Vector2D.Zero;
|
||||
RigidBody.Velocity = Vector2D.Zero;
|
||||
}
|
||||
|
||||
protected override void OnUpdate()
|
||||
public void PhysicsUpdate(float delta)
|
||||
{
|
||||
if (rigidBody.Velocity.MagnitudeSquared <= 0.01f)
|
||||
if (RigidBody.Velocity.MagnitudeSquared <= 0.01f)
|
||||
return;
|
||||
|
||||
Vector2D speedUp = rigidBody.Velocity.Normalized * Universe.Time.DeltaTime;
|
||||
rigidBody.Velocity += speedUp * SpeedUpMultiplier;
|
||||
Vector2D direction = RigidBody.Velocity.Normalized;
|
||||
RigidBody.Velocity += direction * delta * SpeedUpMultiplier;
|
||||
}
|
||||
|
||||
private void OnCollisionDetected(ICollider2D collider2D, CollisionDetectionInformation information)
|
||||
{
|
||||
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
|
||||
rigidBody.Velocity = rigidBody.Velocity.Reflect(information.Normal);
|
||||
RigidBody.Velocity = RigidBody.Velocity.Reflect(information.Normal);
|
||||
networkServer?.SendToClient("*", new BallUpdatePacket(this));
|
||||
}
|
||||
|
||||
public BallBehaviour() { }
|
||||
public BallBehaviour(float speed) => Speed = speed;
|
||||
|
||||
void IPacketListenerClient<BallUpdatePacket>.OnClientPacketArrived(BallUpdatePacket packet)
|
||||
{
|
||||
Transform.TweenPositionAdditive(tweenManager, .25f, Transform.Position.FromTo(packet.Position));
|
||||
RigidBody.Velocity = packet.Velocity;
|
||||
physicsEngine2D.StepIndividual(RigidBody, new System.DateTime(System.DateTime.UtcNow.Ticks - packet.Timestamp).Second);
|
||||
}
|
||||
|
||||
private class BallUpdatePacket : INetworkPacket
|
||||
{
|
||||
public Vector2D Position { get; set; } = Vector2D.Zero;
|
||||
public Vector2D Velocity { get; set; } = Vector2D.Zero;
|
||||
public long Timestamp { get; set; } = 0;
|
||||
|
||||
public BallUpdatePacket() { }
|
||||
public BallUpdatePacket(BallBehaviour ballBehaviour)
|
||||
{
|
||||
Position = ballBehaviour.Transform.Position;
|
||||
Velocity = ballBehaviour.RigidBody.Velocity;
|
||||
Timestamp = System.DateTime.UtcNow.Ticks;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -8,7 +8,8 @@ using Syntriax.Engine.Systems.Input;
|
||||
|
||||
namespace Pong.Behaviours;
|
||||
|
||||
public class PongManagerBehaviour : Behaviour
|
||||
public class PongManagerBehaviour : Behaviour, INetworkEntity,
|
||||
IPacketListenerServer<PongManagerBehaviour.RequestStartPacket>
|
||||
{
|
||||
public Action<PongManagerBehaviour>? OnReset { get; set; } = null;
|
||||
public Action<PongManagerBehaviour>? OnFinished { get; set; } = null;
|
||||
@ -32,7 +33,7 @@ public class PongManagerBehaviour : Behaviour
|
||||
protected override void OnFirstActiveFrame()
|
||||
{
|
||||
IButtonInputs<Keys> buttonInputs = Universe.FindRequired<IButtonInputs<Keys>>();
|
||||
buttonInputs.RegisterOnRelease(Keys.Space, (_, _1) => Reset());
|
||||
buttonInputs.RegisterOnRelease(Keys.Space, (_, _1) => networkClient?.SendToServer(new RequestStartPacket()));
|
||||
|
||||
ball = Universe.FindRequiredBehaviour<BallBehaviour>();
|
||||
networkClient = Universe.Find<INetworkCommunicatorClient>();
|
||||
@ -87,4 +88,14 @@ public class PongManagerBehaviour : Behaviour
|
||||
bool isBackwards = (random.Next() % 2) == 1;
|
||||
return Vector2D.Right.Rotate(isBackwards ? rotation + Syntriax.Engine.Core.Math.PI : rotation);
|
||||
}
|
||||
|
||||
void IPacketListenerServer<RequestStartPacket>.OnServerPacketArrived(RequestStartPacket packet, string from)
|
||||
{
|
||||
if (ball.RigidBody.Velocity.MagnitudeSquared > 0.01f)
|
||||
return;
|
||||
|
||||
ball.LaunchBall(GetBallLaunchDirection());
|
||||
}
|
||||
|
||||
private class RequestStartPacket : INetworkPacket;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user