private void OnCollisionStoppedEvent(ICollisionComponent source, ICollisionComponent previousCollided) { if (OnCollisionStopped != null) { OnCollisionStopped(source, previousCollided); } }
protected MoveResponse ResolveAllCollisions(ICollisionComponent source) { MoveResponse response = new MoveResponse(); //As long as at least one collision occurred attempt to resolve it. //And, of course, only resolve collisions if we're supposed to! if (higherPriorityCollisionList.Count > 0) { correctionVectors.Clear(); for (int i = 0; i < tempCollisionList.Count; i++) { var vector = GetCorrectionVector(source, tempCollisionList[i]); correctionVectors.Add(vector); //Notify of a collision NotifyCollision(source, tempCollisionList[i], vector); } //Now determine the direction for the X and Y axis. CorrectionVector2 directions = GetDirections(correctionVectors); //Correct the movement of this object if we're supposed to if (ResolveCollisions) { CorrectMovement(source, tempCollisionList, directions); //Mark this object as having moved and put it back into the QuadTree. response.moved = true; } } return(response); }
protected virtual void OnCollisionEvent(ICollisionComponent source, ICollisionComponent collided) { if (OnCollision != null) { OnCollision(source, collided); } }
/// <summary> /// Constructor for the engine. /// </summary> /// <param name="collisionComponent">The collision component to use for collision detection.</param> /// <param name="backgroundColour">The game background colour after flushing graphics. /// Transparent by default.</param> public Engine(ICollisionComponent collisionComponent, Color?backgroundColour = null) { // Setup graphics device manager and content directory. graphics = new GraphicsDeviceManager(this); Content.RootDirectory = "Content"; // Set background colour. if (backgroundColour.HasValue) { this.backgroundColour = backgroundColour.Value; } else { this.backgroundColour = Color.Transparent; } // Initialise systems. collisionSystem = new CollisionSystem(collisionComponent); inputSystem = new InputSystem(); loadSystem = new LoadSystem(Content); renderSystem = new RenderSystem(graphics); updateSystem = new UpdateSystem(); // Create scene manager and entity manager. sceneManager = new SceneManager(collisionSystem, inputSystem, renderSystem, updateSystem); entityManager = new EntityManager(loadSystem, sceneManager, (ISceneStateManager)sceneManager); }
/// <summary> /// Requests that the CollidableGameObject be moved to the location where its ProjectedBoundingBox currently resides. /// </summary> /// <param name="objectToMove">The IGameObject to be moved.</param> /// <returns>A MoveResponse object providing information related to the movement.</returns> protected MoveResponse RequestMove(ICollisionComponent objectToMove) { MoveResponse response = new MoveResponse(false); HandleObjectMovement(objectToMove); return(response); }
/// <summary> /// Performs the actual movement of the ICollidable object's position in order to resolve a collision. /// </summary> /// <param name="item">The ICollidable object to move.</param> /// <param name="correction">A CorrectionVector2 detailing the X and Y axis movements required to resolve the collisions.</param> /// <param name="correctHorizontal">True if we are resolving along the X axis, false if we are resolving along the Y axis.</param> private void CorrectCollision(ICollisionComponent item, CorrectionVector2 correction, bool correctHorizontal) { Vector2 newVector = ((IBaseComponent)item).Parent.Position; //Vector2 newVelocity; //Vector2 originalPosition = item.Parent.Position; // Vector2 originalVelocity = item.Parent.Velocity; finalCorrectionVector = correction; if (correctHorizontal) { //newVelocity = new Vector2(0f, item.Parent.Velocity.Y); newVector.X += correction.X * (int)correction.DirectionX; } else { //newVelocity = new Vector2(item.Parent.Velocity.X, 0f); newVector.Y += correction.Y * (int)correction.DirectionY; } ((IBaseComponent)item).Parent.Position = newVector; //item.Parent.Velocity = newVelocity; item.BoundingBox2D.Position = newVector; collisionTree.ObjectMoved(item); /* * //Check if we're still colliding with anything else... * tempCollisionList.Clear(); * collisionTree.GetCollidingWith(item, ref tempCollisionList); * * //If we are colliding with new items, then correct along the other axis instead * if (tempCollisionList.Count > 0) * { * newVector = originalPosition; * * if (correctHorizontal) * { * newVelocity = new Vector2(originalVelocity.X, 0f); * newVector.Y += correction.Y * (int)correction.DirectionY; * } * else * { * newVelocity = new Vector2(0f, originalVelocity.Y); * newVector.X += correction.X * (int)correction.DirectionX; * } * * item.Position = newVector; * item.Velocity = newVelocity; * collisionTree.ObjectMoved(item); * } * */ }
/// <summary> /// Fired whenever a moveable object has changed its position. We will test to /// ensure that the movement is valid and then tell its QuadTree that it has moved. /// </summary> /// <param name="sender">The IMoveable object that has moved, triggering this OnMove event.</param> private void OnMove(IGameObject sender) { ICollisionComponent collisionComp = sender.GetComponent <ICollisionComponent>(); if (Active && collisionComp != null) { collisionTree.ObjectMoved(collisionComp); RequestMove(collisionComp); } }
protected void CullLayers(ICollisionComponent moved, List <IBoundingBox> list) { for (int i = list.Count - 1; i >= 0 && i < list.Count; i--) { if (layerManager != null && !layerManager.LayersInteract(moved.Parent.Layer, list[i].Source.Layer)) { list.RemoveRange(i, 1); } } }
/// <summary> /// Checks if an ICollidable object is colliding against a list of other ICollidable objects. /// </summary> /// <param name="item">The ICollidable object we want to test for collisions.</param> /// <param name="collisionList">The list of ICollidable objects to test for collisions against.</param> /// <returns>True if there are collisions, false if otherwise.</returns> private bool CheckCollisions(ICollisionComponent item, List <ICollisionComponent> collisionList) { int i; for (i = 0; i < collisionList.Count; i++) { if (item.BoundingBox2D.Intersects(collisionList[i].BoundingBox2D)) { return(true); } } return(false); }
public Projectile(string spriteName, Vector2 playerPosition, Entity projectileParent) : base(spriteName) { position = playerPosition; parent = projectileParent; Vector2 mouseState = new Vector2(Mouse.GetState().X, Mouse.GetState().Y); _targetLocation = GameManager.Instance.camera.ScreenToWorld(mouseState); _targetAngle = _targetLocation - position; rotation = (float)Math.Atan2(_targetAngle.Y, _targetAngle.X); velocity = new Vector2((float)Math.Cos(rotation), (float)Math.Sin(rotation)); collisionComponent = new PerPixelCollisionComponent(this); }
public Ship(string spriteName, EntityType type) : base(spriteName, type) { switch (type) { case EntityType.PLAYER: movementComponent = new PlayerMovementComponent(); break; case EntityType.COMPUTER: movementComponent = new AIMovementComponent(); break; } collisionComponent = new PerPixelCollisionComponent(this); _barComponent = new BarComponent(position, new Vector2(-100, 200), new Vector2(200, 50), _maxHealth); }
private void OnGameObjectDestroyed(IGameObject gameObject) { ICollisionComponent collisionComponent = gameObject.GetComponent <ICollisionComponent>(); if (collisionComponent != null) { collisionTree.RemoveObject(collisionComponent); } if (collisionEvents.ContainsKey(gameObject.GUID)) { collisionEvents.Remove(gameObject.GUID); } gameObject.OnMove -= OnMove; gameObject.OnDestroyed -= OnGameObjectDestroyed; }
private void NotifyCollision(ICollisionComponent source, ICollisionComponent collider, CorrectionVector2 collisionInfo) { var sourceGUID = ((IBaseComponent)source).Parent.GUID; var colliderGUID = ((IBaseComponent)collider).Parent.GUID; //Notify any listeners of the source that it has collided with something if (collisionEvents.ContainsKey(sourceGUID) && collisionEvents[sourceGUID] != null) { collisionEvents[sourceGUID](source, collider, collisionInfo); } //Notify any listeners of the collider that is has collided with something if (collisionEvents.ContainsKey(colliderGUID) && collisionEvents[colliderGUID] != null) { collisionEvents[colliderGUID](collider, source, collisionInfo); } }
protected virtual void Collided(ICollisionComponent source, ICollisionComponent collided) { //Just attempt to damage the thing we collided with immediately. var damageAction = Parent.ActionFactory.GetAction<BasicDamageAction>(); damageAction.Damage = DamageComponent.Damage; //Let's fire a particle destruction action while we're at it! var destroyAction = Parent.ActionFactory.GetAction<DestroyGameObjectAction>(); var sequence = Parent.ActionFactory.GetAction<SequenceGameAction>(); sequence.AddAction(damageAction); sequence.AddAction(destroyAction); Parent.FireAction(sequence, ((IBaseComponent) collided).Parent); //And now let's destroy ourself! var selfDestroy = Parent.ActionFactory.GetAction<DestroyGameObjectAction>(); Parent.FireAction(selfDestroy, this.ParentGameObject); }
protected virtual void Collided(ICollisionComponent source, ICollisionComponent collided) { //Just attempt to damage the thing we collided with immediately. var damageAction = Parent.ActionFactory.GetAction <BasicDamageAction>(); damageAction.Damage = DamageComponent.Damage; //Let's fire a particle destruction action while we're at it! var destroyAction = Parent.ActionFactory.GetAction <DestroyGameObjectAction>(); var sequence = Parent.ActionFactory.GetAction <SequenceGameAction>(); sequence.AddAction(damageAction); sequence.AddAction(destroyAction); //And now let's destroy ourself! var selfDestroy = Parent.ActionFactory.GetAction <DestroyGameObjectAction>(); sequence.AddAction(selfDestroy); Parent.FireAction(sequence, collided.Parent); }
private void NotifyCollision(ICollisionComponent source, ICollisionComponent collider) { if (source == null || source.Parent == null || collider == null || (collider).Parent == null) { return; } var sourceGUID = source.Parent.GUID; var colliderGUID = collider.Parent.GUID; //Notify any listeners of the source that it has collided with something if (onCollisionEventListeners.ContainsKey(sourceGUID) && onCollisionEventListeners[sourceGUID] != null) { onCollisionEventListeners[sourceGUID](source, collider); } //Notify any listeners of the collider that is has collided with something if (onCollisionEventListeners.ContainsKey(colliderGUID) && onCollisionEventListeners[colliderGUID] != null) { onCollisionEventListeners[colliderGUID](collider, source); } }
private void NotifyCollisionStopped(ICollisionComponent source, ICollisionComponent previousCollider) { if (source == null || source.Parent == null || previousCollider == null || previousCollider.Parent == null) { return; } var sourceGUID = source.Parent.GUID; var colliderGUID = previousCollider.Parent.GUID; //Notify any listeners of the source that it has stopped collided with what it was previously colliding with. if (onCollisionStoppedEventListeners.ContainsKey(sourceGUID) && onCollisionStoppedEventListeners[sourceGUID] != null) { onCollisionStoppedEventListeners[sourceGUID](source, previousCollider); } //Notify any listeners of the collider that is has stopped colliding with the source. if (onCollisionStoppedEventListeners.ContainsKey(colliderGUID) && onCollisionStoppedEventListeners[colliderGUID] != null) { onCollisionStoppedEventListeners[colliderGUID](previousCollider, source); } }
protected void ResolveIndividualCollision(ICollisionComponent source, ICollisionComponent toMove) { List <ICollisionComponent> temp = new List <ICollisionComponent>(); correctionVectors.Clear(); temp.Add(source); var vector = GetCorrectionVector(toMove, source); correctionVectors.Add(vector); //Now determine the direction for the X and Y axis. CorrectionVector2 directions = GetDirections(correctionVectors); NotifyCollision(source, toMove, vector); //Correct the movement of this object if we're supposed to! if (ResolveCollisions) { CorrectMovement(toMove, temp, directions); } }
/// <summary> /// Checks if an ICollidable object is colliding against a list of other ICollidable objects. /// </summary> /// <param name="item">The ICollidable object we want to test for collisions.</param> /// <param name="collisionList">The list of ICollidable objects to test for collisions against.</param> /// <returns>True if there are collisions, false if otherwise.</returns> private bool CheckCollisions(ICollisionComponent item, List<ICollisionComponent> collisionList) { int i; for (i = 0; i < collisionList.Count; i++) { if (item.BoundingBox2D.Intersects(collisionList[i].BoundingBox2D)) return true; } return false; }
/// <summary> /// Requests that the CollidableGameObject be moved to the location where its ProjectedBoundingBox currently resides. /// </summary> /// <param name="objectToMove">The IGameObject to be moved.</param> /// <returns>A MoveResponse object providing information related to the movement.</returns> protected MoveResponse RequestMove(ICollisionComponent objectToMove) { MoveResponse response = new MoveResponse(false); HandleObjectMovement(objectToMove); return response; }
/// <summary> /// Gets the correction vector to resolve a collision between two ICollidable objects. /// </summary> /// <param name="A">The ICollidable object we want to push out.</param> /// <param name="B">The ICollidable object we resolve the collision against.</param> /// <returns>A CorrectionVector2 that details the movement required to resolve the collision.</returns> private CorrectionVector2 GetCorrectionVector(ICollisionComponent A, ICollisionComponent B) { return A.GetCorrectionVector(B); }
private void CollisionStoppedHandler(ICollisionComponent source, ICollisionComponent previousCollided) { Parent.FireAction(new ColorChangeAction() { Color = Color.Purple }, ParentGameObject); }
private void OnCollisionStoppedEvent(ICollisionComponent source, ICollisionComponent previousCollided) { if (OnCollisionStopped != null) OnCollisionStopped(source, previousCollided); }
protected void ResolveIndividualCollision(ICollisionComponent source, ICollisionComponent toMove) { List<ICollisionComponent> temp = new List<ICollisionComponent>(); correctionVectors.Clear(); temp.Add(source); var vector = GetCorrectionVector(toMove, source); correctionVectors.Add(vector); //Now determine the direction for the X and Y axis. CorrectionVector2 directions = GetDirections(correctionVectors); NotifyCollision(source, toMove, vector); //Correct the movement of this object if we're supposed to! if (ResolveCollisions) { CorrectMovement(toMove, temp, directions); } }
public CorrectionVector2 GetCorrectionVector(ICollisionComponent B) { CorrectionVector2 vector = new CorrectionVector2(); float x1 = Math.Abs(BoundingBox2D.Right - B.BoundingBox2D.Left); float x2 = Math.Abs(BoundingBox2D.Left - B.BoundingBox2D.Right); float y1 = Math.Abs(BoundingBox2D.Bottom - B.BoundingBox2D.Top); float y2 = Math.Abs(BoundingBox2D.Top - B.BoundingBox2D.Bottom); /* * IMovementComponent movement = this.Parent.GetComponent<IMovementComponent>(); * * //If both objects have the same priority, then the correction vector only rolls back along the velocity * if (this.CollisionPriority == B.CollisionPriority) * { * if (movement.Velocity.X != 0.0f) * { * //Then roll back the velocity... * if (x1 < x2) * { * vector.X = x1; * vector.DirectionX = DirectionX.Left; * } * else if (x1 > x2) * { * vector.X = x2; * vector.DirectionX = DirectionX.Right; * } * } * else * { * vector.X = 0.0f; * vector.DirectionX = DirectionX.Right; * } * * if (movement.Velocity.Y != 0.0f) * { * //Calculate the displacement along Y-axis * if (y1 < y2) * { * vector.Y = y1; * vector.DirectionY = DirectionY.Up; * } * else if (y1 > y2) * { * vector.Y = y2; * vector.DirectionY = DirectionY.Down; * } * } * else * { * vector.Y = 0.0f; * vector.DirectionY = DirectionY.Down; * } * } * else * { * * //Calculate the displacement along X-axis * if (x1 < x2) * { * vector.X = x1; * vector.DirectionX = DirectionX.Left; * } * else if (x1 > x2) * { * vector.X = x2; * vector.DirectionX = DirectionX.Right; * } * * //Calculate the displacement along Y-axis * if (y1 < y2) * { * vector.Y = y1; * vector.DirectionY = DirectionY.Up; * } * else if (y1 > y2) * { * vector.Y = y2; * vector.DirectionY = DirectionY.Down; * } * } */ return(vector); }
/// <summary> /// Gets the correction vector to resolve a collision between two ICollidable objects. /// </summary> /// <param name="A">The ICollidable object we want to push out.</param> /// <param name="B">The ICollidable object we resolve the collision against.</param> /// <returns>A CorrectionVector2 that details the movement required to resolve the collision.</returns> private CorrectionVector2 GetCorrectionVector(ICollisionComponent A, ICollisionComponent B) { return(A.GetCorrectionVector(B)); }
/// <summary> /// Constructor for the collision system. /// </summary> /// <param name="collisionComponent">The collision component to use.</param> public CollisionSystem(ICollisionComponent collisionComponent) { // Store collision component. this.collisionComponent = collisionComponent; }
protected void CullLayers(ICollisionComponent moved, List<IBoundingBox> list) { for (int i = list.Count - 1; i >= 0 && i < list.Count; i--) { if (layerManager != null && !layerManager.LayersInteract(moved.Parent.Layer, list[i].Source.Layer)) { list.RemoveRange(i, 1); } } }
/// <summary> /// Corrects the movement of the ICollidable object and places it in a position where it will no longer be colliding /// with any of the ICollidable objects in the provided list. /// </summary> /// <param name="item">The ICollidable object to move/position to resolve collisions.</param> /// <param name="collisionList">The list of ICollidable objects we no longer want to be colliding against</param> /// <param name="corrections">The list of CorrectionVector2's detailing how to resolve each individual collision.</param> private void CorrectMovement(ICollisionComponent item, List <ICollisionComponent> collisionList, CorrectionVector2 corrections) { CorrectionVector2 smallestCorrectionX = GetSmallestCorrectionX(corrections.DirectionX, correctionVectors); CorrectionVector2 smallestCorrectionY = GetSmallestCorrectionY(corrections.DirectionY, correctionVectors); int fixedAxis = 0; bool found = false; int foundIndex = 0; for (int i = 0; i < collisionList.Count && !found; i++) { if (resolvedCollisions.ContainsKey(collisionList[i])) { found = true; foundIndex = i; } } if (!found) { if (smallestCorrectionX.X > smallestCorrectionY.Y) //Then start correcting Y first { CorrectCollision(item, smallestCorrectionY, false); fixedAxis = YAXIS; // if (CheckCollisions(item, collisionList)) // { // CorrectCollision(item, smallestCorrectionX, true); // fixedAxis = BOTHAXIS; // } } else { CorrectCollision(item, smallestCorrectionX, true); fixedAxis = XAXIS; // if (CheckCollisions(item, collisionList)) // { // CorrectCollision(item, smallestCorrectionY, false); // fixedAxis = BOTHAXIS; // } } } else //We've already used this before, so do the opposite! { if (resolvedCollisions[collisionList[foundIndex]] == XAXIS) { CorrectCollision(item, smallestCorrectionY, false); } else if (resolvedCollisions[collisionList[foundIndex]] == YAXIS) { CorrectCollision(item, smallestCorrectionX, true); } else { CorrectCollision(item, smallestCorrectionY, false); CorrectCollision(item, smallestCorrectionX, true); } } for (int i = 0; i < collisionList.Count; i++) { if (!resolvedCollisions.ContainsKey(collisionList[i])) { resolvedCollisions.Add(collisionList[i], fixedAxis); } } }
private void NotifyCollisionStopped(ICollisionComponent source, ICollisionComponent previousCollider) { if (source == null || source.Parent == null || previousCollider == null || previousCollider.Parent == null) return; var sourceGUID = source.Parent.GUID; var colliderGUID = previousCollider.Parent.GUID; //Notify any listeners of the source that it has stopped collided with what it was previously colliding with. if (onCollisionStoppedEventListeners.ContainsKey(sourceGUID) && onCollisionStoppedEventListeners[sourceGUID] != null) { onCollisionStoppedEventListeners[sourceGUID](source, previousCollider); } //Notify any listeners of the collider that is has stopped colliding with the source. if (onCollisionStoppedEventListeners.ContainsKey(colliderGUID) && onCollisionStoppedEventListeners[colliderGUID] != null) { onCollisionStoppedEventListeners[colliderGUID](previousCollider, source); } }
private void NotifyCollision(ICollisionComponent source, ICollisionComponent collider) { if (source == null || source.Parent == null || collider == null || (collider).Parent == null) return; var sourceGUID = source.Parent.GUID; var colliderGUID = collider.Parent.GUID; //Notify any listeners of the source that it has collided with something if (onCollisionEventListeners.ContainsKey(sourceGUID) && onCollisionEventListeners[sourceGUID] != null) { onCollisionEventListeners[sourceGUID](source, collider); } //Notify any listeners of the collider that is has collided with something if (onCollisionEventListeners.ContainsKey(colliderGUID) && onCollisionEventListeners[colliderGUID] != null) { onCollisionEventListeners[colliderGUID](collider, source); } }
protected virtual void OnCollisionEvent(ICollisionComponent source, ICollisionComponent collided) { if (OnCollision != null) OnCollision(source, collided); }
/// <summary> /// Corrects the movement of the ICollidable object and places it in a position where it will no longer be colliding /// with any of the ICollidable objects in the provided list. /// </summary> /// <param name="item">The ICollidable object to move/position to resolve collisions.</param> /// <param name="collisionList">The list of ICollidable objects we no longer want to be colliding against</param> /// <param name="corrections">The list of CorrectionVector2's detailing how to resolve each individual collision.</param> private void CorrectMovement(ICollisionComponent item, List<ICollisionComponent> collisionList, CorrectionVector2 corrections) { CorrectionVector2 smallestCorrectionX = GetSmallestCorrectionX(corrections.DirectionX, correctionVectors); CorrectionVector2 smallestCorrectionY = GetSmallestCorrectionY(corrections.DirectionY, correctionVectors); int fixedAxis = 0; bool found = false; int foundIndex = 0; for (int i = 0; i < collisionList.Count && !found; i++) { if (resolvedCollisions.ContainsKey(collisionList[i])) { found = true; foundIndex = i; } } if (!found) { if (smallestCorrectionX.X > smallestCorrectionY.Y) //Then start correcting Y first { CorrectCollision(item, smallestCorrectionY, false); fixedAxis = YAXIS; // if (CheckCollisions(item, collisionList)) // { // CorrectCollision(item, smallestCorrectionX, true); // fixedAxis = BOTHAXIS; // } } else { CorrectCollision(item, smallestCorrectionX, true); fixedAxis = XAXIS; // if (CheckCollisions(item, collisionList)) // { // CorrectCollision(item, smallestCorrectionY, false); // fixedAxis = BOTHAXIS; // } } } else //We've already used this before, so do the opposite! { if (resolvedCollisions[collisionList[foundIndex]] == XAXIS) { CorrectCollision(item, smallestCorrectionY, false); } else if (resolvedCollisions[collisionList[foundIndex]] == YAXIS) { CorrectCollision(item, smallestCorrectionX, true); } else { CorrectCollision(item, smallestCorrectionY, false); CorrectCollision(item, smallestCorrectionX, true); } } for (int i = 0; i < collisionList.Count; i++) { if (!resolvedCollisions.ContainsKey(collisionList[i])) resolvedCollisions.Add(collisionList[i], fixedAxis); } }
private void CollisionHandler(ICollisionComponent source, ICollisionComponent collided) { Parent.FireAction(new ColorChangeAction() { Color = Color.Red }, ParentGameObject); }
/// <summary> /// Performs the actual movement of the ICollidable object's position in order to resolve a collision. /// </summary> /// <param name="item">The ICollidable object to move.</param> /// <param name="correction">A CorrectionVector2 detailing the X and Y axis movements required to resolve the collisions.</param> /// <param name="correctHorizontal">True if we are resolving along the X axis, false if we are resolving along the Y axis.</param> private void CorrectCollision(ICollisionComponent item, CorrectionVector2 correction, bool correctHorizontal) { Vector2 newVector = ((IBaseComponent) item).Parent.Position; //Vector2 newVelocity; //Vector2 originalPosition = item.Parent.Position; // Vector2 originalVelocity = item.Parent.Velocity; finalCorrectionVector = correction; if (correctHorizontal) { //newVelocity = new Vector2(0f, item.Parent.Velocity.Y); newVector.X += correction.X * (int)correction.DirectionX; } else { //newVelocity = new Vector2(item.Parent.Velocity.X, 0f); newVector.Y += correction.Y*(int) correction.DirectionY; } ((IBaseComponent) item).Parent.Position = newVector; //item.Parent.Velocity = newVelocity; item.BoundingBox2D.Position = newVector; collisionTree.ObjectMoved(item); /* //Check if we're still colliding with anything else... tempCollisionList.Clear(); collisionTree.GetCollidingWith(item, ref tempCollisionList); //If we are colliding with new items, then correct along the other axis instead if (tempCollisionList.Count > 0) { newVector = originalPosition; if (correctHorizontal) { newVelocity = new Vector2(originalVelocity.X, 0f); newVector.Y += correction.Y * (int)correction.DirectionY; } else { newVelocity = new Vector2(0f, originalVelocity.Y); newVector.X += correction.X * (int)correction.DirectionX; } item.Position = newVector; item.Velocity = newVelocity; collisionTree.ObjectMoved(item); } * */ }
private void NotifyCollision(ICollisionComponent source, ICollisionComponent collider, CorrectionVector2 collisionInfo) { var sourceGUID = ((IBaseComponent) source).Parent.GUID; var colliderGUID = ((IBaseComponent) collider).Parent.GUID; //Notify any listeners of the source that it has collided with something if (collisionEvents.ContainsKey(sourceGUID) && collisionEvents[sourceGUID] != null) { collisionEvents[sourceGUID](source, collider, collisionInfo); } //Notify any listeners of the collider that is has collided with something if (collisionEvents.ContainsKey(colliderGUID) && collisionEvents[colliderGUID] != null) { collisionEvents[colliderGUID](collider, source, collisionInfo); } }
protected MoveResponse ResolveAllCollisions(ICollisionComponent source) { MoveResponse response = new MoveResponse(); //As long as at least one collision occurred attempt to resolve it. //And, of course, only resolve collisions if we're supposed to! if (higherPriorityCollisionList.Count > 0) { correctionVectors.Clear(); for (int i = 0; i < tempCollisionList.Count; i++) { var vector = GetCorrectionVector(source, tempCollisionList[i]); correctionVectors.Add(vector); //Notify of a collision NotifyCollision(source, tempCollisionList[i], vector); } //Now determine the direction for the X and Y axis. CorrectionVector2 directions = GetDirections(correctionVectors); //Correct the movement of this object if we're supposed to if (ResolveCollisions) { CorrectMovement(source, tempCollisionList, directions); //Mark this object as having moved and put it back into the QuadTree. response.moved = true; } } return response; }
/// <summary> /// Resolves all collisions against the source ICollidable object. /// </summary> /// <param name="source">The source ICollidable object that has moved and requires collision testing.</param> protected MoveResponse HandleObjectMovement(ICollisionComponent source) { tempCollisionList.Clear(); higherPriorityCollisionList.Clear(); lowerPriorityCollisionList.Clear(); resolvedCollisions.Clear(); finalCorrectionVector = new CorrectionVector2(); MoveResponse response = new MoveResponse(); collisionTree.GetCollidingWith(source, ref tempCollisionList); while (tempCollisionList.Count > 0) { if (source.Solid) { for (int i = 0; i < tempCollisionList.Count; i++) { ICollisionComponent currObject = tempCollisionList[i]; //Check if the object we are colliding with has a priority greater than ours. //If so, then add it to the list of collisions we need to resolve! //We will also consider objects with the same priority so long as both of use are flagged as being able to collide with //objects of the same priority. if (currObject.Solid) { if (currObject.CollisionPriority > source.CollisionPriority || ( (currObject.CollisionPriority == source.CollisionPriority))) { higherPriorityCollisionList.Add(currObject); } //If we've collided with anything of lower priority then we need to push IT out of the way. else if (currObject.CollisionPriority < source.CollisionPriority) { lowerPriorityCollisionList.Add(currObject); } } } } //Now let's resolve those collisions! ResolveAllCollisions(source); //Resolve all of the individual collisions that we are pushing away. for (int j = 0; j < lowerPriorityCollisionList.Count; j++) { ResolveIndividualCollision(source, lowerPriorityCollisionList[j]); } //Notify all the ICollisionComponents that they have collided with something. //for (int j = 0; j < tempCollisionList.Count; j++) //{ // if (collisionEvents.ContainsKey(source.Parent.GUID) && collisionEvents[source.Parent.GUID] != null) // collisionEvents[source.Parent.GUID](source, tempCollisionList[j], finalCorrectionVector); // if (collisionEvents.ContainsKey(tempCollisionList[j].Parent.GUID) && collisionEvents[tempCollisionList[j].Parent.GUID] != null) // collisionEvents[tempCollisionList[j].Parent.GUID](tempCollisionList[j], source, finalCorrectionVector); // } tempCollisionList.Clear(); higherPriorityCollisionList.Clear(); lowerPriorityCollisionList.Clear(); //Only check again if we're resolving collisions! if (ResolveCollisions) { collisionTree.GetCollidingWith(source, ref tempCollisionList); } } return(response); }
/// <summary> /// Resolves all collisions against the source ICollidable object. /// </summary> /// <param name="source">The source ICollidable object that has moved and requires collision testing.</param> protected MoveResponse HandleObjectMovement(ICollisionComponent source) { tempCollisionList.Clear(); higherPriorityCollisionList.Clear(); lowerPriorityCollisionList.Clear(); resolvedCollisions.Clear(); finalCorrectionVector = new CorrectionVector2(); MoveResponse response = new MoveResponse(); collisionTree.GetCollidingWith(source, ref tempCollisionList); while (tempCollisionList.Count > 0) { if (source.Solid) { for (int i = 0; i < tempCollisionList.Count; i++) { ICollisionComponent currObject = tempCollisionList[i]; //Check if the object we are colliding with has a priority greater than ours. //If so, then add it to the list of collisions we need to resolve! //We will also consider objects with the same priority so long as both of use are flagged as being able to collide with //objects of the same priority. if (currObject.Solid) { if (currObject.CollisionPriority > source.CollisionPriority || ( (currObject.CollisionPriority == source.CollisionPriority))) { higherPriorityCollisionList.Add(currObject); } //If we've collided with anything of lower priority then we need to push IT out of the way. else if (currObject.CollisionPriority < source.CollisionPriority) { lowerPriorityCollisionList.Add(currObject); } } } } //Now let's resolve those collisions! ResolveAllCollisions(source); //Resolve all of the individual collisions that we are pushing away. for (int j = 0; j < lowerPriorityCollisionList.Count; j++) { ResolveIndividualCollision(source, lowerPriorityCollisionList[j]); } //Notify all the ICollisionComponents that they have collided with something. //for (int j = 0; j < tempCollisionList.Count; j++) //{ // if (collisionEvents.ContainsKey(source.Parent.GUID) && collisionEvents[source.Parent.GUID] != null) // collisionEvents[source.Parent.GUID](source, tempCollisionList[j], finalCorrectionVector); // if (collisionEvents.ContainsKey(tempCollisionList[j].Parent.GUID) && collisionEvents[tempCollisionList[j].Parent.GUID] != null) // collisionEvents[tempCollisionList[j].Parent.GUID](tempCollisionList[j], source, finalCorrectionVector); // } tempCollisionList.Clear(); higherPriorityCollisionList.Clear(); lowerPriorityCollisionList.Clear(); //Only check again if we're resolving collisions! if (ResolveCollisions) { collisionTree.GetCollidingWith(source, ref tempCollisionList); } } return response; }
public CorrectionVector2 GetCorrectionVector(ICollisionComponent B) { CorrectionVector2 vector = new CorrectionVector2(); float x1 = Math.Abs(BoundingBox2D.Right - B.BoundingBox2D.Left); float x2 = Math.Abs(BoundingBox2D.Left - B.BoundingBox2D.Right); float y1 = Math.Abs(BoundingBox2D.Bottom - B.BoundingBox2D.Top); float y2 = Math.Abs(BoundingBox2D.Top - B.BoundingBox2D.Bottom); /* IMovementComponent movement = this.Parent.GetComponent<IMovementComponent>(); //If both objects have the same priority, then the correction vector only rolls back along the velocity if (this.CollisionPriority == B.CollisionPriority) { if (movement.Velocity.X != 0.0f) { //Then roll back the velocity... if (x1 < x2) { vector.X = x1; vector.DirectionX = DirectionX.Left; } else if (x1 > x2) { vector.X = x2; vector.DirectionX = DirectionX.Right; } } else { vector.X = 0.0f; vector.DirectionX = DirectionX.Right; } if (movement.Velocity.Y != 0.0f) { //Calculate the displacement along Y-axis if (y1 < y2) { vector.Y = y1; vector.DirectionY = DirectionY.Up; } else if (y1 > y2) { vector.Y = y2; vector.DirectionY = DirectionY.Down; } } else { vector.Y = 0.0f; vector.DirectionY = DirectionY.Down; } } else { //Calculate the displacement along X-axis if (x1 < x2) { vector.X = x1; vector.DirectionX = DirectionX.Left; } else if (x1 > x2) { vector.X = x2; vector.DirectionX = DirectionX.Right; } //Calculate the displacement along Y-axis if (y1 < y2) { vector.Y = y1; vector.DirectionY = DirectionY.Up; } else if (y1 > y2) { vector.Y = y2; vector.DirectionY = DirectionY.Down; } } */ return vector; }