#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; }