Advertisement

Zombie movement

Started by June 05, 2006 09:29 PM
6 comments, last by JRavey 18 years, 5 months ago
Here is a small part of my code:

for(int i = 0; i < maxZombies; i++)
{
     bool isInEnv = zombies.getX() > -101 && zombies.getX() < 101 &&
		   zombies.getZ() > -101 && zombies.getZ() < 101 ;
     bool isWithinThreeUnits = ( player1->getX() - zombies.getX() )*( player1->getX() - zombies.getX() ) +
					     ( player1->getZ() - zombies.getZ() ) * ( player1->getZ() - zombies.getZ() ) < 9;
     bool isTouchingOtherZombie = false;
   for(int j = 0; j < maxZombies; j++)
			   {
				   if( j == i)
						continue;
				   if( zombies[j].isDead() )
					   continue;
				   if( ( zombies.getX() <= zombies[j].getX() + 1 ) && (zombies.getX() >= zombies[j].getX() - 1 ) &&
                       ( zombies.getY() <= zombies[j].getY() + 5 ) && (zombies.getY() >= zombies[j].getY() - 3 ) &&
                       ( zombies.getZ() <= zombies[j].getZ() + 1 ) && (zombies.getZ() >= zombies[j].getZ() - 1 ) )
				   {
					   isTouchingOtherZombie = true;
					   break;
				   }

			   }
     if( isInEnv && !isWithinThreeUnits && !isTouchingOtherZombie)
               {   
                   zombies.act(player1->getX(),player1->getY() - 3.25,player1->getZ());   //Move
               }
               else if( isInEnv && isWithinThreeUnits )
               {
                    zombies.attackShortRange(*player1, diff);
               }
               zombies.draw(Zombie2, *player1);
               zombies.determineMovement();
}


Basically, what this does is checks if each zombie is in the environment, if its within three units of the main character, and if a zombie is touching another zombie. If a zombie is in the environment, and its not within three units of the main character, and its not touching another zombie, then move(which for now, just makes the zombie move towards the main character). Otherwise, if the zombie is in the environment and it is within three units of the character, then the zombie should attack. Then everything should redraw. Here's my problem. (for now, lets assume there are 10 zombies) If three zombies are touching eachother, then they won't move, but then they will NEVER move again. What can i tell the zombie to do if it is touching another zombie?
Mitchen Games

You can tell them to move.
Advertisement
Why do you make the zombies clump together and stop? They should continue to wander aimlessly or approach the player, without stopping.
You can randomise the direction if you want, but you need to check for true obstruction: only zombies in the front block movement.
If a zombie is a 2w by 2h box who wants to move its center from (x,y) to (x+dx,y+dy), another zombie at x2,y2 is an obstacle if its box overlaps the hexagon (if dx==0 or dy==0, the rectangle) swept by the moving zombie.
For example, if dx>0 and dy>0 the moving zombie needs a clear hexagon with vertices (x+w,y-h),(x-w,y-h),(x-w,y+h),(x+dx-w,y+dy+h),(x+dx+w,y+dy+h),(x+dx+w,y+dy-h).
For intersection computation the hexagon can be split into 4 triangles by diagonals, 2 squares and 2 triangles (with overlap) etc.
There are only 8 cases and they can possibly be folded together; with little more effort you can even compute partial movements to have your zombies realistically bump into each other, moving in nice waves.

Your zombie to zombie distance calculation is mathematically wrong:
( zombies.getY() <= zombies[j].getY() + 5 ) && (zombies.getY() >= zombies[j].getY() - 3 )

Distance must be symmetric. Did you mean +4 and -4 ? Why do you use the getY() component of position here but not for zombie to player distance?


The repeated accesses to the zombies[] array and the repeated calls to getX(), getY() and getZ() are unnecessary; the performance cost might be small, but the code becomes seriously cluttered and error-prone. You are also computing every zombie to zombie distance twice, but this detail mght be not worth optimizing.

Omae Wa Mou Shindeiru

What do you want to happen when zombies touch each other?

Are they obstucting each other's path when they touch?

Are they happy and idle when they touch?

Are they supposed to flock together until a player wakes them up?

I can't picture the forest for all the trees.

Aren't zombies supposed to wander at a slow speed changing direction either randomly or when they bump into an obstacle?

Remember the awesome zombie town in HL2? Now THAT was fun! :)
Quote: Original post by dgeuss

Remember the awesome zombie town in HL2?


Calgary?

More seriously bballmitch, that kind of code is why you need to use a good structure to express your AI behavior. A simple state machine would help you to see the "big picture" in your problem.

Why do you care if zombie touch each others exactly?

...

Damn I cant make that not sound dirty.

Quote: Original post by Steadtler


Why do you care if zombie touch each others exactly?

...

Damn I cant make that not sound dirty.


overlap
move over (a bit)
exists on the same square

Advertisement
Are you having a collision problem with your zombies, is that you don't want them to move, or is this from your analysis?


It's kind of funny that the zombies meet each other and never move again there's some "broke back" style to that.
Quote:
isTouchingOtherZombie = true;


Edit: That just sounds wrong... just wrong
A wiseman once said nothing, but no one was there to hear it.
I think they should stop if they are walking into a zombie, but if they can proceed unhindered towards their target, they should continue walking. If their target is no long in front of them, they should rotate towards their target and continue walking towards it as long as their is nothing obstructing their path, including another zombie.
屋根を固定するために何パンケーキそれは取るか。紫色、ヘビに足がないばい。

This topic is closed to new replies.

Advertisement