Encapsulate Quad colision handling. More...
#include <CollisionMaster.h>
Public Member Functions | |
| CollisionMaster (Engine *pParent) | |
| Associate CM with parent class. | |
| bool | UpdateCollisions () |
| Detect collisions and perform actions. | |
| CollisionMaster (Engine *pParent) | |
| Associate CM with parent class. | |
| bool | UpdateCollisions () |
| Detect collisions and perform actions. | |
Private Member Functions | |
| void | AddToDeleteList (Quad *quad) |
| Add Quad to delete list. | |
| void | AddToNewList (Quad *quad) |
| Add Quad to new list. | |
| void | AddToDeleteList (Quad *quad) |
| Add Quad to delete list. | |
| void | AddToNewList (Quad *quad) |
| Add Quad to new list. | |
Collision detection routines | |
Colision(Quad, Quad) will call other routines depending of Quad type | |
| bool | Collision (Quad *q1, Quad *q2) |
| bool | Collision (Arrow *arrow, Bongo *bongo) |
| Arrow and Bongo are in collision if arrow that bellongs to bongo expires. | |
| bool | Collision (Arrow *arrow, Ball *ball) |
| If Arrow and Ball are in collision, Ball Will be either broken into two smaller balls or removed from scene. | |
| bool | Collision (Box *box, Arrow *arrow) |
| Arrow will stuck in the roof and hitti will bi created at that spot. | |
| bool | Collision (Box *box, Hitti *hitti) |
| Box and hitti are in collosion when hitti expire. | |
| bool | Collision (Box *box, Bongo *bongo) |
| Don't allow bongo to get out of the box. | |
| bool | Collision (Box *box, Ball *ball) |
| Ball is bouncing inside the box. | |
| bool | Collision (Ball *ball1, Ball *ball2) |
| ignore collision of two balls | |
| bool | Collision (Ball *ball, Bongo *bongo) |
| bool | Collision (Quad *q1, Quad *q2) |
| bool | Collision (Arrow *arrow, Bongo *bongo) |
| Arrow and Bongo are in collision if arrow that bellongs to bongo expires. | |
| bool | Collision (Arrow *arrow, Ball *ball) |
| If Arrow and Ball are in collision, Ball Will be either broken into two smaller balls or removed from scene. | |
| bool | Collision (Box *box, Arrow *arrow) |
| Arrow will stuck in the roof and hitti will bi created at that spot. | |
| bool | Collision (Box *box, Hitti *hitti) |
| Box and hitti are in collosion when hitti expire. | |
| bool | Collision (Box *box, Bongo *bongo) |
| Don't allow bongo to get out of the box. | |
| bool | Collision (Box *box, Ball *ball) |
| Ball is bouncing inside the box. | |
| bool | Collision (Ball *ball1, Ball *ball2) |
| ignore collision of two balls | |
| bool | Collision (Ball *ball, Bongo *bongo) |
Private Attributes | |
| Engine * | mpParent |
| std::list< Quad * > | mQuadNewList |
| std::list< Quad * > | mQuadDeleteList |
Encapsulate Quad colision handling.
This class is part of Engine that takes care of colisions. It is separated in own class only for clearnes of the concept
Definition at line 28 of file CollisionMaster.h.
| CollisionMaster::CollisionMaster | ( | Engine * | pParent | ) |
Associate CM with parent class.
Definition at line 17 of file CollisionMaster.cpp.
: mpParent(pParent) {}
| CollisionMaster::CollisionMaster | ( | Engine * | pParent | ) |
Associate CM with parent class.
| void CollisionMaster::AddToDeleteList | ( | Quad * | quad | ) | [private] |
Add Quad to delete list.
Active flag in Quad Object is used to avoid duplicate entries
Definition at line 133 of file CollisionMaster.cpp.
References Quad::IsActive(), mQuadDeleteList, and Quad::SetActive().
Referenced by Collision().
{
if (quad->IsActive() )
{
quad->SetActive(false);
mQuadDeleteList.push_back(quad);
}
}
| void CollisionMaster::AddToDeleteList | ( | Quad * | quad | ) | [private] |
| void CollisionMaster::AddToNewList | ( | Quad * | quad | ) | [private] |
Add Quad to new list.
Definition at line 142 of file CollisionMaster.cpp.
References mQuadNewList.
Referenced by Collision().
{
mQuadNewList.push_front(quad);
}
| void CollisionMaster::AddToNewList | ( | Quad * | quad | ) | [private] |
Add Quad to new list.
| bool CollisionMaster::Collision | ( | Quad * | q1, |
| Quad * | q2 | ||
| ) | [private] |
Definition at line 458 of file CollisionMaster.cpp.
References Bongo::ClassName(), Ball::ClassName(), Arrow::ClassName(), and Quad::ClassName().
Referenced by UpdateCollisions().
{
Quad *qtemp;
if (0 == strcmp(q1->ClassName(), "Quad") || 0 == strcmp(q2->ClassName(), "Quad") )
return false;
if (0 == strcmp(q2->ClassName(), "Box") )
{
qtemp = q2;
q2 = q1;
q1 = qtemp;
}
if (0 == strcmp(q1->ClassName(), "Box") )
{
if (0 == strcmp(q2->ClassName(), "Ball") )
return Collision((Box*)q1, (Ball*)q2);
else if (0 == strcmp(q2->ClassName(), "Bongo") )
return Collision((Box*)q1, (Bongo*)q2);
else if (0 == strcmp(q2->ClassName(), "Arrow") )
return Collision((Box*)q1, (Arrow*)q2);
else if (0 == strcmp(q2->ClassName(), "Hitti") )
return Collision((Box*)q1, (Hitti*)q2);
else
return false;
}
if (0 == strcmp(q2->ClassName(), "Arrow") )
{
qtemp = q2;
q2 = q1;
q1 = qtemp;
}
if (0 == strcmp(q1->ClassName(), "Arrow") )
{
if (0 == strcmp(q2->ClassName(), "Bongo") )
return Collision((Arrow*)q1, (Bongo*)q2);
else if (0 == strcmp(q2->ClassName(), "Ball") )
return Collision((Arrow*)q1, (Ball*)q2);
else
return false;
}
if (0 == strcmp(q2->ClassName(), "Ball") )
{
qtemp = q2;
q2 = q1;
q1 = qtemp;
}
if (0 == strcmp(q1->ClassName(), "Ball") )
{
if (0 == strcmp(q2->ClassName(), "Bongo") )
return Collision((Ball*)q1, (Bongo*)q2);
else
return false;
}
return false;
}
| bool CollisionMaster::Collision | ( | Quad * | q1, |
| Quad * | q2 | ||
| ) | [private] |
| bool CollisionMaster::Collision | ( | Arrow * | arrow, |
| Bongo * | bongo | ||
| ) | [private] |
| bool CollisionMaster::Collision | ( | Arrow * | arrow, |
| Bongo * | bongo | ||
| ) | [private] |
Arrow and Bongo are in collision if arrow that bellongs to bongo expires.
Note that this is not geometrical collision
Definition at line 148 of file CollisionMaster.cpp.
References Bongo::AddArrow(), AddToDeleteList(), Arrow::GetParent(), and Lifetime::IsExpired().
{
if (!arrow->IsExpired() || arrow->GetParent() != bongo)
return false;
arrow->GetParent()->AddArrow();
AddToDeleteList(arrow);
return true;
}
| bool CollisionMaster::Collision | ( | Arrow * | arrow, |
| Ball * | ball | ||
| ) | [private] |
| bool CollisionMaster::Collision | ( | Arrow * | arrow, |
| Ball * | ball | ||
| ) | [private] |
If Arrow and Ball are in collision, Ball Will be either broken into two smaller balls or removed from scene.
Basicaly if collide ball will be destoyed and if ball has more 'lives' left two smaller copies will be created.
Definition at line 167 of file CollisionMaster.cpp.
References Bongo::AddArrow(), AddToDeleteList(), AddToNewList(), Quad_impl::Direction(), Arrow::GetParent(), halfball(), mpParent, Engine::mToKill, Quad_impl::Position(), Ball::Reincarnate(), Ball::SetDirection(), Quad_impl::SetSize(), Quad_impl::Size(), and vec_rotateY().
{
// aproximate minimal possible (gemetricaly) distance
// between two Quads and assign to variable delta.
double delta = ball->Size() /2 + arrow->Size() / 4;
delta = delta * delta;
const double *ball_pos = ball->Position();
const double *arrow_pos = arrow->Position();
bool colided = false;
// delta2 will be actual distance between
// centers.
double delta2 = 0;
double pom;
for (int i = 0; i < 3; i++)
{
pom = ball_pos[i] - arrow_pos[i];
delta2 += pom * pom;
}
if (delta2 < delta)
colided = true;
else
{
// improve aproximation
delta = ball->Size() / 2 + arrow->Size() / 12;
delta = delta * delta;
if (ball_pos[1] < arrow_pos[1])
{
pom = ball_pos[1] - arrow_pos[1];
delta2 -= pom * pom;
if (delta2 < delta)
colided = true;
}
}
if (colided)
{
// create first smaller ball
Ball *b1 = ball->Reincarnate();
if (b1)
{
// create second smaller ball
Ball *b2 = new Ball(*b1);
double r2 = halfball(ball->Size());
b1->SetSize(r2);
b2->SetSize(r2);
const double* dir = b1->Direction();
double dr1[] = { dir[0], dir[1], dir[2] };
double dr2[] = { dir[0], dir[1], dir[2] };
// rotate for PI/4
vec_rotateY(dr1, M_PI_4);
vec_rotateY(dr2, -M_PI_4);
b1->SetDirection(dr1);
b2->SetDirection(dr2);
AddToNewList(b1);
mpParent->mToKill++;
AddToNewList(b2);
mpParent->mToKill++;
}
// get back arrow to bongo
arrow->GetParent()->AddArrow();
AddToDeleteList(arrow);
AddToDeleteList(ball);
mpParent->mToKill--;
return true;
}
return false;
}
| bool CollisionMaster::Collision | ( | Box * | box, |
| Arrow * | arrow | ||
| ) | [private] |
Arrow will stuck in the roof and hitti will bi created at that spot.
| bool CollisionMaster::Collision | ( | Box * | box, |
| Arrow * | arrow | ||
| ) | [private] |
Arrow will stuck in the roof and hitti will bi created at that spot.
Definition at line 247 of file CollisionMaster.cpp.
References AddToNewList(), Quad_impl::Color(), Box::Dim(), Arrow::HitBox(), Arrow::Move(), mpParent, Engine::mTimerDelay, Quad_impl::Position(), Quad_impl::SetDirection(), Quad_impl::Size(), and VZERO.
{
const double *arrow_pos = arrow->Position();
const double *box_dim = box->Dim();
double forse[] = { 0.0, 0.0, 0.0 };
// arrow passed trough the box floor
if (arrow_pos[1] > box_dim[1] )
{
// get it back
forse[1] = - (arrow_pos[1] - box_dim[1]);
arrow->Move(forse);
// notify arrow. it shell ignore gravitation afterwards
arrow->HitBox();
arrow->SetDirection(VZERO);
// create hitti at this spot
double pos[] = { arrow_pos[0], box_dim[1], arrow_pos[2] };
Hitti *hit = new Hitti(
pos,
arrow->Size(),
pos, 0.0,
arrow->Color(),
3,
1000/mpParent->mTimerDelay);
AddToNewList(hit);
}
return false;
}
| bool CollisionMaster::Collision | ( | Box * | box, |
| Hitti * | hitti | ||
| ) | [private] |
Box and hitti are in collosion when hitti expire.
Note that this is not geometrical collision.
Definition at line 279 of file CollisionMaster.cpp.
References AddToDeleteList(), and Hitti::IsExpired().
{
if (!hitti->IsExpired() )
return false;
AddToDeleteList(hitti);
return true;
}
| bool CollisionMaster::Collision | ( | Box * | box, |
| Hitti * | hitti | ||
| ) | [private] |
Box and hitti are in collosion when hitti expire.
Note that this is not geometrical collision.
| bool CollisionMaster::Collision | ( | Box * | box, |
| Bongo * | bongo | ||
| ) | [private] |
Don't allow bongo to get out of the box.
| bool CollisionMaster::Collision | ( | Box * | box, |
| Bongo * | bongo | ||
| ) | [private] |
Don't allow bongo to get out of the box.
ignore z coordinate
Definition at line 289 of file CollisionMaster.cpp.
References Box::Dim(), Quad_impl::Move(), Quad_impl::Position(), Quad_impl::SetDirection(), Quad_impl::Size(), and VZERO.
{
const double *bongo_pos = bongo->Position();
const double *box_dim = box->Dim();
double forse[] = { 0.0, 0.0, 0.0 };
bool col = false;
// for each coordinate check two two sides of the box
for (int i = 0; i < 3; i++)
{
if (i == 1) continue;
if (bongo_pos[i] < bongo->Size()/2)
{
forse[i] = -2 * (bongo_pos[i] - bongo->Size()/2) ;
col = true;
}
if (bongo_pos[i] > box_dim[i] - bongo->Size()/2)
{
forse[i] = -2 * (bongo_pos[i] - box_dim[i] + bongo->Size()/2);
col = true;
}
}
if (col)
{
// get it back
bongo->Move(forse);
bongo->SetDirection(VZERO);
}
return col;
}
| bool CollisionMaster::Collision | ( | Box * | box, |
| Ball * | ball | ||
| ) | [private] |
| bool CollisionMaster::Collision | ( | Box * | box, |
| Ball * | ball | ||
| ) | [private] |
Ball is bouncing inside the box.
Hitti will be crated at the place of hit.
Definition at line 326 of file CollisionMaster.cpp.
References AddToNewList(), Quad_impl::Color(), Box::Dim(), Quad_impl::Direction(), Box::HasHitti(), Ball::Move(), mpParent, Engine::mTimerDelay, Quad_impl::Position(), Quad_impl::Power(), Ball::SetDirection(), and Quad_impl::Size().
{
const double *ball_pos = ball->Position();
double ball_size = ball->Size() / 2;
const double *box_dim = box->Dim();
const double *ball_dir = ball->Direction();
double forse[] = { 0.0, 0.0, 0.0 };
double new_dir[] = { ball_dir[0], ball_dir[1], ball_dir[2] };
double hit_pos[] = { ball_pos[0], ball_pos[1], ball_pos[2] };
double hit_rot[] = { 0.0, 0.0, 0.0 };
double hit_angle = 0.0;
bool col = false;
bool gcol = false;
for (int i = 0; i < 3; i++)
{
col = false;
if (ball_pos[i] < ball_size)
{
col = true;
forse[i] = 2 * (ball_size - ball_pos[i]);
hit_pos[i] = 0.01;
hit_rot[2 - i] = 1.0;
if (0 == i)
hit_angle = 90.0;
else if (1 == i)
hit_angle = 0.0;
else
hit_angle = -90;
}
else if (ball_pos[i] > box_dim[i] - ball_size)
{
col = true;
forse[i] = - 2 * (ball_size + ball_pos[i] - box_dim[i]);
// make hitti apear in front of the box
hit_pos[i] = box_dim[i] - 0.01;
hit_rot[2-i] = 1.0;
if (0 == i)
hit_angle = -90.0;
else if (1 == i)
hit_angle = 180.0;
else
hit_angle = 90;
}
if (col)
{
gcol = true;
if (1 == i && (-new_dir[i] > pow(ball->Size(), 0.5) * ball->Power() ) )
new_dir[i] = pow(ball->Size(), 0.5) * ball->Power();
else
new_dir[i] = -new_dir[i];
}
}
if (gcol)
{
if (box->HasHitti() && hit_pos[1] > 0)
{
AddToNewList(
new Hitti(
hit_pos,
ball_size*0.8,
hit_rot,
hit_angle,
ball->Color(),
3,
1000/mpParent->mTimerDelay)
);
}
ball->Move(forse);
ball->SetDirection(new_dir);
}
return gcol;
}
| bool CollisionMaster::Collision | ( | Ball * | ball1, |
| Ball * | ball2 | ||
| ) | [private] |
ignore collision of two balls
| bool CollisionMaster::Collision | ( | Ball * | ball1, |
| Ball * | ball2 | ||
| ) | [private] |
| bool CollisionMaster::Collision | ( | Ball * | ball, |
| Bongo * | bongo | ||
| ) | [private] |
if ball hit the bongo it will lose a life if it lost last life game will be over.
| bool CollisionMaster::Collision | ( | Ball * | ball, |
| Bongo * | bongo | ||
| ) | [private] |
if ball hit the bongo it will lose a life if it lost last life game will be over.
Definition at line 409 of file CollisionMaster.cpp.
References AddToDeleteList(), AddToNewList(), Ball::Capture(), Bongo::IsVulnerable(), Bongo::Kill(), Engine::mLives, mpParent, Engine::mpStatusDisplay, Quad_impl::Position(), StrokeDisplay::Print(), Quad_impl::SetActive(), Lifetime::SetLongLife(), Quad_impl::Size(), and Engine::UpdateLivesDisplay().
{
// it's flashing or dead
if (!bongo->IsVulnerable() )
return false;
// minimal distance
double delta = (ball->Size() + bongo->Size() )/2;
delta = delta * delta;
const double *ball_pos = ball->Position();
const double *arrow_pos = bongo->Position();
bool colided = false;
double delta2 = 0;
double pom;
for (int i = 0; i < 3; i++)
{
pom = ball_pos[i] - arrow_pos[i];
delta2 += pom * pom;
}
if (delta2 < delta)
colided = true;
if (colided)
{
int lives = bongo->Kill();
mpParent->mLives = lives;
mpParent->UpdateLivesDisplay();
// is it game over? let's see
if (0 == lives)
{
bongo->SetActive(false);
Ball* bl = new Ball(*ball);
// capture bongo in the ball
bl->Capture(bongo);
AddToDeleteList(ball);
AddToNewList(bl);
mpParent->mpStatusDisplay->Print("\nGame Over");
mpParent->mpStatusDisplay->SetLongLife(true);
}
}
return colided;
}
| bool CollisionMaster::UpdateCollisions | ( | ) |
Detect collisions and perform actions.
| bool CollisionMaster::UpdateCollisions | ( | ) |
Detect collisions and perform actions.
Update collision will use two passes.
In pass 1 Quad will be first moved and then check for collisions. During collision check some objects will be added to mQuadNewList and some to mQuadDelete list.
In pass 2 Quads from delete list will be deleted and quads in new list will be added to the scene
Definition at line 30 of file CollisionMaster.cpp.
References Quad::ClassName(), Collision(), Quad::Direction(), Quad::Forse(), Quad::IsActive(), Engine::mGravitation, Quad::Move(), mpParent, mQuadDeleteList, mQuadNewList, Engine::mQuads, Engine::mToKill, and Engine::NextLevel().
{
list<Quad*>::iterator i, j;
Quad *q1;
// first pass: move objects and detect collisions
// update mQuadNewList and mQuadDeleteList
bool col = false;
for (i = mpParent->mQuads.begin(); i != mpParent->mQuads.end(); i++)
{
q1 = *i;
// ignore object that is already deactivated (added to delete list)
if (!q1->IsActive() )
continue;
q1->Move(q1->Direction());
// gravitation will affect all objects except bongo
if (0 != strcmp(q1->ClassName(), "Bongo") )
{
// move object
q1->Move(mpParent->mGravitation);
// speed up falling
q1->Forse(mpParent->mGravitation);
}
// detect collision with remainig objects in list
j = i;
j++;
for (; j != mpParent->mQuads.end(); j++)
{
// Ignore deactivated Quads
// (alredy added to delete list)
if (!(*j)->IsActive() )
continue;
if (Collision(q1, *j) )
col = true;
// If current object is deactivated
// doent check any further
if (!q1->IsActive() )
break;
}
}
// pragmatic algorityham efficency check
static unsigned long traversing = 0;
static unsigned long searches = 0;
searches++;
// pass two: delete and add objects
if (col)
{
list<Quad*>::const_iterator i = mQuadDeleteList.begin();
list<Quad*>::iterator j = mpParent->mQuads.begin();
// delete Quads from mQuadDeleteList
while (i != mQuadDeleteList.end() && j!= mpParent->mQuads.end() )
{
while (*j != *i)
{
j++;
// we could avoid this traversing, but it happend only in 0.1%
if (j == mpParent->mQuads.end() )
{
traversing++;
// assert(traversing-1 < searches / 100);
printf("traversiing %ld, searchs %ld...\n", traversing, searches);
j = mpParent->mQuads.begin();
}
}
delete *j;
j = mpParent->mQuads.erase(j);
i++;
}
mQuadDeleteList.clear();
// add Quads from mQuadNewList
for (i = mQuadNewList.begin(); i != mQuadNewList.end(); i++)
if ( (*i)->Color()[3] == 1.0 )
mpParent->mQuads.push_back(*i);
else
{
mpParent->mQuads.push_front(*i);
}
mQuadNewList.clear();
}
// if there are no Balls to kill
// it's time to go to the next level
if (0 == mpParent->mToKill)
{
mpParent->NextLevel();
}
return col;
}
Engine * CollisionMaster::mpParent [private] |
Definition at line 99 of file CollisionMaster.h.
Referenced by Collision(), and UpdateCollisions().
std::list< Quad * > CollisionMaster::mQuadDeleteList [private] |
Definition at line 101 of file CollisionMaster.h.
Referenced by AddToDeleteList(), and UpdateCollisions().
std::list< Quad * > CollisionMaster::mQuadNewList [private] |
Definition at line 100 of file CollisionMaster.h.
Referenced by AddToNewList(), and UpdateCollisions().
1.8.0