Well i have tried but cant get it to work "Prevented Collision Detection"

ok first you might wonder what “Prevented CD” is!

“Prevented CD”
you are walking towards a wall and the wall stops the player/you from walking through it!

“Event CD”
you shoot a bullet at a wall “The Bullet” can go through the wall but you most likely remove it and make it disappear

my problem is that i never understand how to create this checks i have tried some tutorials but the collision just makes me go in to the wall then be stuck there i don’t get it perfect as i want it and i cant move it back or set new player location then it makes the player sometimes just go on top or at the bottom off the block

i have tried many tutorials so if you could create a good tutorial down below that is easy to read and understand! then thanks!

please help me i just want to move on i have had this problem for over a year now i want to learn how to do it so i don’t need to struggle with it anymore!

  • VirtueeL

Currently I’m working on a game that involves such type of collision detection(the kind that prevents the player from walking through the wall). Here is a piece of my code that takes care of that:

@Override
	public void setMonkeyPosition(float x, float y) {
		if (x+Values.Monkey_Width >= Values.SCREEN_WIDTH)
			x = Values.SCREEN_WIDTH - Values.Monkey_Width;
		else if (x <= 0)
			x = 0;
		if (y+Values.Monkey_Height >= Values.SCREEN_HEIGHT)
			y = Values.SCREEN_HEIGHT - Values.Scalar_Height;
		else if (y <= 0)
			y = 0;
		monkeyPosition.set(x+Values.Monkey_Width/2, y+Values.Monkey_Height/2);
		// Tween Engine Interpolation to Monkey
		UIHelper.tweenMonkeyMovement(monkey, x, y);
	}

Everytime the player moves, the new coordinates are checked and if they are beyond the screen, they are not defined as the new player’s position.

sounds like something like …

event :

  • take previous position
  • trace from previous position to current position
  • test for intersection
  • constraint object position according to intersection

prevented :

  • take current position
  • calculate future position based on direction and speed
  • trace from current position to future position
  • test for intersection
  • constraint input (which would make an object move) to prevent object being moved beyond intersection.

or maybe :

event : collision happend, fix world
prevented : collision will happen, fix input.

both ways are good.

now, to implement that it depends on your current code. the way you setup the world, how you handle input, how to do the animations, etc. you have a few systems playing together. … is the world full 3D or 2D … or tilebased, or or or :slight_smile:

want me to post my movement code? and block class? and input class?

and you might be able to help me ?

thanks but i dont use openGL or libGDX i use java2D

The tutorial is not about libgx or OpenGL, its about collision detection.

its written in lwjgl ,opengl

i got it to work but now there is another problem…

| = wall
[] = player

when i walk in to it, it some times stops at different places! and sometimes inside the wall!

|[]
| []
| []
|[]
| []
|[]

Instead of


speed = 5;
if (level.canMove(position + speed))
{
     position += speed;
}

Do this:


speed = 5;

for (int i = 0; i < speed; i++)
{
     if (level.canMove(position + 1))
     {
          position += 1;
     }
}

this is how i do it now!

		for(Block b : PlayingState.blocks){
			if(b.isSolid()){
				
				//CHECKS
				for (int i = 0; i < speed; i++){
					if(isLeft() && PlayingState.checkCollision(xpos + 1 + PlayingState.xOffset, ypos + height + PlayingState.yOffset) 
							|| PlayingState.checkCollision(xpos + 1 + PlayingState.xOffset, ypos  + PlayingState.yOffset)
							){
						left = false;
					}
				}
				
			}
		}

The method trollwarrior1 mentioned is too move the player inside the for loop by “1” if that spot is open. So if your speed is 10, and there is a wall “8” away, your player will be able to move by 7 (given that 8 will prevent the player from moving forward) within the loop and when it exits the loop you will be right next to the wall.

From what I gather of your code, it doesn’t appear that you update the player’s position by “1” each time through the loop. This would explain why you end up at different positions from the wall. So using the previous example, if your speed is 10 and there is a wall 8 away, when you check each position up to 10 and then only set motion to “false” if there there is a wall at any point in that range (which 8 would be) then you will immediately stop moving and remain 8 away from the wall.

I assume you check the “left” flag somewhere else and then update the position according to the flag? If so, then you could remove the flag and update the position right there inside of the loop. Then you could update the position by “1” instead of only being able to update position by the value of speed.

could you give me an example? once i learn this i wont need to learn it agine! =D

It’s fairly simple , instead of checking the current position of the object you check the 4 relative (or however many planes that the object may touch) planes. so instead of if(checkcollision(position.x,position.y)) instead do if(checkcollision(position.x+1,position.y+1))

It’s kind of hard to give an example that works specifically in your code since you are doing other things outside of your short snippet.

Elsewhere in your code, you determine whether you are moving left and set the “left” flag, correct? If so, then instead of setting a flag that you are moving left, put the check loop there to see if you can move left and move left if you can.

There maybe a better way to do this but just a quick idea:

Also, I’m not sure what the PlayingState.offset does exactly, so I’m removing it for now just to illustrate the idea. :wink:

if (***LEFT key press***){
	for (int i = 0; i < speed; i++){
		// CHECK
		if(PlayingState.checkCollision(xpos - 1, ypos + height) || PlayingState.checkCollision(xpos - 1, ypos)){
			break;
		}
		// MOVE
		xpos -= 1;
	}
}
if (***RIGHT key press***){
	for (int i = 0; i < speed; i++){
		// CHECK
		if(PlayingState.checkCollision(xpos + 1, ypos + height) || PlayingState.checkCollision(xpos + 1, ypos)){
			break;
		}
		// MOVE
		xpos += 1;
	}
}

That performs your collision check and if there is no collision it updates the position by one and keeps going until it moves the position by “speed”. When there is a collision it breaks out of the loop and doesn’t update the position. You would do the same thing for vertical movement.

fixed the teleport it was that i was checking all blocks at the same time * speed

that made me teleport to a wall =/ perfect!
but i dont want to teleport
xD

How about stopping right next to the wall? Were you able to get that working also?

I did not read the whole page, but i just want to throw in something:
I guess the terms “Prevented Collision Detection” and “Event Collision Detection” are not the rigth one.
They are both some kind of Collision Response, the Detection itself should be the same and occures before the 2 described things happen.

So basicly Collision Detection is the detection, of whether 2 objects touch/hit/overlap each other or not.
The Collision Response then describes what the objects should do.
While the first kind of collision detection should move the moving entity back to the last posible position,
the second one should damage one or both touching entities.