00001 #include <iostream> 00002 00003 #include "Collisionhandler.h" 00004 #include "glfuncs.h" 00005 #include "Level.h" 00006 #include <cmath> 00007 00008 #include <vector> 00009 00010 00011 using namespace std; 00012 00013 CollisionHandler* CollisionHandler::_instance = NULL; 00014 00015 CollisionHandler::CollisionHandler() 00016 :_currentLevel( NULL ) 00017 { 00018 } 00019 00020 CollisionHandler* CollisionHandler::instance() 00021 { 00022 if( _instance == NULL ) 00023 _instance = new CollisionHandler(); 00024 return _instance; 00025 } 00026 00027 bool CollisionHandler::checkCollision( Object *o ) 00028 { 00029 bool collided = false; 00030 vector<Object *> objects = ObjsColliding(o); 00031 00032 for(vector< Object* >::iterator i = objects.begin(); i != objects.end(); i++ ) 00033 { 00034 //non solid objects don't collide with one another 00035 if( (o->solid() )||(*i)->solid() ) 00036 { 00037 o->collide( (*i) ); 00038 (*i)->collide( o ); 00039 collided = true; 00040 } 00041 } 00042 00043 return collided; 00044 } 00045 00046 std::vector<Object*> CollisionHandler::ObjsColliding( Object *o, bool solidOnly) 00047 { 00048 vector<Object*> returnme; 00049 00050 Level* level = Level::instance(); 00051 if( level == NULL ) 00052 return returnme; 00053 00054 bool collided = false; 00055 vector< Object* >& objects = level->getObjects(); 00056 Tile* t; 00057 SDL_Rect box = o->getBox(); 00058 00059 for( int i = box.x / Level::tileWidth; i < ceil( (double)( box.x + box.w ) / Level::tileWidth ); i++ ) 00060 { 00061 for( int j = box.y / Level::tileHeight; j < ceil( (double)( box.y + box.h ) / Level::tileHeight ); j++ ) 00062 { 00063 t = level->getTile( i, j ); 00064 00065 if( t != NULL && o->collidable() && t->collidable() ) 00066 { 00067 /*o->collide( t ); 00068 t->collide( o ); 00069 00070 collided = true;*/ 00071 returnme.push_back(t); 00072 } 00073 } 00074 } 00075 00076 for( vector< Object* >::iterator i = objects.begin(); i != objects.end(); i++ ) 00077 { 00078 // FIXME need some way to only call the collide function of the soonest collision 00079 if( o != (*i) && glfuncs::intersect( box, (*i)->getBox() ) && o->collidable() && (*i)->collidable() && !(o->getType() == BOSS && (*i)->getType() == PLAYER) ) 00081 { 00082 /*o->collide( (*i) ); 00083 (*i)->collide( o ); 00084 00085 collided = true;*/ 00086 returnme.push_back(*i); 00087 } 00088 } 00089 00090 if(solidOnly) 00091 { 00092 for( vector<Object *>::iterator i = returnme.begin(); i!= returnme.end();) 00093 { 00094 if(!(*i)->solid()) 00095 i = returnme.erase(i); 00096 else 00097 i++; 00098 } 00099 } 00100 return returnme; 00101 }
1.4.6-NO