I’m in early stage of pet project about space battles.
In this experiment I expolre flocking behavoir for oponent AI + controllig ship.
Ship heads (and push) towards anywhere I click, and 2 flocks try to maintain their cohesion and chase ship. No models so far, only arrows (green arrow is velocity, colored arrow is facing) and particle emmiters.
http://www.youtube.com/watch?v=i1qo_DjvWo4
and earlier experiments, lot of yellow arrows chasing red arrow (and being dumb doing it, so they orbit it instead flying through)
http://www.youtube.com/watch?v=JVpGLeGcWpI
Looks cool I fixed your links so the youtube videos get displayed right in the forum.
Thanx
I found serious error in weighting repulsion force, i accidentaly made higher with distance instead of lower. Instead of something like f = 1/(d*d) I used f = sqrt(sqrt(d)).
After correcting it, it does not look so good, repulsion is localised and overall its much more chaotic.
How are you “steering” the ‘birds’ in the flock?
they have circular sight
for everyone in sight
average of speeds
average of positions
sum of repelent “force”
how much I differe from avg speed & position
how far from point where I want to be I am (but clap this, so it cannot become dominant).
multiply it with weights and add it together.
Result is vector in which direction I want to move.
Rotate to face this direction.
If facing in this direction “enough”, engage thrusters.
Problem with this: If ship faces wrong way, it cannot take evasive action until it rotates at least 90degrees towards its intended direction.
[java] public AgentAction applyTo(Agent agent,
float timeDelta) {
AgentState cs = agent.getCurrState();
Vector2f dest = getDest();
Vector2f toDest = new Vector2f(dest.x, dest.y).subtract(cs.getPos());
SmartMap<Agent> sm = r2.getSmartMap();
List<Agent> seen = sm.findAll(cs.getPos(), sight);
Vector2f accPos = new Vector2f();
Vector2f accVel = new Vector2f();
Vector2f accRep = new Vector2f();
int seenFlock = 0;
Vector2f pos = cs.getPos();
for (Agent a : seen) {
if (a == agent) {
continue;
}
// collision avoidance
Vector2f dp = a.getPos().subtract(pos);
float angle = dp.getAngle();
float l = dp.length();
// float modl = -sqrt(sqrt(l * 2.0f));
float modl = -1.0f/(l*l);
accRep.addLocal(cos(angle) * modl, sin(angle) * modl);
// flock specific
if (isMemberOfMyFlock(a)) {
seenFlock++;
AgentState acs = a.getCurrState();
Vector2f apos = acs.getPos();
Vector2f avel = acs.getVel();
accPos.addLocal(apos);
accVel.addLocal(avel);
}
}
float posWeight = 1.0f;
float velWeight = 0.5f;
float repWeight = 10.00f;
float todWeight = 0.05f;
float maxToDest = 20;
Vector2f want = new Vector2f();
if (seenFlock > 0) {
Vector2f avgPos = accPos.divide(seenFlock);
Vector2f wantDp = avgPos.subtract(pos);
want.addLocal(wantDp.mult(posWeight));
Vector2f avgVel = accVel.divide(seenFlock);
Vector2f wantDv = avgVel.subtract(cs.getVel());
want.addLocal(wantDv.mult(velWeight));
}
want.addLocal(accRep.mult(repWeight));
float tda = toDest.getAngle();
float tdl = toDest.length();
tdl = clamp(tdl, 0, maxToDest);
Vector2f mToDest = vectFromPolar(tdl, tda);
want.addLocal(mToDest.mult(todWeight));
float dif2 = BehavoirUtil.relAngle(want, cs);
float rot2 = BehavoirUtil.rotateTo(agent, timeDelta, dif2);
ForceAndAngle faa2;
float maxForceXDirDif2 = HALF_PI * 2 / 3;
faa2 = BehavoirUtil.accInDir(agent, dif2, maxForceXDirDif2);
return new AgentAction(rot2, faa2);
}
[/java]
PS: I don’t use bullet physics, because I wanted
- 2d movement - maybe will later turn it 3d, but this is simpler both for me and for player
- know exactly whats going on (NIH syndrome)
- be able to slow down simulation when step takes too long (Maybe bullet does it too, I don’t know)
- interpolate graphical state based on current “rules” state, next one and estimated game time.
If I learn how to do it with bullet, I will migrate it (and especialy when I will turn it realy 3d)
Alpedar said:
Result is vector in which direction I want to move.
Rotate to face this direction.
If facing in this direction "enough", engage thrusters.
In the flocking stuff I've written, speed was always constant so that may be where some of your chaos is coming from. The boids-style algorithm is pretty sensitive to change and I found that both movement speed and turn speed were critical factors in keeping the flock together or making it look more or less chaotic. If this is an issue and you find a good speed that keeps the flock together then you could make this the minimum travel speed and then speed up or slow down based on how far off the average direction a ship was.
...but I'll admit that I haven't clicked through to your video yet. :) I've just written flocking a few times before. :)
Video of corrected behavoir:
http://www.youtube.com/watch?v=TQruNiSjAYU
In first part, yellow flock expands and contrats to get to more stable dispersion, in second part orange flock is shown and common target moves, both flocks slowly start to chase it, but they maintain flock
even at cost of being realy slow persuer.
So what did you end up doing?
The last flocking behavior I played with was just for background in a game I was writing for my kids. You can see it in a test build here:
http://www.progeeks.com/temp/
A couple school of fish are just swimming around. They aren’t following anything though. The flock just goes where it wants to.
I’m still at begining of path.
But my idea is, that they will try to get to prefered distance from enemy, and when main guns are charged, they will strongly prefare facing the enemy. And there will be scouts that will report what they see to rest of flock/fleet.
But I’m bit afraid I will have to go down a lot in flock sizes, because 200 unit that react on each other gives huge performace hit (processing them takes me more than 20ms). I can have 5*100 without problem, but once they bunch up, I have to slow down simulation.
Hm reminds me of the flockgun mod for the ut2003 flock gun. (Yes they fly around the map kinda like tat, but try to chase enemy players from time to time activly)