/// <summary> /// If the entity is simply colliding with terrain anywhere, it will raise an event. /// </summary> public void CheckSimpleTerrainCollision() { int[] q = GetNearbyTileIndexes(); foreach (int index in q) { if (index >= 0 && index <= GameWorld.TileArray.Length - 1 && GameWorld.TileArray[index].IsSolid == true) { if (CollRectangle.Intersects(GameWorld.TileArray[index].DrawRectangle)) { CollidedWithTerrain(this, GameWorld.TileArray[index]); break; } } } }
/// <summary> /// Whether the entity is simply intersecting terrain. /// </summary> /// <returns></returns> public bool IsTouchingTerrain() { int[] q = GetNearbyTileIndexes(); foreach (int quadrant in q) { if (quadrant >= 0 && quadrant <= GameWorld.TileArray.Length - 1 && GameWorld.TileArray[quadrant].IsSolid) { if (CollRectangle.Intersects(GameWorld.TileArray[quadrant].DrawRectangle)) { return(true); } } } return(false); }
/// <summary> /// This will check for terrain collision if entity implements ICollidable. /// </summary> private void CheckTerrainCollision() { int[] q = GetNearbyTileIndexes(); //Solve Y collisions MoveBy(0, Velocity.Y); foreach (int quadrant in q) { if (quadrant >= 0 && quadrant < GameWorld.TileArray.Length) { Tile tile = GameWorld.TileArray[quadrant]; if (quadrant >= 0 && quadrant < GameWorld.TileArray.Length && GameWorld.WorldData.IsTopDown ? tile.IsSolidTopDown : tile.IsSolid) { Rectangle tileRect = tile.DrawRectangle; if (CollRectangle.Intersects(tileRect)) { if (Velocity.Y > 0) { if (tile.CurrentCollisionType == Tile.CollisionType.FromAbove) { // Do I know why I have to use the last position instead of the current? No. But does it work? Yes. if (_positionInLastFrame.Y + CollRectangle.Height * 2 / 3 > tile.DrawRectangle.Y) { continue; } if (WantsToMoveDownPlatform) { continue; } } CollidedWithTileBelow(this, tile); CollidedWithTerrain(this, tile); } else if (tile.CurrentCollisionType == Tile.CollisionType.FromAbove) { continue; } else if (Velocity.Y < 0) { CollidedWithTileAbove(this, tile); CollidedWithTerrain(this, tile); } } } } } //Solve X Collisions MoveBy(Velocity.X, 0); foreach (int quadrant in q) { if (quadrant >= 0 && quadrant < GameWorld.TileArray.Length) { Tile tile = GameWorld.TileArray[quadrant]; if (tile.CurrentCollisionType == Tile.CollisionType.FromAbove) { continue; } if (quadrant >= 0 && quadrant < GameWorld.TileArray.Length && GameWorld.WorldData.IsTopDown ? tile.IsSolidTopDown : tile.IsSolid) { Rectangle tileRect = tile.DrawRectangle; if (CollRectangle.Intersects(tile.DrawRectangle)) { if (Velocity.X > 0) { CollidedWithTileToRight(this, tile); CollidedWithTerrain(this, tile); } else if (Velocity.X < 0) { CollidedWithTileToLeft(this, tile); CollidedWithTerrain(this, tile); } } } } } // Check for interactables updates. foreach (int quadrant in q) { Tile tile = GameWorld.GetTile(quadrant); if (tile.GetDrawRectangle().Intersects(CollRectangle)) { tile.OnEntityTouch(this); } } }