public void SelectUnit(int pixelX, int pixelY) { var cube = HexGridMath.HexToCube(HexGridMath.PixelToHex(pixelX, pixelY)); var selected = HexGridMath.CubeToOffset(cube.X, cube.Y, cube.Z); var unit = _units.FindUnit(selected.Col, selected.Row); if (unit != null && _alliedEnemyMatrix.AreAlliedOrEqual(unit.Nationality, NATIONALITY.USA)) { if (unit.TurnComplete && unit.Sleep == false) { unit.Selected = false; unit.Flash = null; return; } // unselect previously selected unit foreach (var otherUnit in _units) { if (otherUnit != unit) { otherUnit.Selected = false; otherUnit.Flash = null; } } unit.Selected = true; unit.Sleep = false; _units.IdleUnit = unit; unit.Flash = new UnitFlash(-1, 0.6f, new Color(100, 200, 100)); ShowUnitRangeMask = true; } }
public void PlayerDrawRoute(int pixelX, int pixelY) { var startUnit = _units.FindSelectedUnit(); if (startUnit != null) { var cube = HexGridMath.HexToCube(HexGridMath.PixelToHex(pixelX, pixelY)); var destination = HexGridMath.CubeToOffset(cube.X, cube.Y, cube.Z); if (startUnit.Col != destination.Col || startUnit.Row != destination.Row) { _shortestPath.ComputeShortestPath((TerrainMap)_terrainMap, startUnit.Col, startUnit.Row, destination.Col, destination.Row, startUnit.UnitType); if (_shortestPath.WayPoint.Count > 0) { _shortestPath.WayPoint.Insert(0, new Offset(startUnit.Col, startUnit.Row)); } for (int i = 1; i < _shortestPath.WayPoint.Count; i++) { GameContent.Sb.Begin(SpriteSortMode.BackToFront, BlendState.AlphaBlend); GraphicHelpers.DrawLine(_shortestPath.WayPoint[i - 1].ToPixel, _shortestPath.WayPoint[i].ToPixel, Color.Red, 6); GameContent.Sb.End(); } } } }
/// <summary> /// Find all adjacent cells that are passible by the unitType provided /// </summary> /// <param name="col"></param> /// <param name="row"></param> /// <param name="unitType"></param> /// <param name="range"></param> /// <returns></returns> public List <MapCoordinates> FindAdjacentCells(int col, int row, int unitType, int range) { var list = new List <MapCoordinates>(); // first convert to cube coords var cube = HexGridMath.OffsetToCube(col, row); for (int dx = -range; dx <= range; dx++) { var maxDx = Math.Max(-range, -dx - range); var minDx = Math.Min(range, -dx + range); for (int dy = maxDx; dy <= minDx; dy++) { var dz = -dx - dy; if (dx != 0 || dy != 0 || dz != 0) // don't include the square occupied by the unit { var terrain = (TerrainCell)Map[FindMapHash(cube.X + dx, cube.Y + dy, cube.Z + dz)]; if (terrain != null) { if (unitType == -1 || (!terrain.Blocked(unitType))) // don't include any blocked terrain (mountains, oceans) { var offset = HexGridMath.CubeToOffset(cube.X + dx, cube.Y + dy, cube.Z + dz); list.Add(new MapCoordinates(offset.Col, offset.Row)); } } } } } return(list); }
/// <summary> /// Allows the game to run logic such as updating the world, /// checking for collisions, gathering input, and playing audio. /// </summary> /// <param name="gameTime">Provides a snapshot of timing values.</param> protected override void Update(GameTime gameTime) { // Allows the game to exit if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed) { Exit(); } // place the red dot at the mouse coordinates _mouseState = Mouse.GetState(); var pos = new Vector2(_mouseState.X, _mouseState.Y); var newKeyboardState = Keyboard.GetState(); // get the newest state if (_oldKeyboardState.IsKeyUp(Keys.N) && newKeyboardState.IsKeyDown(Keys.N)) { // next turn for this unit _gameBoard.NextUnit = true; } else if (_oldKeyboardState.IsKeyUp(Keys.S) && newKeyboardState.IsKeyDown(Keys.S)) { // unit sleep _gameBoard.SleepUnit = true; } else if (_oldKeyboardState.IsKeyUp(Keys.D) && newKeyboardState.IsKeyDown(Keys.D)) { // dump game data to a text file for analysis _gameBoard.DumpGameData = true; } else if (_oldKeyboardState.IsKeyUp(Keys.T) && newKeyboardState.IsKeyDown(Keys.T)) { // end the current turn _gameBoard.NextTurn = true; } if (newKeyboardState.IsKeyDown(Keys.LeftShift)) { // temporarily show everything _gameBoard.ShowAll = true; } else { _gameBoard.ShowAll = false; } _oldKeyboardState = newKeyboardState; // set the new state as the old state for next time var temp = HexGridMath.PixelToHex(pos.X, pos.Y); var cube = HexGridMath.HexToCube(temp.Q, temp.R); _selectedHex = cube.CubeToOffset(); _gameBoard.Update(gameTime); base.Update(gameTime); }
public void PlayerUnitMouseUp(int pixelX, int pixelY) { var cube = HexGridMath.HexToCube(HexGridMath.PixelToHex(pixelX, pixelY)); var offset = HexGridMath.CubeToOffset(cube.X, cube.Y, cube.Z); var enemyUnit = _units.FindUnit(offset.Col, offset.Row); if (enemyUnit != null && _alliedEnemyMatrix.AreEnemies(NATIONALITY.USA, enemyUnit.Nationality)) { AttackUnit(enemyUnit); return; } //TODO: need to tweak algorithm so an allied unit cannot slide past an enemy unit. Can only back away to a square that has no enemy _units in any surrounding hex. // user just dropped the unit var unit = _units.FindSelectedUnit(); if (unit != null) { if (unit.Movement < 0.1) { return; } _units.IdleUnit = unit; //check to see if this is a new hex location if (unit.Col != offset.Col || unit.Row != offset.Row) { //TODO: need to account for coordinates that are off the map (negatives, etc.) int endCol = offset.Col; int endRow = offset.Row; // find the path unit.FindShortestPath(_terrainMap, unit.Col, unit.Row, endCol, endRow, unit.UnitType); _nextAlliedUnitToMove = unit; } else { // user clicked on unit, wake unit and make this unit the active unit if (!unit.TurnComplete) { unit.Sleep = false; } } return; } _units.UnselectUnits(); }
/// <summary> /// create a blank map of grass /// </summary> /// <param name="width"></param> /// <param name="height"></param> public void InitializeBoard(int width, int height) { Width = width; Height = height; for (var y = 0; y < Height; y++) { for (var x = 0; x < Width; x++) { var cube = HexGridMath.OffsetToCube(x, y); Map[FindMapHash(cube.X, cube.Y, cube.Z)] = new TerrainCell(cube.X, cube.Y, cube.Z, 0); } } }
public void HighlightRange(int col, int row, int range, Color color) { var cube = HexGridMath.OffsetToCube(col, row); GameContent.Sb.Begin(SpriteSortMode.BackToFront, BlendState.AlphaBlend); for (var dx = -range; dx <= range; dx++) { for (var dy = Math.Max(-range, -dx - range); dy <= Math.Min(range, -dx + range); dy++) { var dz = -dx - dy; var center = new Point(60 * (dx + cube.X) + GameContent.XOffset - 40, 35 * (dx + cube.X) + (dz + cube.Z) * 70 + GameContent.YOffset - 35); GameContent.Sb.Draw(GameContent.WhiteMask, new Vector2(center.X, center.Y), color); } } GameContent.Sb.End(); }
/// <summary> /// using offset coords /// </summary> /// <param name="col"></param> /// <param name="row"></param> /// <param name="range"></param> public void SetView(int col, int row, int range) { var cube = HexGridMath.OffsetToCube(col, row); for (var dx = -range; dx <= range; dx++) { var maxDx = Math.Max(-range, -dx - range); var minDx = Math.Min(range, -dx + range); for (var dy = maxDx; dy <= minDx; dy++) { var dz = -dx - dy; var terrain = (TerrainCell)Map[FindMapHash(cube.X + dx, cube.Y + dy, cube.Z + dz)]; if (terrain != null) { terrain.View = true; } } } }
public TerrainCell this[int col, int row] { get { var cube = HexGridMath.OffsetToCube(col, row); return((TerrainCell)Map[FindMapHash(cube.X, cube.Y, cube.Z)]); } set { var cube = HexGridMath.OffsetToCube(col, row); var hash = FindMapHash(cube.X, cube.Y, cube.Z); if (Map[hash] != null) { Map.Remove(hash); } Map.Add(hash, value); } }
private void DecodeMap(StreamReader file) { var line = file.ReadLine(); var temp = line.Split(','); // need to assert if not equal to two cells _terrainMap.Width = int.Parse(temp[0]); _terrainMap.Height = int.Parse(temp[1]); // read the map for (var y = 0; y < _terrainMap.Height; y++) { line = file.ReadLine(); var tempRow = line.Split(','); for (var x = 0; x < tempRow.Length; x++) { var cube = HexGridMath.OffsetToCube(x, y); _terrainMap[x, y] = new TerrainCell(cube.X, cube.Y, cube.Z, TerrainDecode(tempRow[x].Trim())); } } }
public long FindMapHash(int x, int y, int z) { var hex = HexGridMath.CubeToHex(x, y, z); return(FindMapHash(hex.Q, hex.R)); }
public void PlotRoad(int startCol, int startRow, int destCol, int destRow) { // find shortest path _shortestPath.ComputeShortestPath(this, startCol, startRow, destCol, destRow, -1); // add the starting cell to the path _shortestPath.WayPoint.Insert(0, new Offset(startCol, startRow)); TerrainCell prevTerrain = null; Cube prevTerrainCube = null; foreach (var wayPointOffset in _shortestPath.WayPoint) { var terrainCube = HexGridMath.OffsetToCube(wayPointOffset.Col, wayPointOffset.Row); var terrain = (TerrainCell)Map[FindMapHash(terrainCube.X, terrainCube.Y, terrainCube.Z)]; // figure out which sides of the cell are touching if (prevTerrain != null) { if (prevTerrainCube.Y == terrainCube.Y) // lower left to upper right { if (terrainCube.X > prevTerrainCube.X) { if (prevTerrain.BackgroundType != 40) { prevTerrain.Roads |= RoadType.Road3; } if (terrain.BackgroundType != 40) { terrain.Roads |= RoadType.Road6; } } else { if (prevTerrain.BackgroundType != 40) { prevTerrain.Roads |= RoadType.Road6; } if (terrain.BackgroundType != 40) { terrain.Roads |= RoadType.Road3; } } } else if (prevTerrainCube.Z == terrainCube.Z) // upper left to lower right { if (terrainCube.Y > prevTerrainCube.Y) { if (prevTerrain.BackgroundType != 40) { prevTerrain.Roads |= RoadType.Road5; } if (terrain.BackgroundType != 40) { terrain.Roads |= RoadType.Road2; } } else { if (prevTerrain.BackgroundType != 40) { prevTerrain.Roads |= RoadType.Road2; } if (terrain.BackgroundType != 40) { terrain.Roads |= RoadType.Road5; } } } else if (prevTerrainCube.X == terrainCube.X) // vertical line { if (terrainCube.Y > prevTerrainCube.Y) { if (prevTerrain.BackgroundType != 40) { prevTerrain.Roads |= RoadType.Road4; } if (terrain.BackgroundType != 40) { terrain.Roads |= RoadType.Road1; } } else { if (prevTerrain.BackgroundType != 40) { prevTerrain.Roads |= RoadType.Road1; } if (terrain.BackgroundType != 40) { terrain.Roads |= RoadType.Road4; } } } else { // should never get here System.Diagnostics.Debug.Assert(false); } } prevTerrain = terrain; prevTerrainCube = terrainCube; } }
public void Draw() { var width = GameContent.UnitSprite[UnitType].Width; var height = GameContent.UnitSprite[UnitType].Height; var cube = HexGridMath.OffsetToCube(Col, Row); // center point var lnX = 60 * cube.X + GameContent.XOffset; var lnY = 35 * cube.X + cube.Z * 70 + GameContent.YOffset; Color nationalityColor; if (Nationality == NATIONALITY.USA) { if (Sleep) { nationalityColor = new Color(129, 245, 129); } else { nationalityColor = new Color(208, 254, 208); } } else { nationalityColor = new Color(221, 221, 221); } GameContent.Sb.Begin(SpriteSortMode.BackToFront, BlendState.AlphaBlend); GameContent.Sb.Draw(GameContent.UnitSprite[UnitType], new Vector2(lnX - (int)(width / 2.0), lnY - (int)(height / 2.0)), nationalityColor); GameContent.Sb.End(); if (IdleFlash) { GameContent.Sb.Begin(SpriteSortMode.BackToFront, BlendState.AlphaBlend); GameContent.Sb.Draw(GameContent.UnitSprite[UnitType], new Vector2(lnX - (int)(width / 2.0), lnY - (int)(height / 2.0)), new Color(50, 200, 50)); GameContent.Sb.End(); } /* * if (RedHilight) * { * GameContent.Sb.Begin(SpriteSortMode.BackToFront, BlendState.AlphaBlend); * GameContent.Sb.Draw(GameContent.UnitSprite[UnitType], new Vector2(lnX - (int)(width / 2.0), lnY - (int)(height / 2.0)), new Color(200, 100, 100)); * GameContent.Sb.End(); * } * * if (GreenHilight) * { * GameContent.Sb.Begin(SpriteSortMode.BackToFront, BlendState.AlphaBlend); * GameContent.Sb.Draw(GameContent.UnitSprite[UnitType], new Vector2(lnX - (int)(width / 2.0), lnY - (int)(height / 2.0)), new Color(100, 200, 100)); * GameContent.Sb.End(); * } */ if (Flash != null) { if (Flash.UnitHighlighted) { GameContent.Sb.Begin(SpriteSortMode.BackToFront, BlendState.AlphaBlend); GameContent.Sb.Draw(GameContent.UnitSprite[UnitType], new Vector2(lnX - (int)(width / 2.0), lnY - (int)(height / 2.0)), Flash.HighlightColor); GameContent.Sb.End(); } } GameContent.Sb.Begin(SpriteSortMode.BackToFront, BlendState.AlphaBlend); // offense (upper left) GameContent.Sb.DrawString(GameContent.Arial10Font, Offense.ToString(), new Vector2(lnX - 20, lnY - 23), Color.Black, 0, new Vector2(0, 0), 1.0f, SpriteEffects.None, 0.5f); // defense (lower left) GameContent.Sb.DrawString(GameContent.Arial10Font, Defense.ToString(), new Vector2(lnX - 20, lnY + 8), Color.Black, 0, new Vector2(0, 0), 1.0f, SpriteEffects.None, 0.5f); // range (upper right) GameContent.Sb.DrawString(GameContent.Arial10Font, Range.ToString(), new Vector2(lnX + 22 - (int)(GameContent.Arial10Font.MeasureString(Range.ToString()).X), lnY - 23), Color.Black, 0, new Vector2(0, 0), 1.0f, SpriteEffects.None, 0.5f); // movement (lower right) GameContent.Sb.DrawString(GameContent.Arial10Font, Movement.ToString(), new Vector2(lnX + 22 - (int)(GameContent.Arial10Font.MeasureString(Movement.ToString()).X), lnY + 8), Color.Black, 0, new Vector2(0, 0), 1.0f, SpriteEffects.None, 0.5f); // unit number (temporary - upper center) GameContent.Sb.DrawString(GameContent.Arial6Font, UnitNumber.ToString(), new Vector2(lnX - (int)(GameContent.Arial6Font.MeasureString(UnitNumber.ToString()).X / 2.0), lnY - 22), Color.Red, 0, new Vector2(0, 0), 1.0f, SpriteEffects.None, 0.5f); GameContent.Sb.End(); }