Test 43124

This commit is contained in:
Syntriax 2023-12-04 13:35:31 +03:00
parent 682bd62ffc
commit c66eec61ac
3 changed files with 84 additions and 11 deletions

View File

@ -64,7 +64,7 @@ public class Game1 : Game
gameObjectBall.Transform.Position = Vector2.Zero;
gameObjectBall.Transform.Scale = new Vector2(1f / 51.2f, 1f / 51.2f);
engine.AddRigidBody(gameObjectBall.BehaviourController.AddBehaviour<RigidBody2D>());
gameObjectBall.BehaviourController.AddBehaviour<Collider2DBehaviour>((System.Collections.Generic.IList<Vector2>)[new Vector2(1, 1) * 5f, new Vector2(-1, 1) * 5f, new Vector2(1, -1) * 5f, new Vector2(-1, -1) * 5f]);
gameObjectBall.BehaviourController.AddBehaviour<Collider2DBehaviour>((System.Collections.Generic.IList<Vector2>)[new Vector2(1, 1) * 5f, new Vector2(-1, 1) * 5f, new Vector2(1, -1) * 5f, new Vector2(-1, -1) * 5f]).OffsetScale = Vector2.One * 51.2f;
// gameObjectBall.BehaviourController.AddBehaviour<MovementBallBehaviour>(new Vector2(.1f, .1f), playAreaBehaviour, 100f);
gameObjectBall.BehaviourController.AddBehaviour<DisplayableSpriteBehaviour>().Assign(spriteBall);
IGameObject gameObjectBall2 = gameManager.InstantiateGameObject<GameObject>();
@ -74,7 +74,7 @@ public class Game1 : Game
RigidBody2D rigidBody = gameObjectBall2.BehaviourController.AddBehaviour<RigidBody2D>();
rigidBody.Velocity = Vector2.UnitY * 100f;
engine.AddRigidBody(rigidBody);
gameObjectBall2.BehaviourController.AddBehaviour<Collider2DBehaviour>((System.Collections.Generic.IList<Vector2>)[new Vector2(1, 1) * 5f, new Vector2(-1, 1) * 5f, new Vector2(1, -1) * 5f, new Vector2(-1, -1) * 5f]);
gameObjectBall2.BehaviourController.AddBehaviour<Collider2DBehaviour>((System.Collections.Generic.IList<Vector2>)[new Vector2(1, 1) * 5f, new Vector2(-1, 1) * 5f, new Vector2(1, -1) * 5f, new Vector2(-1, -1) * 5f]).OffsetScale = Vector2.One * 51.2f;
// gameObjectBall2.BehaviourController.AddBehaviour<MovementBallBehaviour>(new Vector2(.1f, .1f), playAreaBehaviour, 100f);
gameObjectBall2.BehaviourController.AddBehaviour<DisplayableSpriteBehaviour>().Assign(spriteBall);
@ -83,7 +83,7 @@ public class Game1 : Game
gameObjectBall3.Transform.Position = Vector2.UnitY * -120f + Vector2.UnitX * 10f;
gameObjectBall3.Transform.Scale = new Vector2(1f / 51.2f, 1f / 51.2f);
engine.AddRigidBody(gameObjectBall3.BehaviourController.AddBehaviour<RigidBody2D>());
gameObjectBall3.BehaviourController.AddBehaviour<Collider2DBehaviour>((System.Collections.Generic.IList<Vector2>)[new Vector2(1, 1) * 5f, new Vector2(-1, 1) * 5f, new Vector2(1, -1) * 5f, new Vector2(-1, -1) * 5f]);
gameObjectBall3.BehaviourController.AddBehaviour<Collider2DBehaviour>((System.Collections.Generic.IList<Vector2>)[new Vector2(1, 1) * 5f, new Vector2(-1, 1) * 5f, new Vector2(1, -1) * 5f, new Vector2(-1, -1) * 5f]).OffsetScale = Vector2.One * 51.2f;
// gameObjectBall3.BehaviourController.AddBehaviour<MovementBallBehaviour>(new Vector2(.1f, .1f), playAreaBehaviour, 100f);
gameObjectBall3.BehaviourController.AddBehaviour<DisplayableSpriteBehaviour>().Assign(spriteBall);
// IGameObject gameObjectLeft = gameManager.InstantiateGameObject<GameObject>();

View File

@ -44,7 +44,7 @@ public class Collider2DBehaviour(IList<Vector2> vertices) : BehaviourOverride, I
public bool CheckCollision(Vector2 point, ICollider2D otherCollider, out Vector2 normal)
{
normal = Vector2.Zero;
normal = Vector2.UnitX;
foreach (var triangle in triangles)
{
@ -53,7 +53,17 @@ public class Collider2DBehaviour(IList<Vector2> vertices) : BehaviourOverride, I
OnCollision?.Invoke(this, otherCollider);
normal = Transform.Position - otherCollider.Transform.Position;
Edge main = new() { A = otherCollider.Transform.Position, B = point };
foreach (var edge in GetEdges(triangle))
{
if (!DoIntersect(main, edge))
continue;
normal = edge.A - edge.B;
normal.Normalize();
normal = new Vector2(normal.Y, normal.X);
break;
}
return true;
}
@ -66,7 +76,10 @@ public class Collider2DBehaviour(IList<Vector2> vertices) : BehaviourOverride, I
_vertices.Clear();
foreach (var vertex in verticesOriginal)
_vertices.Add(vertex + Transform.Position);
{
Vector2 scaledPosition = new Vector2(vertex.X * Transform.Scale.X * OffsetScale.X, vertex.Y * Transform.Scale.Y * OffsetScale.Y);
_vertices.Add(scaledPosition + Transform.Position);
}
Triangle superTriangle = GetSuperTriangle(_vertices);
triangles.Add(superTriangle);
@ -248,4 +261,63 @@ public class Collider2DBehaviour(IList<Vector2> vertices) : BehaviourOverride, I
return result;
}
// Given three collinear points p, q, r, the function checks if
// point q lies on line segment 'pr'
private bool OnSegment(Vector2 p, Vector2 q, Vector2 r)
{
if (q.X <= Math.Max(p.X, r.X) && q.X >= Math.Min(p.X, r.X) &&
q.Y <= Math.Max(p.Y, r.Y) && q.Y >= Math.Min(p.Y, r.Y))
return true;
return false;
}
// To find orientation of ordered triplet (p, q, r).
// The function returns following values
// 0 --> p, q and r are collinear
// 1 --> Clockwise
// 2 --> Counterclockwise
private int Orientation(Vector2 p, Vector2 q, Vector2 r)
{
// See https://www.geeksforgeeks.org/orientation-3-ordered-points/
// for details of below formula.
float val = (q.Y - p.Y) * (r.X - q.X) -
(q.X - p.X) * (r.Y - q.Y);
if (val == 0) return 0; // collinear
return (val > 0) ? 1 : 2; // clock or counterclock wise
}
// The main function that returns true if line segment 'edge1.Aedge1.B'
// and 'edge2.Aedge2.B' intersect.
private bool DoIntersect(Edge edge1, Edge edge2)
{
// Find the four orientations needed for general and
// special cases
int o1 = Orientation(edge1.A, edge1.B, edge2.A);
int o2 = Orientation(edge1.A, edge1.B, edge2.B);
int o3 = Orientation(edge2.A, edge2.B, edge1.A);
int o4 = Orientation(edge2.A, edge2.B, edge1.B);
// General case
if (o1 != o2 && o3 != o4)
return true;
// Special Cases
// edge1.A, edge1.B and edge2.A are collinear and edge2.A lies on segment edge1.Aedge1.B
if (o1 == 0 && OnSegment(edge1.A, edge2.A, edge1.B)) return true;
// edge1.A, edge1.B and edge2.B are collinear and edge2.B lies on segment edge1.Aedge1.B
if (o2 == 0 && OnSegment(edge1.A, edge2.B, edge1.B)) return true;
// edge2.A, edge2.B and edge1.A are collinear and edge1.A lies on segment edge2.Aedge2.B
if (o3 == 0 && OnSegment(edge2.A, edge1.A, edge2.B)) return true;
// edge2.A, edge2.B and edge1.B are collinear and edge1.B lies on segment edge2.Aedge2.B
if (o4 == 0 && OnSegment(edge2.A, edge1.B, edge2.B)) return true;
return false; // Doesn't fall in any of the above cases
}
}

View File

@ -59,14 +59,15 @@ public class PhysicsEngine2D : IPhysicsEngine2D
for (int colliderIY = colliderIX + 1; colliderIY < colliders.Count; colliderIY++)
foreach (var vertex in colliderX.Vertices)
{
if (!colliders[colliderIY].CheckCollision(vertex, colliderX, out var collisionInformation))
if (!colliders[colliderIY].CheckCollision(vertex, colliderX, out var normal))
continue;
if (colliders[colliderIX].BehaviourController.TryGetBehaviour(out IRigidBody2D? rigidX))
rigidX.Velocity = -normal * rigidX.Velocity.Length();
if (colliders[colliderIY].BehaviourController.TryGetBehaviour(out IRigidBody2D? rigidY))
rigidY.Velocity = normal * rigidY.Velocity.Length();
// Console.WriteLine($"Collision");
// if (colliders[colliderIX].BehaviourController.TryGetBehaviour(out IRigidBody2D? rigidX))
// rigidX.Velocity = -rigidX.Velocity;
// if (colliders[colliderIY].BehaviourController.TryGetBehaviour(out IRigidBody2D? rigidY))
// rigidY.Velocity = -rigidY.Velocity;
break;
}
}