public void Collide(MovingObject a, ImmobileObject b, Vector2[] linePoints) { Vector2[] aVertices = a.GetAllVertices(); for (int i = 0; i < aVertices.Length; i++) { aVertices[i] += a.Position; } Vector2[] bVertices = b.GetAllVertices(); for (int i = 0; i < bVertices.Length; i++) { bVertices[i] += b.Position; } Vector2 closestOnB = ClosestPointToLine(a.Center + a.Position, linePoints[2], linePoints[3]); Vector2 closestOnA = GetClosestPoint(closestOnB, aVertices); a.Position -= closestOnA - closestOnB; Vector2 bVector = linePoints[3] - linePoints[2]; bVector.Normalize(); bVector *= a.Velocity.Length(); a.Velocity = ClosestPointToLine(a.Velocity, -bVector, bVector); Vector2 normalizedVelocity = new Vector2(a.Velocity.X, a.Velocity.Y); normalizedVelocity.Normalize(); if (a.Velocity.LengthSquared() > b.Friction * b.Friction) { a.Velocity -= normalizedVelocity * b.Friction; } else { a.Velocity.X = 0; a.Velocity.Y = 0; } }
public Vector2[][] GetCollision(MovingObject a, ImmobileObject b) { List <Vector2[]> collisions = new List <Vector2[]>(); Vector2 lastVertexA = a.GetVertex(a.VertexCount - 1) + a.Position; for (int i = 0; i < a.VertexCount; i++) { Vector2 vertexA = a.GetVertex(i) + a.Position; Vector2 lastVertexB = b.GetVertex(b.VertexCount - 1) + b.Position; for (int j = 0; j < b.VertexCount; j++) { Vector2 vertexB = b.GetVertex(j) + b.Position; if (CheckLineIntersection(lastVertexA, vertexA, lastVertexB, vertexB)) { collisions.Add(new Vector2[] { lastVertexA, vertexA, lastVertexB, vertexB }); } lastVertexB = vertexB; } lastVertexA = vertexA; } return(collisions.ToArray()); }
public bool CheckCollision(MovingObject a) { for (int i = 0; i < ImmobileObjects.Count; i++) { ImmobileObject obj = ImmobileObjects[i]; if (GetCollision(a, obj).Length > 0) { return(true); } } return(false); }
public void Update() { foreach (MovingObject obj in MovingObjects) { obj.Velocity += Gravity; obj.Update(); } for (int i = 0; i < MovingObjects.Count; i++) { MovingObject obj = MovingObjects[i]; obj.TouchingSurface = false; for (int j = 0; j < ImmobileObjects.Count; j++) { ImmobileObject targetObj = ImmobileObjects[j]; Vector2[][] allLinePoints = GetCollision(obj, targetObj); Vector2[] closest = null; float? closestDist = null; foreach (Vector2[] linePoints in allLinePoints) { float dist = (ClosestPointToLine(obj.Center + obj.Position, linePoints[2], linePoints[3]) - (obj.Center + obj.Position)).LengthSquared(); if (closest == null || dist < closestDist) { closest = linePoints; closestDist = dist; } } if (closest != null) { Collide(obj, targetObj, closest); obj.TouchingSurface = true; } } if (!obj.TouchingSurface) { Vector2 normalizedVelocity = new Vector2(obj.Velocity.X, obj.Velocity.Y); normalizedVelocity.Normalize(); if (obj.Velocity.LengthSquared() > AirFriction.LengthSquared()) { obj.Velocity -= normalizedVelocity * AirFriction; } else { obj.Velocity.X = 0; obj.Velocity.Y = 0; } } } for (int i = 0; i < GameObjectLinks.Count; i++) { GameObjectLink link = GameObjectLinks[i]; link.Update(); } }