B4A Library [Lib] Steering Behaviors

This library will bring life to the animated characters of your game by giving them autonomy. It is based on the Craig Reynold's article: Steering Behaviors For Autonomous Characters.

Let's imagine a game where a cat pursues a mouse. You have to write the code to move the mouse, to move the cat and to take the right decisions for both: the cat wants to catch the mouse, the mouse wants to evade the cat. This library will do this very easily. You create two vehicles: a cat and a mouse, with an initial location, a maximum speed, a mass, etc. Then you add their behaviors (with the Steer function) in the main loop: Pursue for the cat, Evade for the mouse. You apply these behaviors with Cat.Move and Mouse.Move, and that's it. You're ready to watch them running around.

You have many behaviors available: Align, Arrive, AvoidObstacles, AvoidVehicles, Cohere, Evade, Flee, FollowPath, Pursue, Seek, Separate, View, and Wander. By combining them, you can create new behaviors like Flock, FollowLeader, StayOnPath...

Starting from version 2, the library is released as a donationware. That means: if you want to use it in your application, please donate something by using the link in my signature. I'll send you the file as soon as I receive your donation.

You can donate what you want, from one dollar to one million dollars (for such an amount, you'll be my friend forever ).
I don't do that to earn a lot of money, just to be rewarded for my work (and I probably won't earn a lot of money this way ;-)).

Thanks in advance for your support.

Version 1.1 Free
11 behaviors: Align, Arrive, AvoidObstacles, Cohere, Evade, Flee, FollowPath, Pursue, Seek, Separate, and Wander.
11 examples.

Version 2.3 Donationware
13 behaviors: Align, Arrive, AvoidObstacles, AvoidVehicles, Cohere, Evade, Flee, FollowPath, Pursue, Seek, Separate, View, and Wander.
Align, Cohere and Separate have an additional parameter: VisionAngle.
New classes: SB_Grid, SB_Node and SB_Pathfinder, with new functions for pathfinding (based on a very fast variant of the A* algorithm)
14 examples.

I provide help only to my donators.

The Accelerated Surface library is required to run the examples.
 

Attachments

  • SteeringBehaviors v1.1.zip
    46.4 KB · Views: 858
Last edited:

wonder

Expert
Licensed User
Longtime User
I haven't tried Box2D yet, but I certainly will in my next project. :)
Out of curiosity, does it support elastic collisions, such as the balls in a pool table?
 

ilan

Expert
Licensed User
Longtime User
SB handles only obstacles with a circular or rectangular shape so you will have to do complex calculations with other shapes. Don't forget to take into account the size of the vehicle for the detection and the risk of tunnel effect (that's why a stepped simulation with a little step is mandatory). You can use the functions of lgMathPolygon and lgMathIntersector to ease your work.


Your collision test is only right for the AABB of the ellipse, not for the ellipse itself, and only if your vehicle is just a point. If this test suits your needs, use a rectangle instead. The ellipse is useless. Otherwise, use the Contains function of the lgMathEllipse function.
Anyway, how do you detect that the car goes off the road with an ellipse ??? I don't understand the idea.


Thanx for your detailed answer.

With the ellipse i cannot know if my vehicle is off the road i just wanted to test a collision with my vehicle.

you have an example in your SB lib "stay on path" maybe i can use it and check if the vehicle exit the path, for the start i will use a reqt with rounded edges and see how i can get collision also if enter or exit the rounded edges (not like the code i wrote above) as you say its onle checking the walls of the ellipse instead of its shape..

Just an idea, could i check with bitmap.getpixel the color of the road and if vehicle is not on that color then he is out of the road??
 
Last edited:

wonder

Expert
Licensed User
Longtime User
It's a very slow method and that means you cannot use the same colors for vehicles and for environment. It's a bit restrictive.
I tried bitmap.getpixel once... never again! SLOOOOOOOOOOOOOOOOOOOOOOOOOOOWWWWWWWWWWWWW ;)
 

sorex

Expert
Licensed User
Longtime User
It's a very slow method and that means you cannot use the same colors for vehicles and for environment.

sure you can, just use single colored sprite masks for the detection ;)

@wonder : it depends on how you do it, it's been used like that in the 90s for pixel perfect collisions and machines where 500+ times slower than what we have now.
 

Informatix

Expert
Licensed User
Longtime User
sure you can, just use single colored sprite masks for the detection ;)

@wonder : it depends on how you do it, it's been used like that in the 90s for pixel perfect collisions and machines where 500+ times slower than what we have now.
That means:
1) you have to create a mask for every collidable object (and if the object is animated, it's a mask for each frame).
2) you have to compare each pixel of these masks (in the overlapping area of their AABB).
3) you have to write very fast functions to do that.
If someone has a working example for Android, I'd be curious to look at its performance.
libGDX-Box2D can detect a collision between any shapes in less than 1 ms and return a lot of useful data about the contact (angle, force, etc.).
 

sorex

Expert
Licensed User
Longtime User
1) right, but photoshop is your friend or you just do it during the splash screen with a few lines of code
2) it depends on the object and if they rotate or not. for "static" ones you can split it up in segments and only scan the segment that falls into the clash.
3) yeah, that always helps ;)

that 1ms is based on that poly method I guess?
 

sorex

Expert
Licensed User
Longtime User
it also depends on how you set up your level. if you use a tile based one you know what to skip aswell.
 

Informatix

Expert
Licensed User
Longtime User
1) right, but photoshop is your friend or you just do it during the splash screen with a few lines of code
To avoid wasting memory, your mask should be an array of booleans (false=transparent, true=opaque), not an image.

that 1ms is based on that poly method I guess?
Yes. It's the time to do a few computations of intersection between collidable polygons. If you increase the number of possible collisions, the computation time increases of course but unless you reach hundreds of contacts (as in my Tumbler demo) Box2D is really usable in real-time (it is used by almost all games under Android that rely upon a physics simulation, e.g. Angry Birds). Box2D is written in C, not in Java.
 

wonder

Expert
Licensed User
Longtime User
Box2D is written in C, not in Java.
That's why I trying to learn how Android NDK works. I've already written my collision detector in C++, but I have no idea how to turn it into a working B4A library... yet.
I'm sure Box2D is way better than my own code, but I'm really looking for a head-to-head performance benchmark once I'm able to get C++ to work with B4A. :D

@Erel, if you're reading this, please consider the C/C++ code integration in B4A, or at least an Android NDK tutorial. :)
 

Informatix

Expert
Licensed User
Longtime User
That's why I trying to learn how Android NDK works. I've already written my collision detector in C++, but I have no idea how to turn it into a working B4A library... yet.
I'm sure Box2D is way better than my own code, but I'm really looking for a head-to-head performance benchmark once I'm able to get C++ to work with B4A. :D

@Erel, if you're reading this, please consider the C/C++ code integration in B4A, or at least an Android NDK tutorial. :)
You should look at my OpenSL library. It includes the code of a C library with the Java wrapper for B4A.
 

ilan

Expert
Licensed User
Longtime User
could it be that the Vehicle speed is effected by the density of the phone?

if i use different phone resolution i get different speed.

i solved it for now like this:

B4X:
V.maxspeed = 7.5/Density
V.maxforce = 2.7/Density

the reason i use 7.5 and 2.7 because i get a good result with those numbers

so on density 3, speed of 2.5 and force of 0.9 is what i want
density 2 also gives me good result. (the less density the faster i need to move the car)

i dont know why its working like this and i dont think this is the right solution.

i will add a calibration mode where the car start driving and hits the first wall.
then i will calculate the time it took for the car to hit the wall and compare it with the time it should be (865ms) and like this calculate the speed for this phone and save it on a text file. every start it will take those values and use them for the speed and force of the vehicle, like this i get the result i really want, but the problem is, every new install this process will be done :confused:
 

Informatix

Expert
Licensed User
Longtime User
could it be that the Vehicle speed is effected by the density of the phone?

if i use different phone resolution i get different speed.
Of course. A speed is expressed in meters/second. On a device, this is converted to pixels/second, so the density matters. Either you choose the dip or % units and you get rid of the density problems, or you stay with pixels and you have to take the density into account.
 

Informatix

Expert
Licensed User
Longtime User
i will add a calibration mode where the car start driving and hits the first wall.
then i will calculate the time it took for the car to hit the wall and compare it with the time it should be (865ms) and like this calculate the speed for this phone and save it on a text file. every start it will take those values and use them for the speed and force of the vehicle, like this i get the result i really want, but the problem is, every new install this process will be done :confused:
That should not be necessary. In my Box2dLight examples, I show how to adapt the fixed time step needed by Box2D to varying conditions.
 

ilan

Expert
Licensed User
Longtime User
Thanx informatix,

Could it be that two phone with the same density will have different speed behaver?

In genymotion i tried my game on a motorola razr with resolution 580*960 density 1.5 and i get a very fast vehicle.speed..

But with an other 1.5 density phone the speed was ok. What else could effect the speed?

Android version?
 

Informatix

Expert
Licensed User
Longtime User
What else could effect the speed?
The speed of the device, that can fluctuate a lot if you have services running in the background (email, antivirus, etc.). That's why a speed should always be affected by the delta time value returned by libGDX (the time spent to compute and render each frame). There's a chapter devoted to the time step in my tutorial about games.
 

ilan

Expert
Licensed User
Longtime User
Thank you, i learned again something new from you. :)

I like the steering behavior lib. It is really how you allready said "bringing life to your characters"
 
Top