Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. #include "collision.h"
  2. #include "math.h"
  3. #include "game.h"
  4. #include "PHL.h"
  5. #include "object.h"
  6.  
  7. int checkMix(Mask r, Mask c);
  8. int checkRect(Mask r1, Mask r2);
  9. int checkCircle(Mask c1, Mask c2);
  10.  
  11. int checkCollision(Mask m1, Mask m2)
  12. {
  13.         if (m1.unused != 1 && m2.unused != 1) {
  14.                 if (m1.circle == 0 && m2.circle == 0) {
  15.                         return checkRect(m1, m2);
  16.                 }else if (m1.circle == 1 && m2.circle == 1) {
  17.                         return checkCircle(m1, m2);
  18.                 }else if (m1.circle == 1 && m2.circle == 0) {
  19.                         return checkMix(m2, m1);
  20.                 }else if (m1.circle == 0 && m2.circle == 1) {
  21.                         return checkMix(m1, m2);
  22.                 }
  23.         }
  24.        
  25.         return 0;
  26. }
  27.  
  28. int checkCollisionXY(Mask m, int x, int y)
  29. {
  30.         int result = 0;
  31.        
  32.         if (m.unused != 1) {
  33.                 if (m.circle == 1) {
  34.                         if (sqrt( pow(x - m.x, 2) + pow(y - m.y, 2) ) <= m.w) {
  35.                                 result = 1;
  36.                         }
  37.                 }else{
  38.                         if (x < m.x || x > m.x + m.w || y < m.y || y > m.y + m.h) {
  39.                         }else{
  40.                                 result = 1;
  41.                         }
  42.                 }
  43.         }
  44.        
  45.         return result;
  46. }
  47.  
  48. //Returns 1 or 0 depending on if there is a collision with a type of tile
  49. int checkTileCollision(int type, Mask m)
  50. {
  51.         int result = 0;
  52.        
  53.         if (m.x < 0) {
  54.                 m.x = 0;
  55.         }else if (m.x + m.w > 640) {
  56.                 m.x = 640 - m.w;
  57.         }
  58.        
  59.         if (m.y < 0) {
  60.                 m.y = 0;
  61.         }else if (m.y + m.h > 480) {
  62.                 m.y = 480 - m.h;
  63.         }
  64.        
  65.         int i;
  66.         for (i = 0; i < 4; i++) {
  67.                 int tileX = (int)m.x / 40;
  68.                 int tileY = (int)m.y / 40;
  69.                
  70.                 if (i == 1) {
  71.                         tileX = (int)((m.x + m.w - 1) / 40);
  72.                 }else if (i == 2) {
  73.                         tileY = (int)((m.y + m.h - 1) / 40);
  74.                 }else if (i == 3) {
  75.                         tileX = (int)((m.x + m.w - 1) / 40);
  76.                         tileY = (int)((m.y + m.h - 1) / 40);
  77.                 }
  78.                
  79.                 if (collisionTiles[tileX][tileY] == type) {
  80.                         result = 1;
  81.                         i = 4;
  82.                 }
  83.         }
  84.        
  85.         return result;
  86. }
  87.  
  88. //Returns a tile's demension. Overkill for a lot of situations.
  89. PHL_Rect getTileCollision(int type, Mask m)
  90. {
  91.         PHL_Rect result;
  92.         result.x = -1;
  93.         result.y = -1;
  94.         result.w = 40;
  95.         result.h = 40;
  96.        
  97.         //updateMask();
  98.        
  99.         if (m.x < 0) {
  100.                 m.x = 0;
  101.         }else if (m.x + m.w > 640) {
  102.                 m.x = 640 - m.w;
  103.         }
  104.        
  105.         if (m.y < 0) {
  106.                 m.y = 0;
  107.         }else if (m.y + m.h > 480) {
  108.                 m.y = 480 - m.h;
  109.         }
  110.        
  111.         //PHL_DrawRect(mask.x, mask.y, mask.w, mask.h, PHL_NewRGB(0x00, 0x00, 0xFF));
  112.        
  113.         int i;
  114.         for (i = 0; i < 4; i++) {
  115.                 int tileX = (int)m.x / 40;
  116.                 int tileY = (int)m.y / 40;
  117.                
  118.                 if (i == 1) {
  119.                         tileX = (int)((m.x + m.w - 1) / 40);
  120.                 }else if (i == 2) {
  121.                         tileY = (int)((m.y + m.h - 1) / 40);
  122.                 }else if (i == 3) {
  123.                         tileX = (int)((m.x + m.w - 1) / 40);
  124.                         tileY = (int)((m.y + m.h - 1) / 40);
  125.                 }
  126.                
  127.                 if (collisionTiles[tileX][tileY] == type) {
  128.                         result.x = tileX * 40;
  129.                         result.y = tileY * 40;
  130.                         i = 4;
  131.                         //PHL_DrawRect(result.x, result.y, 40, 40, PHL_NewRGB(0xFF, 0x00, 0x00));
  132.                 }
  133.                 //PHL_DrawRect(tileX * 40, tileY * 40, 40, 40, PHL_NewRGB(0x00, 0xFF, 0x00));
  134.         }
  135.        
  136.         //updateMask();
  137.         return result;
  138. }
  139.  
  140. int checkTileCollisionXY(int type, int x, int y)
  141. {
  142.         int result = 0;
  143.        
  144.         if (x < 0) {
  145.                 x = 0;
  146.         }else if (x > 640) {
  147.                 x = 640;
  148.         }
  149.        
  150.         if (y < 0) {
  151.                 y = 0;
  152.         }else if (y > 480) {
  153.                 y = 480;
  154.         }
  155.        
  156.         int tileX = (int)x / 40;
  157.         int tileY = (int)y / 40;
  158.                
  159.         if (collisionTiles[tileX][tileY] == type) {
  160.                 result = 1;
  161.         }
  162.        
  163.         return result;
  164. }
  165.  
  166. PHL_Rect getTileCollisionXY(int type, int x, int y)
  167. {
  168.         PHL_Rect result;
  169.         result.x = -1;
  170.         result.y = -1;
  171.         result.w = 40;
  172.         result.h = 40;
  173.        
  174.         if (x < 0) {
  175.                 x = 0;
  176.         }else if (x > 640) {
  177.                 x = 640;
  178.         }
  179.        
  180.         if (y < 0) {
  181.                 y = 0;
  182.         }else if (y > 480) {
  183.                 y = 480;
  184.         }
  185.        
  186.         int tileX = (int)x / 40;
  187.         int tileY = (int)y / 40;
  188.                
  189.         if (collisionTiles[tileX][tileY] == type) {
  190.                 result.x = tileX * 40;
  191.                 result.y = tileY * 40;
  192.         }
  193.        
  194.         return result;
  195. }
  196.  
  197. void PHL_DrawMask(Mask m)
  198. {
  199.         if (m.circle == 0) {
  200.                 PHL_DrawRect(m.x, m.y, m.w, m.h, PHL_NewRGB(255, 255, 255));
  201.         }else if (m.circle == 1) {
  202.                 PHL_DrawRect(m.x - m.w, m.y - m.w, m.w * 2, m.w * 2, PHL_NewRGB(255, 255, 255));
  203.         }
  204. }
  205.  
  206. int checkMix(Mask r, Mask c)
  207. {
  208.         int insidex = 0, insidey = 0;
  209.        
  210.         if (c.x >= r.x && c.x <= r.x + r.w) {
  211.                 insidex = 1;
  212.         }
  213.         if (c.y >= r.y && c.y <= r.y + r.h) {
  214.                 insidey = 1;
  215.         }
  216.        
  217.         //Check if circle center is inside rectangle
  218.         if (insidex == 1 && insidey == 1) {
  219.         }
  220.         else if (insidex == 1) {
  221.                 if ((c.y < r.y && r.y - c.y <= c.w) ||
  222.                         (c.y > (r.y + r.h) && c.y - (r.y + r.h) <= c.w)) {
  223.                 }else{
  224.                         return 0;
  225.                 }
  226.         }else if (insidey == 1) {
  227.                 if ((c.x < r.x && r.x - c.x <= c.w) ||
  228.                         (c.x > (r.x + r.w) && c.x - (r.x + r.w) <= c.w)) {
  229.                 }else{
  230.                         return 0;
  231.                 }
  232.         }else{
  233.                 //Check points
  234.                 if (sqrt( pow(r.x - c.x, 2) + pow(r.y - c.y, 2) ) <= c.w) {
  235.                 }else if (sqrt( pow(r.x + r.w - c.x, 2) + pow(r.y - c.y, 2) ) <= c.w) {
  236.                 }else if (sqrt( pow(r.x - c.x, 2) + pow(r.y + r.h - c.y, 2) ) <= c.w) {
  237.                 }else if (sqrt( pow(r.x + r.w - c.x, 2) + pow( r.y + r.h -  c.y, 2) ) <= c.w) {
  238.                 }else{
  239.                         return 0;
  240.                 }
  241.         }
  242.                
  243.         return 1;
  244. }
  245.  
  246. int checkRect(Mask r1, Mask r2)
  247. {
  248.         if (r1.x > r2.x + r2.w ||
  249.                 r1.x + r1.w < r2.x ||
  250.                 r1.y > r2.y + r2.h ||
  251.                 r1.y + r1.h < r2.y)
  252.         {
  253.                 return 0;
  254.         }
  255.        
  256.         return 1;
  257. }
  258.  
  259. int checkCircle(Mask c1, Mask c2)
  260. {
  261.         int maxdis = c1.w + c2.w;
  262.         int dis = sqrt(pow(c2.x - c1.x, 2) + pow(c2.y - c1.y, 2));
  263.        
  264.         if (dis <= maxdis) {
  265.                 return 1;
  266.         }
  267.        
  268.         return 0;
  269. }
  270.  
  271. //Heavier tile collision that omits destroyable blocks
  272. PHL_Rect getTileCollisionWeapon(int type, Mask m)
  273. {
  274.         PHL_Rect result;
  275.         result.x = -1;
  276.         result.y = -1;
  277.         result.w = 40;
  278.         result.h = 40;
  279.        
  280.         //updateMask();
  281.        
  282.         if (m.x < 0) {
  283.                 m.x = 0;
  284.         }else if (m.x + m.w > 640) {
  285.                 m.x = 640 - m.w;
  286.         }
  287.        
  288.         if (m.y < 0) {
  289.                 m.y = 0;
  290.         }else if (m.y + m.h > 480) {
  291.                 m.y = 480 - m.h;
  292.         }
  293.        
  294.         //PHL_DrawRect(mask.x, mask.y, mask.w, mask.h, PHL_NewRGB(0x00, 0x00, 0xFF));
  295.        
  296.         int i;
  297.         for (i = 0; i < 4; i++) {
  298.                 int tileX = (int)m.x / 40;
  299.                 int tileY = (int)m.y / 40;
  300.                
  301.                 if (i == 1) {
  302.                         tileX = (int)((m.x + m.w - 1) / 40);
  303.                 }else if (i == 2) {
  304.                         tileY = (int)((m.y + m.h - 1) / 40);
  305.                 }else if (i == 3) {
  306.                         tileX = (int)((m.x + m.w - 1) / 40);
  307.                         tileY = (int)((m.y + m.h - 1) / 40);
  308.                 }
  309.                
  310.                 if (collisionTiles[tileX][tileY] == type) {
  311.                         result.x = tileX * 40;
  312.                         result.y = tileY * 40;
  313.                        
  314.                         //Check if destroyable block
  315.                         int a;
  316.                         for (a = 0; a < MAX_OBJECTS; a++) {
  317.                                 if (objects[a] != NULL) {
  318.                                         if (objects[a]->type == 3) {
  319.                                                 Destroyable* d = objects[a]->data;
  320.                                                 if (result.x == d->x && result.y == d->y) {
  321.                                                         result.x = -1;
  322.                                                         result.y = -1;
  323.                                                 }
  324.                                         }
  325.                                 }
  326.                         }
  327.                        
  328.                         if (result.x != -1) {
  329.                                 i = 4;
  330.                         }
  331.                 }
  332.         }
  333.        
  334.         //updateMask();
  335.         return result;
  336. }