Coverage Summary for Class: TileMapGraph (com.mygdx.game.AI)

Class Class, % Method, % Line, %
TileMapGraph 0% (0/1) 0% (0/12) 0% (0/57)


1 package com.mygdx.game.AI; 2  3 import com.badlogic.gdx.ai.pfa.Connection; 4 import com.badlogic.gdx.ai.pfa.indexed.IndexedGraph; 5 import com.badlogic.gdx.maps.MapLayer; 6 import com.badlogic.gdx.maps.MapLayers; 7 import com.badlogic.gdx.maps.tiled.TiledMap; 8 import com.badlogic.gdx.maps.tiled.TiledMapTileLayer; 9 import com.badlogic.gdx.math.Vector2; 10 import com.badlogic.gdx.utils.Array; 11 import com.badlogic.gdx.utils.ObjectMap; 12  13 import static com.mygdx.utils.TileMapCells.OBSTACLE; 14 import static com.mygdx.utils.TileMapCells.PASSABLE; 15  16 /** 17  * The Graphical representation of the tilemap with each cell being bidirectionally to the adjacent nodes. 18  */ 19 public class TileMapGraph implements IndexedGraph<Node> { 20  //private final NodeHeuristic heuristic; - commented out for Assessment 2 because heuristic functionality was removed due to redundancy 21  private final Array<Node> nodes; 22  private final Array<Path> paths; 23  private final Vector2 mapDim; 24  25  private final ObjectMap<Node, Array<Connection<Node>>> nodePaths; 26  27  private TileMapGraph() { 28  //heuristic = new NodeHeuristic(); - commented out for Assessment 2 because heuristic functionality was removed due to redundancy 29  nodes = new Array<>(); 30  paths = new Array<>(); 31  nodePaths = new ObjectMap<>(); 32  mapDim = new Vector2(); 33  } 34  35  /** 36  * Creates a Graph from the given tilemap 37  * @param map the source tilemap 38  */ 39  public TileMapGraph(TiledMap map) { 40  this(); 41  42  MapLayers layers = map.getLayers(); 43  TiledMapTileLayer layer = null; 44  45  // find the collision layer 46  for (MapLayer l : layers) { 47  if (l.getName().equals("Collision")) { 48  layer = (TiledMapTileLayer) l; 49  } 50  } 51  // if there is no collision layer 52  if (layer == null) { 53  return; 54  } 55  // the map dimensions 56  mapDim.set(layer.getWidth(), layer.getHeight()); 57  58  nodes.ensureCapacity((int) mapDim.x * (int) mapDim.y); 59  60  // create all the nodes 61  for (int i = 0; i < mapDim.x * mapDim.y; i++) { 62  nodes.add(new Node(0, 0)); 63  } 64  65  // for each column 66  for (int x = 0; x < layer.getWidth(); x++) { 67  // for each row 68  for (int y = 0; y < layer.getHeight(); y++) { 69  TiledMapTileLayer.Cell center = layer.getCell(x, y); 70  71  if (getType(center) == OBSTACLE) { 72  continue; 73  } 74  // the central node 75  addNode(x, y); 76  77  // all surrounding nodes 78  for (int i = -1; i < 2; i++) { 79  for (int j = -1; j < 2; j++) { 80  81  // prevents the node pathing to its self 82  if (i == 0 && j == 0) { 83  continue; 84  } 85  86  TiledMapTileLayer.Cell cell = layer.getCell(x + i, y + j); 87  // is cell outside the map 88  if (cell == null) { 89  continue; 90  } 91  92  // is the cell passable 93  if (cell.getTile().getId() == PASSABLE) { 94  95  addNode(x + i, y + j); 96  addPath(x, y, x + i, y + j); 97  } 98  } 99  } 100  } 101  } 102  } 103  104  /** 105  * Node a position (x, y) 106  * @param x co-ord 107  * @param y co-ord 108  * @return Node at (x, y) or null 109  */ 110  public Node getNode(float x, float y) { 111  Node n = nodes.get(getIndex(x, y)); 112  if (n.cost == -1) { 113  return null; 114  } 115  return n; 116  } 117  118  /** 119  * Find index of a position (x, y) 120  * @param x co-ord 121  * @param y co-ord 122  * @return the index of the parsed co-ordinate 123  */ 124  private int getIndex(float x, float y) { 125  return (int) (mapDim.x * y + x); 126  } 127  128  /** 129  * @return type of cell as far as the tile map is condensed 130  */ 131  private int getType(TiledMapTileLayer.Cell c) { 132  return c.getTile().getId(); 133  } 134  135  /** 136  * Find index of a position (x, y) 137  * @param x co-ord 138  * @param y co-ord 139  * @return the index of the parsed co-ordinate 140  */ 141  private int getIndex(int x, int y) { 142  return (int) mapDim.x * y + x; 143  } 144  145  /** 146  * adds Node unless node is already present 147  * @param x x pos 148  * @param y y pos 149  */ 150  private void addNode(float x, float y) { 151  Node n = nodes.get(getIndex((int) x, (int) y)); 152  if (n.cost > 0) { 153  return; 154  } 155  n.set(x, y); 156  n.cost = 1; 157  } 158  159  /** 160  * Adds path to map (doesn't check for duplicates) 161  * @param a src 162  * @param b dst 163  */ 164  private void addPath(Node a, Node b) { 165  Path path = new Path(a, b); 166  167  if (!nodePaths.containsKey(a)) { 168  nodePaths.put(a, new Array<>()); 169  } 170  nodePaths.get(a).add(path); 171  paths.add(path); 172  } 173  174  /** 175  * Adds path to map (doesn't check for duplicates) 176  * @param x1 src.x 177  * @param y1 src.y 178  * @param x2 dst.x 179  * @param y2 dst.y 180  */ 181  private void addPath(float x1, float y1, float x2, float y2) { 182  Node a = getNode(x1, y1); 183  Node b = getNode(x2, y2); 184  185  addPath(a, b); 186  } 187  188  /** 189  * @param node the node being queried 190  * @return the index of the parsed node 191  */ 192  @Override 193  public int getIndex(Node node) { 194  return getIndex(node.getPosition().x, node.getPosition().y); 195  } 196  197  /** 198  * @return the amount of nodes present in the map 199  */ 200  @Override 201  public int getNodeCount() { 202  return (int) (mapDim.x * mapDim.y); 203  } 204  205  /** 206  * @param fromNode the node being queried 207  * @return the list of connections present starting from the parsed node 208  */ 209  @Override 210  public Array<Connection<Node>> getConnections(Node fromNode) { 211  if (nodePaths.containsKey(fromNode)) { 212  return nodePaths.get(fromNode); 213  } 214  215  return new Array<>(); 216  } 217  218  //public GraphPath<Node> findPath(Node start, Node goal) { 219  // if (start == null || goal == null) { 220  // return null; 221  // } 222  // GraphPath<Node> path = new DefaultGraphPath<>(); 223  // new IndexedAStarPathFinder<>(this).searchNodePath(start, goal, heuristic, path); 224  // return path; 225  // } 226  227  //public QueueFIFO<Vector2> findOptimisedPath(Node a, Node b) { 228  // GraphPath<Node> path = findPath(a, b); 229  // QueueFIFO<Vector2> res = new QueueFIFO<>(); 230  // Vector2 delta = new Vector2(); 231  // float sequenceLength = 0; // the amount of times a 232  // Vector2 cur = new Vector2(); 233  // 234  // Vector2 prev = path.get(0).getPosition(); 235  // for (int i = 1; i < path.getCount(); i++) { 236  // Node n = path.get(i); 237  // cur.set(n.getPosition()); 238  // // d contains the current vector between the current pos and prev 239  // Vector2 d = cur.cpy(); 240  // d.sub(prev); 241  // 242  // 243  // if (delta.x == d.x && delta.y == d.y) { 244  // sequenceLength++; 245  // } else { 246  // res.add(delta.scl(sequenceLength)); 247  // delta = d; 248  // sequenceLength = 1; 249  // } 250  // prev.set(cur); 251  // } 252  // res.remove(0); 253  // res.add(delta.scl(sequenceLength)); 254  // return res; 255  // } 256  257  //public QueueFIFO<Vector2> findOptimisedPath(Vector2 a, Vector2 b) { 258  // Node n1 = getNode(a.x, a.y); 259  // Node n2 = getNode(b.x, b.y); 260  // return findOptimisedPath(n1, n2); 261  // } 262  263  //public QueueFIFO<Vector2> findOptimisedPath(float x1, float y1, float x2, float y2) { 264  // Node a = getNode(x1, y1); 265  // Node b = getNode(x2, y2); 266  // return findOptimisedPath(a, b); 267  // } 268 }