85 lines
3.2 KiB
C#
85 lines
3.2 KiB
C#
using Syntriax.Engine.Core;
|
|
using Syntriax.Engine.Network;
|
|
using Syntriax.Engine.Physics2D;
|
|
using Syntriax.Engine.Systems.Tween;
|
|
|
|
namespace Pong.Behaviours;
|
|
|
|
public class BallBehaviour : Behaviour2D, IFirstFrameUpdate, IPhysicsUpdate, INetworkEntity,
|
|
IPacketListenerClient<BallBehaviour.BallUpdatePacket>
|
|
{
|
|
public float Speed { get; set; } = 500f;
|
|
public float SpeedUpMultiplier { get; set; } = .0125f;
|
|
|
|
public IRigidBody2D RigidBody { get; private set; } = null!;
|
|
|
|
private IPhysicsEngine2D physicsEngine2D = null!;
|
|
private ITweenManager tweenManager = null!;
|
|
private INetworkCommunicatorServer? networkServer = null;
|
|
|
|
public void FirstActiveFrame()
|
|
{
|
|
BehaviourController.GetRequiredBehaviour<ICollider2D>().OnCollisionDetected.AddListener(OnCollisionDetected);
|
|
physicsEngine2D = Universe.FindRequiredBehaviour<IPhysicsEngine2D>();
|
|
tweenManager = Universe.FindRequiredBehaviour<ITweenManager>();
|
|
RigidBody = BehaviourController.GetRequiredBehaviour<IRigidBody2D>();
|
|
networkServer = Universe.FindBehaviour<INetworkCommunicatorServer>();
|
|
}
|
|
|
|
public void LaunchBall(Vector2D launchDirection)
|
|
{
|
|
ResetBall();
|
|
RigidBody.Velocity = launchDirection * Speed;
|
|
networkServer?.SendToClient("*", new BallUpdatePacket(this));
|
|
}
|
|
|
|
public void ResetBall()
|
|
{
|
|
Transform.Position = Vector2D.Zero;
|
|
RigidBody.Velocity = Vector2D.Zero;
|
|
}
|
|
|
|
public void PhysicsUpdate(float delta)
|
|
{
|
|
if (RigidBody.Velocity.MagnitudeSquared <= 0.01f)
|
|
return;
|
|
|
|
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;
|
|
else
|
|
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;
|
|
}
|
|
}
|
|
}
|