Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- bool Player::colliding(shape::rect thing_rect, shape::fpoint* target_p){
- //convert the 2 rects from x,y,w,h to x0,y0,x1,y1
- thing_rect.w += thing_rect.x; //convert width and height to a second point
- thing_rect.h += thing_rect.y; //that defines the thing's bounding box
- //(size of the bounding box, anyway)
- shape::point player_size(RND(6.0f*scale), RND(8.0f*scale));
- shape::rect player_rect;
- player_rect.x = RND(pos.x) - player_size.x/2;
- player_rect.y = RND(pos.y) - player_size.y/2;
- player_rect.w = player_rect.x + player_size.x ;
- player_rect.h = player_rect.y + player_size.y ;
- //detect collision while getting the area of intersection
- shape::rect inter_rect; //inter[section]
- inter_rect.x = MAX(player_rect.x, thing_rect.x); //max of left edges
- inter_rect.y = MAX(player_rect.y, thing_rect.y); //max of top edges
- inter_rect.w = MIN(player_rect.w, thing_rect.w); //min of right edges
- inter_rect.h = MIN(player_rect.h, thing_rect.h); //min of bottom edges
- bool collision = inter_rect.x < inter_rect.w && inter_rect.y < inter_rect.h;
- //forward declare some stuff so msvc doesn't complain about me using gotos
- shape::fpoint thing_center;
- shape::fpoint target; //'where should the player have to move to avoid thing?'
- bool horizontal; //'should player be displaced vertically or horizontally?'
- if(!collision) goto _draw_collisions_;
- thing_center.x = (f32)(thing_rect.x + thing_rect.w)/2;
- thing_center.y = (f32)(thing_rect.y + thing_rect.h)/2;
- #if defined(_DEBUG) && defined(SHOW_COLLISIONS)
- if(thing_center.x > pos.x) inter_rect.w = -(inter_rect.w - inter_rect.x);
- else inter_rect.w -= inter_rect.x;
- if(thing_center.y > pos.y) inter_rect.h = -(inter_rect.h - inter_rect.y);
- else inter_rect.h -= inter_rect.y;
- #endif /* if defined(_DEBUG) && defined(SHOW_COLLISIONS) */
- thing_center -= pos; //get position of thing relative to the player
- //'should player be displaced vertically or horizontally?'
- horizontal = fabsf(thing_center.x) >= fabsf(thing_center.y);
- //to prevent the player from potentially getting stuck due to rounding errors
- #define EPSILON 0.0001f
- if(horizontal){
- if(thing_center.x>0) target.x = thing_rect.x-(3.0f*scale)-EPSILON; //push left
- else target.x = thing_rect.w+(3.0f*scale)+EPSILON; //push right
- } else { //vertical
- if(thing_center.y>0) target.y = thing_rect.y-(4.0f*scale)-EPSILON; //push up
- else target.y = thing_rect.h+(4.0f*scale)+EPSILON; //push down
- }
- if(target_p) *target_p = target;
- //_printf("%5.2f, %5.2f\n", delta.x, delta.y);
- _printf("%3i, %3i, %3i, %3i\n", thing_rect.x, thing_rect.y, thing_rect.w, thing_rect.h);
- _draw_collisions_:
- #if defined(_DEBUG) && defined(SHOW_COLLISIONS)
- //(make sure inter_rect's width and height is positive)
- if(inter_rect.w < 0) inter_rect.w = -inter_rect.w;
- if(inter_rect.h < 0) inter_rect.h = -inter_rect.h;
- if(collision) gl_win->drawRectangles(&inter_rect, 1, 0x007fff);
- shape::point p[5];
- shape::point thing_center_s32;
- thing_center_s32.x = (thing_rect.x + thing_rect.w)/2;
- thing_center_s32.y = (thing_rect.y + thing_rect.h)/2;
- if(collision){
- p[0] = shape::point(thing_center_s32.x, thing_center_s32.y);
- p[1] = shape::point(thing_rect.x , thing_rect.y );
- p[2] = shape::point(thing_rect.w-1, thing_rect.y );
- p[3] = shape::point(thing_rect.x, thing_rect.h-1);
- p[4] = shape::point(thing_rect.w-1, thing_rect.h-1);
- gl_win->drawLines((shape::point*)&p, 2, 0xffffff); p[1] = p[2];
- gl_win->drawLines((shape::point*)&p, 2, 0xffffff); p[1] = p[3];
- gl_win->drawLines((shape::point*)&p, 2, 0xffffff); p[1] = p[4];
- gl_win->drawLines((shape::point*)&p, 2, 0xffffff);
- }
- p[0] = shape::point(thing_rect.x , thing_rect.y );
- p[1] = shape::point(thing_rect.w-1, thing_rect.y );
- p[3] = shape::point(thing_rect.x, thing_rect.h-1);
- p[2] = shape::point(thing_rect.w-1, thing_rect.h-1);
- p[4] = p[0];
- //gl_win->drawPoints((shape::point*)&p, lengthof(p,shape::point),
- // (collision) ? 0xff00 : 0xff0000, true);
- gl_win->drawLines((shape::point*)&p, lengthof(p,shape::point),
- (collision) ? 0xff00 : 0xff0000, 1);
- p[0] = shape::point(player_rect.x , player_rect.y );
- p[1] = shape::point(player_rect.w-1, player_rect.y );
- p[3] = shape::point(player_rect.x , player_rect.h-1);
- p[2] = shape::point(player_rect.w-1, player_rect.h-1);
- p[4] = p[0];
- //gl_win->drawPoints((shape::point*)&p, lengthof(p,shape::point),
- // (collision) ? 0xff00 : 0xff0000, true);
- gl_win->drawLines((shape::point*)&p, lengthof(p,shape::point),
- (collision) ? 0xff00 : 0xff0000, 1);
- if(collision){
- p[0] = shape::point(thing_center_s32.x, thing_center_s32.y);
- p[1] = shape::point((s32)pos.x, (s32)pos.y);
- gl_win->drawLines((shape::point*)&p, 2, (horizontal) ? 0x00ffff : 0xffff00);
- gl_textf((s32)gl_player.pos.x + PLAYER_HALF,
- (s32)gl_player.pos.y - PLAYER_HALF,
- "horizontal=%s", boolStr(horizontal));
- }
- #endif /* if defined(_DEBUG) && defined(SHOW_COLLISIONS) */
- return collision;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement