diff --git a/Game/Game1.cs b/Game/Game1.cs index 9cb06d1..9d822d4 100644 --- a/Game/Game1.cs +++ b/Game/Game1.cs @@ -16,7 +16,8 @@ public class Game1 : Game private GraphicsDeviceManager _graphics = null!; private PhysicsEngine2D engine; private SpriteBatch _spriteBatch = null!; - private GameManager gameManager = null!; + public static GameManager gameManager = null!; + public static Sprite spriteBox = null!; public Game1() { @@ -45,7 +46,7 @@ public class Game1 : Game engine = new PhysicsEngine2D(); _spriteBatch = new SpriteBatch(GraphicsDevice); - Sprite spriteBox = new Sprite() { Texture2D = Content.Load("Sprites/Pixel") }; + spriteBox = new Sprite() { Texture2D = Content.Load("Sprites/Pixel") }; Sprite spriteBall = new Sprite() { Texture2D = Content.Load("Sprites/Circle") }; IGameObject gameObjectCamera = gameManager.InstantiateGameObject(); @@ -87,23 +88,27 @@ public class Game1 : Game IGameObject goPlayAreaTop = gameManager.InstantiateGameObject(); goPlayAreaTop.Transform.Position = new Vector2(0f, 288f + 20f); - goPlayAreaTop.Transform.Scale = new Vector2(1024f, 40f); + goPlayAreaTop.Transform.Scale = new Vector2(10240f, 40f); + goPlayAreaTop.BehaviourController.AddBehaviour().Assign(spriteBox); goPlayAreaTop.BehaviourController.AddBehaviour((System.Collections.Generic.IList)[new Vector2(.5f, .5f), new Vector2(-.5f, .5f), new Vector2(.5f, -.5f), new Vector2(-.5f, -.5f)]); engine.AddRigidBody(goPlayAreaTop.BehaviourController.AddBehaviour()); IGameObject goPlayAreaBottom = gameManager.InstantiateGameObject(); goPlayAreaBottom.Transform.Position = new Vector2(0f, -(288f + 20f)); - goPlayAreaBottom.Transform.Scale = new Vector2(1024f, 40f); + goPlayAreaBottom.Transform.Scale = new Vector2(10240f, 40f); + goPlayAreaBottom.BehaviourController.AddBehaviour().Assign(spriteBox); goPlayAreaBottom.BehaviourController.AddBehaviour((System.Collections.Generic.IList)[new Vector2(.5f, .5f), new Vector2(-.5f, .5f), new Vector2(.5f, -.5f), new Vector2(-.5f, -.5f)]); engine.AddRigidBody(goPlayAreaBottom.BehaviourController.AddBehaviour()); IGameObject goPlayAreaRight = gameManager.InstantiateGameObject(); goPlayAreaRight.Transform.Position = new Vector2(512f + 20f, 0f); - goPlayAreaRight.Transform.Scale = new Vector2(40f, 576f); + goPlayAreaRight.Transform.Scale = new Vector2(40f, 5760f); + goPlayAreaRight.BehaviourController.AddBehaviour().Assign(spriteBox); goPlayAreaRight.BehaviourController.AddBehaviour((System.Collections.Generic.IList)[new Vector2(.5f, .5f), new Vector2(-.5f, .5f), new Vector2(.5f, -.5f), new Vector2(-.5f, -.5f)]); engine.AddRigidBody(goPlayAreaRight.BehaviourController.AddBehaviour()); IGameObject goPlayAreaLeft = gameManager.InstantiateGameObject(); goPlayAreaLeft.Transform.Position = new Vector2(-(512f + 20f), 0f); - goPlayAreaLeft.Transform.Scale = new Vector2(40f, 576f); + goPlayAreaLeft.Transform.Scale = new Vector2(40f, 5760f); + goPlayAreaLeft.BehaviourController.AddBehaviour().Assign(spriteBox); goPlayAreaLeft.BehaviourController.AddBehaviour((System.Collections.Generic.IList)[new Vector2(.5f, .5f), new Vector2(-.5f, .5f), new Vector2(.5f, -.5f), new Vector2(-.5f, -.5f)]); engine.AddRigidBody(goPlayAreaLeft.BehaviourController.AddBehaviour()); @@ -142,9 +147,14 @@ public class Game1 : Game if (Keyboard.GetState().IsKeyDown(Keys.E)) gameManager.Camera.Rotation -= gameTime.ElapsedGameTime.Nanoseconds * 0.000025f; + + if (Keyboard.GetState().IsKeyDown(Keys.Space)) + seconds += gameTime.ElapsedGameTime.Milliseconds * .0005f; + // TODO: Add your update logic here while (physicsTimer + 0.01f < gameTime.TotalGameTime.TotalMilliseconds * .001f) { + Console.WriteLine($"Physics Timer: {physicsTimer}"); physicsTimer += 0.01f; engine.Step(.01f); } @@ -152,6 +162,7 @@ public class Game1 : Game base.Update(gameTime); } static float physicsTimer = 0f; + static float seconds = 0f; protected override void Draw(GameTime gameTime) { diff --git a/Game/Physics2D/Abstract/ICollider2D.cs b/Game/Physics2D/Abstract/ICollider2D.cs index dad186f..f0717ee 100644 --- a/Game/Physics2D/Abstract/ICollider2D.cs +++ b/Game/Physics2D/Abstract/ICollider2D.cs @@ -19,7 +19,7 @@ public interface ICollider2D : IBehaviour, IAssignableTransform IReadOnlyList Vertices { get; } - bool CheckCollision(Vector2 point, ICollider2D otherCollider, out Vector2 normal); + bool CheckCollision(Vector2 point, ICollider2D otherCollider, out CollisionInformation collisionInformation); void RecalculateVertices(); } diff --git a/Game/Physics2D/Collider2DBehaviour.cs b/Game/Physics2D/Collider2DBehaviour.cs index 336f98a..f2b0c5c 100644 --- a/Game/Physics2D/Collider2DBehaviour.cs +++ b/Game/Physics2D/Collider2DBehaviour.cs @@ -3,9 +3,10 @@ using System.Collections.Generic; using System.Collections.ObjectModel; using System.Diagnostics.CodeAnalysis; using Microsoft.Xna.Framework; - +using Pong; using Syntriax.Engine.Core; using Syntriax.Engine.Core.Abstract; +using Syntriax.Engine.Graphics.TwoDimensional; using Syntriax.Engine.Physics2D.Abstract; namespace Syntriax.Engine.Physics2D; @@ -42,9 +43,9 @@ public class Collider2DBehaviour(IList vertices) : BehaviourOverride, I public bool Assign(ITransform transform) => GameObject.Assign(transform); - public bool CheckCollision(Vector2 point, ICollider2D otherCollider, out Vector2 normal) + public bool CheckCollision(Vector2 point, ICollider2D otherCollider, out CollisionInformation collisionInformation) { - normal = Vector2.UnitX; + collisionInformation = new CollisionInformation(Vector2.Zero, Vector2.Zero); foreach (var triangle in triangles) { @@ -59,9 +60,19 @@ public class Collider2DBehaviour(IList vertices) : BehaviourOverride, I { if (!DoIntersect(main, edge)) continue; - normal = edge.A - edge.B; + + Vector2 contactPoint = ClosestPointOnEdge(point, edge); + + Vector2 normal = contactPoint - point; normal.Normalize(); - normal = new Vector2(normal.Y, normal.X); + + collisionInformation = new CollisionInformation(normal, contactPoint); + + GameObject gameObject = Game1.gameManager.InstantiateGameObject(); + gameObject.BehaviourController.AddBehaviour().Assign(Game1.spriteBox); + gameObject.Transform.Position = point; + gameObject.Transform.Scale = new Vector2(1f, .01f) * 100f; + gameObject.Transform.Rotation = (float)Math.Atan2(normal.Y, normal.X); break; } return true; @@ -143,6 +154,25 @@ public class Collider2DBehaviour(IList vertices) : BehaviourOverride, I // } } + private Vector2 ClosestPointOnEdge(Vector2 point, Edge edge) + { + // Convert edge points to vectors + var edgeVector = new Vector2(edge.B.X - edge.A.X, edge.B.Y - edge.A.Y); + var pointVector = new Vector2(point.X - edge.A.X, point.Y - edge.A.Y); + + // 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); + + // Clamp t to the range [0, 1] to ensure the closest point is on the edge + t = Math.Max(0, Math.Min(1, t)); + + // Calculate the closest point on the edge + float closestX = edge.A.X + t * edgeVector.X; + float closestY = edge.A.Y + t * edgeVector.Y; + + return new Vector2(closestX, closestY); + } + private bool DoesEdgeExistInTriangles(Edge edge, List triangles) { foreach (var triangle in triangles) diff --git a/Game/Physics2D/CollisionInformation.cs b/Game/Physics2D/CollisionInformation.cs index d7da43d..24d561d 100644 --- a/Game/Physics2D/CollisionInformation.cs +++ b/Game/Physics2D/CollisionInformation.cs @@ -1,12 +1,9 @@ using Microsoft.Xna.Framework; -using Syntriax.Engine.Physics2D.Abstract; namespace Syntriax.Engine.Physics2D; public record CollisionInformation ( Vector2 Normal, - float Impulse, - IRigidBody2D? RigidBodyX, - IRigidBody2D? RigidBodyY + Vector2 ContactPosition ); diff --git a/Game/Physics2D/PhysicsEngine2D.cs b/Game/Physics2D/PhysicsEngine2D.cs index 83f50f4..f4a3737 100644 --- a/Game/Physics2D/PhysicsEngine2D.cs +++ b/Game/Physics2D/PhysicsEngine2D.cs @@ -57,18 +57,39 @@ public class PhysicsEngine2D : IPhysicsEngine2D { ICollider2D colliderX = colliders[colliderIX]; for (int colliderIY = colliderIX + 1; colliderIY < colliders.Count; colliderIY++) - foreach (var vertex in colliderX.Vertices) + for (int i1 = 0; i1 < colliderX.Vertices.Count; i1++) { - if (!colliders[colliderIY].CheckCollision(vertex, colliderX, out var normal)) + Vector2 vertex = colliderX.Vertices[i1]; + if (!colliders[colliderIY].CheckCollision(vertex, colliderX, out var collisionInformation)) continue; + Console.WriteLine($"normal = {collisionInformation.Normal}"); + // // if (colliders[colliderIX].BehaviourController.TryGetBehaviour(out IRigidBody2D? rigidX)) + // // rigidX.Velocity = Vector2.Reflect(rigidX.Velocity, collisionInformation.Normal); if (colliders[colliderIX].BehaviourController.TryGetBehaviour(out IRigidBody2D? rigidX)) - rigidX.Velocity = Vector2.Reflect(rigidX.Velocity, normal); + { + Console.WriteLine($"rigidX.Velocity = {rigidX.Velocity}"); + rigidX.Velocity = Vector2.Reflect(rigidX.Velocity, collisionInformation.Normal); + + Vector2 vector2 = -new Vector2(collisionInformation.Normal.X * rigidX.Velocity.X, collisionInformation.Normal.Y * rigidX.Velocity.Y); + Console.WriteLine($"Displacement = {vector2}"); + rigidX.Transform.Position += vector2 * intervalDeltaTime * 2; + Console.WriteLine($"rigidX.Velocity = {rigidX.Velocity}"); + } if (colliders[colliderIY].BehaviourController.TryGetBehaviour(out IRigidBody2D? rigidY)) - rigidY.Velocity = Vector2.Reflect(rigidY.Velocity, normal); + { + Console.WriteLine($"rigidY.Velocity = {rigidY.Velocity}"); + rigidY.Velocity = Vector2.Reflect(rigidY.Velocity, collisionInformation.Normal); + Vector2 vector2 = -new Vector2(collisionInformation.Normal.X * rigidY.Velocity.X, collisionInformation.Normal.Y * rigidY.Velocity.Y); + Console.WriteLine($"Displacement = {vector2}"); + rigidY.Transform.Position += vector2 * intervalDeltaTime * 2; + Console.WriteLine($"rigidY.Velocity = {rigidY.Velocity}"); + } + Console.WriteLine($"/////////////////////////////////////////////"); + colliders[colliderIY].RecalculateVertices(); + colliders[colliderIX].RecalculateVertices(); // Console.WriteLine($"Collision"); - break; } } }