summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile9
-rw-r--r--cObject.h20
-rw-r--r--cObjectHandler.cpp66
-rw-r--r--cObjectHandler.h12
-rw-r--r--collision.txt11
-rw-r--r--test.cpp48
-rw-r--r--test_old.cpp165
7 files changed, 289 insertions, 42 deletions
diff --git a/Makefile b/Makefile
index 14a7242..ee0f6d2 100644
--- a/Makefile
+++ b/Makefile
@@ -37,9 +37,12 @@ clean:
rm -df $(OBJ) test.o version.h
rm -Rdf $(BUILDDIR)/lib $(BUILDDIR)/inc $(BUILDDIR)/test doc/
-run: test
+run: gentest
./$(BUILDDIR)/test/test
+memleak: gentest
+ valgrind ./$(BUILDDIR)/test/test
+
genversion:
@echo Building Version
@echo "//Generated by MAKEFILE. DO NOT Edit." > version.h
@@ -50,9 +53,11 @@ genversion:
@echo "#define DATE \"`date +'%d.%m.20%y'`\"" >> version.h
@echo "#define TIME \"`date +'%H:%M:%S'`\"" >> version.h
-test: genversion test.o $(OBJ)
+gentest: genversion test.o $(OBJ)
mkdir -p $(BUILDDIR)/test
$(CC) $(DEBUGFLAGS) -o $(BUILDDIR)/test/test test.o $(OBJ) $(LDFLAGS)
+
+test: gentest
./$(BUILDDIR)/test/test test
doc:
diff --git a/cObject.h b/cObject.h
index d0947da..50b9d18 100644
--- a/cObject.h
+++ b/cObject.h
@@ -3,8 +3,12 @@
#include "cRender.h"
-struct sObject
+#define _HIT_TOP 1
+#define _HIT_BOTTOM 2
+#define _HIT_LEFT 3
+#define _HIT_RIGHT 4
+struct sObject
{
sPos pos;
WORD **wColor;
@@ -60,6 +64,20 @@ public:
*/
virtual void onChar(unsigned char _c){}
+
+ /** Called by cObjectHandler if Object hits another during move operation
+ * return true to abort move, false to continue and allow overlap
+ */
+ virtual bool onCollisionActive(unsigned int _hit, int _passiveObject) { return false; }
+
+ /** Called by cObjectHandler if Object is hit by another object
+ * return any integer value to be identified by hitting object
+ */
+ virtual int onCollisionPassive(unsigned int _hit) { return 0; }
+
+
+
+
protected: //For child classes
cObject();
/** For inheriting classes: sets size of framebuffer
diff --git a/cObjectHandler.cpp b/cObjectHandler.cpp
index ee47226..5f2782b 100644
--- a/cObjectHandler.cpp
+++ b/cObjectHandler.cpp
@@ -26,11 +26,33 @@ int cObjectHandler::moveObject(int _object, sPos _pos, int _mode)
return 1;
sPos objPosition = objects[_object]->getPosition();
+ sPos newPosition;
if (_mode == _MOVE_RELATIVE)
- objects[_object]->setPosition(sPos{ objPosition.x + _pos.x, objPosition.y + _pos.y });
+ 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 = 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);
buildHitmap();
return 0;
@@ -256,3 +278,45 @@ sPos cObjectHandler::getCameraPosition()
{
return cameraPosition;
}
+
+sCollision cObjectHandler::checkCollision(sPos _pos, sPos _size)
+{
+ sCollision ret;
+ vector<unsigned int> collisions;
+ vector<int> hitTypes;
+ ret.idc = 0;
+
+ int sizeX, sizeY;
+
+ sizeX = render->getSize().x;
+ sizeY = render->getSize().y;
+
+ //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]);
+ }
+ }
+ }
+
+ ret.idc = collisions.size();
+ ret.idv = (unsigned int*) malloc( sizeof(*ret.idv) * ret.idc );
+
+ for(int i = 0; i < ret.idc; i++)
+ {
+ ret.idv[i] = collisions[i];
+ }
+
+ return ret;
+}
diff --git a/cObjectHandler.h b/cObjectHandler.h
index 0e7750c..1e872b3 100644
--- a/cObjectHandler.h
+++ b/cObjectHandler.h
@@ -8,9 +8,16 @@
//movemodes
#define _MOVE_RELATIVE 0
#define _MOVE_ABSOLUTE 1
+#define _MOVE_FORCE_ABSOLUTE 2
using namespace std;
+struct sCollision
+{
+ unsigned int *idv;
+ int *hitv;
+ unsigned int idc;
+};
/**
* Manages cObject and cWiremesh and writes them to a cRender framebuffer.
@@ -32,7 +39,8 @@ public:
/**
* Alters position of _object by _pos either relative to old position or Absolute
- * Depending on selected _mode (_MOVE_RELATIVE / _MOVE_ABSOLUTE).
+ * Depending on selected _mode (_MOVE_RELATIVE / _MOVE_ABSOLUTE / _MOVE_ABSOLUTE).
+ * _MOVE_ABSOLUTE not recommended: Collision is only checked at destination. To ensure initialisation, use _MOVE_FORCE_ABSOLUTE!
*/
int moveObject(int _object, sPos _pos, int _mode);
@@ -89,6 +97,8 @@ public:
private:
+ sCollision checkCollision(sPos _pos, sPos _size);
+
void buildHitmap();
vector<cObject*> objects;
diff --git a/collision.txt b/collision.txt
new file mode 100644
index 0000000..509e1bd
--- /dev/null
+++ b/collision.txt
@@ -0,0 +1,11 @@
+collision check by using object map from click registering
+collision passed as returns
+cObject::collision? for both objects?
+
+bool onCollisionActive(unsigned int _hit, onCollisionPassice(_hit))
+_hit: TOP,BOTTOM,LEFT,RIGHT
+return true: abort move ; false: continue move
+
+int onCollisionPassive(unsigned int _hit)
+_hit: TOP,BOTTOM,LEFT,RIGHT
+return: Maybe object type to tell object what it hit
diff --git a/test.cpp b/test.cpp
index 313b632..7d0c9b9 100644
--- a/test.cpp
+++ b/test.cpp
@@ -32,6 +32,11 @@ public:
drawPoint('Q', _pos, true, _COL_YELLOW);
}
+ virtual bool onCollisionActive(unsigned int _hit, int _passiveObject){
+ drawPoint('K', {0,0}, true, _COL_RED);
+ return true;
+ }
+
virtual void onChar(unsigned char _c) { drawPoint(_c, {1,1},true, _COL_BLUE); }
private:
int cc;
@@ -42,7 +47,6 @@ int main(int argc, char* argv[])
cRender render(' ', _COL_DEFAULT, 30,30);
cObjectHandler handler(&render);
cObject ver(45,1);
- cWiremesh obj;
testobject obj2;
cInput input;
@@ -60,37 +64,15 @@ int main(int argc, char* argv[])
ver.drawText(DATE, {20,0}, _COL_WHITE);
ver.drawText(VERSTRING, {0,0}, _COL_WHITE);
int iver = handler.createObject(&ver);
- handler.moveObject(iver, {0,0}, _MOVE_ABSOLUTE);
-
- int x = 15;
- int y = 15;
- int z = 30;
-
- obj.addVector({-x,-y,z}, {2*x,0,0}, '+', _COL_RED);
- obj.addVector({-x,-y,z}, {0,2*y,0}, '+', _COL_RED);
- obj.addVector({-x,y,z}, {2*x,0,0}, '+', _COL_RED);
- obj.addVector({x,-y,z}, {0,2*y,0}, '+', _COL_RED);
-
- obj.addVector({-x,-y,0}, {0,0,z}, ':', _COL_RED);
- obj.addVector({x,-y,0}, {0,0,z}, ':', _COL_RED);
- obj.addVector({-x,y,0}, {0,0,z}, ':', _COL_RED);
- obj.addVector({x,y,0}, {0,0,z}, ':', _COL_RED);
-
- obj.addVector({-x,-y,0}, {2*x,0,0}, ',', _COL_RED);
- obj.addVector({-x,-y,0}, {0,2*y,0}, ',', _COL_RED);
- obj.addVector({-x,y,0}, {2*x,0,0}, ',', _COL_RED);
- obj.addVector({x,-x,0}, {0,2*y,0}, ',', _COL_RED);
- int imesh = handler.createWiremesh(&obj);
+ handler.moveObject(iver, {0,0}, _MOVE_FORCE_ABSOLUTE);
int iobj2 = handler.createObject((cObject*)&obj2);
- handler.moveObject(iobj2, {3,3}, _MOVE_ABSOLUTE);
+ handler.moveObject(iobj2, {3,3}, _MOVE_FORCE_ABSOLUTE);
sPos middle = render.getSize();
middle.x /= 2;
middle.y /= 2;
- handler.moveWiremesh(imesh,{middle.x,middle.y,0}, _MOVE_ABSOLUTE);
-
while( loop )
{
sInputEvent ie = input.poll();
@@ -126,22 +108,16 @@ int main(int argc, char* argv[])
switch(ie.c)
{
case 'w':
- handler.rotateWiremesh(imesh,{-10,0,0});
+ handler.moveObject(iobj2, {0,-1}, _MOVE_RELATIVE);
break;
case 's':
- handler.rotateWiremesh(imesh,{10,0,0});
+ handler.moveObject(iobj2, {0,1}, _MOVE_RELATIVE);
break;
case 'a':
- handler.rotateWiremesh(imesh,{0,-10,0});
+ handler.moveObject(iobj2, {-1,0}, _MOVE_RELATIVE);
break;
case 'd':
- handler.rotateWiremesh(imesh,{0,10,0});
- break;
- case 'q':
- handler.rotateWiremesh(imesh,{0,0,-10});
- break;
- case 'e':
- handler.rotateWiremesh(imesh,{0,0,10});
+ handler.moveObject(iobj2, {1,0}, _MOVE_RELATIVE);
break;
};
}
@@ -151,8 +127,6 @@ int main(int argc, char* argv[])
}
}
- handler.rotateWiremesh(imesh,{1,1,1});
-
handler.write();
render.render();
framecounter++;
diff --git a/test_old.cpp b/test_old.cpp
new file mode 100644
index 0000000..313b632
--- /dev/null
+++ b/test_old.cpp
@@ -0,0 +1,165 @@
+#include <unistd.h>
+#include <string>
+
+#include "version.h"
+
+#include "cRender.h"
+#include "cObject.h"
+#include "cObjectHandler.h"
+#include "cInput.h"
+#include "cWiremesh.h"
+
+//#include "testobject.h"
+
+class testobject : cObject
+{
+public:
+ testobject()
+ {
+ setSize(10,5);
+ cc = 0;
+
+ drawRectangle('#', NULL, {0,0}, {9,4}, _COL_GREEN, _COL_DEFAULT);
+ }
+
+ ~testobject() { destruct(); }
+
+ virtual void onClick(sPos _pos, unsigned int _button)
+ {
+ cc++;
+ drawText(std::to_string(cc), {2,2}, _COL_RED);
+
+ drawPoint('Q', _pos, true, _COL_YELLOW);
+ }
+
+ virtual void onChar(unsigned char _c) { drawPoint(_c, {1,1},true, _COL_BLUE); }
+private:
+ int cc;
+};
+
+int main(int argc, char* argv[])
+{
+ cRender render(' ', _COL_DEFAULT, 30,30);
+ cObjectHandler handler(&render);
+ cObject ver(45,1);
+ cWiremesh obj;
+ testobject obj2;
+
+ cInput input;
+
+ unsigned int framecounter = 0;
+ bool loop = true;
+
+ if(argc > 1)
+ {
+ loop = false;
+ }
+
+ render.render();
+
+ ver.drawText(DATE, {20,0}, _COL_WHITE);
+ ver.drawText(VERSTRING, {0,0}, _COL_WHITE);
+ int iver = handler.createObject(&ver);
+ handler.moveObject(iver, {0,0}, _MOVE_ABSOLUTE);
+
+ int x = 15;
+ int y = 15;
+ int z = 30;
+
+ obj.addVector({-x,-y,z}, {2*x,0,0}, '+', _COL_RED);
+ obj.addVector({-x,-y,z}, {0,2*y,0}, '+', _COL_RED);
+ obj.addVector({-x,y,z}, {2*x,0,0}, '+', _COL_RED);
+ obj.addVector({x,-y,z}, {0,2*y,0}, '+', _COL_RED);
+
+ obj.addVector({-x,-y,0}, {0,0,z}, ':', _COL_RED);
+ obj.addVector({x,-y,0}, {0,0,z}, ':', _COL_RED);
+ obj.addVector({-x,y,0}, {0,0,z}, ':', _COL_RED);
+ obj.addVector({x,y,0}, {0,0,z}, ':', _COL_RED);
+
+ obj.addVector({-x,-y,0}, {2*x,0,0}, ',', _COL_RED);
+ obj.addVector({-x,-y,0}, {0,2*y,0}, ',', _COL_RED);
+ obj.addVector({-x,y,0}, {2*x,0,0}, ',', _COL_RED);
+ obj.addVector({x,-x,0}, {0,2*y,0}, ',', _COL_RED);
+ int imesh = handler.createWiremesh(&obj);
+
+ int iobj2 = handler.createObject((cObject*)&obj2);
+ handler.moveObject(iobj2, {3,3}, _MOVE_ABSOLUTE);
+
+ sPos middle = render.getSize();
+ middle.x /= 2;
+ middle.y /= 2;
+
+ handler.moveWiremesh(imesh,{middle.x,middle.y,0}, _MOVE_ABSOLUTE);
+
+ while( loop )
+ {
+ sInputEvent ie = input.poll();
+
+ if(ie.type != _EVENT_NULL)
+ {
+ if(ie.type == _EVENT_KEY)
+ {
+ switch (ie.c)
+ {
+ case 'A'://up
+ handler.setCameraPosition({0,-1}, _MOVE_RELATIVE);
+ break;
+ case 'B'://down
+ handler.setCameraPosition({0,1}, _MOVE_RELATIVE);
+ break;
+ case 'C'://right
+ handler.setCameraPosition({1,0}, _MOVE_RELATIVE);
+ break;
+ case 'D'://left
+ handler.setCameraPosition({-1,0}, _MOVE_RELATIVE);
+ break;
+ };
+ }
+ else if (ie.type == _EVENT_MOUSE)
+ {
+ if(ie.b == 0)
+ handler.clickEvent({ie.x, ie.y}, 0);
+ }
+ else if (ie.type == _EVENT_CHAR)
+ {
+ //handler.charEvent(ie.c);
+ switch(ie.c)
+ {
+ case 'w':
+ handler.rotateWiremesh(imesh,{-10,0,0});
+ break;
+ case 's':
+ handler.rotateWiremesh(imesh,{10,0,0});
+ break;
+ case 'a':
+ handler.rotateWiremesh(imesh,{0,-10,0});
+ break;
+ case 'd':
+ handler.rotateWiremesh(imesh,{0,10,0});
+ break;
+ case 'q':
+ handler.rotateWiremesh(imesh,{0,0,-10});
+ break;
+ case 'e':
+ handler.rotateWiremesh(imesh,{0,0,10});
+ break;
+ };
+ }
+ else if (ie.type == _EVENT_TERM)
+ {
+ return 0;
+ }
+ }
+
+ handler.rotateWiremesh(imesh,{1,1,1});
+
+ handler.write();
+ render.render();
+ framecounter++;
+
+ if(loop)
+ usleep(10*1000);
+ }
+
+ return 0;
+}