PDA

Click to See Complete Forum and Search --> : Super Mario Clone ... Collisions


BramVandenbon
Oct 9th, 2004, 10:59 AM
Please take a look at the JPEG file of the attachement for a clearer view of what I am going to explain... Because this thread will make a great challenge.:)

I am currently making a supermario game and I am having some problems with the collision detection. This is part of a level class but that is (not really important) I have tried to put all keywords in bold making it easy to read through my thread rapidly if you dont feel like reading everything ;).

My level is a 2D array. It is loaded from a file(not important) and is filled up with numbers. Those numbers tell us what kind of object is placed in that position. Ofcourse in my application I have about 20 different kind of objects but here I would like to keep things simple.

//my 2D array
int board[][];

//constants
int solid_block = 1;
int air = 2;

I also have an array that holds pictures. Using threading my window is repeanted every 20ms according to the values inside the 2Darray. All blocks have the same size in height and width (a int unit) and their positions are calculated using the x and y from the array. It looks a bit like this:

int unit = 30; //constant for calculating the position

Image img;
for x to ...{
for y to ...{
if board[x][y] == solid_block{ // board[x][y] == 1 ,
//there is a block on this position
img = imageblock,
}else{
img = imageair;
}
g.drawImage(img, x*unit, y*unit, unit,unit, this);
}
}


Inside my game I have SelfmadeObjects and those are moving accross the board. These images are moving on top of the level. For example SuperMario himself.

Now we arrive to the problem:
For collisiondetection I use a function


// int[][] Board, int unit, int solid_block, int air are globally defined
public Point collision (Rectangle2D A, Point B){
return new Point(x,y);
}



Rectangle2D is SuperMario. It has a height a width and a x and y position. (Note that this class has properties like getCentralX and getCentralY, maybe it comes in handy.)

Point B is actually used as a geneometric vector. It has a deltaX and a deltaY.[B] These are the distances that [b]SuperMario would like to move. These can be negative if mario wants to move to the left or to the top.

The return value of this function should be the distance X and distance Y that SuperMario can move in that direction without having a collision with one of the solid blocks. Ofcourse I return this value as a Point (because you can not return 2 values.)

I have tried to program this before... But I am having all kind of bugs and problems. I would appreciate if somebody else would give it a try?

(Codelistings are welcome, stuff like "Your program is all wrong and you should start over again", is not welcome)

If so, thank you very much in advance. :)

CornedBee
Oct 10th, 2004, 07:06 AM
Your method is all wrong and you should start over again :D

Seriously, though, I don't get a tiny thing. In a frame-based game, the moving object has a current position and speed. Each frame, you calculate a new position according to the speed. Then you check if anything is already in that new position. If so, you have a collision and the object cannot move further. In both cases, you then adjust the speed. Increase or decrease horizontal speed according to the direction keys pressed, increase vertical downward speed if object is in the air, come to a dead stop if object runs into a wall etc.

I don't see why you would want to look ahead to see how far the object can go. That's a job for ray tracing, bullet tracking and AI, not for player movements.

BramVandenbon
Oct 10th, 2004, 10:17 AM
Oh come on cornbee, offcourse my game has all those things

I allready have several speed variables for jumping, walking, falling, even factors to increase and decrease speed.

You are right in normal conditions I would only need to look to objects next to SuperMario.

But that is thinking small and simplistic. In my program all speeds are constants and constants can be changed. So, the speed can exceed the size of an object. In that case the object next to supermario can be air, but the next object can be a block.

If you do not understand my explanation, then just trust me, I have thought this out, and I know what I need. ;)

CornedBee
Oct 10th, 2004, 10:33 AM
Ok, I get it. I was wondering about this exact thing after I posted, but your screenshot confused me, because the traveled path was so long.

What you basically need is to compute the intersection point between two line segments: one is the movement vector and the other is the edge of the objcet. You have to do that more than once for each object - you have to do it for both edges (that assumes rectangular objects) that face the character. If there is no intersection point, you're collision-free.

I have the math in a game programming book, but I can't write it down here.

BramVandenbon
Oct 10th, 2004, 11:02 AM
Till there I could do it...

But I also need a return value that gives the distance I can travel before the collision.

Because mario is still allowed to move just to the point where he touches the object. (The point just before overlapping).

Hmmm, I guess I can not expect that some magic free super programmer will jump at this post and give me a clear sample :(. But if anybody still wants to give it a shot it would be nice :)

Thank you in advance.

CornedBee
Oct 10th, 2004, 11:08 AM
Once you have the collision point, the distance is easy. It's the distance between the collision point and, strictly seen, the intersection point between the movement vector and Mario's outline. But you can simplify this because Mario is in fact a rectangle, so you can just take half his width or height, depending on how he collides.