diff options
author | Jonas Gunz <himself@jonasgunz.de> | 2019-03-06 15:04:57 +0100 |
---|---|---|
committer | Jonas Gunz <himself@jonasgunz.de> | 2019-03-06 15:04:57 +0100 |
commit | f439ae911923ee70937592b1ee535e8e8e133808 (patch) | |
tree | 7e23e023d0187caf2d81b26217b3a484bd37f799 /src/cObjectHandler.cpp | |
parent | 6856fcf08c8c4686ddf9e5cb60862184e15d6f0b (diff) | |
download | termgl-f439ae911923ee70937592b1ee535e8e8e133808.tar.gz |
Directory updates
Moved source files to ./src and exmaple and test to ./example
Updated Makefile and .doxygen to use those directorys
Diffstat (limited to 'src/cObjectHandler.cpp')
-rw-r--r-- | src/cObjectHandler.cpp | 368 |
1 files changed, 368 insertions, 0 deletions
diff --git a/src/cObjectHandler.cpp b/src/cObjectHandler.cpp new file mode 100644 index 0000000..11c02e6 --- /dev/null +++ b/src/cObjectHandler.cpp @@ -0,0 +1,368 @@ +#include "cObjectHandler.h" + +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(); +} + +int cObjectHandler::createObject(cObject *_object) +{ + objects.push_back(_object); + + buildHitmap(); + return objects.size() - 1; +} + +int cObjectHandler::moveObject(int _object, sPos _pos, int _mode) +{ + if (_object >= objects.size()) //prevent segmentation faults + return 1; + + if (!objects[_object]) + return 1; + + sPos objPosition = objects[_object]->getPosition(); + sPos newPosition; + + if (_mode == _MOVE_RELATIVE) + newPosition = { objPosition.x + _pos.x, objPosition.y + _pos.y }; + else if (_mode == _MOVE_ABSOLUTE) + newPosition = _pos; + else if (_mode == _MOVE_FORCE_ABSOLUTE) + { + objects[_object]->setPosition(_pos); + return 0; + } + + sCollision coll; + + coll = checkCollision(newPosition, objects[_object]->getSize()); + + bool abort = false; + + if(coll.idc) + { + for(int i = 0; i < coll.idc; i++) + { + if(coll.idv[i] != _object) + abort += objects[_object]->onCollisionActive(0, objects[coll.idv[0]]->onCollisionPassive(0)); + } + } + + if(!abort) + objects[_object]->setPosition(newPosition); + + if(coll.idv) + free (coll.idv); + if(coll.hitv) + free (coll.hitv); + + buildHitmap(); + return 0; +} + +int cObjectHandler::destroyObject(int _object) +{ + if(!objects[_object]) + return 1; + + delete objects[_object]; + objects[_object] = NULL; + + buildHitmap(); + return 0; +} + +int cObjectHandler::write() +{ + render->clear(); + + for (unsigned long int i = 0; i < meshes.size(); i++) + { + if(meshes[i]) + { + moveWiremesh(i,{-cameraPosition.x, -cameraPosition.y, 0} ,_MOVE_RELATIVE); + meshes[i]->write(render); + moveWiremesh(i,{cameraPosition.x, cameraPosition.y, 0},_MOVE_RELATIVE); + } + } + + for (unsigned long int i = 0; i < objects.size(); i++) + { + if (objects[i]) // Check if objects[i] is existent + { + //Draw every Object + sObject obj = objects[i]->getObject(); //get Object #i + + for (int o = 0; o < obj.sizeY; o++) { //y axis + for (int p = 0; p < obj.sizeX; p++) { //x axis + if (obj.cScreen[p][o]) { //Dont overwrite empty pixels + sPos pos{ obj.pos.x + p - cameraPosition.x, + obj.pos.y + o - cameraPosition.y }; + render->drawPoint(obj.cScreen[p][o], pos, true, obj.wColor[p][o]); + } + } + } + } + } + + return 0; +} + +int cObjectHandler::clickEvent(sPos _pos, unsigned int _button) +{ + if(_pos.x >= iHitMap.size()) + return 1; + if(_pos.y >= iHitMap[_pos.x].size()) + return 1; + + + if(objects[ iHitMap[_pos.x][_pos.y] ]) + { + sPos rel_pos; + sPos obj_pos = objects[ iHitMap[_pos.x][_pos.y] ]->getPosition(); + rel_pos.x = _pos.x - obj_pos.x + cameraPosition.x; + rel_pos.y = _pos.y - obj_pos.y + cameraPosition.y; + + iActiveObject = iHitMap[_pos.x][_pos.y]; //Set active object + objects[ iHitMap[_pos.x][_pos.y] ]->onClick(rel_pos, _button); + } + else + return 1; + + return 0; +} + +int cObjectHandler::charEvent(unsigned char _c) +{ + if(objects.size() > iActiveObject) + { + if(objects[iActiveObject]) + { + objects[iActiveObject]->onChar(_c); + } + else + return 1; + } + + return 0; +} + +void cObjectHandler::buildHitmap() +{ + if(!enableInputMapping) + return; + + //Rebuild 2D vector + sPos size = render->getSize(); + + vector<unsigned int> cp; + + while(size.y > cp.size()) + { + cp.push_back(0); + } + + while (size.x > iHitMap.size()) + { + iHitMap.push_back(cp); + } + + while (size.x <= iHitMap.size()) + { + iHitMap.pop_back(); + } + for(unsigned int x = 0; x < iHitMap.size(); x++) + { + for(unsigned int y = 0; y < iHitMap[x].size(); y++) + { + iHitMap[x][y] = 0; + } + } + //Write object IDs to iHitMap + for(unsigned int i = 0; i < objects.size(); i++) + { + if(objects[i]) + { + sPos oPos = objects[i]->getPosition(); + sPos oSize = objects[i]->getSize(); + + oPos.x -= cameraPosition.x; + oPos.y -= cameraPosition.y; + + for(int x = oPos.x; x < oPos.x + oSize.x; x++) + { + for(int y = oPos.y; y < oPos.y + oSize.y; y++) + { + if((x < size.x && y < size.y) && (x >= 0 && y >= 0)) //Objects can be outside the screen. + iHitMap[x][y] = i; + }//for + }//for + }//if + }//for +}//buildHitmap + +void cObjectHandler::focusNext() +{ + iActiveObject++; + + if(iActiveObject >= objects.size()) + iActiveObject = 0; +} + +void cObjectHandler::focus(unsigned int _id) +{ + if(_id >= objects.size()) + iActiveObject = objects.size(); + else + iActiveObject = _id; +} + +int cObjectHandler::createWiremesh(cWiremesh *_mesh) +{ + meshes.push_back(_mesh); + + return meshes.size() - 1; +} + +int cObjectHandler::moveWiremesh(int _mesh, sCoord3d _pos, int _mode) +{ + if (_mesh >= meshes.size()) //prevent segmentation faults + return 1; + + if (!meshes[_mesh]) + return 1; + + sCoord3d meshPosition = meshes[_mesh]->getPosition(); + + if (_mode == _MOVE_RELATIVE) + meshes[_mesh]->setPosition(meshPosition + _pos); + else if (_mode == _MOVE_ABSOLUTE) + meshes[_mesh]->setPosition(_pos); + + return 0; +} + +int cObjectHandler::destroyWiremesh(int _mesh) +{ + if(!meshes[_mesh]) + return 1; + + delete meshes[_mesh]; + meshes[_mesh] = NULL; + + return 0; +} + +int cObjectHandler::rotateWiremesh(int _mesh, sCoord3d _angle) +{ + if (_mesh >= meshes.size()) //prevent segmentation faults + return 1; + + if (!meshes[_mesh]) + return 1; + + meshes[_mesh]->rotate(_angle); + + return 0; +} + +void cObjectHandler::setCameraPosition(sPos _pos, int _mode) +{ + if(_mode == _MOVE_ABSOLUTE) + cameraPosition = _pos; + else if(_mode == _MOVE_RELATIVE) + { + cameraPosition.x += _pos.x; + cameraPosition.y += _pos.y; + } + + buildHitmap(); +} + +sPos cObjectHandler::getCameraPosition() +{ + return cameraPosition; +} + +sCollision cObjectHandler::checkCollision(sPos _pos, sPos _size) +{ + sCollision ret; + vector<unsigned int> collisions; + vector<int> hitTypes; + ret.idc = 0; + 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()) || + (_pos.y < cameraPosition.y && _pos.y + _size.y + cameraPosition.y < 0) || + (_pos.y - cameraPosition.y >= iHitMap[0].size() && _pos.y + _size.y - cameraPosition.y >= iHitMap[0].size()) ) + return ret; + + for(int x = _pos.x - cameraPosition.x; x < _pos.x + _size.x - cameraPosition.x; x++) + { + for(int y = _pos.y - cameraPosition.y; y < _pos.y + _size.y - cameraPosition.y; y++) + { + if(!(x >= sizeX || x < 0 || y >= sizeY || y < 0)) + { + 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(unsigned int i = 0; i < ret.idc; i++) + { + ret.idv[i] = collisions[i]; + } + + return ret; +} |