Code: Select all
//
// this is the game main loop
//
void gameLoop()
{
while(game->isRunning())
{
u32 deltaMillis = getElapsedTime();
if(game->isServerOnly())
{
serverMain(deltaMillis);
}
else if(game->isClientOnly())
{
clientMain(deltaMillis);
}
else
{
mixedModeMain(deltaMillis);
}
}
}
//
// Server Main Loop
//
void serverMain(u32 deltaMillis)
{
//process the incoming server event queue
processIncomingEvents();
//run the server game
runServerGame(deltaMillis);
//send the server state update to clients
sendUpdatesToClients();
}
//
// client main loop
//
void clientMain(u32 deltaMillis)
{
//receive incoming server updates
//and apply them
processServerUpdates();
//render the game
render(deltaMillis);
//process local input events
//game generate devents and create updates
runClientGame(deltaMillis);
// generate updates and send to server
sendUpdatesToServer();
}
// this is for a server with local client
// or a single player game
void mixedModeMain(u32 deltaMillis)
{
serverMain(deltaMillis);
clientMain(deltaMillis);
}
//this is your main loop for running the server game
void runServerGame(u32 deltaMillis)
{
//run the bot clients
runBots(deltaMillis);
//apply the object transforms
applyObjectTransforms(deltaMillis);
//run collisions
runCollisions();
//process collisions
processCollisions();
}
// this method applies the linear and angular velocities on the objects
// and stores them in the new transformation field
void applyObjectTransforms(u32 deltaMillis)
{
for(int i = 0; i < objectCount; i++)
{
Object* obj = objects[i];
obj->applyTransforms(deltaMillis);
}
}
// this method processes the object with all other objects
// for possible collisions and creates a collision list
void runCollisions()
{
for(int i = 0; i < objectCount; i++)
{
Object* obj = objects[i];
array<Object> collisionCandidates = getProbableCollisionCandidates(obj);
for(int j = 0; j < collisionCandidateCount; j++)
{
Object* testObj = collisionCandidates[j];
if(obj->collide(testObj))
{
CollisionData *cdata = createCollisionData(testObj, obj->getDenyMask());
obj->addCollision(cdata);
}
}
//collision list is sorted in this order
// a) all ghost collisions first
// b) all collision points arranged in increasing order from the oldPosition
obj->sortCollisionList();
}
}
//
// this method narrows down the list of available objects down to the
// list of objects which could probably interact with this object
//
array<Object> getProbableCollisionCandidates(Object* obj, Mask denyMask)
{
array<Object> candidates;
Sphere sphere(obj->getPosition(), COLLISION_RADIUS);
for(int i = 0; i < objectCount; i++)
{
Object* testObj = objects[i];
if(testObj != obj)
{
f32 distance = distance(sphere->getCenter(),testObj->getPosition()) - testObj->getRadius();
if(sphere.getRadius() >= distance)
{
//we check if the object should be allowed or denied outright
if(denyMask->test(testObj->getMask()) )
{
candidates.push_back(testObj);
}
}
}
}
}
//
// this is where we actually process the collisions for each object
//
//
void processCollisions()
{
for(int i = 0; i < objectCount; i++)
{
Object* obj = objects[i];
if(obj->hasNoCollisions())
{
//object did not collide with any
//thing so finalize the transformations
obj->finalizeTransforms();
}
else
{
for(int j = 0; j < obj->getCollisionCount(); j++)
{
CollisionData *cdata = obj->getCollision[j];
if(cdata->isGhostCollision())
{
//process a ghost collision like with a target or a trigger or a zone
obj->processGhostCollision(cdata);
}
else if(cdata->isHardCollision())
{
//process a hard collision like hitting some world object (asteroid, missile)
obj->processHardCollision(cdata);
}
}
if(object->hasHardCollisions())
{
//if the object has a hard collision
// revert to old position
obj->revertToOldPosition();
}
}
obj->clearCollisions();
}
}
//create the collision data describing a single collision
//and its properties
CollisionData* createCollisionData(Object* obj,Object* testObj)
{
CollisionData* cdata;
if(testObj->isGhost())
{
cdata->setGhostCollision(true);
}
else
{
cdata->setHardCollision(false);
}
data->setCollidingObject(testObj);
data->setCollidionTriangles(getCollidingTriangles(obj,testObj));
data->setCollisionPoint(getCollisionPoint(obj,testObj));
return data;
}