0

I want a sprite to follow the player and I tried to achieve this with the Pathfinding of GameplayKit. This is working, but there's problem. I get the path from the enemy sprite to the player sprite with the following code:

func moveEnemy(to playerPos: CGPoint){
    guard !moving else { return }
    moving = true
    let startNode = GKGraphNode2D(point: float2(Float(self.position.x), Float(self.position.y)))
    let endNode = GKGraphNode2D(point: float2(Float(playerPos.x), Float(playerPos.y)))

    PhysicsHelper.graph.connectUsingObstacles(node: startNode)
    PhysicsHelper.graph.connectUsingObstacles(node: endNode)
    let path = PhysicsHelper.graph.findPath(from: startNode, to: endNode)
    guard path.count > 0 else{ return }

    var actions = [SKAction]()
    for node in path{
        if let point2d = node as? GKGraphNode2D{
            let point = CGPoint(x:CGFloat(point2d.position.x) , y:CGFloat(point2d.position.y))
            let action = SKAction.move(to: point, duration: 1)
            actions.append(action)
        }
    }
    let seq = SKAction.sequence(actions)
    self.run(seq) {
        self.moving = false
    }
}

This is called in another function of my enemy in this block:

case .follow:
    if allowMovement{
        if self.action(forKey: "Hurt") == nil{
           //   orientEnemy(to: playerPos)
              moveEnemy(to: playerPos)
           //   animateWalk()
        }
    }

and this function is called in the update function of my GameScene in this block:

if enemy.checkCircularIntersection(player: player, node: enemy, radius: 40){
     print("Enemy is close to player")
     enemy.update(playerPos: player.position)
}

The checkCircularIntersection function only checks, if the player is near the enemy.

My problem is that the enemy follows the player but when the player moves, the enemy moves to the point where the player stands before, then it stops for a second and then it moves again to the point where the player stood. But the player is already moved away.
Is there a way to let the enemy permanently follow the player and avoid obstacles without stopping?

Marcel
  • 472
  • 2
  • 6
  • 19

1 Answers1

1

Your code specifically guards against moving again until the existing move is completed.

guard !moving else { return }
moving = true

If you want to use paths you will have to recompute and reapply the path movement regularly to account for the target's movement.

However, to achieve your aim, Paths are not the most suitable GameKit tool to use. GKAgents are specifically designed for that kind of thing. It will require a significant refactoring of your code, but take a look at Agents, Goals and Behaviours.

Ali Beadle
  • 4,486
  • 3
  • 30
  • 55
  • What I don't understand is why the enemy sprite is waiting for a second. The function for calculating the path is called by the update method of the GameScene. So when the enemy finishes the path, it should walk the new path directly without waiting. Or does the path finding need that long to find a new path? But thanks for the hint! I will have a deeper look into how to use GameplayKit. – Marcel Dec 01 '17 at 14:37