feat: ball networking
This commit is contained in:
		
							
								
								
									
										2
									
								
								Engine
									
									
									
									
									
								
							
							
								
								
								
								
								
							
						
						
									
										2
									
								
								Engine
									
									
									
									
									
								
							 Submodule Engine updated: 8f8558a262...feb2a05aa3
									
								
							@@ -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;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user