I have a map with obstacles that can be placed by the user. And sprites that move from the right of the map to the left.
As the user places obstacles they're added to my game's graph (GKObstacleGraph) and each time I check if a path from the start point to the end point is available. If it's not, it means the user has blocked the path entirely, so I remove the placed obstacle.
That should open the path up again, however it doesn't. It's as if the obstacle is still there.
I have a debug function which loops through all the obstacles in my graph node, showing me visually where they are. It runs each time I add an obstacle. And after I place an obstacle that blocks the path (which is then removed immediately) it shows that there is no obstacle there. The path is clear.
func createObstacle(coordinates: CCCordinates) {
let tX = -game.mapSize.widthHalf + (coordinates.x*game.tileSize.value) + (game.tileSize.valueHalf)
let tY = game.mapSize.heightHalf - (coordinates.y*game.tileSize.value) - (game.tileSize.valueHalf)
let obstacle = CCObstacle(color: color.red, size: game.obstacleSize.size)
obstacle.position = CGPoint(x: tX, y: tY)
let polygonObstacle = getPolygonObstacleForSpriteNode(obstacle)
game.graph.addObstacles([polygonObstacle])
let pathClear = checkPath()
print("Path Clear: \(pathClear)")
if pathClear {
let texture = SKTexture(imageNamed: "obstacle")
obstacle.texture = texture
obstacle.coordinates = coordinates
obstacle.name = "obstacle:\(obstacle.coordinates.convertToString())"
obstacle.zPosition = 5
for var i = 0; i < game.sprites.count; i++ {
let sprite = game.sprites[i]
updatePathForSprite(sprite)
}
panels.map.addChild(obstacle)
} else {
game.graph.removeObstacles([polygonObstacle])
print("removedObstacle")
}
drawAllObstacleOutlines()
}
This code works perfectly until pathClear returns false and the code in else runs. Even though the obstacle is removed from the graph (and the drawAllObstacleOutlines() function confirms that) pathClear always returns false afterwards.
Unless I use:
game.graph.removeAllObstacles()
If I replace the removeObstacles([]) line with that line above. It lets me place obstacles again. (It works even if I add back all the obstacles that were removed, excluding the one that blocked the path.)
The function updatePathForSprite basically calls this one below:
func getPathForNodeToEndPoint(startPoint: CGPoint) -> [GKGraphNode] {
let startNode = GKGraphNode2D(point: float2(Float(startPoint.x), Float(startPoint.y)))
let endNode = GKGraphNode2D(point: float2(Float(game.finishPoint.x), Float(game.finishPoint.y)))
game.graph.connectNodeUsingObstacles(startNode, ignoringBufferRadiusOfObstacles: game.outerTileObstacles)
game.graph.connectNodeUsingObstacles(endNode, ignoringBufferRadiusOfObstacles: game.outerTileObstacles)
let path:[GKGraphNode2D] = game.graph.findPathFromNode(startNode, toNode: endNode) as! [GKGraphNode2D]
game.graph.removeNodes([startNode, endNode])
return path
}
Does anyone know what's going on here?
EDIT: I may have found something weird.
When I add the following lines above the drawAllObstacleOutlines() line:
print("Obstacles \(game.graph.obstacles.count)")
print("Nodes \(game.graph.nodes!.count)")
It increases as I add obstacles... In my case, nodes is 404 and obstacles is 101, however when I place the obstacle that blocks the path, the output is: obstacles 101, Nodes 0
For some reason it's removing all the other nodes in the graph, even though I only removed one obstacle.