From de29b11a88dbdd3af0824e59b51528b91ee73c54 Mon Sep 17 00:00:00 2001 From: ptitSeb Date: Thu, 30 Nov 2017 22:49:38 +0100 Subject: First commit. Version works on Linux (keyboard only, not configurable) --- src/collision.c | 336 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 336 insertions(+) create mode 100644 src/collision.c (limited to 'src/collision.c') 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 -- cgit v1.2.3