protected MapItem(IntVector2 hexQuoords, World world) { HexQuoordinates = hexQuoords; World = world; Tasks = new Queue<Task>(); }
public Hex(IntVector2 mapQuoordinate) { MapQuoordinate = mapQuoordinate; _maxResources = 5; _resources = new List<Resource>(5); MoveCost = 1; }
/// <summary> /// Gets the Hex that us under the screen position supplied. /// </summary> /// <param name="positionOnScreen"></param> /// <param name="hex"></param> /// <returns>True if hex was found, false otherwise.</returns> public bool GetHexFromScreenPosition(IntVector2 positionOnScreen, out IntVector2 hex) { // alows us to return early if no hex can be found. hex = IntVector2.Zero; IntVector2 mouseRelativeToWorld = positionOnScreen - _worldScreenOffset; // find the most likely hex at that mouse X (could still be one to the left or right) IntVector2 suspectHex = new IntVector2(0, 0); suspectHex.X = mouseRelativeToWorld.X / (_hexTextureDims.X - _hexXOverlapPixels); suspectHex.Y = _world.hexIsSunken(suspectHex.X) ? (mouseRelativeToWorld.Y - (_hexTextureDims.Y/2)) / _hexTextureDims.Y : mouseRelativeToWorld.Y / _hexTextureDims.Y; // object clicked on was not a hex if(!_world.IsValidHexQuoord(suspectHex)) return false; // get all the the hexes it could potentially be (thse form a bone shape around the suspect hex) List<IntVector2> potentialHexes = _world.getBoneShapeHexLocations(suspectHex); // the middleHex has already been evaluated so we should have at least one potential hex Debug.Assert(potentialHexes.Count != 0); // now we just need to find the hex that is closest to the mouse and that is the one that was clicked on IntVector2 closestToMouseHex = suspectHex; float distanceToMouse = 999999; foreach (IntVector2 v in potentialHexes) { float testDistance = (_getHexCenter(v) - mouseRelativeToWorld).Length(); if(testDistance < distanceToMouse) { distanceToMouse = testDistance; closestToMouseHex = v; } } hex = closestToMouseHex; return true; }
public MobileMapItem(IntVector2 hexQuoords, World world) : base(hexQuoords, world) { MoveIntervalInSeconds = 0.25; }
public Image(Texture2D texture) { Texture = texture; DrawOffset = new IntVector2(0, 0); }
public Image(Texture2D texture, IntVector2 drawOffset) { Texture = texture; DrawOffset = drawOffset; }
// function A*(start,goal) public Stack<IntVector2> AStar(IntVector2 start, IntVector2 goal) { Node[,] nodeArray = new Node[world.MapSize.X, world.MapSize.Y]; for (int x = 0; x < world.MapSize.X; x++) { for (int y = 0; y < world.MapSize.Y; y++) { nodeArray[x, y] = new Node(); nodeArray[x, y].Location = new IntVector2(x, y); } } // closedset := the empty set % The set of nodes already evaluated. List<Node> closedset = new List<Node>(); // openset := set containing the initial node % The set of tentative nodes to be evaluated. List<Node> openset = new List<Node>(); openset.Add(nodeArray[start.X, start.Y]); // g_score[start] := 0 % Distance from start along optimal path. nodeArray[start.X, start.Y].GScore = 0; // h_score[start] := heuristic_estimate_of_distance(start, goal) nodeArray[start.X, start.Y].HScore = huristicDistance(start, goal); // f_score[start] := h_score[start] % Estimated total distance from start to goal through y. //nodeArray[start.X, start.Y].FScore = nodeArray[start.X, start.Y].HScore; // while openset is not empty while (openset.Count > 0) { // x := the node in openset having the lowest f_score[] value Node x = openset.Where(n => n.FScore == openset.Min(m => m.FScore)).First(); // if x = goal if(x.Location == goal) { // return reconstruct_path(came_from,goal) return reconstructPath(goal, start, nodeArray); } // remove x from openset openset.Remove(x); // add x to closedset closedset.Add(x); // foreach y in neighbor_nodes(x) foreach(IntVector2 y in world.neighborHexes(x.Location)) { Node yNode = nodeArray[y.X, y.Y]; // if y in closedset // continue if(closedset.Where(n => n.Location == y).Count() > 0) continue; // tentative_g_score := g_score[x] + dist_between(x,y) float tentativeGScore = x.GScore + world.getMoveCost(x.Location, y); bool tentativeIsBetter = false; // if y not in openset // add y to openset // tentative_is_better := true // elseif tentative_g_score < g_score[y] // tentative_is_better := true // else // tentative_is_better := false if(openset.Where(n => n.Location == y).Count() == 0) { openset.Add(yNode); tentativeIsBetter = true; } else if(tentativeGScore < yNode.GScore) tentativeIsBetter = true; // if tentative_is_better = true // came_from[y] := x // g_score[y] := tentative_g_score // h_score[y] := heuristic_estimate_of_distance(y, goal) // f_score[y] := g_score[y] + h_score[y] if(tentativeIsBetter) { yNode.cameFrom = x.Location; yNode.GScore = tentativeGScore; yNode.HScore = huristicDistance(y, goal); } } } // return failure return null; }
//function reconstruct_path(came_from,current_node) Stack<IntVector2> reconstructPath(IntVector2 currentNode, IntVector2 start, Node[,] nodeArray) { // if came_from[current_node] is set // p = reconstruct_path(came_from,came_from[current_node]) // return (p + current_node) // else // return the empty path Stack<IntVector2> path = new Stack<IntVector2>(); IntVector2 current = currentNode; while (current != start) { path.Push(current); current = nodeArray[current.X, current.Y].cameFrom; } return path; }
/// <summary> /// I tested this huristic and it works perfectly if every move costs 1 point. /// </summary> /// <param name="current"></param> /// <param name="goal"></param> /// <param name="world"></param> /// <returns></returns> int huristicDistance(IntVector2 current, IntVector2 goal) { double changeX = Math.Abs(current.X - goal.X); double changeY = Math.Abs(current.Y - goal.Y); double unroundedAnswer = changeX + Math.Max((changeY - changeX / 2), 0); if(world.hexIsSunken(current.X)) return (int)Math.Floor(unroundedAnswer); else return (int)Math.Ceiling(unroundedAnswer); }
/*public Hex DestinationTile { get { throw new NotImplementedException(); }//return base.DestinationTile; } set { throw new NotImplementedException(); }// base.DestinationTile = value; } }*/ public Unit(UnitType unittype, IntVector2 hexQuoords, World world) : base(hexQuoords, world) { this.UnitType = unittype; HitPoints = 4; }
IntVector2 _getScreenPositionOfHex(IntVector2 hexQuoords) { return new IntVector2 ( hexQuoords.X * (_hexTextureDims.X - _hexXOverlapPixels), hexQuoords.Y * _hexTextureDims.Y + (_world.hexIsSunken(hexQuoords.X) ? _hexTextureDims.Y / 2 : 0) ) + _worldScreenOffset; }
IntVector2 _getHexCenter(IntVector2 hexQuoords) { IntVector2 center = _hexTextureDims / 2; center.Y += hexQuoords.Y * _hexTextureDims.Y; center.X += hexQuoords.X * (_hexTextureDims.X - _hexXOverlapPixels); if (_world.hexIsSunken(hexQuoords.X)) center.Y += _hexTextureDims.Y / 2; return center; }