private void checkVerticalCollision(Unit unit, int pxDown) { if (unit.Bottom >= _collisionLayer.LayerHeight * _collisionLayer.TileHeight) { unit.Y += pxDown; return; //let unit fall } int forwardEdge = (pxDown > 0) ? unit.Bottom : unit.Top; //1 for down, -1 for up int yDirection = pxDown / Math.Abs(pxDown); //start at initial forward edge int startRow = forwardEdge / _collisionLayer.TileHeight; //assume unit moves full distance unit.Y += pxDown; //check up to new assumed unit hitrect edge int endRow = (forwardEdge + pxDown) / _collisionLayer.TileHeight; startRow = (int)MathHelper.Clamp(startRow, 0, _collisionLayer.LayerHeight - 1); endRow = (int)MathHelper.Clamp(endRow, 0, _collisionLayer.LayerHeight - 1); for (int row = startRow; row != (endRow + yDirection); row = row + yDirection) { for (int col = (unit.Left + 1) / _collisionLayer.TileWidth; col <= (unit.Right - 1) / _collisionLayer.TileWidth; col++) { if (!_collisionLayer.IsValidTileLocation(col, row)) { continue; } //pickup checks if (unit == _gino && _pickupLayer.IsValidTileLocation(col, row) && _pickupLayer.Tiles[col, row] != null) { if (_pickupLayer.Tiles[col, row].TileIndexProperties.ContainsKey("PickupType")) { getPickup(_pickupLayer.Tiles[col, row].TileIndexProperties["PickupType"], row, col); } } if (_collisionLayer.Tiles[col, row] != null && _collisionLayer.Tiles[col, row].TileIndex != 0) { if (pxDown > 0) { unit.CollideWithObstacle(Direction.South); unit.Bottom = row * _collisionLayer.TileHeight; } else { unit.CollideWithObstacle(Direction.North); unit.Top = (row + 1) * _collisionLayer.TileHeight; } break; //no need to check more } } } }
private void checkHorizontalCollision(Unit unit, int pxRight) { if (unit.Left < 0 || unit.Right >= _collisionLayer.LayerWidth * _collisionLayer.TileWidth) { unit.X += pxRight; return; } //Get the coordinate of the forward-facing edge //If walking left, forwardEdge = left of bounding box //If walking right, forwardEdge = right of bounding box int forwardEdge = (pxRight > 0) ? unit.Right : unit.Left; //-1 for left, 1 for right int xDirection = pxRight / Math.Abs(pxRight); int startCol = forwardEdge / _collisionLayer.TileWidth; int endCol = (forwardEdge + pxRight) / _collisionLayer.TileWidth; startCol = (int)MathHelper.Clamp(startCol, 0, _collisionLayer.LayerWidth - 1); endCol = (int)MathHelper.Clamp(endCol, 0, _collisionLayer.LayerWidth - 1); unit.X += pxRight; for (int col = startCol; col != (endCol + xDirection); col = col + xDirection) { for (int row = unit.Top / _collisionLayer.TileHeight; row <= (unit.Bottom - 1) / _collisionLayer.TileHeight; row++) { if (!_collisionLayer.IsValidTileLocation(col, row)) { continue; } //pickup checks if (unit == _gino && _pickupLayer.Tiles[col, row] != null) { if (_pickupLayer.Tiles[col, row].TileIndexProperties.ContainsKey("PickupType")) { getPickup(_pickupLayer.Tiles[col, row].TileIndexProperties["PickupType"], row, col); } } //check boundary collision for enemies if (_enemyLayer.IsValidTileLocation(col, row)) { if (_enemyLayer.Tiles[col, row] != null && _enemyLayer.Tiles[col, row].TileIndexProperties.ContainsKey("Name") && _enemyLayer.Tiles[col, row].TileIndexProperties["Name"] == "Bound") { unit.CollideWithObstacle(pxRight > 0 ? Direction.East : Direction.West); } } //within bounds -- check tile collision if (_collisionLayer.Tiles[col, row] != null && _collisionLayer.Tiles[col, row].TileIndex != 0) { if (pxRight > 0) { unit.CollideWithObstacle(Direction.East); unit.Right = col * _collisionLayer.TileWidth; } else { unit.CollideWithObstacle(Direction.West); unit.Left = (col + 1) * _collisionLayer.TileWidth; } break; //no need to check more } } } }