[SOLVED] Platformer game, problem with collision detection calling

EDIT :
i changed the title from “A better way than AABB collision to solve precision problem” to this new one cause i found that my AABB method is working fine and the real problem is due when i call it

Hello,
i don’t know if this is happening because of the collision method i wrote, or this is a common problem due of AABB use,
the main problem is precision, the collision doesn’t always happens in the correct “time”, for example in a platformer game, there is always those time when the player get under the “ground” a little bit, also when it comes to find from which direction the object it’s colliding, i always found myself stacked :-\

the method i use :

public boolean aabb(double x1, double y1, double w1, double h1, double x2,
			double y2, double w2, double h2) {

		double cntrX1 = x1 + w1 / 2;
		double cntrY1 = y1 + h1 / 2;

		double cntrX2 = x2 + w2 / 2;
		double cntrY2 = y2 + h2 / 2;

		double distanceX = Math.abs(cntrX1 - cntrX2);
		double distanceY = Math.abs(cntrY1 - cntrY2);

		double sumWidth = (w1 / 2 + w2 / 2);
		double sumHeight = (h1 / 2 + h2 / 2);

		if (distanceX < sumWidth && distanceY < sumHeight ) {
			
				return true;
			
		}
		return false;

	}

the way i call it :


for (int y = 0; y < height; y++) {
			for (int x = 0; x < width; x++) {
				int blockX = x * 32;
				int blockY = y * 32;
				String block = myWorld[y][x];
				// testing if hitting the ground from the buttom
				if (tool.aabb(hero.getX(), hero.getY(), hero.getWidth(),
						hero.getHeight(), blockX, blockY, 32, 32)) {
					if (block.equals("1")) {
						onGround = true;

					} else {
						onGround = false;
					}
				}

				// testing if from the right
				if (tool.aabb(hero.getX() + hero.getWidth(), hero.getY(),
						hero.getWidth(), hero.getHeight(), blockX, blockY, 32,
						32)) {

					if (block.equals("4")) {
						System.out.println("right");
						draw.fillRect(hero.getX() + hero.getWidth() / 2,
								hero.getY(), 5, 5);
					}
				}

			}

		}

what am trying to do is :
-checking if the bottom of the player is colliding with the ground which cause him to stop falling (done)
-checking if the upper of the player is colliding with the ground which can stop the jump
-checking if the player is colliding from left/right with the ground/wall which will stop the movement in the current direction
PS :
i saw demos about jBox2D, do you suggest that i start using it to solve problems like these or is it too advanced for me now ??

thank you

Let´s say we have object A and B. If object A is 1 pixel away from object B and the speed of A is 5 pixels per frame you will only get a “true” from the collision check when A is overlapping with 4 pixels. What you want to do is to correct the overlap by the minimum amount. I wrote a bit about this in your last thread about collision detection so I won´t repeat myself, but read it and hopefully you´ll get some ideas.

thanx for answering
the problem seems to be more (or less) than that, please take a look to these pictures .
this one is a nice working collision (after failed with making AABB collision with the whole player quad, i said maybe using different rectangles for each side would help )

http://s20.postimg.org/rmp1uk9q1/image.png

and this when the collision doesn’t works

http://s20.postimg.org/neyuzjxo9/image.png

notice that here am not trying to make collision from left/right sides, actually i already done this and it works perfecty, my problem is when it collides with the ground, see when am in this state :

http://s20.postimg.org/rmp1uk9q1/image.png

“onGround” is returning true
but when am in this state (i paused the game) :

http://s20.postimg.org/4b5jj7ku1/image.png

“onGround” is returning false

i also tried to use 2 quads on the buttom one for the right and other for the left, but the results is always the same, and sometimes it returns true and false immediately and it still doesn’t works…
that’s why am trying to improve the collision method.

thanx alot

I think you´re complicating it and thereby introducing more bugs that´s gonna be harder to debug. Try to keep it simple. If you need two rectangles and two AABB you´re doing it wrong and should go back to the drawing board. For example, you shouldn´t need to do two intersection test since you can get all the information you need from one test. In your case you check which axis has the smallest overlap and then the collision will occur on that axis.

One thing I found that helped with my collision detection, is that if the rectangle moves more than half it’s smallest dimension, I would split the moves into parts that equaled less than half that distance. So if the rectangle is (WxL) 10x10, and it moved 50 units that cycle, then I would split it up into 10 smaller moves, and run a collision detection on each one. One problem with that is that it does increase the amount of calculations considerably, but it lets you catch cases where you get too far past the bounds before catching it. I’m not sure if this answers your question exactly, but might help out a bit.

Adam

thank you all for your help but i think the real trouble is not because of the collision method but is because of the way i called it,
this code


for (int y = 0; y < height; y++) {
         for (int x = 0; x < width; x++) {
            int blockX = x * 32;
            int blockY = y * 32;
            String block = myWorld[y][x];
            // testing if hitting the ground from the buttom
            if (tool.aabb(hero.getX(), hero.getY(), hero.getWidth(),
                  hero.getHeight(), blockX, blockY, 32, 32)) {
               if (block.equals("1")) {
                  onGround = true;

               } else {
                  onGround = false;
               }
            }

which mean :
"if the rectangle is colliding with any of the grid rectangle then, check if the grid rectangle is a ground, if it is then stop moving, but if it’s not a ground, then you can move "
now the problem happens when the rectangle is colliding with a ground grid and another type of the grid, it gives true and false in the same time, the strange thing is that it works if am on the left edge of the ground grid but if am on the right then the player keep falling

any help please ?

It is an interesting problem alaslipknot. But the way to solve it is just to always collide based on the true variable. As long as a collision is happening, you should be reacting to it. Only when there are absolutely no collisions happening should you actually fall back to gravity.

THANK YOU !! you know that moment when …

http://s20.postimg.org/417oaq1x9/my_code.png

all i had to do is make all the “else” result before the for loop, so it’s always falling unless it collides with the correct grid block

thank you all for your help