chore: updated engine to use MonoGame integrations

This commit is contained in:
2025-06-01 18:37:59 +03:00
committed by Syntriax
parent 1ff26f5be4
commit 29df4a36e9
21 changed files with 154 additions and 320 deletions

View File

@@ -5,7 +5,7 @@ using Syntriax.Engine.Systems.Tween;
namespace Pong.Behaviours;
public class BallBehaviour : Behaviour2D, IPhysicsUpdate, INetworkEntity,
public class BallBehaviour : Behaviour2D, IFirstFrameUpdate, IPhysicsUpdate, INetworkEntity,
IPacketListenerClient<BallBehaviour.BallUpdatePacket>
{
public float Speed { get; set; } = 500f;
@@ -17,7 +17,7 @@ public class BallBehaviour : Behaviour2D, IPhysicsUpdate, INetworkEntity,
private ITweenManager tweenManager = null!;
private INetworkCommunicatorServer? networkServer = null;
protected override void OnFirstActiveFrame()
public void FirstActiveFrame()
{
BehaviourController.GetRequiredBehaviour<ICollider2D>().OnCollisionDetected.AddListener(OnCollisionDetected);
physicsEngine2D = Universe.GetRequiredUniverseObject<IPhysicsEngine2D>();

View File

@@ -1,27 +1,28 @@
using Microsoft.Xna.Framework.Input;
using Syntriax.Engine.Core;
using Syntriax.Engine.Integration.MonoGame;
using Syntriax.Engine.Systems.Input;
namespace Pong.Behaviours;
public class CameraController : Behaviour
public class CameraController : Behaviour, IFirstFrameUpdate, IUpdate
{
private MonoGameCamera2DBehaviour cameraBehaviour = null!;
private IButtonInputs<Keys> buttonInputs = null!;
private float defaultZoomLevel = 1f;
protected override void OnFirstActiveFrame()
public void FirstActiveFrame()
{
cameraBehaviour ??= BehaviourController.GetRequiredBehaviour<MonoGameCamera2DBehaviour>();
cameraBehaviour = BehaviourController.GetRequiredBehaviour<MonoGameCamera2DBehaviour>();
buttonInputs = Universe.FindRequiredBehaviour<IButtonInputs<Keys>>();
buttonInputs.RegisterOnPress(Keys.F, SwitchToFullScreen);
buttonInputs.RegisterOnPress(Keys.R, ResetCamera);
}
protected override void OnUpdate()
public void Update()
{
if (buttonInputs.IsPressed(Keys.U))
cameraBehaviour.Zoom += Universe.Time.DeltaTime * 5f;

View File

@@ -6,7 +6,7 @@ using Syntriax.Engine.Core;
namespace Pong.Behaviours;
public class CircleBehaviour : Syntriax.Engine.Physics2D.Collider2DCircleBehaviour, IDisplayableShape
public class CircleBehaviour : Syntriax.Engine.Physics2D.Collider2DCircleBehaviour, IDrawableShape
{
public Color Color { get; set; } = Color.White;
public float Thickness { get; set; } = .5f;

View File

@@ -1,101 +0,0 @@
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Syntriax.Engine.Core;
namespace Pong.Behaviours;
public class MonoGameCamera2DBehaviour(GraphicsDeviceManager Graphics) : Behaviour2D, ICamera2D
{
public event OnMatrixTransformChangedDelegate? OnMatrixTransformChanged = null;
public event OnViewportChangedDelegate? OnViewportChanged = null;
public event OnZoomChangedDelegate? OnZoomChanged = null;
private Matrix _matrixTransform = Matrix.Identity;
private Viewport _viewport = default;
private float _zoom = 1f;
public GraphicsDeviceManager Graphics { get; } = Graphics;
public Matrix MatrixTransform
{
get => _matrixTransform;
set
{
if (_matrixTransform == value)
return;
_matrixTransform = value;
OnMatrixTransformChanged?.Invoke(this);
}
}
public Vector2D Position
{
get => Transform.Position;
set => Transform.Position = value;
}
public Viewport Viewport
{
get => _viewport;
set
{
if (_viewport.Equals(value))
return;
_viewport = value;
OnViewportChanged?.Invoke(this);
}
}
public float Zoom
{
get => _zoom;
set
{
float newValue = Math.Max(0.1f, value);
if (_zoom == newValue)
return;
_zoom = newValue;
OnZoomChanged?.Invoke(this);
}
}
public float Rotation
{
get => Transform.Rotation;
set => Transform.Rotation = value;
}
// TODO This causes delay since OnPreDraw calls assuming this is called in in Update
public Vector2D ScreenToWorldPosition(Vector2D screenPosition)
{
Vector2D worldPosition = Vector2.Transform(screenPosition.ToVector2(), Matrix.Invert(MatrixTransform)).ToVector2D();
return worldPosition.Scale(EngineConverter.screenScale);
}
public Vector2D WorldToScreenPosition(Vector2D worldPosition)
{
Vector2D screenPosition = Vector2.Transform(worldPosition.ToVector2(), MatrixTransform).ToVector2D();
return screenPosition.Scale(EngineConverter.screenScale);
}
protected override void OnFirstActiveFrame()
=> Viewport = Graphics.GraphicsDevice.Viewport;
protected override void OnPreDraw()
{
MatrixTransform =
Matrix.CreateTranslation(new Vector3(-Position.X, Position.Y, 0f)) *
Matrix.CreateRotationZ(Rotation * Math.DegreeToRadian) *
Matrix.CreateScale(Zoom) *
Matrix.CreateTranslation(new Vector3(_viewport.Width * .5f, _viewport.Height * .5f, 0f));
}
public delegate void OnMatrixTransformChangedDelegate(MonoGameCamera2DBehaviour sender);
public delegate void OnViewportChangedDelegate(MonoGameCamera2DBehaviour sender);
public delegate void OnZoomChangedDelegate(MonoGameCamera2DBehaviour sender);
}

View File

@@ -3,7 +3,7 @@ using Syntriax.Engine.Physics2D;
namespace Pong.Behaviours;
public class MovementBallBehaviour : Behaviour2D
public class MovementBallBehaviour : Behaviour2D, IFirstFrameUpdate, IUpdate
{
public Vector2D StartDirection { get; private set; } = Vector2D.Zero;
public float Speed { get; set; } = 500f;
@@ -11,7 +11,7 @@ public class MovementBallBehaviour : Behaviour2D
private IRigidBody2D rigidBody = null!;
protected override void OnFirstActiveFrame()
public void FirstActiveFrame()
{
rigidBody = BehaviourController.GetRequiredBehaviour<IRigidBody2D>();
@@ -19,7 +19,7 @@ public class MovementBallBehaviour : Behaviour2D
BehaviourController.GetRequiredBehaviour<ICollider2D>().OnCollisionDetected.AddListener(OnCollisionDetected);
}
protected override void OnUpdate()
public void Update()
{
if (rigidBody.Velocity.MagnitudeSquared <= 0.01f)
return;

View File

@@ -9,7 +9,7 @@ using Syntriax.Engine.Systems.Input;
namespace Pong.Behaviours;
public class PaddleBehaviour(Keys Up, Keys Down, float High, float Low, float Speed) : Behaviour2D, IPostPhysicsUpdate,
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;
@@ -32,7 +32,7 @@ public class PaddleBehaviour(Keys Up, Keys Down, float High, float Low, float Sp
Transform.Position = new Vector2D(Transform.Position.X, MathF.Max(MathF.Min(Transform.Position.Y, High), Low));
}
protected override void OnFirstActiveFrame()
public void FirstActiveFrame()
{
physicsEngine2D = Universe.GetRequiredUniverseObject<IPhysicsEngine2D>();
inputs = Universe.FindRequired<IButtonInputs<Keys>>();
@@ -99,14 +99,18 @@ public class PaddleBehaviour(Keys Up, Keys Down, float High, float Low, float Sp
public bool IsDownPressed { get; set; } = default!;
public long Timestamp { get; set; } = 0;
public PaddleKeyStatePacket() { }
public PaddleKeyStatePacket(PaddleBehaviour paddleBehaviour)
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);
}
}

View File

@@ -8,7 +8,7 @@ using Syntriax.Engine.Systems.Input;
namespace Pong.Behaviours;
public class PongManagerBehaviour : Behaviour, INetworkEntity,
public class PongManagerBehaviour : Behaviour, INetworkEntity, IFirstFrameUpdate,
IPacketListenerServer<PongManagerBehaviour.RequestStartPacket>
{
public Action<PongManagerBehaviour>? OnReset { get; set; } = null;
@@ -30,7 +30,7 @@ public class PongManagerBehaviour : Behaviour, INetworkEntity,
public PongManagerBehaviour() => WinScore = 5;
public PongManagerBehaviour(int winScore) => WinScore = winScore;
protected override void OnFirstActiveFrame()
public void FirstActiveFrame()
{
IButtonInputs<Keys> buttonInputs = Universe.FindRequired<IButtonInputs<Keys>>();
buttonInputs.RegisterOnRelease(Keys.Space, (_, _1) => networkClient?.SendToServer(new RequestStartPacket()));

View File

@@ -8,7 +8,7 @@ using Syntriax.Engine.Systems.Input;
namespace Pong.Behaviours;
public class ShapeAABBBehaviour : Behaviour2D, IDisplayableShape
public class ShapeAABBBehaviour : Behaviour2D, IDrawableShape, IFirstFrameUpdate
{
private IShapeCollider2D? shapeCollider = null;
@@ -16,7 +16,7 @@ public class ShapeAABBBehaviour : Behaviour2D, IDisplayableShape
public float Thickness { get; set; } = .5f;
public bool display = true;
protected override void OnFirstActiveFrame()
public void FirstActiveFrame()
{
BehaviourController.TryGetBehaviour(out shapeCollider);

View File

@@ -0,0 +1,35 @@
using System.Collections.Generic;
using Apos.Shapes;
using Syntriax.Engine.Core;
using Syntriax.Engine.Integration.MonoGame;
namespace Pong.Behaviours;
public class ShapeBatcher : BehaviourBase, IFirstFrameUpdate, IDraw
{
private static Comparer<IBehaviour> SortByPriority() => Comparer<IBehaviour>.Create((x, y) => y.Priority.CompareTo(x.Priority));
private ShapeBatch shapeBatch = null!;
private MonoGameCamera2DBehaviour camera2D = null!;
private readonly ActiveBehaviourCollectorSorted<IDrawableShape> drawableShapes = new() { SortBy = SortByPriority() };
public void FirstActiveFrame()
{
MonoGameWindowContainer windowContainer = BehaviourController.UniverseObject.Universe.FindRequiredBehaviour<MonoGameWindowContainer>();
camera2D = BehaviourController.UniverseObject.Universe.FindRequiredBehaviour<MonoGameCamera2DBehaviour>();
shapeBatch = new(windowContainer.Window.GraphicsDevice, windowContainer.Window.Content);
drawableShapes.Unassign();
drawableShapes.Assign(Universe);
}
public void Draw()
{
shapeBatch.Begin(camera2D.MatrixTransform);
for (int i = drawableShapes.Count - 1; i >= 0; i--)
drawableShapes[i].Draw(shapeBatch);
shapeBatch.End();
}
}

View File

@@ -6,7 +6,7 @@ using Syntriax.Engine.Core;
namespace Pong.Behaviours;
public class ShapeBehaviour : Syntriax.Engine.Physics2D.Collider2DShapeBehaviour, IDisplayableShape
public class ShapeBehaviour : Syntriax.Engine.Physics2D.Collider2DShapeBehaviour, IDrawableShape
{
public Color Color { get; set; } = Color.White;
public float Thickness { get; set; } = .5f;

View File

@@ -2,10 +2,11 @@ using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Syntriax.Engine.Core;
using Syntriax.Engine.Integration.MonoGame;
namespace Pong.Behaviours;
public class TextBehaviour : Behaviour2D, IDisplayableSprite
public class TextBehaviour : Behaviour2D, IDrawableSprite
{
public SpriteFont? Font { get; set; } = null;
public int Size { get; set; } = 16;
@@ -13,7 +14,7 @@ public class TextBehaviour : Behaviour2D, IDisplayableSprite
public void Draw(SpriteBatch spriteBatch)
{
if (!IsActive || Font is null)
if (Font is null)
return;
spriteBatch.DrawString(Font, Text, Transform.Position.ToDisplayVector2(), Color.White, Transform.Rotation, Vector2.One * .5f, Transform.Scale.Magnitude, SpriteEffects.None, 0f);

View File

@@ -3,13 +3,13 @@ using Syntriax.Engine.Core;
namespace Pong.Behaviours;
public class TextScoreBehaviour : TextBehaviour
public class TextScoreBehaviour : TextBehaviour, IFirstFrameUpdate
{
public bool IsLeft { get; }
private PongManagerBehaviour? pongManager = null;
protected override void OnFirstActiveFrame()
public void FirstActiveFrame()
{
if (!UniverseObject.Universe.TryFindBehaviour(out pongManager))
return;

View File

@@ -5,11 +5,11 @@ using Syntriax.Engine.Physics2D;
namespace Pong.Behaviours;
public class WallScoreBehaviour(Action OnCollision) : Behaviour2D
public class WallScoreBehaviour(Action OnCollision) : Behaviour2D, IFirstFrameUpdate
{
private Action OnCollision { get; } = OnCollision;
protected override void OnFirstActiveFrame()
public void FirstActiveFrame()
{
if (!BehaviourController.TryGetBehaviour(out ICollider2D? collider2D))
return;