Advertisement
Kitomas

section of the player collision detection thing as of 2024-05-24

May 24th, 2024
571
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.24 KB | None | 0 0
  1. bool Player::colliding(shape::rect thing_rect, shape::fpoint* target_p){
  2.   //convert the 2 rects from x,y,w,h to x0,y0,x1,y1
  3.   thing_rect.w += thing_rect.x; //convert width and height to a second point
  4.   thing_rect.h += thing_rect.y;  //that defines the thing's bounding box
  5.  
  6.    //(size of the bounding box, anyway)
  7.   shape::point player_size(RND(6.0f*scale), RND(8.0f*scale));
  8.  
  9.   shape::rect player_rect;
  10.   player_rect.x = RND(pos.x)    - player_size.x/2;
  11.   player_rect.y = RND(pos.y)    - player_size.y/2;
  12.   player_rect.w = player_rect.x + player_size.x  ;
  13.   player_rect.h = player_rect.y + player_size.y  ;
  14.  
  15.  
  16.  
  17.   //detect collision while getting the area of intersection
  18.   shape::rect inter_rect; //inter[section]
  19.   inter_rect.x = MAX(player_rect.x, thing_rect.x); //max of left edges
  20.   inter_rect.y = MAX(player_rect.y, thing_rect.y); //max of top edges
  21.   inter_rect.w = MIN(player_rect.w, thing_rect.w); //min of right edges
  22.   inter_rect.h = MIN(player_rect.h, thing_rect.h); //min of bottom edges
  23.  
  24.   bool collision = inter_rect.x < inter_rect.w  &&  inter_rect.y < inter_rect.h;
  25.  
  26.   //forward declare some stuff so msvc doesn't complain about me using gotos
  27.   shape::fpoint thing_center;
  28.   shape::fpoint target; //'where should the player have to move to avoid thing?'
  29.   bool horizontal; //'should player be displaced vertically or horizontally?'
  30.   if(!collision) goto _draw_collisions_;
  31.  
  32.  
  33.  
  34.   thing_center.x = (f32)(thing_rect.x + thing_rect.w)/2;
  35.   thing_center.y = (f32)(thing_rect.y + thing_rect.h)/2;
  36.  
  37. #if defined(_DEBUG) && defined(SHOW_COLLISIONS)
  38.   if(thing_center.x > pos.x) inter_rect.w  = -(inter_rect.w - inter_rect.x);
  39.   else                       inter_rect.w -= inter_rect.x;
  40.   if(thing_center.y > pos.y) inter_rect.h  = -(inter_rect.h - inter_rect.y);
  41.   else                       inter_rect.h -= inter_rect.y;
  42. #endif /* if defined(_DEBUG) && defined(SHOW_COLLISIONS) */
  43.  
  44.  
  45.  
  46.   thing_center -= pos; //get position of thing relative to the player
  47.  
  48.   //'should player be displaced vertically or horizontally?'
  49.   horizontal = fabsf(thing_center.x) >= fabsf(thing_center.y);
  50.  
  51.   //to prevent the player from potentially getting stuck due to rounding errors
  52.   #define EPSILON 0.0001f
  53.  
  54.   if(horizontal){
  55.     if(thing_center.x>0) target.x = thing_rect.x-(3.0f*scale)-EPSILON; //push left
  56.     else                 target.x = thing_rect.w+(3.0f*scale)+EPSILON; //push right
  57.  
  58.   } else { //vertical
  59.     if(thing_center.y>0) target.y = thing_rect.y-(4.0f*scale)-EPSILON; //push up
  60.     else                 target.y = thing_rect.h+(4.0f*scale)+EPSILON; //push down
  61.  
  62.   }
  63.  
  64.   if(target_p) *target_p = target;
  65.  
  66.   //_printf("%5.2f, %5.2f\n", delta.x, delta.y);
  67.   _printf("%3i, %3i, %3i, %3i\n", thing_rect.x, thing_rect.y, thing_rect.w, thing_rect.h);
  68.  
  69.  
  70.  
  71.   _draw_collisions_:
  72. #if defined(_DEBUG) && defined(SHOW_COLLISIONS)
  73.  
  74.   //(make sure inter_rect's width and height is positive)
  75.   if(inter_rect.w < 0) inter_rect.w = -inter_rect.w;
  76.   if(inter_rect.h < 0) inter_rect.h = -inter_rect.h;
  77.   if(collision) gl_win->drawRectangles(&inter_rect, 1, 0x007fff);
  78.  
  79.  
  80.   shape::point p[5];
  81.   shape::point thing_center_s32;
  82.   thing_center_s32.x = (thing_rect.x + thing_rect.w)/2;
  83.   thing_center_s32.y = (thing_rect.y + thing_rect.h)/2;
  84.  
  85.   if(collision){
  86.     p[0] = shape::point(thing_center_s32.x, thing_center_s32.y);
  87.     p[1] = shape::point(thing_rect.x  , thing_rect.y  );
  88.     p[2] = shape::point(thing_rect.w-1, thing_rect.y  );
  89.     p[3] = shape::point(thing_rect.x,   thing_rect.h-1);
  90.     p[4] = shape::point(thing_rect.w-1, thing_rect.h-1);
  91.     gl_win->drawLines((shape::point*)&p, 2, 0xffffff); p[1] = p[2];
  92.     gl_win->drawLines((shape::point*)&p, 2, 0xffffff); p[1] = p[3];
  93.     gl_win->drawLines((shape::point*)&p, 2, 0xffffff); p[1] = p[4];
  94.     gl_win->drawLines((shape::point*)&p, 2, 0xffffff);
  95.   }
  96.  
  97.  
  98.   p[0] = shape::point(thing_rect.x  , thing_rect.y  );
  99.   p[1] = shape::point(thing_rect.w-1, thing_rect.y  );
  100.   p[3] = shape::point(thing_rect.x,   thing_rect.h-1);
  101.   p[2] = shape::point(thing_rect.w-1, thing_rect.h-1);
  102.   p[4] = p[0];
  103.   //gl_win->drawPoints((shape::point*)&p, lengthof(p,shape::point),
  104.   //                   (collision) ? 0xff00 : 0xff0000, true);
  105.   gl_win->drawLines((shape::point*)&p, lengthof(p,shape::point),
  106.                     (collision) ? 0xff00 : 0xff0000, 1);
  107.  
  108.  
  109.   p[0] = shape::point(player_rect.x  , player_rect.y  );
  110.   p[1] = shape::point(player_rect.w-1, player_rect.y  );
  111.   p[3] = shape::point(player_rect.x  , player_rect.h-1);
  112.   p[2] = shape::point(player_rect.w-1, player_rect.h-1);
  113.   p[4] = p[0];
  114.   //gl_win->drawPoints((shape::point*)&p, lengthof(p,shape::point),
  115.   //                   (collision) ? 0xff00 : 0xff0000, true);
  116.   gl_win->drawLines((shape::point*)&p, lengthof(p,shape::point),
  117.                     (collision) ? 0xff00 : 0xff0000, 1);
  118.  
  119.  
  120.   if(collision){
  121.     p[0] = shape::point(thing_center_s32.x, thing_center_s32.y);
  122.     p[1] = shape::point((s32)pos.x, (s32)pos.y);
  123.     gl_win->drawLines((shape::point*)&p, 2, (horizontal) ? 0x00ffff : 0xffff00);
  124.     gl_textf((s32)gl_player.pos.x + PLAYER_HALF,
  125.              (s32)gl_player.pos.y - PLAYER_HALF,
  126.              "horizontal=%s", boolStr(horizontal));
  127.   }
  128.  
  129. #endif /* if defined(_DEBUG) && defined(SHOW_COLLISIONS) */
  130.  
  131.  
  132.   return collision;
  133.  
  134. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement