I am trying to make a sprite move towards a point while avoiding some obstacles. The graph that I am using is a GKObstacleGraph
, obtained from this scene:
For simplicity I decided not to use a circular physics body for the obstacles, but it's enough to use the sprites' bounds for now. So this is how I created the graph:
lazy var graph:GKObstacleGraph? =
{
guard let spaceship = self.spaceship else { return nil }
let obstacles = SKNode.obstacles(fromNodeBounds: self.rocks)
let graph = GKObstacleGraph(obstacles: obstacles, bufferRadius: Float(spaceship.size.width))
return graph
}()
When the user taps on any location of the scene, the spaceship should start moving toward that position by avoiding the obstacles:
func tap(locationInScene location:CGPoint)
{
guard let graph = self.graph else { return }
guard let spaceship = self.spaceship else { return }
let startNode = GKGraphNode2D(point: vector_float2(withPoint: spaceship.position))
let endNode = GKGraphNode2D(point: vector_float2(withPoint: location))
graph.connectUsingObstacles(node: startNode)
graph.connectUsingObstacles(node: endNode)
let path = graph.findPath(from: startNode, to: endNode)
print(path)
let goal = GKGoal(toFollow: GKPath(graphNodes: path, radius: Float(spaceship.size.width)) , maxPredictionTime: 1.0, forward: true)
let behavior = GKBehavior(goal: goal, weight: 1.0)
let agent = GKAgent2D()
agent.behavior = behavior
graph.remove([startNode, endNode])
spaceship.entity?.addComponent(agent)
// This is necessary. I don't know why, but if I don't do that, I
// end up having a duplicate entity in my scene's entities array.
self.entities = [spaceship.entity!]
}
But when I tap on a point on the scene, the spaceship starts moving indefinitely upwards. I tried to print the position of the GKAgent
at every frame, and this is what I got:
With very low values, the spaceship still keeps moving upwards without stopping, ever.
This is my project on GitHub.
location
)? – Alvertaalveslazy var graph
... it looks like it's not letting you useself.rocks
orself.spaceship
for some reason. I tried fixing it for a minute but I'm scratching my head myself here. – Complementrock.physicsBody = SKPhysicsBody(circleOfRadius: rock.size.width)
inside yourrocks
computed property getter. I have no idea why this happens, but to avoid it you can go to GameScene.sks, highlight all the rocks, go to the attributes inspector, and under Physics Definition, select Bounding Circle for Body Type. Make sure you deselect Dynamic, Allows Rotation, and Affected By Gravity. Now your rocks will have physics bodies, and your ship will not move up. Though it looks like your entity behavior still doesn't work... – Destitution