private void CheckBorders(ICollider sourceCollider, int sourceWidth, int sourceHeight) { // Check borders for all rooms except basement if (!LoZGame.Instance.Dungeon.CurrentRoom.IsBasement) { // is right wall if (sourceCollider.Physics.Bounds.Right > LoZGame.Instance.ScreenWidth - BlockSpriteFactory.Instance.HorizontalOffset) { sourceCollider.OnCollisionResponse(sourceWidth, sourceHeight, CollisionSide.Right); } // is left wall else if (sourceCollider.Physics.Bounds.Left < BlockSpriteFactory.Instance.HorizontalOffset) { sourceCollider.OnCollisionResponse(sourceWidth, sourceHeight, CollisionSide.Left); } // is bottom wall if (sourceCollider.Physics.Bounds.Bottom > BlockSpriteFactory.Instance.BottomOffset) { sourceCollider.OnCollisionResponse(sourceWidth, sourceHeight, CollisionSide.Bottom); } // is top wall else if (sourceCollider.Physics.Bounds.Top < BlockSpriteFactory.Instance.TopOffset) { sourceCollider.OnCollisionResponse(sourceWidth, sourceHeight, CollisionSide.Top); } } // Check borders for basement exception else { if (sourceCollider.Physics.Location.Y < LoZGame.Instance.InventoryOffset) { if (!(sourceCollider is IPlayer) || ((IPlayer)sourceCollider).DamageTimer > 0) { sourceCollider.OnCollisionResponse(sourceWidth, sourceHeight, CollisionSide.Top); } } else if (sourceCollider.Physics.Location.Y > LoZGame.Instance.ScreenHeight - sourceHeight) { sourceCollider.OnCollisionResponse(sourceWidth, sourceHeight, CollisionSide.Bottom); } else if (sourceCollider.Physics.Location.X < 0) { sourceCollider.OnCollisionResponse(sourceWidth, sourceHeight, CollisionSide.Left); } else if (sourceCollider.Physics.Location.X > LoZGame.Instance.ScreenWidth - sourceWidth) { sourceCollider.OnCollisionResponse(sourceWidth, sourceHeight, CollisionSide.Right); } } }
private static bool CheckAllCollisions <T>(ICollider sourceCollider, Rectangle sourceRect, ReadOnlyCollection <T> targetColliders) { if (!typeof(ICollider).IsAssignableFrom(typeof(T)) || sourceCollider == null || sourceRect == Rectangle.Empty || targetColliders == null) { return(false); } bool collided = false; float biggestCollisionLength = Zero; ICollider targetCollider = null; CollisionSide biggestSourceSide = CollisionSide.None, biggestTargetSide = CollisionSide.None; //Find biggest collision intersection foreach (ICollider col in targetColliders) { CollisionSide sourceSide, targetSide; if (sourceCollider != col && CheckCollision(sourceRect, col.Bounds, out sourceSide, out targetSide)) { collided = true; Rectangle overlap = Rectangle.Intersect(sourceRect, col.Bounds); float colSize = overlap.Width * overlap.Height; if (colSize > biggestCollisionLength) { biggestCollisionLength = colSize; targetCollider = col; biggestSourceSide = sourceSide; biggestTargetSide = targetSide; } } } //Only apply collision response for the collider which we collided most with this frame if (collided && targetCollider != null && biggestSourceSide != CollisionSide.None && biggestTargetSide != CollisionSide.None) { sourceCollider.OnCollisionResponse(targetCollider, biggestSourceSide); targetCollider.OnCollisionResponse(sourceCollider, biggestTargetSide); } return(collided); }
private bool CheckCollisions <T>(ICollider sourceCollider, ReadOnlyCollection <T> targetColliders) { ICollider targetCollider = null; CollisionSide biggestSourceSide = CollisionSide.None; CollisionSide biggestTargetSide = CollisionSide.None; float biggestOverlapArea = 0; bool currentlyColliding; // Identify largest collision in case of multiple occurring at once. foreach (ICollider collider in targetColliders) { CollisionSide sourceSide = GetCollisionSide(sourceCollider.Physics.Bounds, collider.Physics.Bounds); CollisionSide targetSide = GetCollisionSide(collider.Physics.Bounds, sourceCollider.Physics.Bounds); Rectangle overlap = Rectangle.Intersect(sourceCollider.Physics.Bounds, collider.Physics.Bounds); float overlapArea = overlap.Width * overlap.Height; if (overlapArea > biggestOverlapArea) { biggestOverlapArea = overlapArea; targetCollider = collider; biggestSourceSide = sourceSide; biggestTargetSide = targetSide; } } // Handle each collision appropriately. if (targetCollider != null && biggestSourceSide != CollisionSide.None && biggestTargetSide != CollisionSide.None) { sourceCollider.OnCollisionResponse(targetCollider, biggestSourceSide); targetCollider.OnCollisionResponse(sourceCollider, biggestTargetSide); currentlyColliding = true; } else { currentlyColliding = false; } return(currentlyColliding); }