aboutsummaryrefslogtreecommitdiff
path: root/src/collision.c
diff options
context:
space:
mode:
authorptitSeb2017-11-30 22:49:38 +0100
committerptitSeb2017-11-30 22:49:38 +0100
commitde29b11a88dbdd3af0824e59b51528b91ee73c54 (patch)
treee1aabf8752043998663279fae4359a18c4b4af07 /src/collision.c
parentd87f450f51372ddf013e6bac09f1ef588e6f8bea (diff)
downloadhydracastlelabyrinth-de29b11a88dbdd3af0824e59b51528b91ee73c54.tar.gz
hydracastlelabyrinth-de29b11a88dbdd3af0824e59b51528b91ee73c54.tar.bz2
hydracastlelabyrinth-de29b11a88dbdd3af0824e59b51528b91ee73c54.zip
First commit. Version works on Linux (keyboard only, not configurable)
Diffstat (limited to 'src/collision.c')
-rw-r--r--src/collision.c336
1 files changed, 336 insertions, 0 deletions
diff --git a/src/collision.c b/src/collision.c
new file mode 100644
index 0000000..34d4ddb
--- /dev/null
+++ b/src/collision.c
@@ -0,0 +1,336 @@
+#include "collision.h"
+#include "math.h"
+#include "game.h"
+#include "PHL.h"
+#include "object.h"
+
+int checkMix(Mask r, Mask c);
+int checkRect(Mask r1, Mask r2);
+int checkCircle(Mask c1, Mask c2);
+
+int checkCollision(Mask m1, Mask m2)
+{
+ if (m1.unused != 1 && m2.unused != 1) {
+ if (m1.circle == 0 && m2.circle == 0) {
+ return checkRect(m1, m2);
+ }else if (m1.circle == 1 && m2.circle == 1) {
+ return checkCircle(m1, m2);
+ }else if (m1.circle == 1 && m2.circle == 0) {
+ return checkMix(m2, m1);
+ }else if (m1.circle == 0 && m2.circle == 1) {
+ return checkMix(m1, m2);
+ }
+ }
+
+ return 0;
+}
+
+int checkCollisionXY(Mask m, int x, int y)
+{
+ int result = 0;
+
+ if (m.unused != 1) {
+ if (m.circle == 1) {
+ if (sqrt( pow(x - m.x, 2) + pow(y - m.y, 2) ) <= m.w) {
+ result = 1;
+ }
+ }else{
+ if (x < m.x || x > m.x + m.w || y < m.y || y > m.y + m.h) {
+ }else{
+ result = 1;
+ }
+ }
+ }
+
+ return result;
+}
+
+//Returns 1 or 0 depending on if there is a collision with a type of tile
+int checkTileCollision(int type, Mask m)
+{
+ int result = 0;
+
+ if (m.x < 0) {
+ m.x = 0;
+ }else if (m.x + m.w > 640) {
+ m.x = 640 - m.w;
+ }
+
+ if (m.y < 0) {
+ m.y = 0;
+ }else if (m.y + m.h > 480) {
+ m.y = 480 - m.h;
+ }
+
+ int i;
+ for (i = 0; i < 4; i++) {
+ int tileX = (int)m.x / 40;
+ int tileY = (int)m.y / 40;
+
+ if (i == 1) {
+ tileX = (int)((m.x + m.w - 1) / 40);
+ }else if (i == 2) {
+ tileY = (int)((m.y + m.h - 1) / 40);
+ }else if (i == 3) {
+ tileX = (int)((m.x + m.w - 1) / 40);
+ tileY = (int)((m.y + m.h - 1) / 40);
+ }
+
+ if (collisionTiles[tileX][tileY] == type) {
+ result = 1;
+ i = 4;
+ }
+ }
+
+ return result;
+}
+
+//Returns a tile's demension. Overkill for a lot of situations.
+PHL_Rect getTileCollision(int type, Mask m)
+{
+ PHL_Rect result;
+ result.x = -1;
+ result.y = -1;
+ result.w = 40;
+ result.h = 40;
+
+ //updateMask();
+
+ if (m.x < 0) {
+ m.x = 0;
+ }else if (m.x + m.w > 640) {
+ m.x = 640 - m.w;
+ }
+
+ if (m.y < 0) {
+ m.y = 0;
+ }else if (m.y + m.h > 480) {
+ m.y = 480 - m.h;
+ }
+
+ //PHL_DrawRect(mask.x, mask.y, mask.w, mask.h, PHL_NewRGB(0x00, 0x00, 0xFF));
+
+ int i;
+ for (i = 0; i < 4; i++) {
+ int tileX = (int)m.x / 40;
+ int tileY = (int)m.y / 40;
+
+ if (i == 1) {
+ tileX = (int)((m.x + m.w - 1) / 40);
+ }else if (i == 2) {
+ tileY = (int)((m.y + m.h - 1) / 40);
+ }else if (i == 3) {
+ tileX = (int)((m.x + m.w - 1) / 40);
+ tileY = (int)((m.y + m.h - 1) / 40);
+ }
+
+ if (collisionTiles[tileX][tileY] == type) {
+ result.x = tileX * 40;
+ result.y = tileY * 40;
+ i = 4;
+ //PHL_DrawRect(result.x, result.y, 40, 40, PHL_NewRGB(0xFF, 0x00, 0x00));
+ }
+ //PHL_DrawRect(tileX * 40, tileY * 40, 40, 40, PHL_NewRGB(0x00, 0xFF, 0x00));
+ }
+
+ //updateMask();
+ return result;
+}
+
+int checkTileCollisionXY(int type, int x, int y)
+{
+ int result = 0;
+
+ if (x < 0) {
+ x = 0;
+ }else if (x > 640) {
+ x = 640;
+ }
+
+ if (y < 0) {
+ y = 0;
+ }else if (y > 480) {
+ y = 480;
+ }
+
+ int tileX = (int)x / 40;
+ int tileY = (int)y / 40;
+
+ if (collisionTiles[tileX][tileY] == type) {
+ result = 1;
+ }
+
+ return result;
+}
+
+PHL_Rect getTileCollisionXY(int type, int x, int y)
+{
+ PHL_Rect result;
+ result.x = -1;
+ result.y = -1;
+ result.w = 40;
+ result.h = 40;
+
+ if (x < 0) {
+ x = 0;
+ }else if (x > 640) {
+ x = 640;
+ }
+
+ if (y < 0) {
+ y = 0;
+ }else if (y > 480) {
+ y = 480;
+ }
+
+ int tileX = (int)x / 40;
+ int tileY = (int)y / 40;
+
+ if (collisionTiles[tileX][tileY] == type) {
+ result.x = tileX * 40;
+ result.y = tileY * 40;
+ }
+
+ return result;
+}
+
+void PHL_DrawMask(Mask m)
+{
+ if (m.circle == 0) {
+ PHL_DrawRect(m.x, m.y, m.w, m.h, PHL_NewRGB(255, 255, 255));
+ }else if (m.circle == 1) {
+ PHL_DrawRect(m.x - m.w, m.y - m.w, m.w * 2, m.w * 2, PHL_NewRGB(255, 255, 255));
+ }
+}
+
+int checkMix(Mask r, Mask c)
+{
+ int insidex = 0, insidey = 0;
+
+ if (c.x >= r.x && c.x <= r.x + r.w) {
+ insidex = 1;
+ }
+ if (c.y >= r.y && c.y <= r.y + r.h) {
+ insidey = 1;
+ }
+
+ //Check if circle center is inside rectangle
+ if (insidex == 1 && insidey == 1) {
+ }
+ else if (insidex == 1) {
+ if ((c.y < r.y && r.y - c.y <= c.w) ||
+ (c.y > (r.y + r.h) && c.y - (r.y + r.h) <= c.w)) {
+ }else{
+ return 0;
+ }
+ }else if (insidey == 1) {
+ if ((c.x < r.x && r.x - c.x <= c.w) ||
+ (c.x > (r.x + r.w) && c.x - (r.x + r.w) <= c.w)) {
+ }else{
+ return 0;
+ }
+ }else{
+ //Check points
+ if (sqrt( pow(r.x - c.x, 2) + pow(r.y - c.y, 2) ) <= c.w) {
+ }else if (sqrt( pow(r.x + r.w - c.x, 2) + pow(r.y - c.y, 2) ) <= c.w) {
+ }else if (sqrt( pow(r.x - c.x, 2) + pow(r.y + r.h - c.y, 2) ) <= c.w) {
+ }else if (sqrt( pow(r.x + r.w - c.x, 2) + pow( r.y + r.h - c.y, 2) ) <= c.w) {
+ }else{
+ return 0;
+ }
+ }
+
+ return 1;
+}
+
+int checkRect(Mask r1, Mask r2)
+{
+ if (r1.x > r2.x + r2.w ||
+ r1.x + r1.w < r2.x ||
+ r1.y > r2.y + r2.h ||
+ r1.y + r1.h < r2.y)
+ {
+ return 0;
+ }
+
+ return 1;
+}
+
+int checkCircle(Mask c1, Mask c2)
+{
+ int maxdis = c1.w + c2.w;
+ int dis = sqrt(pow(c2.x - c1.x, 2) + pow(c2.y - c1.y, 2));
+
+ if (dis <= maxdis) {
+ return 1;
+ }
+
+ return 0;
+}
+
+//Heavier tile collision that omits destroyable blocks
+PHL_Rect getTileCollisionWeapon(int type, Mask m)
+{
+ PHL_Rect result;
+ result.x = -1;
+ result.y = -1;
+ result.w = 40;
+ result.h = 40;
+
+ //updateMask();
+
+ if (m.x < 0) {
+ m.x = 0;
+ }else if (m.x + m.w > 640) {
+ m.x = 640 - m.w;
+ }
+
+ if (m.y < 0) {
+ m.y = 0;
+ }else if (m.y + m.h > 480) {
+ m.y = 480 - m.h;
+ }
+
+ //PHL_DrawRect(mask.x, mask.y, mask.w, mask.h, PHL_NewRGB(0x00, 0x00, 0xFF));
+
+ int i;
+ for (i = 0; i < 4; i++) {
+ int tileX = (int)m.x / 40;
+ int tileY = (int)m.y / 40;
+
+ if (i == 1) {
+ tileX = (int)((m.x + m.w - 1) / 40);
+ }else if (i == 2) {
+ tileY = (int)((m.y + m.h - 1) / 40);
+ }else if (i == 3) {
+ tileX = (int)((m.x + m.w - 1) / 40);
+ tileY = (int)((m.y + m.h - 1) / 40);
+ }
+
+ if (collisionTiles[tileX][tileY] == type) {
+ result.x = tileX * 40;
+ result.y = tileY * 40;
+
+ //Check if destroyable block
+ int a;
+ for (a = 0; a < MAX_OBJECTS; a++) {
+ if (objects[a] != NULL) {
+ if (objects[a]->type == 3) {
+ Destroyable* d = objects[a]->data;
+ if (result.x == d->x && result.y == d->y) {
+ result.x = -1;
+ result.y = -1;
+ }
+ }
+ }
+ }
+
+ if (result.x != -1) {
+ i = 4;
+ }
+ }
+ }
+
+ //updateMask();
+ return result;
+} \ No newline at end of file