Pattern based AI for Shmup?

Started by
7 comments, last by RPGeezus 18 years ago
Im currently coding a shoot em up, and I was wondering what the best way to implement pattern based AI is? My current idea is to create an array of accelerations that would be applied every few updates to the sprite... ie

int Acceleratons[50];

if(++iTimer > 5)
{
pSprite->vel.x += Accelerations.x;
pSprite->vel.x += Accelerations.y;
iTimer = 0;
i++;
}
Something like that, of course there would be checks to make sure the array wasn't finished and whatnot but that was the gist of the implementation that I thought up for pattern based AI ala Galaga style. Anything better? Or is that how it's done in those type of games too?
Advertisement
I've never worked on a shoot em up, but I guess adding a spline editor to define your paths would be way easier for you to work with.

Also, beware of the kind of code you've written, it's frame based. (by this I mean that computers running at different speed will have a different level of difficuly, as faster computers will move faster through your array. you should get the system time and move forward in your array when the sum of your delta times since last move reaches a threshold (depending on your update rate))

Hope this helps
so something like this then?

int Accelerations[50];
float iTimer = 0;

if(iTimer > 5)
{
pSprite->vel.x += Accelerations.x;
pSprite->vel.x += Accelerations.y;
iTimer -= 5;
i++;
}

iTimer += GetTickCount();


As far as using a spline editor to define my paths, Ill have to look into that.

Would seem much easier for me at least to make the patterns! Although even with the array it would be populated with data from a separate program.
Yep exactly, this is way better.

What you did is very important, just remove the value you were "if"ing on, so that you keep the remainer of the substraction to keep a constant time based update rate.

Also, for your i, you could do something like

const int MaxArrayElem = 50;
int Acceleratons[MaxArrayElem];

...

i = ++i % MaxArrayElem;

so that your i will loop back to 0 as soon as it will reach MaxArrayElem

Also, think of renaming iTimer to something like fTimer ;)

You should also make sure that the resolution of the system call you're using to know your delta t returns you small enough values, under windows I guess you should use timeGetTime or something.

Hope this helps

Eric
Yah for higher resolution under windows there is QueryPerformanceCounter() which gives you a pointer to the hardware clock.

I gotta figure out what there is for SDL but that shouldn't be a problem.

Thanks!
Quote:Original post by xEricx
I've never worked on a shoot em up, but I guess adding a spline editor to define your paths would be way easier for you to work with.

Thats how I did this a while ago, I created a little editor which I could draw curves in and save out as data files, Enemies then follow their predetermined paths in game. AI is practically nonexistant (and not really needed). Some enemies have multiple paths, like an 'in' path which they follow first, then a 'loop' path which they just keep going round and round until they die.

For the curves themselves I found regular bezier curves to work well. A full path is composed of multiple bezier curves all connected together at the ends. This has the advantage of being mathematically much simpler than more complicated curves, and tweeking one control point only tends to affect the local bit of the curve (ie. easy to get the shape you want).
I know half the fun is doing it yourself... but more hours of sleep is also fun... so, anyone has a spline editor source code?
Well, i don't think you need a full-blown spline editor for rock n roll. What you might look for is a regular "spline thingy" on the internet (i'm thinking someone out there must have a java applet for that sort of thing). Then just take the "points" when you make a line you like and hardcode those into your game.

I think you would find it very usefull to program an "interpolator" class that works like this:

Interpolator i;
i.DefineCurve(CURVE_SPLINE);
i.DefinePoints( /* a list of points*/ );

Then when you need a value on the graph, you just ask:
i.GetValue( time );

Basically you are defining a little graph. You set limits on the graph for time (say, from 0-5 seconds) and then define the points for the values. That way you can rip out any position from any point in time:

Interpolator x;
Interpolator y;
/* set up points here */

// move a unit's x/y position:
Unit.MoveTo( x.GetValue(time), y.GetValue(time) )


I have something like this already, but it's only linear. No fancy curve fitting. I think you would find this sort of thing handy though, so if you program it now you can keep it forever. You might also look around and see if anyone else already made something like it. I'm sure someone has.
Quote:Original post by Cubed3
so something like this then?

int Accelerations[50];
float iTimer = 0;

if(iTimer > 5)
{
pSprite->vel.x += Accelerations.x;
pSprite->vel.x += Accelerations.y;
iTimer -= 5;
i++;
}

iTimer += GetTickCount();


I wouldn't do that, myself.

The reason is that it can look jerky sometimes.

This is because you're essentially saying:

Regadless of how much time has passed, provided it greater than 'n', move the object by a fixed amount.

One option is to keep a velocity in terms of pixels per second (or pixels per 1/30th a second), and keep track of the last time you updated the object. (you can have a global value for this).

float elapsedTime = currentTimeMillis() - gLastFrameUpdateTime;elapsedTime = elapsedTime / 1000;   // How many seconds have passed?pSprite->vel.x += Accelerations.x * ( PIXELS_PER_SECOND * elapsedTime);


or something like that. :) Of course, doing it the way you described might be just fine for your application, in which case stick with it.



Best of luck!
Will
------------------http://www.nentari.com

This topic is closed to new replies.

Advertisement