Page 1 of 1

Coding AI for a zombie class

Posted: Fri Sep 11, 2009 11:05 am
by tomtetlaw
I'm trying to code AI for a base class for zombies called CBaseZombie, and it's proving quite a challenge, all I want him to do at the moment is if the camera is a certain distance away from the zombie, then make the zombie slowly move toward the camera. Here is what I have so far:

Code: Select all

//---------------------------------------------------
//
// CBaseZombie::Update
// Input:
//		ICameraSceneNode* cam:
//			the camera node(for distance finding) 
// Output:
// Notes:
//
//----------------------------------------------------
void CBaseZombie::Update(ICameraSceneNode* cam)
{
	if(node)
	{
		pos = node->getPosition();
		rot = node->getRotation();

		if(!pos.X == cam->getPosition().X && pos.Z == cam->getPosition().Z)
		{
			if((cam->getPosition().X - pos.X) < 1)
			{
					node->setPosition(vector3df(pos.X + mov_speed.X, pos.Y, pos.Z)); 
			}
			if((cam->getPosition().Z - pos.Z) < 1)
			{
					node->setPosition(vector3df(pos.X, pos.Y, pos.Z - mov_speed.Z));
			}
		}
	}
}
mov_speed = vector3df(1,1,1)

This sort of works. It moves the zombie towards the camera, but only on the Z axis, I also want it to move toward the camera on the X axis. Can someone give me some ideas or pseudo code to achieve this, I don't want you to just give me the code.

Posted: Fri Sep 11, 2009 11:20 am
by LegendaryZ
Note :

Code: Select all

if(!pos.X == cam->getPosition().X && pos.Z == cam->getPosition().Z) 
the condition is true only if

pos.X != cam->getPosition().X
AND
pos.Z == cam->getPosition().Z

Do you mean by that : "if zombie is away from the camera" ?


I suggest you use vector3df comparison methods, not raw coordinates, I think it's easier

Posted: Fri Sep 11, 2009 11:25 am
by JP
what about:

Code: Select all

void CBaseZombie::Update(ICameraSceneNode* cam)
{
   if(node)
   {
      pos = node->getPosition();
      rot = node->getRotation();

      core::vector3df vec = cam->getPosition() - pos; // the vector towards the camera from the zombie's position

      // calculate how much you want to move towards the camera this frame, I'm just going to do one unit by normalising the vector;
      vec = vec.normalise(); // i think that's the right code, check the docs to be sure

      // move the zombie
      node->setPosition( node->getPosition() + vec );

} 
obviously you also want to rotate the zombie slowly towards the camera, there's code elsewhere on the forum showing how you can do that.

you may be interested to look at IrrAI if all this is a bit much for you... you could atleast get some pointers from looking at the code if you didn't want to use all of it.

Posted: Fri Sep 11, 2009 11:53 am
by tomtetlaw
hey thanks guys for the quick reply, JP, when I run it with your code, the zombie moves REALLY fast lol how would I make it slower?

Posted: Fri Sep 11, 2009 11:57 am
by JP
That's because it's moving one unit every frame. If your game is running at 60fps, for example, then every second the zombie will move 60 units.

What you really want to do is to pass in the elapsed time since the last frame and use that, together with a defined speed of movement for your zombie, to calculate the distance it should move and you multiple the normalised vector by that.

If you search the forum for elapsed AND time then I'm sure you'll find some code showing you how to easily calculate it. It basically gives you consistent movement regardless of your framerate.

Posted: Fri Sep 11, 2009 12:24 pm
by tomtetlaw
Hey thanks, I searched for that and I got LOTS of posts, I didn't know which one to go on, so I chose a random one, it was calleed "syncing the game to a constant fps." and I got this code from it:

Code: Select all

while(device->run()) 
{ 
starttime = timer.getTime(); 
do_stuff(); 
current_deltaT = timer.getTime() - starttime; 

if(current_deltaT < your_wished_constant_delta_time) 
device->sleep(your_wished_constant_delta_time - current_deltaT); 
and I didn't understand it at all :P can you explain it?

Posted: Fri Sep 11, 2009 1:24 pm
by JP
That's not what you're after and should keep looking through the other threads to try and find what it is you need. Though you don't really know what you need so I'll throw you a bone:

Code: Select all

ITimer* pTimer = pDevice->getTimer();
u32 uLastTime = pTimer->getTime();
while( pDevice->run() )
{
    u32 uCurrentTime = pTimer.getTime();
    u32 uElapsedTime = uCurrentTime - uLastTime;
    uLastTime = uCurrentTime;

    // now you do all your necessary updates in which you can use the elapsed time.
    // the distance you want to move your zombie might go something like this:
    f32 fDistance = uElapsedTime * fZombieSpeed;
    // so you multiply the normalised vector within your update function in your previous post with the distance
    vec = vec.normalise() * fDistance;
    
    // now do your render stuff
}
fZombieSpeed you will have to trial and error to find a nice speed for the zombie. The elapsed time will be in milliseconds (i think) so you'll probably want a rather small fZombieSpeed... 0.05f might be a good place to start, even smaller may be better

Posted: Sat Sep 12, 2009 12:38 am
by tomtetlaw
thanks it worked