Advertisement

2D Collisions

Started by June 03, 2001 11:35 PM
2 comments, last by DekuTree64 23 years, 8 months ago
Ok, I give up. I''ve been trying and trying to figure out collision detection in my side-scroller on my own for months, and I''m sick of it. Appearently there''s something I''m missing, since all articles I''ve been able to find just tell how to check if 2 rectangles are overlapping. That''s all fine, but what I''m having trouble with is figuring out how to make a character land ON the ground, not above or below it. What I mean is, if you''re moving faster than 1 pixel/frame, you''ll most likely be a few pixels above the ground one frame, and a few below in the next, so if you check to see if you''ll hit it in the next frame, then you''ll stop right above it, and then start moving again due to gravity, which will get you right on the ground, but not without jumping between your falling and standing animations first. Then if you check if you''re colliding, and then set your velocity according to that, you''ll most likely land a few pixels past the ground, and then you won''t be able to walk, since the area in front of you is also part of the tile you''re standing in. So, how do you find the exact point of the collision, and stop there? If anybody has any tutorials on it, that would be fine, or an explanation in code or english. Anything to end my confusion^_^ P.S. sorry if I''m not asking too politely. I''m just a bit grouchy cause I can''t come up with a solution on my own. Thanks to anyone who''s even still reading this^^
-Deku-chan DK Art (my site, which has little programming-related stuff on it, but you should go anyway^_^)
Ive spent alot of time trying to get it right, and eventually I got it perfect, check out my game at
www.angelfire.com/realm/zeroone

If you check the sprites'' collision by simply using the new position you will find all sorts of problems including the problem you are having.

This is how its done...

What you need to do is at every frame, check each pixel one by one using a line algorithm (see below).

Here are the steps involved...

1) Save the old sprite position and calculate the new position.
2) Fill out a global line path array with the two positions using the below function, PlotLinePathArray(ptOld, ptNew), it will return the last array location containing ptNew
3) check each Line array location from 0 to LinePathLastPoint, it the POINT hits the ground, stop checking the array positions and set the sprites'' pos to the last good array location in the line array.



  // Line path globals.#define MAXPATHLINEPOINTS 512int   LinePathLastPoint;POINT LinePathArray[MAXPATHLINEPOINTS];//// * Counter returned is always above 0.// * Array 0 is the first point given (POINT *a)//int PlotLinePathArray(POINT *a, POINT *b){  register int  d, x, y, ax, ay, sx, sy, dx, dy, x1, y1;  int counter = 0;  LinePathArray[0].x = a->x;  LinePathArray[0].y = a->y;  dx = b->x - a->x;  ax = abs(dx) << 1;  sx = Sgn(dx);    dy = b->y - a->y;  ay = abs(dy) << 1;  sy = Sgn(dy);  x  = a->x;  y  = a->y;  x1 = b->x;  y1 = b->y;  if (ax > ay)   {    d = ay - (ax >> 1);    while (x != x1)     {      if (d >= 0)       {	    y += sy;	    d -= ax;      }      x += sx;      d += ay;      counter++;      LinePathArray[counter].x = x;      LinePathArray[counter].y = y;      if(counter>=MAXPATHLINEPOINTS)      {          return MAXPATHLINEPOINTS;      }    }  }   else   {    d = ax - (ay >> 1);    while (y != y1)     {      if (d >= 0)       {	    x += sx;	    d -= ay;      }      y += sy;      d += ax;      counter++;      LinePathArray[counter].x = x;      LinePathArray[counter].y = y;      if(counter>=MAXPATHLINEPOINTS)      {          return MAXPATHLINEPOINTS;      }    }  }  counter++;  LinePathLastPoint = counter;  return counter;}  



The line algorithm is very fast so you will be able to have hundreds of sprite in your level with pixel perfect collision detection

Dont hesitate to email me at SikCiv@Hotmail.com if you need more info or code



Demo Download: www.angelfire.com/realm/zeroone

  Downloads:  ZeroOne Realm

Advertisement
Well his answer seems to be pretty complicated to me, so I just figured I''d through out an easy to understand solution.

You should know the boundry of your ground, so say the ground was at point 500. If your person goes below 500, put him exactly at 500. Problem solved.

Any questions?
BalAhan: Thanks, but actually that''s what I''m using right now, which is great if your ground is perfectly flat, but I don''t think a side-scroller would be much fun if you couldn''t climb around on stuff^^

SikCiv: Yes, this is exactly what I needed^^ Haven''t totally figured out what all those variables do, but I''ve written a line routine, and this sems to be just that, except storing the values into an array instead of the screen, so it shouldn''t be too hard to decipher. Actually, I thought of checking each pixel, but thought it would be too slow. Guess not though, especially after reading this 3D collision tutorial, which has quite a few multiplies per triangle earlier today. That thing is absolute genius, but it doesn''t really apply to 2D very well. I''d suggest giving it a read if you ever make a 3D game though^^

Thanks again, hopefully I can figure out how to decide which tiles are in range on my own. Couldn''t be too hard, right? Right?? Damn. Guess I''d better get to it then^^



-Deku-chan

DK Art (my site, which has little programming-related stuff on it, but you should go anyway^_^)

This topic is closed to new replies.

Advertisement