/// <summary> /// Returns the array of collision cells that a scene node should be checked against. /// </summary> /// <param name="node">Scene node object.</param> /// <returns>Array of collision cells.</returns> private CollisionCell[] getCellsToCheck(SceneNode node) { // Collision cells that should be checked against CollisionCell[] cellsToCheck = new CollisionCell[9]; int currentCellIndex = 0; for (int i = -1; i < 2; i++) { for (int j = -1; j < 2; j++) { cellsToCheck[currentCellIndex] = null; // Check X index bounds int cellXIndex = collisionGrid.GetCellAtPosition(node.Position).XIndex + i; if (cellXIndex >= 0 && cellXIndex < collisionGrid.Cells.GetLength(0)) { // Check Y index bounds int cellYIndex = collisionGrid.GetCellAtPosition(node.Position).YIndex + j; if (cellYIndex >= 0 && cellYIndex < collisionGrid.Cells.GetLength(1)) { cellsToCheck[currentCellIndex] = collisionGrid.Cells[cellXIndex, cellYIndex]; } } currentCellIndex++; } } return(cellsToCheck); }
/// <summary> /// Default constructor. /// </summary> /// <param name="sceneDimensions">Dimensions (in pixels) of the scene.</param> /// <param name="gridDimensions">Dimensions (in cells) of the collision grid.</param> public CollisionGrid(Dimensions2 sceneDimensions, Dimensions2 gridDimensions) { cells = new CollisionCell[gridDimensions.X, gridDimensions.Y]; cellDimensions = new Dimensions2(sceneDimensions.X / gridDimensions.X, sceneDimensions.Y / gridDimensions.Y); for (int i = 0; i < gridDimensions.X; i++) { for (int j = 0; j < gridDimensions.Y; j++) { cells[i, j] = new CollisionCell(i, j); } } }
/// <summary> /// Update method called every game frame. /// </summary> /// <param name="gameTime">Snapshot of timing values.</param> public void Update(GameTime gameTime) { tileMap.Update(gameTime); foreach (SceneNode node in sceneNodeDictionary.Values) { if (node is Entity) { Entity entity = node as Entity; prevEntityPositions[entity.Name] = entity.Position; } node.Update(gameTime); handleNodeCollisions(node); // Check if the collision cell should be changed if (!node.IsStatic) { CollisionCell newCell = collisionGrid.GetCellAtPosition(node.Position); if (newCell != node.CollisionCell) { // Remove scene node from old cell and add to new node.CollisionCell.SceneNodeList.Remove(node); newCell.SceneNodeList.Add(node); node.CollisionCell = newCell; node.CollisionCellsToCheck = getCellsToCheck(node); } // Clamp position to scene bounds node.ClampToSceneBounds(nodeMaxBounds); } } // Update scene position position = -sceneNodeDictionary["Player"].Position; position += positionOffset; position.X = MathHelper.Clamp(position.X, positionMinBounds.X, positionMaxBounds.X); position.Y = MathHelper.Clamp(position.Y, positionMinBounds.Y, positionMaxBounds.Y); }
/// <summary> /// Creates a collision grid for the scene. /// </summary> /// <param name="gridDimensions">Dimensions (in cells) of the collision grid.</param> public void CreateCollisionGrid(Dimensions2 gridDimensions) { Dimensions2 sceneDimensions = tileMap.Dimensions * tileMap.TileDimensions; collisionGrid = new CollisionGrid(sceneDimensions, gridDimensions); // Add tiles to the proper collision grid cell foreach (Tile tile in tileMap.TileArray) { collisionGrid.GetCellAtPosition(tile.Position).TileList.Add(tile); } // Add scene nodes to the proper collision grid cell foreach (SceneNode node in sceneNodeDictionary.Values) { CollisionCell cell = collisionGrid.GetCellAtPosition(node.Position); cell.SceneNodeList.Add(node); node.CollisionCell = cell; node.CollisionCellsToCheck = getCellsToCheck(node); } }