Engine DeMonoGame #2

This commit is contained in:
Syntriax 2024-01-23 12:16:58 +03:00
parent 0486b0343a
commit ba284a199a
17 changed files with 135 additions and 124 deletions

2
Engine

@ -1 +1 @@
Subproject commit 485dfcc51ea548a50eec57b003bc3cb31cfdf579 Subproject commit 39e553ebbf61f398a3ed9a96b20f6819a197cd86

View File

@ -6,12 +6,12 @@ using Syntriax.Engine.Input;
using Syntriax.Engine.Physics2D.Abstract; using Syntriax.Engine.Physics2D.Abstract;
namespace Pong.Behaviours; namespace Pong.Behaviours;
public class MovementBallBehaviour(Vector2 StartDirection, float Speed) : BehaviourOverride public class MovementBallBehaviour(Vector2D StartDirection, float Speed) : BehaviourOverride
{ {
public Vector2 StartDirection { get; private set; } = Vector2.Normalize(StartDirection); public Vector2D StartDirection { get; private set; } = Vector2D.Normalize(StartDirection);
public float Speed { get; set; } = Speed; public float Speed { get; set; } = Speed;
protected override void OnFirstActiveFrame(GameTime time) protected override void OnFirstActiveFrame()
{ {
if (!BehaviourController.TryGetBehaviour(out IRigidBody2D? rigidBody)) if (!BehaviourController.TryGetBehaviour(out IRigidBody2D? rigidBody))
throw new Exception($"Where's my {nameof(IRigidBody2D)}????"); throw new Exception($"Where's my {nameof(IRigidBody2D)}????");

View File

@ -17,25 +17,25 @@ public class MovementBoxBehaviour(Keys Up, Keys Down, float High, float Low, flo
private bool isUpPressed = false; private bool isUpPressed = false;
private bool isDownPressed = false; private bool isDownPressed = false;
private IKeyboardInputs inputs = null!; private IButtonInputs<Keys> inputs = null!;
protected override void OnUpdate(GameTime time) protected override void OnUpdate()
{ {
if (isUpPressed && isDownPressed) if (isUpPressed && isDownPressed)
return; return;
if (isUpPressed) if (isUpPressed)
GameObject.Transform.Position = GameObject.Transform.Position + Vector2.UnitY * (float)time.ElapsedGameTime.TotalSeconds * Speed; GameObject.Transform.Position = GameObject.Transform.Position + Vector2D.Up * (float)Time.Elapsed.TotalSeconds * Speed;
else if (isDownPressed) else if (isDownPressed)
GameObject.Transform.Position = GameObject.Transform.Position + -Vector2.UnitY * (float)time.ElapsedGameTime.TotalSeconds * Speed; GameObject.Transform.Position = GameObject.Transform.Position + -Vector2D.Up * (float)Time.Elapsed.TotalSeconds * Speed;
GameObject.Transform.Position = new Vector2(GameObject.Transform.Position.X, MathF.Max(MathF.Min(GameObject.Transform.Position.Y, High), Low)); GameObject.Transform.Position = new Vector2D(GameObject.Transform.Position.X, MathF.Max(MathF.Min(GameObject.Transform.Position.Y, High), Low));
} }
protected override void OnFirstActiveFrame(GameTime time) protected override void OnFirstActiveFrame()
{ {
if (!BehaviourController.TryGetBehaviour<IKeyboardInputs>(out var behaviourResult)) if (!BehaviourController.TryGetBehaviour<IButtonInputs<Keys>>(out var behaviourResult))
throw new Exception($"{nameof(IKeyboardInputs)} is missing on ${GameObject.Name}."); throw new Exception($"{nameof(IButtonInputs<Keys>)} is missing on ${GameObject.Name}.");
inputs = behaviourResult; inputs = behaviourResult;
@ -55,8 +55,8 @@ public class MovementBoxBehaviour(Keys Up, Keys Down, float High, float Low, flo
inputs.UnregisterOnRelease(Down, OnDownReleased); inputs.UnregisterOnRelease(Down, OnDownReleased);
} }
private void OnUpPressed(IKeyboardInputs inputs, Keys keys) => isUpPressed = true; private void OnUpPressed(IButtonInputs<Keys> inputs, Keys keys) => isUpPressed = true;
private void OnUpReleased(IKeyboardInputs inputs, Keys keys) => isUpPressed = false; private void OnUpReleased(IButtonInputs<Keys> inputs, Keys keys) => isUpPressed = false;
private void OnDownPressed(IKeyboardInputs inputs, Keys keys) => isDownPressed = true; private void OnDownPressed(IButtonInputs<Keys> inputs, Keys keys) => isDownPressed = true;
private void OnDownReleased(IKeyboardInputs inputs, Keys keys) => isDownPressed = false; private void OnDownReleased(IButtonInputs<Keys> inputs, Keys keys) => isDownPressed = false;
} }

11
Game/EngineConverted.cs Normal file
View File

@ -0,0 +1,11 @@
using System.Runtime.CompilerServices;
using Microsoft.Xna.Framework;
using Syntriax.Engine.Core;
namespace Pong;
public static class EngineConverted
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static EngineTime ToEngineTime(this GameTime gameTime) => new(gameTime.TotalGameTime, gameTime.ElapsedGameTime);
}

View File

@ -26,7 +26,6 @@
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\Engine\Engine.Core\Engine.Core.csproj" /> <ProjectReference Include="..\Engine\Engine.Core\Engine.Core.csproj" />
<ProjectReference Include="..\Engine\Engine.Input\Engine.Input.csproj" /> <ProjectReference Include="..\Engine\Engine.Input\Engine.Input.csproj" />
<ProjectReference Include="..\Engine\Engine.Graphics\Engine.Graphics.csproj" />
</ItemGroup> </ItemGroup>
<Target Name="RestoreDotnetTools" BeforeTargets="Restore"> <Target Name="RestoreDotnetTools" BeforeTargets="Restore">
<Message Text="Restoring dotnet tools" Importance="High" /> <Message Text="Restoring dotnet tools" Importance="High" />

View File

@ -1,5 +1,4 @@
using System; using System;
using Microsoft.Xna.Framework; using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics; using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input; using Microsoft.Xna.Framework.Input;
@ -19,7 +18,9 @@ public class Game1 : Game
private PhysicsEngine2D engine; private PhysicsEngine2D engine;
private SpriteBatch _spriteBatch = null!; private SpriteBatch _spriteBatch = null!;
public static GameManager gameManager = null!; public static GameManager gameManager = null!;
public static Sprite spriteBox = null!; // public static Sprite spriteBox = null!;
private MonoGameCameraBehaviour cameraBehaviour;
public Game1() public Game1()
{ {
@ -49,16 +50,16 @@ public class Game1 : Game
{ {
_spriteBatch = new SpriteBatch(GraphicsDevice); _spriteBatch = new SpriteBatch(GraphicsDevice);
spriteBox = new Sprite() { Texture2D = Content.Load<Texture2D>("Sprites/Pixel") }; // spriteBox = new Sprite() { Texture2D = Content.Load<Texture2D>("Sprites/Pixel") };
Sprite spriteBall = new Sprite() { Texture2D = Content.Load<Texture2D>("Sprites/Circle") }; // Sprite spriteBall = new Sprite() { Texture2D = Content.Load<Texture2D>("Sprites/Circle") };
IGameObject gameObjectCamera = gameManager.InstantiateGameObject<GameObject>(); IGameObject gameObjectCamera = gameManager.InstantiateGameObject<GameObject>();
gameObjectCamera.Name = "Camera"; gameObjectCamera.Name = "Camera";
gameObjectCamera.Transform.Position = Vector2D.Zero; gameObjectCamera.Transform.Position = Vector2D.Zero;
MonoGameCameraBehaviour monoGameCameraBehaviour = gameObjectCamera.BehaviourController.AddBehaviour<MonoGameCameraBehaviour>(); cameraBehaviour = gameObjectCamera.BehaviourController.AddBehaviour<MonoGameCameraBehaviour>();
monoGameCameraBehaviour.Viewport = GraphicsDevice.Viewport; cameraBehaviour.Viewport = GraphicsDevice.Viewport;
gameManager.Camera = monoGameCameraBehaviour; gameManager.Camera = cameraBehaviour;
GameObject gameObjectBall = gameManager.InstantiateGameObject<GameObject>(); GameObject gameObjectBall = gameManager.InstantiateGameObject<GameObject>();
gameObjectBall.Name = "Ball"; gameObjectBall.Name = "Ball";
@ -67,7 +68,7 @@ public class Game1 : Game
engine.AddRigidBody(gameObjectBall.BehaviourController.AddBehaviour<RigidBody2D>()); engine.AddRigidBody(gameObjectBall.BehaviourController.AddBehaviour<RigidBody2D>());
gameObjectBall.BehaviourController.AddBehaviour<MovementBallBehaviour>(new Vector2D(.1f, .1f), 500f); gameObjectBall.BehaviourController.AddBehaviour<MovementBallBehaviour>(new Vector2D(.1f, .1f), 500f);
// gameObjectBall.BehaviourController.AddBehaviour<DisplayableSpriteBehaviour>().Assign(spriteBall); // gameObjectBall.BehaviourController.AddBehaviour<DisplayableSpriteBehaviour>().Assign(spriteBall);
gameObjectBall.BehaviourController.AddBehaviour<Collider2DAABBBehaviour>().AABBLocal = new AABB(-Vector2.One * 512f * .5f, Vector2.One * 512f * .5f); gameObjectBall.BehaviourController.AddBehaviour<Collider2DAABBBehaviour>().AABBLocal = new AABB(-Vector2D.One * 512f * .5f, Vector2D.One * 512f * .5f);
// gameObjectBall = gameManager.InstantiateGameObject<GameObject>(); // gameObjectBall = gameManager.InstantiateGameObject<GameObject>();
// gameObjectBall.Name = "Ball"; // gameObjectBall.Name = "Ball";
// gameObjectBall.Transform.Position = Vector2D.UnitY * 30f; // gameObjectBall.Transform.Position = Vector2D.UnitY * 30f;
@ -102,26 +103,26 @@ public class Game1 : Game
goPlayAreaTop.Transform.Position = new Vector2D(0f, 288f + 20f); goPlayAreaTop.Transform.Position = new Vector2D(0f, 288f + 20f);
goPlayAreaTop.Transform.Scale = new Vector2D(10240f, 40f); goPlayAreaTop.Transform.Scale = new Vector2D(10240f, 40f);
// goPlayAreaTop.BehaviourController.AddBehaviour<DisplayableSpriteBehaviour>().Assign(spriteBox); // goPlayAreaTop.BehaviourController.AddBehaviour<DisplayableSpriteBehaviour>().Assign(spriteBox);
goPlayAreaTop.BehaviourController.AddBehaviour<Collider2DAABBBehaviour>().AABBLocal = new AABB(-Vector2D.One * .5f, Vector2D.One * .5f); // goPlayAreaTop.BehaviourController.AddBehaviour<Collider2DAABBBehaviour>().AABBLocal = new AABB(-Vector2D.One * .5f, Vector2D.One * .5f);
engine.AddRigidBody(goPlayAreaTop.BehaviourController.AddBehaviour<RigidBody2D>()); engine.AddRigidBody(goPlayAreaTop.BehaviourController.AddBehaviour<RigidBody2D>());
IGameObject goPlayAreaBottom = gameManager.InstantiateGameObject<GameObject>(); IGameObject goPlayAreaBottom = gameManager.InstantiateGameObject<GameObject>();
goPlayAreaBottom.Transform.Position = new Vector2D(0f, -(288f + 20f)); goPlayAreaBottom.Transform.Position = new Vector2D(0f, -(288f + 20f));
goPlayAreaBottom.Transform.Scale = new Vector2D(10240f, 40f); goPlayAreaBottom.Transform.Scale = new Vector2D(10240f, 40f);
// goPlayAreaBottom.BehaviourController.AddBehaviour<DisplayableSpriteBehaviour>().Assign(spriteBox); // goPlayAreaBottom.BehaviourController.AddBehaviour<DisplayableSpriteBehaviour>().Assign(spriteBox);
goPlayAreaBottom.BehaviourController.AddBehaviour<Collider2DAABBBehaviour>().AABBLocal = new AABB(-Vector2D.One * .5f, Vector2D.One * .5f); // goPlayAreaBottom.BehaviourController.AddBehaviour<Collider2DAABBBehaviour>().AABBLocal = new AABB(-Vector2D.One * .5f, Vector2D.One * .5f);
engine.AddRigidBody(goPlayAreaBottom.BehaviourController.AddBehaviour<RigidBody2D>()); engine.AddRigidBody(goPlayAreaBottom.BehaviourController.AddBehaviour<RigidBody2D>());
IGameObject goPlayAreaRight = gameManager.InstantiateGameObject<GameObject>(); IGameObject goPlayAreaRight = gameManager.InstantiateGameObject<GameObject>();
goPlayAreaRight.Transform.Position = new Vector2D(512f + 20f, 0f); goPlayAreaRight.Transform.Position = new Vector2D(512f + 20f, 0f);
goPlayAreaRight.Transform.Scale = new Vector2D(40f, 5760f); goPlayAreaRight.Transform.Scale = new Vector2D(40f, 5760f);
// goPlayAreaRight.BehaviourController.AddBehaviour<DisplayableSpriteBehaviour>().Assign(spriteBox); // goPlayAreaRight.BehaviourController.AddBehaviour<DisplayableSpriteBehaviour>().Assign(spriteBox);
goPlayAreaRight.BehaviourController.AddBehaviour<Collider2DAABBBehaviour>().AABBLocal = new AABB(-Vector2D.One * .5f, Vector2D.One * .5f); // goPlayAreaRight.BehaviourController.AddBehaviour<Collider2DAABBBehaviour>().AABBLocal = new AABB(-Vector2D.One * .5f, Vector2D.One * .5f);
engine.AddRigidBody(goPlayAreaRight.BehaviourController.AddBehaviour<RigidBody2D>()); engine.AddRigidBody(goPlayAreaRight.BehaviourController.AddBehaviour<RigidBody2D>());
IGameObject goPlayAreaLeft = gameManager.InstantiateGameObject<GameObject>(); IGameObject goPlayAreaLeft = gameManager.InstantiateGameObject<GameObject>();
goPlayAreaLeft.Transform.Position = new Vector2D(-(512f + 20f), 0f); goPlayAreaLeft.Transform.Position = new Vector2D(-(512f + 20f), 0f);
goPlayAreaLeft.Transform.Scale = new Vector2D(40f, 5760f); goPlayAreaLeft.Transform.Scale = new Vector2D(40f, 5760f);
// goPlayAreaLeft.BehaviourController.AddBehaviour<DisplayableSpriteBehaviour>().Assign(spriteBox); // goPlayAreaLeft.BehaviourController.AddBehaviour<DisplayableSpriteBehaviour>().Assign(spriteBox);
goPlayAreaLeft.BehaviourController.AddBehaviour<Collider2DAABBBehaviour>().AABBLocal = new AABB(-Vector2D.One * .5f, Vector2D.One * .5f); // goPlayAreaLeft.BehaviourController.AddBehaviour<Collider2DAABBBehaviour>().AABBLocal = new AABB(-Vector2D.One * .5f, Vector2D.One * .5f);
engine.AddRigidBody(goPlayAreaLeft.BehaviourController.AddBehaviour<RigidBody2D>()); engine.AddRigidBody(goPlayAreaLeft.BehaviourController.AddBehaviour<RigidBody2D>());
// IGameObject goPlayAreaCenter = gameManager.InstantiateGameObject<GameObject>(); // IGameObject goPlayAreaCenter = gameManager.InstantiateGameObject<GameObject>();
@ -132,7 +133,7 @@ public class Game1 : Game
// TODO: use this.Content to load your game content here // TODO: use this.Content to load your game content here
} }
protected override void Update(Microsoft.Xna.Framework.GameTime gameTime) protected override void Update(GameTime gameTime)
{ {
if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed || Keyboard.GetState().IsKeyDown(Keys.Escape)) if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed || Keyboard.GetState().IsKeyDown(Keys.Escape))
Exit(); Exit();
@ -148,21 +149,21 @@ public class Game1 : Game
_graphics.IsFullScreen = true; _graphics.IsFullScreen = true;
_graphics.ApplyChanges(); _graphics.ApplyChanges();
float previousScreenSize = MathF.Sqrt(MathF.Pow(gameManager.Camera.Viewport.Width, 2f) + MathF.Pow(gameManager.Camera.Viewport.Height, 2f)); float previousScreenSize = MathF.Sqrt(MathF.Pow(cameraBehaviour.Viewport.Width, 2f) + MathF.Pow(cameraBehaviour.Viewport.Height, 2f));
float currentScreenSize = MathF.Sqrt(MathF.Pow(GraphicsDevice.Viewport.Width, 2f) + MathF.Pow(GraphicsDevice.Viewport.Height, 2f)); float currentScreenSize = MathF.Sqrt(MathF.Pow(GraphicsDevice.Viewport.Width, 2f) + MathF.Pow(GraphicsDevice.Viewport.Height, 2f));
gameManager.Camera.Zoom /= previousScreenSize / currentScreenSize; cameraBehaviour.Zoom /= previousScreenSize / currentScreenSize;
gameManager.Camera.Viewport = GraphicsDevice.Viewport; cameraBehaviour.Viewport = GraphicsDevice.Viewport;
} }
if (Keyboard.GetState().IsKeyDown(Keys.U)) if (Keyboard.GetState().IsKeyDown(Keys.U))
gameManager.Camera.Zoom += gameTime.ElapsedGameTime.Nanoseconds * 0.00025f; cameraBehaviour.Zoom += gameTime.ElapsedGameTime.Nanoseconds * 0.00025f;
if (Keyboard.GetState().IsKeyDown(Keys.J)) if (Keyboard.GetState().IsKeyDown(Keys.J))
gameManager.Camera.Zoom -= gameTime.ElapsedGameTime.Nanoseconds * 0.00025f; cameraBehaviour.Zoom -= gameTime.ElapsedGameTime.Nanoseconds * 0.00025f;
if (Keyboard.GetState().IsKeyDown(Keys.Q)) if (Keyboard.GetState().IsKeyDown(Keys.Q))
gameManager.Camera.Transform.Rotation += gameTime.ElapsedGameTime.Nanoseconds * 0.000025f; cameraBehaviour.BehaviourController.GameObject.Transform.Rotation += gameTime.ElapsedGameTime.Nanoseconds * 0.000025f;
if (Keyboard.GetState().IsKeyDown(Keys.E)) if (Keyboard.GetState().IsKeyDown(Keys.E))
gameManager.Camera.Transform.Rotation -= gameTime.ElapsedGameTime.Nanoseconds * 0.000025f; cameraBehaviour.BehaviourController.GameObject.Transform.Rotation -= gameTime.ElapsedGameTime.Nanoseconds * 0.000025f;
if (Keyboard.GetState().IsKeyDown(Keys.N)) if (Keyboard.GetState().IsKeyDown(Keys.N))
{ {
@ -210,7 +211,7 @@ public class Game1 : Game
// physicsTimer += 0.01f; // physicsTimer += 0.01f;
// engine.Step(.01f); // engine.Step(.01f);
// } // }
gameManager.Update(gameTime); gameManager.Update(gameTime.ToEngineTime());
base.Update(gameTime); base.Update(gameTime);
} }
static float physicsTimer = 0f; static float physicsTimer = 0f;
@ -224,9 +225,9 @@ public class Game1 : Game
// Console.WriteLine($"Pos: {gameManager.Camera.Position}"); // Console.WriteLine($"Pos: {gameManager.Camera.Position}");
// TODO: Add your drawing code here // TODO: Add your drawing code here
gameManager.PreDraw(gameTime); gameManager.PreDraw();
gameManager.Camera.Update(); gameManager.Camera.Update();
gameManager.Draw(_spriteBatch); // gameManager.Draw(_spriteBatch);
base.Draw(gameTime); base.Draw(gameTime);
} }

View File

@ -1,8 +1,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using Microsoft.Xna.Framework; using Syntriax.Engine.Core;
using Syntriax.Engine.Core.Abstract; using Syntriax.Engine.Core.Abstract;
namespace Syntriax.Engine.Physics2D.Abstract; namespace Syntriax.Engine.Physics2D.Abstract;
@ -13,8 +12,8 @@ public interface ICollider2D : IBehaviour, IAssignableTransform
IRigidBody2D? RigidBody2D { get; } IRigidBody2D? RigidBody2D { get; }
IList<Vector2> Vertices { get; } IList<Vector2D> Vertices { get; }
bool CheckCollision(Vector2 point); bool CheckCollision(Vector2D point);
void Recalculate(); void Recalculate();
} }

View File

@ -1,5 +1,4 @@
using Microsoft.Xna.Framework; using Syntriax.Engine.Core;
using Syntriax.Engine.Core.Abstract; using Syntriax.Engine.Core.Abstract;
namespace Syntriax.Engine.Physics2D.Abstract; namespace Syntriax.Engine.Physics2D.Abstract;
@ -8,7 +7,7 @@ public interface IRigidBody2D : IBehaviour, IAssignableTransform
{ {
IPhysicsMaterial2D Material { get; set; } IPhysicsMaterial2D Material { get; set; }
Vector2 Velocity { get; set; } Vector2D Velocity { get; set; }
float AngularVelocity { get; set; } float AngularVelocity { get; set; }
float Mass { get; set; } float Mass { get; set; }

View File

@ -1,8 +1,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Syntriax.Engine.Core; using Syntriax.Engine.Core;
using Syntriax.Engine.Core.Abstract; using Syntriax.Engine.Core.Abstract;
using Syntriax.Engine.Physics2D.Abstract; using Syntriax.Engine.Physics2D.Abstract;
@ -16,7 +14,7 @@ public class Collider2DAABBBehaviour : BehaviourOverride, ICollider2D
public AABB AABBWorld { get; private set; } = null!; public AABB AABBWorld { get; private set; } = null!;
private IRigidBody2D? _rigidBody2D = null; private IRigidBody2D? _rigidBody2D = null;
private List<Vector2> _vertices = new List<Vector2>(4); private List<Vector2D> _vertices = new List<Vector2D>(4);
public IRigidBody2D? RigidBody2D public IRigidBody2D? RigidBody2D
{ {
@ -35,9 +33,9 @@ public class Collider2DAABBBehaviour : BehaviourOverride, ICollider2D
ITransform IAssignableTransform.Transform => Transform; ITransform IAssignableTransform.Transform => Transform;
public bool Assign(ITransform transform) => GameObject.Assign(transform); public bool Assign(ITransform transform) => GameObject.Assign(transform);
public IList<Vector2> Vertices => _vertices; public IList<Vector2D> Vertices => _vertices;
public bool CheckCollision(Vector2 point) public bool CheckCollision(Vector2D point)
{ {
return AABBWorld.Overlaps(point); return AABBWorld.Overlaps(point);
} }
@ -51,11 +49,11 @@ public class Collider2DAABBBehaviour : BehaviourOverride, ICollider2D
Vertices.Clear(); Vertices.Clear();
Vertices.Add(AABBWorld.LowerBoundary); Vertices.Add(AABBWorld.LowerBoundary);
Vertices.Add(new Vector2(AABBWorld.LowerBoundary.X, AABBWorld.UpperBoundary.Y)); Vertices.Add(new Vector2D(AABBWorld.LowerBoundary.X, AABBWorld.UpperBoundary.Y));
Vertices.Add(AABBWorld.UpperBoundary); Vertices.Add(AABBWorld.UpperBoundary);
Vertices.Add(new Vector2(AABBWorld.UpperBoundary.X, AABBWorld.LowerBoundary.Y)); Vertices.Add(new Vector2D(AABBWorld.UpperBoundary.X, AABBWorld.LowerBoundary.Y));
} }
public Collider2DAABBBehaviour(Vector2 lowerBoundary, Vector2 upperBoundary) public Collider2DAABBBehaviour(Vector2D lowerBoundary, Vector2D upperBoundary)
{ {
AABBLocal = new AABB(lowerBoundary, upperBoundary); AABBLocal = new AABB(lowerBoundary, upperBoundary);
AABBWorld = new AABB(lowerBoundary, upperBoundary); AABBWorld = new AABB(lowerBoundary, upperBoundary);
@ -63,7 +61,7 @@ public class Collider2DAABBBehaviour : BehaviourOverride, ICollider2D
public Collider2DAABBBehaviour() public Collider2DAABBBehaviour()
{ {
AABBLocal = new(Vector2.Zero, Vector2.Zero); AABBLocal = new(Vector2D.Zero, Vector2D.Zero);
AABBWorld = new(Vector2.Zero, Vector2.Zero); AABBWorld = new(Vector2D.Zero, Vector2D.Zero);
} }
} }

View File

@ -2,7 +2,7 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using Microsoft.Xna.Framework; using Microsoft.Xna.Framework;
using Syntriax.Engine.Core;
using Syntriax.Engine.Core.Abstract; using Syntriax.Engine.Core.Abstract;
using Syntriax.Engine.Physics2D.Abstract; using Syntriax.Engine.Physics2D.Abstract;
using Syntriax.Engine.Physics2D.Primitives; using Syntriax.Engine.Physics2D.Primitives;
@ -60,7 +60,7 @@ public class PhysicsEngine2D : IPhysicsEngine2D
} }
} }
private void ResolveCollision(ICollider2D c1, ICollider2D c2, Vector2 vertex, float intervalDeltaTime) private void ResolveCollision(ICollider2D c1, ICollider2D c2, Vector2D vertex, float intervalDeltaTime)
{ {
if (c1.RigidBody2D is not IRigidBody2D) if (c1.RigidBody2D is not IRigidBody2D)
return; return;
@ -71,16 +71,16 @@ public class PhysicsEngine2D : IPhysicsEngine2D
c2.Vertices.ToLines(lines); c2.Vertices.ToLines(lines);
Vector2 normal = Vector2.UnitY; Vector2D normal = Vector2D.Up;
float t = 1f; float t = 1f;
bool hasIntersectedWithLines = false; bool hasIntersectedWithLines = false;
foreach (var line in lines) foreach (var line in lines)
{ {
if (!vertexTrajectory.Intersects(line, out Vector2? intersectionPoint)) if (!vertexTrajectory.Intersects(line, out Vector2D? intersectionPoint))
continue; continue;
if (intersectionPoint is not Vector2 ip) if (intersectionPoint is not Vector2D ip)
continue; continue;
float tTemp = vertexTrajectory.GetT(ip); float tTemp = vertexTrajectory.GetT(ip);
@ -88,7 +88,7 @@ public class PhysicsEngine2D : IPhysicsEngine2D
continue; continue;
t = tTemp; t = tTemp;
Vector2 lineDirection = line.Direction; Vector2D lineDirection = line.Direction;
normal = new(lineDirection.Y, lineDirection.X); normal = new(lineDirection.Y, lineDirection.X);
hasIntersectedWithLines = true; hasIntersectedWithLines = true;
} }
@ -99,11 +99,11 @@ public class PhysicsEngine2D : IPhysicsEngine2D
float rewindInterval = intervalDeltaTime - t * intervalDeltaTime; float rewindInterval = intervalDeltaTime - t * intervalDeltaTime;
StepRigidBody(c1.RigidBody2D, -rewindInterval); StepRigidBody(c1.RigidBody2D, -rewindInterval);
c1.RigidBody2D.Velocity = Vector2.Reflect(c1.RigidBody2D.Velocity, normal); c1.RigidBody2D.Velocity = Vector2D.Reflect(c1.RigidBody2D.Velocity, normal);
StepRigidBody(c1.RigidBody2D, rewindInterval); StepRigidBody(c1.RigidBody2D, rewindInterval);
} }
private void CheckCollisions(ICollider2D collider2D, List<ICollider2D> collider2Ds, Action<ICollider2D, ICollider2D, Vector2> OnCollisionDetectedAction) private void CheckCollisions(ICollider2D collider2D, List<ICollider2D> collider2Ds, Action<ICollider2D, ICollider2D, Vector2D> OnCollisionDetectedAction)
{ {
for (int i = 0; i < collider2Ds.Count; i++) for (int i = 0; i < collider2Ds.Count; i++)
{ {
@ -113,7 +113,7 @@ public class PhysicsEngine2D : IPhysicsEngine2D
for (int y = 0; y < collider2D.Vertices.Count; y++) for (int y = 0; y < collider2D.Vertices.Count; y++)
{ {
Vector2 vertex = collider2D.Vertices[y]; Vector2D vertex = collider2D.Vertices[y];
if (collider2DItem.CheckCollision(vertex)) if (collider2DItem.CheckCollision(vertex))
{ {
OnCollisionDetectedAction?.Invoke(collider2D, collider2DItem, vertex); OnCollisionDetectedAction?.Invoke(collider2D, collider2DItem, vertex);
@ -128,7 +128,7 @@ public class PhysicsEngine2D : IPhysicsEngine2D
private void StepRigidBody(IRigidBody2D rigidBody, float intervalDeltaTime) private void StepRigidBody(IRigidBody2D rigidBody, float intervalDeltaTime)
{ {
Vector2 nextPosition = rigidBody.Transform.Position; Vector2D nextPosition = rigidBody.Transform.Position;
nextPosition += rigidBody.Velocity * intervalDeltaTime; nextPosition += rigidBody.Velocity * intervalDeltaTime;
rigidBody.Transform.Position = nextPosition; rigidBody.Transform.Position = nextPosition;

View File

@ -2,22 +2,22 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using Microsoft.Xna.Framework; using Microsoft.Xna.Framework;
using Syntriax.Engine.Core;
using Syntriax.Engine.Physics2D.Primitives; using Syntriax.Engine.Physics2D.Primitives;
namespace Syntriax.Engine.Physics2D; namespace Syntriax.Engine.Physics2D;
public static class PhysicsMath public static class PhysicsMath
{ {
public static Vector2 Scale(this Vector2 original, Vector2 scale) public static Vector2D Scale(this Vector2D original, Vector2D scale)
=> new Vector2(original.X * scale.X, original.Y * scale.Y); => new Vector2D(original.X * scale.X, original.Y * scale.Y);
public static Triangle ToSuperTriangle(this IList<Vector2> vertices) public static Triangle ToSuperTriangle(this IList<Vector2D> vertices)
{ {
float minX = float.MaxValue, minY = float.MaxValue; float minX = float.MaxValue, minY = float.MaxValue;
float maxX = float.MinValue, maxY = float.MinValue; float maxX = float.MinValue, maxY = float.MinValue;
foreach (Vector2 point in vertices) foreach (Vector2D point in vertices)
{ {
minX = MathF.Min(minX, point.X); minX = MathF.Min(minX, point.X);
minY = MathF.Min(minY, point.Y); minY = MathF.Min(minY, point.Y);
@ -31,21 +31,21 @@ public static class PhysicsMath
float midX = (minX + maxX) / 2; float midX = (minX + maxX) / 2;
float midY = (minY + maxY) / 2; float midY = (minY + maxY) / 2;
Vector2 p1 = new Vector2((float)midX - 20f * (float)deltaMax, (float)midY - (float)deltaMax); Vector2D p1 = new Vector2D((float)midX - 20f * (float)deltaMax, (float)midY - (float)deltaMax);
Vector2 p2 = new Vector2((float)midX, (float)midY + 20 * (float)deltaMax); Vector2D p2 = new Vector2D((float)midX, (float)midY + 20 * (float)deltaMax);
Vector2 p3 = new Vector2((float)midX + 20 * (float)deltaMax, (float)midY - (float)deltaMax); Vector2D p3 = new Vector2D((float)midX + 20 * (float)deltaMax, (float)midY - (float)deltaMax);
return new Triangle(p1, p2, p3); return new Triangle(p1, p2, p3);
} }
public static IList<Line> ToLines(this IList<Vector2> vertices) public static IList<Line> ToLines(this IList<Vector2D> vertices)
{ {
List<Line> lines = new List<Line>(vertices.Count - 1); List<Line> lines = new List<Line>(vertices.Count - 1);
ToLines(vertices, lines); ToLines(vertices, lines);
return lines; return lines;
} }
public static void ToLines(this IList<Vector2> vertices, IList<Line> lines) public static void ToLines(this IList<Vector2D> vertices, IList<Line> lines)
{ {
lines.Clear(); lines.Clear();
for (int i = 0; i < vertices.Count - 1; i++) for (int i = 0; i < vertices.Count - 1; i++)
@ -53,13 +53,13 @@ public static class PhysicsMath
lines.Add(new(vertices[^1], vertices[0])); lines.Add(new(vertices[^1], vertices[0]));
} }
public static bool LaysOn(this Vector2 point, Line line) public static bool LaysOn(this Vector2D point, Line line)
=> line.Resolve(point.X).ApproximatelyEquals(point); => line.Resolve(point.X).ApproximatelyEquals(point);
// Given three collinear points p, q, r, the function checks if // Given three collinear points p, q, r, the function checks if
// point q lies on line segment 'pr' // point q lies on line segment 'pr'
public static bool OnSegment(Vector2 p, Vector2 q, Vector2 r) public static bool OnSegment(Vector2D p, Vector2D q, Vector2D r)
{ {
if (q.X <= MathF.Max(p.X, r.X) && q.X >= MathF.Min(p.X, r.X) && if (q.X <= MathF.Max(p.X, r.X) && q.X >= MathF.Min(p.X, r.X) &&
q.Y <= MathF.Max(p.Y, r.Y) && q.Y >= MathF.Min(p.Y, r.Y)) q.Y <= MathF.Max(p.Y, r.Y) && q.Y >= MathF.Min(p.Y, r.Y))
@ -73,7 +73,7 @@ public static class PhysicsMath
// 0 --> p, q and r are collinear // 0 --> p, q and r are collinear
// 1 --> Clockwise // 1 --> Clockwise
// 2 --> Counterclockwise // 2 --> Counterclockwise
public static int Orientation(Vector2 p, Vector2 q, Vector2 r) public static int Orientation(Vector2D p, Vector2D q, Vector2D r)
{ {
// See https://www.geeksforgeeks.org/orientation-3-ordered-points/ // See https://www.geeksforgeeks.org/orientation-3-ordered-points/
// for details of below formula. // for details of below formula.
@ -85,7 +85,7 @@ public static class PhysicsMath
return (val > 0) ? 1 : 2; // clock or counterclock wise return (val > 0) ? 1 : 2; // clock or counterclock wise
} }
public static float IntersectionParameterT(Vector2 p0, Vector2 p1, Vector2 q0, Vector2 q1) public static float IntersectionParameterT(Vector2D p0, Vector2D p1, Vector2D q0, Vector2D q1)
=> ((q0.X - p0.X) * (p1.Y - p0.Y) - (q0.Y - p0.Y) * (p1.X - p0.X)) / => ((q0.X - p0.X) * (p1.Y - p0.Y) - (q0.Y - p0.Y) * (p1.X - p0.X)) /
((q1.Y - q0.Y) * (p1.X - p0.X) - (q1.X - q0.X) * (p1.Y - p0.Y)); ((q1.Y - q0.Y) * (p1.X - p0.X) - (q1.X - q0.X) * (p1.Y - p0.Y));
@ -96,6 +96,10 @@ public static class PhysicsMath
=> ApproximatelyEquals(a, b, float.Epsilon); => ApproximatelyEquals(a, b, float.Epsilon);
public static bool ApproximatelyEquals(this Vector2 a, Vector2 b, float epsilon) public static bool ApproximatelyEquals(this Vector2 a, Vector2 b, float epsilon)
=> ApproximatelyEquals(a.X, b.X, epsilon) && ApproximatelyEquals(a.Y, b.Y, epsilon); => ApproximatelyEquals(a.X, b.X, epsilon) && ApproximatelyEquals(a.Y, b.Y, epsilon);
public static bool ApproximatelyEquals(this Vector2D a, Vector2D b)
=> ApproximatelyEquals(a, b, float.Epsilon);
public static bool ApproximatelyEquals(this Vector2D a, Vector2D b, float epsilon)
=> ApproximatelyEquals(a.X, b.X, epsilon) && ApproximatelyEquals(a.Y, b.Y, epsilon);
public static bool ApproximatelyEquals(this float a, float b, float epsilon) public static bool ApproximatelyEquals(this float a, float b, float epsilon)
{ {
if (a == b) if (a == b)

View File

@ -1,10 +1,10 @@
using Microsoft.Xna.Framework; using Syntriax.Engine.Core;
namespace Syntriax.Engine.Physics2D.Primitives; namespace Syntriax.Engine.Physics2D.Primitives;
public record AABB(Vector2 LowerBoundary, Vector2 UpperBoundary) public record AABB(Vector2D LowerBoundary, Vector2D UpperBoundary)
{ {
public bool Overlaps(Vector2 point) public bool Overlaps(Vector2D point)
=> point.X >= LowerBoundary.X && point.X <= UpperBoundary.X && => point.X >= LowerBoundary.X && point.X <= UpperBoundary.X &&
point.Y >= LowerBoundary.Y && point.Y <= UpperBoundary.Y; point.Y >= LowerBoundary.Y && point.Y <= UpperBoundary.Y;

View File

@ -1,8 +1,8 @@
using Microsoft.Xna.Framework; using Syntriax.Engine.Core;
namespace Syntriax.Engine.Physics2D.Primitives; namespace Syntriax.Engine.Physics2D.Primitives;
public record Circle(Vector2 Position, float Radius) public record Circle(Vector2D Position, float Radius)
{ {
public bool Intersects(Circle other) public bool Intersects(Circle other)
{ {
@ -12,7 +12,7 @@ public record Circle(Vector2 Position, float Radius)
return distanceSquared < radiusSumSquared; return distanceSquared < radiusSumSquared;
} }
public bool Overlaps(Vector2 point) => (Position - point).LengthSquared() <= Radius * Radius; public bool Overlaps(Vector2D point) => (Position - point).LengthSquared() <= Radius * Radius;
public bool ApproximatelyEquals(Circle other) public bool ApproximatelyEquals(Circle other)
=> Position.ApproximatelyEquals(other.Position) && Radius.ApproximatelyEquals(other.Radius); => Position.ApproximatelyEquals(other.Position) && Radius.ApproximatelyEquals(other.Radius);
} }

View File

@ -2,14 +2,14 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis; using System.Diagnostics.CodeAnalysis;
using Microsoft.Xna.Framework; using Syntriax.Engine.Core;
namespace Syntriax.Engine.Physics2D.Primitives; namespace Syntriax.Engine.Physics2D.Primitives;
public record Line(Vector2 From, Vector2 To) public record Line(Vector2D From, Vector2D To)
{ {
public Line Reversed => new(To, From); public Line Reversed => new(To, From);
public Vector2 Direction => Vector2.Normalize(To - From); public Vector2D Direction => Vector2D.Normalize(To - From);
public float Length => (From - To).Length(); public float Length => (From - To).Length();
public float LengthSquared => (From - To).LengthSquared(); public float LengthSquared => (From - To).LengthSquared();
@ -17,7 +17,7 @@ public record Line(Vector2 From, Vector2 To)
{ {
get get
{ {
Vector2 slopeVector = To - From; Vector2D slopeVector = To - From;
float slope = slopeVector.Y / slopeVector.X; float slope = slopeVector.Y / slopeVector.X;
float yOffset = From.Y - (slope * From.X); float yOffset = From.Y - (slope * From.X);
@ -26,10 +26,10 @@ public record Line(Vector2 From, Vector2 To)
} }
} }
public bool Intersects(Vector2 point) public bool Intersects(Vector2D point)
=> Resolve(point.X).ApproximatelyEquals(point); => Resolve(point.X).ApproximatelyEquals(point);
public float GetT(Vector2 point) public float GetT(Vector2D point)
{ {
float fromX = MathF.Abs(From.X); float fromX = MathF.Abs(From.X);
float toX = MathF.Abs(To.X); float toX = MathF.Abs(To.X);
@ -51,18 +51,18 @@ public record Line(Vector2 From, Vector2 To)
return t; return t;
} }
public bool Exist(List<Vector2> vertices) public bool Exist(List<Vector2D> vertices)
{ {
for (int i = 0; i < vertices.Count - 1; i++) for (int i = 0; i < vertices.Count - 1; i++)
{ {
Vector2 vertexCurrent = vertices[i]; Vector2D vertexCurrent = vertices[i];
Vector2 vertexNext = vertices[i]; Vector2D vertexNext = vertices[i];
if (From == vertexCurrent && To == vertexNext) return true; if (From == vertexCurrent && To == vertexNext) return true;
if (From == vertexNext && To == vertexCurrent) return true; if (From == vertexNext && To == vertexCurrent) return true;
} }
Vector2 vertexFirst = vertices[0]; Vector2D vertexFirst = vertices[0];
Vector2 vertexLast = vertices[^1]; Vector2D vertexLast = vertices[^1];
if (From == vertexFirst && To == vertexLast) return true; if (From == vertexFirst && To == vertexLast) return true;
if (From == vertexLast && To == vertexFirst) return true; if (From == vertexLast && To == vertexFirst) return true;
return false; return false;
@ -80,20 +80,20 @@ public record Line(Vector2 From, Vector2 To)
return numerator / denominator; return numerator / denominator;
} }
public Vector2 Lerp(float t) public Vector2D Lerp(float t)
=> new Vector2( => new Vector2D(
From.X + (To.X - From.X) * t, From.X + (To.X - From.X) * t,
From.Y + (To.Y - From.Y) * t From.Y + (To.Y - From.Y) * t
); );
public Vector2 Resolve(float x) public Vector2D Resolve(float x)
=> new Vector2(x, LineEquation.Resolve(x)); => new Vector2D(x, LineEquation.Resolve(x));
public Vector2 ClosestPointTo(Vector2 point) public Vector2D ClosestPointTo(Vector2D point)
{ {
// Convert edge points to vectors // Convert edge points to vectors
var edgeVector = new Vector2(To.X - From.X, To.Y - From.Y); var edgeVector = new Vector2D(To.X - From.X, To.Y - From.Y);
var pointVector = new Vector2(point.X - From.X, point.Y - From.Y); var pointVector = new Vector2D(point.X - From.X, point.Y - From.Y);
// Calculate the projection of pointVector onto edgeVector // Calculate the projection of pointVector onto edgeVector
float t = (pointVector.X * edgeVector.X + pointVector.Y * edgeVector.Y) / (edgeVector.X * edgeVector.X + edgeVector.Y * edgeVector.Y); float t = (pointVector.X * edgeVector.X + pointVector.Y * edgeVector.Y) / (edgeVector.X * edgeVector.X + edgeVector.Y * edgeVector.Y);
@ -105,11 +105,11 @@ public record Line(Vector2 From, Vector2 To)
float closestX = From.X + t * edgeVector.X; float closestX = From.X + t * edgeVector.X;
float closestY = From.Y + t * edgeVector.Y; float closestY = From.Y + t * edgeVector.Y;
return new Vector2((float)closestX, (float)closestY); return new Vector2D((float)closestX, (float)closestY);
} }
public Vector2 IntersectionPoint(Line other) public Vector2D IntersectionPoint(Line other)
=> Vector2.Lerp(From, To, IntersectionParameterT(other)); => Vector2D.Lerp(From, To, IntersectionParameterT(other));
public bool Intersects(Line other) public bool Intersects(Line other)
{ {
@ -129,7 +129,7 @@ public record Line(Vector2 From, Vector2 To)
return false; return false;
} }
public bool Intersects(Line other, [NotNullWhen(returnValue: true)] out Vector2? point) public bool Intersects(Line other, [NotNullWhen(returnValue: true)] out Vector2D? point)
{ {
point = null; point = null;

View File

@ -1,11 +1,11 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using Microsoft.Xna.Framework; using Syntriax.Engine.Core;
namespace Syntriax.Engine.Physics2D.Primitives; namespace Syntriax.Engine.Physics2D.Primitives;
public record Shape(IList<Vector2> Vertices) public record Shape(IList<Vector2D> Vertices)
{ {
public Triangle SuperTriangle public Triangle SuperTriangle
{ {
@ -14,7 +14,7 @@ public record Shape(IList<Vector2> Vertices)
float minX = float.MaxValue, minY = float.MaxValue; float minX = float.MaxValue, minY = float.MaxValue;
float maxX = float.MinValue, maxY = float.MinValue; float maxX = float.MinValue, maxY = float.MinValue;
foreach (Vector2 point in Vertices) foreach (Vector2D point in Vertices)
{ {
minX = MathF.Min(minX, point.X); minX = MathF.Min(minX, point.X);
minY = MathF.Min(minY, point.Y); minY = MathF.Min(minY, point.Y);
@ -28,9 +28,9 @@ public record Shape(IList<Vector2> Vertices)
float midX = (minX + maxX) / 2; float midX = (minX + maxX) / 2;
float midY = (minY + maxY) / 2; float midY = (minY + maxY) / 2;
Vector2 p1 = new Vector2((float)midX - 20f * (float)deltaMax, (float)midY - (float)deltaMax); Vector2D p1 = new Vector2D((float)midX - 20f * (float)deltaMax, (float)midY - (float)deltaMax);
Vector2 p2 = new Vector2((float)midX, (float)midY + 20 * (float)deltaMax); Vector2D p2 = new Vector2D((float)midX, (float)midY + 20 * (float)deltaMax);
Vector2 p3 = new Vector2((float)midX + 20 * (float)deltaMax, (float)midY - (float)deltaMax); Vector2D p3 = new Vector2D((float)midX + 20 * (float)deltaMax, (float)midY - (float)deltaMax);
return new Triangle(p1, p2, p3); return new Triangle(p1, p2, p3);
} }

View File

@ -1,10 +1,10 @@
using System; using System;
using Microsoft.Xna.Framework; using Syntriax.Engine.Core;
namespace Syntriax.Engine.Physics2D.Primitives; namespace Syntriax.Engine.Physics2D.Primitives;
public record Triangle(Vector2 A, Vector2 B, Vector2 C) public record Triangle(Vector2D A, Vector2D B, Vector2D C)
{ {
public float Area => MathF.Abs(( public float Area => MathF.Abs((
A.X * (B.Y - C.Y) + A.X * (B.Y - C.Y) +
@ -16,27 +16,27 @@ public record Triangle(Vector2 A, Vector2 B, Vector2 C)
{ {
get get
{ {
Vector2 midAB = (A + B) / 2; Vector2D midAB = (A + B) / 2;
Vector2 midBC = (B + C) / 2; Vector2D midBC = (B + C) / 2;
float slopeAB = (B.Y - A.Y) / (B.X - A.X); float slopeAB = (B.Y - A.Y) / (B.X - A.X);
float slopeBC = (C.Y - B.Y) / (C.X - B.X); float slopeBC = (C.Y - B.Y) / (C.X - B.X);
Vector2 center; Vector2D center;
if (MathF.Abs(slopeAB - slopeBC) > float.Epsilon) if (MathF.Abs(slopeAB - slopeBC) > float.Epsilon)
{ {
float x = (slopeAB * slopeBC * (A.Y - C.Y) + slopeBC * (A.X + B.X) - slopeAB * (B.X + C.X)) / (2 * (slopeBC - slopeAB)); float x = (slopeAB * slopeBC * (A.Y - C.Y) + slopeBC * (A.X + B.X) - slopeAB * (B.X + C.X)) / (2 * (slopeBC - slopeAB));
float y = -(x - (A.X + B.X) / 2) / slopeAB + (A.Y + B.Y) / 2; float y = -(x - (A.X + B.X) / 2) / slopeAB + (A.Y + B.Y) / 2;
center = new Vector2(x, y); center = new Vector2D(x, y);
} }
else else
center = (midAB + midBC) * .5f; center = (midAB + midBC) * .5f;
return new(center, Vector2.Distance(center, A)); return new(center, Vector2D.Distance(center, A));
} }
} }
public bool Overlaps(Vector2 point) public bool Overlaps(Vector2D point)
{ {
float originalTriangleArea = Area; float originalTriangleArea = Area;

View File

@ -15,7 +15,7 @@ public class RigidBody2D : BehaviourOverride, IRigidBody2D
public IPhysicsMaterial2D Material { get; set; } = null!; public IPhysicsMaterial2D Material { get; set; } = null!;
public Vector2 Velocity { get; set; } = Vector2.Zero; public Vector2D Velocity { get; set; } = Vector2D.Zero;
public float AngularVelocity { get; set; } = 0f; public float AngularVelocity { get; set; } = 0f;
public float Mass { get; set; } = 0f; public float Mass { get; set; } = 0f;
ITransform IAssignableTransform.Transform => Transform; ITransform IAssignableTransform.Transform => Transform;