CSE 380 – Computer Game ProgrammingAI & Collision Strategy
Erin Catto’s Box2D
The Big Picture
• Game::processGameLogic:
void Game::processGameLogic()
{
// NOW PERFORM ALL AI
ai->update(this);
// NOW CORRECT FOR COLLISION DETECTION
physics->update(this);
// UPDATE THE WORLD, INCLUDING SPRITE AND
// PARTICLE POSITIONS, FACTORING IN INPUT
// AND AI
world->update(this);
}
This should usually only change sprite velocities.
Exception: spawning
This will update position of all sprites
This may do additional updates for special cases
So what’s our AI strategy?
• SpriteManager has access to all sprites– these are the only things that move
– each frame we must test them against:• each other
• collidable Background tiles
• User Input & AI– should typically only change a character’s velocity
– there are exceptions of course (init positioning)
• Recommendation:– attach a Bot & BotType to each AnimatedSprite
One AI Possibility• class AnimatedSprite HAS-A Bot instance variable• class Bot HAS-A BotType instance variable
– describes current AI state for sprite• bot state, bot frame, bot counter, etc.
– has an update method to update all variables• updates sprite’s vX and vY, not position
• class BotType– describes a type of bot
– types of states, state behaviors, etc.
• Each Frame, GameAI’s update method:
– goes through all sprites and calls update on bot
What about physics?
• Every time we detect a collision, we can store data about that event in one of these objects:
class Collision
{
public:
CollidableObject *co1;
CollidableObject *co2;
float timeOfCollision;
float startTimeOfXCollision;
float startTimeOfYCollision;
float endTimeOfXCollision;
float endTimeOfYCollision;
};
Collision Construction Warning
• Each frame you’ll test for collisions
• You may find multiple collisions each frame
• You’ll want to store info about each collision in a Collision object. Why?– so you can sort them – use them to update the CollidableObjects
• DON’T construct new Collision objects each frame– recycle them instead
Recycling Collision objects
• When your game starts, construct an array of Collision objects. How many?– 100 should do, make it 1000 to be over-safe– an array stack is easiest
• When a collision is detected:– take a collision object from array to use
• When collision resolved:– put it back
GamePhysics::update strategy1. For each sprite: find all collisions with tiles, make a Collision
object for each and compute time of collision. Add each Collision object to a collisions array
2. For each sprite, do the same as step 1 but for all Sprite-Sprite collisions
3. Sort the Collision array by time of collision
4. If collisions array is not empty, move all sprites to time of first collision (change their x, y according to vX, vY and % of frame)
5. Resolve collision (change vX, vY of sprites involved)
…
GamePhysics::update strategy6. Execute collision response code
– Ex: sprite type 1 collides with sprite type 2, so reduce HP of sprite type 1
– this step may be combined with step 5. i.e., sometimes you might not want to change velocity of a sprite after collision
7. Remove all collisions from array involved in resolved collision
8. Perform steps 1 & 2 only for sprites involved in collisions
• Continue to do these steps until you reach the end of the frame
• NOTE: after each collision resolution, make sure the objects are not colliding. Why?
– floating point error
Top Related