September 19, 2010 13

Post-A-Day #4 – Objective-C Flocking-Behaviors/Boid Class

By in Uncategorized

This post a day thing is great, it’s really made me kick some stuff into gear.

I love flocking behaviors, they’re awesome.
What are Flocking Behaviors?


They were created in the 1980′s from by Criag Renolds, the gist of it is that using 3 simple behaviors, surprisingly complex motion can be formed when you have many actors ( Referred to as Boids, i think Craig meant it as a another way of saying Birds, a more new york way).


The three rules are simple, i’ll explain them as i know them but im no expert.
Separation: Boids want to stay a little away from each other, some elbow room.
Cohesion: Boids want to be grouped, as long as they dont get too close they violate rule 1
Alignment: Boids within a certain range, care about which way other boids are going.

Simple right? Anyway, it makes for very pretty stuff.


A few months ago a friend of mine gave a talk based on Kieth Peters book AdvancED ActionScript 3.0 Animation (a great book). This re-sparked my interest in them, and with my on going interest in iphone development – I decided to try and port Kieth Peters code to Objective-C as best I could with the more limited knowledge I had at the time.

It actually didn’t work all that great, but, I came across SoulWire’s interpretation of Flocking (also in AS3), and I ported that. Maybe it was because it was my second attempt at porting, but this time I got really great results.
200 Objects flocking, all aware of every single other one, on a tiny iphone in your hand, that was very rewarding.
The problem was that I used Box2D’s point class B2Vec2, and then i modified it a little to boot, because I wanted to add a few operators it didn’t have built in. So it left me with something I could not really share with anyone else, and also it was now Combining Objective-C and C++, which always seems like you should avoid it whenever possible.

This was many months ago (march according to my SVN), and i had my fun playing with it and left it at that.
However, recently on the Cocos2D forums someone brought up making a heat seeking missile and I mentioned that stearing behaviors would be a great for that, if maybe over complicated but being a game forum – you worry about that less as it might be a great jumping platform from which additional gameplay ideas stem.

I decided I would revisit my class, as I had been wanting to for a long time, and re-write it using only CGPoints so that it could be pure Objective-C.

This was the result:

LittleBirds from mario gonzalez on Vimeo.

Here’s how to use the class:

 
// Creating it
boid = [Boid spriteWithSpriteSheet:_sheet rect: boidRect];
[boid setSpeedMax: 2.0f andSteeringForceMax: 1.0f];
[boid setWanderingRadius: 16.0f lookAheadDistance: 40.0f andMaxTurningAngle:0.2f];
 
// On your update function
while(boid)
	{
		Boid* b = boid;
		boid = b->_next;
		[b wander: 0.19f];
		[b 
		 flock:_flockPointer
		 withSeparationWeight:0.6f
		 andAlignmentWeight:0.1f
		 andCohesionWeight:0.2f
		 andSeparationDistance:10.0f
		 andAlignmentDistance:30.0f
		 andCohesionDistance:20.0f
		 ];
 
		[b flee:badThingPosition panicAtDistance:5 usingMultiplier:0.6f]; // avoid touch
		[b seek:yummyFoodPosition withinRange:75 usingMultiplier:0.35f]; // go towards touch
                [b update];
	}

The class may be downloaded here:
BoidsExample Version 0.2

It’s coded to the best of my ability, if you have (impactful) optimizations please share.

Update #1:
Fixed Flocking example class linked list creation bug.

Simple rules combine to make seemingly complex behaviors:

Tags: , ,

13 Responses to “Post-A-Day #4 – Objective-C Flocking-Behaviors/Boid Class”

  1. Justin says:

    Looks great Mario. Thanks for sharing and keep up the good work.

  2. [...] This post was mentioned on Twitter by ▲nshuman, cocos2d. cocos2d said: Nice Flocking class for cocos2d: http://bit.ly/cj1YPL thanks Mario Gonzalez. [...]

    [WORDPRESS HASHCASH] The comment’s server IP (208.74.66.43) doesn’t match the comment’s URL host IP (74.112.128.10) and so is spam.

  3. [...] Objective-C Flocking Behaviors has a cocos2d example. (h/t: @cocos2d) [...]

    [WORDPRESS HASHCASH] The comment’s server IP (173.236.157.147) doesn’t match the comment’s URL host IP (173.236.128.158) and so is spam.

  4. Jegolas says:

    Mario,

    I’m trying to use your class in order to move box2d objects around instead of sprites. I want to use box2d so I can take advantage of the collision etc. I added a box2d object and followed some instructions to set the linear velocity of the object from the forum (cocos2d). When I used it, the objects moved, but I had to increase the speed, radius, wander numbers to something high. At this point the objects all floated to the right but displayed some wandering etc. which gave me some hope.

    So I am asking, is this a baseline that can be used to add box2d bodies and have them flock like regular sprites? Would I need to tweak the math in order to take into consideration the physics object(s)?

    Thank you for your response and for sharing your code.

    • onedayitwillmake says:

      Hi Jegolas,

      Interesting approach. One problem that you are probably facing, is that you have two independent sources attempting to move a single object all the time.
      Somewhat like having two telephones, one in each hand giving you instructions, you’re just going to get confused results.

      Is what you want from Box2D to get back, collision detection? Or do you require it to provide collision resolution (that is bounce the ball in the correct direction after it hits the wall for example).

      What you want to do, set the Box2D’s Body position based on the sprite, then run the simulation step after that each tick.

      The boids themselves do not maintain state, each step they are unaware or don’t care where they were last step so once box2d does it’s movement of two overlapping objects, the boids movement of the same object will take over.

      • Jegolas says:

        Oh I figured that there was some confusion somewhere, I was not sure where. Before I went in and perform surgery, I wanted to make sure.

        The reason I want to use box2d is for collision detection. I want to have my objects have the “flocking” gene, so they follow each other etc., and sometimes are attracted to the “food” in some places and avoid others. So these objects can be fish, let’s say, but if they collide with an object (bigger, different fish or wall), then I can perform an action.

        I guess I can run the simulation, position my box2d objects on the location of the boid, then check for collisions. I don’t think I need to handle the collision resolution, at least not right now. This approach might work for what I want.

        Thank you for the info. I’ll give this a try see how it works out.

        Thanks again.

        • onedayitwillmake says:

          That behavior will work perfectly then, what you want are Box2D contact listeners attached to each body

          This entry on my iphone programming blog might be what you’re looking for…
          http://www.learningiphone.com/2009/12/lets-try-creating-box2d-contactlisteners/

          • Jegolas says:

            I created the bodies on each boid and moved the bodies with this line:

            _body->SetTransform(b2Vec2(_internalPosition.x/PTM_RATIO,_internalPosition.y/PTM_RATIO), 0);

            The box2d objects I created are circles so every boid has a circle around the boid image and moves along with it. So far so good. I have implemented a contact listener for my project with the same type logic, actorA contacts actorB set variable etc.

            This type of flocking is what I was looking for to make the actors behave somewhat realistic and have them flock and avoid certain points.

            Thank you again.

  5. I noticed that the project does not compile under iOS 5.0 using the included Cocos2D Sources, so I updated it to support iOS 5.0 and Cocos2D-1.0. You can grab it here:

    http://www.satishmaha.com/BoidsExample_Updated.zip

    Changes:
    - Replaced Cocos2D sources with Cocos2D 1.0 sources
    - Renamed deprecated attributes: CCSpriteSheet and methods associated with it.

  6. onedayitwillmake says:

    Thanks Satish!

    I’m going to move this project onto Github soon, so i note your contributions.

  7. Jiaren Wu says:

    Hi Mario,

    Thank you for sharing this wonderful class, I am sure I could use it in my project for avoiding.

    • onedayitwillmake says:

      How does this class hold up with current version of Cocos2D, im wondering if I need to revisit it or does it generally just work?

Leave a Reply

*