diff options
author | Jonas Gunz <himself@jonasgunz.de> | 2019-03-05 18:07:29 +0100 |
---|---|---|
committer | Jonas Gunz <himself@jonasgunz.de> | 2019-03-05 18:07:29 +0100 |
commit | d855a4198d67eac8bdb7a180c0a25d747d5e8bfa (patch) | |
tree | d34da81fdb80dc177be12a985d0704d5471e470f | |
parent | da1a27f74e13d6ab94696fd8dc5d20526c6973c6 (diff) | |
download | termgl-d855a4198d67eac8bdb7a180c0a25d747d5e8bfa.tar.gz |
Fixes + Optimisation to collision detection
Collision is only triggered once for every Object
Added options to deactivate collision and input handling to save
resources
-rw-r--r-- | cObjectHandler.cpp | 46 | ||||
-rw-r--r-- | cObjectHandler.h | 12 |
2 files changed, 52 insertions, 6 deletions
diff --git a/cObjectHandler.cpp b/cObjectHandler.cpp index 1daf3c5..11c02e6 100644 --- a/cObjectHandler.cpp +++ b/cObjectHandler.cpp @@ -1,9 +1,12 @@ #include "cObjectHandler.h" -cObjectHandler::cObjectHandler(cRender *_render) : cameraPosition ({0,0}), iActiveObject(0) +cObjectHandler::cObjectHandler(cRender *_render, bool _enableInputMapping, bool _enableCollision) : cameraPosition ({0,0}), iActiveObject(0) { render = _render; + enableInputMapping = _enableInputMapping; + enableCollision = enableInputMapping ? _enableCollision : false; // Collision requires input mapping + objects.push_back(NULL); //Create first Object as Catcher for Events buildHitmap(); @@ -38,7 +41,9 @@ int cObjectHandler::moveObject(int _object, sPos _pos, int _mode) return 0; } - sCollision coll = checkCollision(newPosition, objects[_object]->getSize()); + sCollision coll; + + coll = checkCollision(newPosition, objects[_object]->getSize()); bool abort = false; @@ -152,6 +157,9 @@ int cObjectHandler::charEvent(unsigned char _c) void cObjectHandler::buildHitmap() { + if(!enableInputMapping) + return; + //Rebuild 2D vector sPos size = render->getSize(); @@ -293,11 +301,15 @@ sCollision cObjectHandler::checkCollision(sPos _pos, sPos _size) ret.idv = NULL; ret.hitv = NULL; + if(!enableCollision) + return ret; + int sizeX, sizeY; sizeX = render->getSize().x; sizeY = render->getSize().y; + //The mother of if-statements //No collision for offscreen objects if( (_pos.x < cameraPosition.x && _pos.x + _size.x + cameraPosition.x < 0) || (_pos.x - cameraPosition.x >= iHitMap.size() && _pos.x + _size.x - cameraPosition.x >= iHitMap.size()) || @@ -311,17 +323,43 @@ sCollision cObjectHandler::checkCollision(sPos _pos, sPos _size) { if(!(x >= sizeX || x < 0 || y >= sizeY || y < 0)) { - //Triggers multiple times for one Object. Fix! if(iHitMap[x][y]) collisions.push_back(iHitMap[x][y]); } } } + //Since Object can hit on multiple Pixels, duplications can occur. + //Sort and set duplicates to zero + //-> zeros are at front of vector + for(unsigned int swaps = 1; swaps > 0;) + { + swaps = 0; + + for(unsigned int i = 0; i < collisions.size() - 1; i++) + { + if(collisions[i] > collisions[i + 1]) + { + swaps ++; + unsigned int tmp = 0; + + tmp = collisions[i]; + collisions[i] = collisions[i + 1]; + collisions[i + 1] = tmp; + } + if(collisions[i] == collisions[i + 1]) + collisions[i] = 0; + } + } + + //Since every empty entry is in front, pop them + while(!collisions.front()) + collisions.erase(collisions.begin()); + ret.idc = collisions.size(); ret.idv = (unsigned int*) malloc( sizeof(*ret.idv) * ret.idc ); - for(int i = 0; i < ret.idc; i++) + for(unsigned int i = 0; i < ret.idc; i++) { ret.idv[i] = collisions[i]; } diff --git a/cObjectHandler.h b/cObjectHandler.h index 1e872b3..4a0306b 100644 --- a/cObjectHandler.h +++ b/cObjectHandler.h @@ -20,16 +20,19 @@ struct sCollision }; /** -* Manages cObject and cWiremesh and writes them to a cRender framebuffer. +* Manages cObject and cWiremesh and writes them to a cRender framebuffer (Also works on cObject, since it inherits from cRender!). * forwards input events to corresponding cObject. +* Runs collision checking for every move operation. This is very expensive, so deactivate if not needed (eg. for background animations etc)! */ class cObjectHandler { public: /** * *_render: pointer to instance of cRender all objects will be written to + * _enableCollision: activate collision checking globally. CAUTION: Collision requires InputMapping. If InputMapping is disabled, Collision will NOT WORK! + * _enableInputMapping: activate Input mapping for mouse and keyboard events */ - explicit cObjectHandler(cRender *_render); + explicit cObjectHandler(cRender *_render, bool _enableInputMapping = true, bool _enableCollision = true); /** * Adds _object to managed objects vector @@ -97,6 +100,9 @@ public: private: + /** + * This function is very expensive! Only use when needed! + */ sCollision checkCollision(sPos _pos, sPos _size); void buildHitmap(); @@ -107,4 +113,6 @@ private: cRender *render; unsigned long int iActiveObject; sPos cameraPosition; + bool enableCollision; + bool enableInputMapping; }; |