Herding Success

I finally found a decent fix for the GameplayKit/physics problem I’ve been fussing over for months (and that I wrote about yesterday). The good news is that it’s simple. The bad news is that it’s really only applicable to my particular game and probably won’t help anyone else that is looking for a way to get GKAgents to avoid the edges of the screen. Sorry! If it helps, I filed a radar about it.

Prior to figuring this out, I had just set my sheep to wander at a slow speed when they spawned. I set a low weight for the wandering goal because I mostly wanted them to flee from the corgi. I set the weight of each sheep’s fleeing goal high when the corgi approached, and back to zero when the corgi was farther away. I never changed the wandering goal.

The solution was to switch between the fleeing goal and the wandering goal, turning each completely on or off depending on the distance between sheep and corgi. I also assigned a higher weight to the wandering goal and increased the speed. Here’s the function that handles that logic:

func checkDistanceBetweenCorgiAndCritters() {
        enumerateChildNodesWithName("critter", usingBlock: { node, _ in
            let critter = node as! Critter
            let playerVector = CGPointMake(CGFloat(self.player.agent.position.x), CGFloat(self.player.agent.position.y))
            let critterVector = CGPointMake(CGFloat(critter.agent.position.x), CGFloat(critter.agent.position.y))
            let distance = self.distanceFromCGPoints(playerVector, b: critterVector)
            let maxDistance:CGFloat = 200.0
            
            if distance < maxDistance {
                critter.agent.behavior?.setWeight(100, forGoal: self.fleeGoal)
                critter.agent.behavior?.setWeight(0, forGoal: self.wanderGoal)
            } else {
                critter.agent.behavior?.setWeight(0, forGoal: self.fleeGoal)
                critter.agent.behavior?.setWeight(100, forGoal: self.wanderGoal)
            }
        })
    }

I call them critters instead of sheep so that I have some species-flexibility. ;) The above function borrows a method from Apple’s “AgentCatalog” demo project that calculates the distance between two positions. Now when the sheep get “stuck” along the edges, it’s only momentary because as soon as the corgi moves away, they’re super focused on wandering around.

https://www.youtube.com/watch?v=Grdr028WZFk

What’s Next
Here’s my short list of things to work on next:

  • Add some “flocking” behavior so the sheep tend to travel in cohesive groups.
  • Add a “run” animation for the corgi so it’s not just a legless blob.
  • Animate a little “+1” whenever a sheep enters the pen.
  • Add a pause menu with “resume” and “retry” options (and later an option to quit and return to the main menu).
  • Work on background art.