public Vector2 CheckCollision(Vector2 position, int width, int height) { int minI = Math.Max(0, (int)Math.Floor((position.Y - (height / 2)) / 16)); int maxI = Math.Min(Map.Instance.CurrentPanel.Tiles.GetLength(0) - 1, (int)Math.Floor((position.Y + (height / 2)) / 16)); int minJ = Math.Max(0, (int)Math.Floor((position.X - (width / 2)) / 16)); int maxJ = Math.Min(Map.Instance.CurrentPanel.Tiles.GetLength(1) - 1, (int)Math.Floor((position.X + (width / 2)) / 16)); Rectangle bounds = new Rectangle((int)position.X - (width / 2), (int)position.Y - (height / 2), width, height); for (int i = minI; i <= maxI; ++i) { for (int j = minJ; j <= maxJ; j++) { if (Map.Instance.CurrentPanel.Tiles[i, j] == 1) { Rectangle tileBounds = new Rectangle(j * 16, i * 16, 16, 16); Vector2 depth = bounds.GetIntersectionDepth(tileBounds); if (depth != Vector2.Zero) { float absDepthX = Math.Abs(depth.X); float absDepthY = Math.Abs(depth.Y); if (absDepthY < absDepthX) { bounds.Y += (int)depth.Y; position.Y += depth.Y; } else { bounds.X += (int)depth.X; position.X += depth.X; } } } } } return position; }
private void ProcessLevelCollisions(Entity entity) { Entity level = _world.EntityManager.GetEntities(Aspect.All(typeof(Map)))[0]; if (level == null) return; Map map = level.GetComponent<Map>(); CollisionBox box = entity.GetComponent<CollisionBox>(); Position position = entity.GetComponent<Position>(); Rectangle bounds = new Rectangle( (int)position.X + box.OffsetX, (int)position.Y + box.OffsetY, box.Width, box.Height ); int leftTile = (int) Math.Floor((float) bounds.Left/TilesetConstants.TileWidth); int rightTile = (int)Math.Ceiling(((float)bounds.Right / TilesetConstants.TileWidth)) - 1; int topTile = (int) Math.Floor((float) bounds.Top/TilesetConstants.TileHeight); int bottomTile = (int) Math.Ceiling(((float) bounds.Bottom/TilesetConstants.TileHeight)) - 1; for (int y = topTile; y <= bottomTile; ++y) { for (int x = leftTile; x <= rightTile; ++x) { if (x >= map.Width || x < 0 || y >= map.Height || y < 0) continue; TileData tile = map.Tiles[x, y]; if (tile != null && tile.IsCollidable) { Rectangle tileBounds = new Rectangle( x * TilesetConstants.TileWidth, y * TilesetConstants.TileHeight, TilesetConstants.TileWidth, TilesetConstants.TileHeight ); Vector2 depth = bounds.GetIntersectionDepth(tileBounds); var type = bounds.GetCollisionType(tileBounds); // Entity's bottom collided with top of tile. if (type == CollisionType.Top) { position.Y += depth.Y; position.IsOnGround = true; break; } else if (type == CollisionType.Left) { } else if (type == CollisionType.Right) { } else if (type == CollisionType.Bottom) { } } } } }