Collision Testing - Questions

Hi

So I was working on my project, and I started collision testing for a tilemap. Now I ran into an issue… glitching through walls. When WASD movement is handled, if keys are clicked fast enough then collision testing doesn’t work.

Background:
Each tile has a rectangle for it’s region, and the player has it’s own region. For collision checking, I see if the regions intersect and the return that there was a collision.

Movement handling:
[icode] /**
* Handle movement for the player
*/
public void handleMovement(float speed){

	if(System.nanoTime() - stamp < 600000)
		return;
	stamp = System.nanoTime();
	// handle the coordinates
	Keyboard.poll();
	float x = 0.0f;
	float y = 0.0f;
	boolean left = false, top = false, right = false, bottom = false;
	if (Keyboard.isKeyDown(Keyboard.KEY_W)) {
		y = speed;
		top = true;
    }
	if (Keyboard.isKeyDown(Keyboard.KEY_S)) {
		y = -speed;
		bottom = true;
    }
	if (Keyboard.isKeyDown(Keyboard.KEY_A)) {
		x = speed;
		left = true;
    }
	if (Keyboard.isKeyDown(Keyboard.KEY_D)) {
		x = -speed;
		right = true;
    }
    // change movement
	int direction = convertDirection(left, right, top, bottom);
	if(!Collisions.isCollision(direction)){
		if(!Collisions.isCollision(direction)){
			camera.addToPosition(x, y);
		}
	} else {
		// back up
		camera.addToPosition(-x, -y);
	}
	if(direction > 0){
		if(Collisions.isCollision(direction)){
			if(Collisions.isCollision(direction)){
				camera.addToPosition(-x, -y);
			}
		} else {
			if(Collisions.isCollision(direction)){
				if(Collisions.isCollision(direction)){
					camera.addToPosition(-x, -y);
				}
			} else {
				// Nothing.
			}
		}
	}
	
}

[/icode]
[icode] /**
* Convert the four booleans to an integer
*/
public int convertDirection(boolean left, boolean right,
boolean top, boolean bottom){

	if(left){
		if(right){
			// Doubtully so
			return -1;
		} else {
			if(top){
				if(bottom){
					// Doubtully so
					return -1;
				} else {
					return 5;
				}
			} else {
				if(bottom){
					return 6;
				} else {
					return 1;
				}
			}
		}
	} else {
		if(right){
			if(top){
				if(bottom){
					// Doubtully so
					return -1;
				} else {
					return 8;
				}
			} else {
				if(bottom){
					return 7;
				} else {
					return 2;
				}
			}
		} else {
			if(top){
				if(bottom){
					// Doubtully so
					return -1;
				} else {
					return 4;
				}
			} else {
				if(bottom){
					return 3;
				} else {
					// Doubtully so
					return -1;
				}
			}
		}
	}
	
}

[/icode]

Any thoughts or suggestions would help :slight_smile:

I honestly have no idea what your code is doing, and i doubt you really do either. Go back think about the logic, re-read your code. Split things into more functions. Stop using so many if statements i’m sure you don’t need that many nested if’s.

I doubt anyone will be able to help you until you clean up your code

where the heck did you learn to code like that? :o

I’d love to help, but I’m not even sure what I am looking at. This part really confuses me:


      if(!Collisions.isCollision(direction)){
         if(!Collisions.isCollision(direction)){
            camera.addToPosition(x, y);
         }
      } else {
         // back up
         camera.addToPosition(-x, -y);
      }
      if(direction > 0){
         if(Collisions.isCollision(direction)){
            if(Collisions.isCollision(direction)){
               camera.addToPosition(-x, -y);
            }
         } else {
            if(Collisions.isCollision(direction)){
               if(Collisions.isCollision(direction)){
                  camera.addToPosition(-x, -y);
               }
            } else {
               // Nothing.
            }
         }
      }

Why can’t this just be: (although still kinda hacky)


          if(!Collisions.isCollision(direction)){
               camera.addToPosition(x, y);
          } else {
               camera.addToPosition(-x, -y);
          }
          if((direction > 0) && (Collisions.isCollision(direction))){
               camera.addToPosition(-x, -y);
          }

As for the second part of your code, I’m not even sure what it’s doing. :o

Mario (cut & paste in IDE)

Yeah, I’m not a fan of checking collision from within the Key Press listener. If you can check it all within the update, it would probably be a little easier to see the logic. You can use the above example if you have the time to read through it, it is not as documented as my other ones though…

Alright, I’m gonna back up to the design phase:

[quote]When WASD movement is handled, if keys are clicked fast enough then collision testing doesn’t work.
[/quote]
Hmm… sounds like he’s using a polling model…

Yeah, that’s polling. That means that the code only checks if the user is pressing a key right that at that moment it’s checking. I recommend using an observer system/event queue instead, you won’t miss key events that way.

Also, if you really need to “pack” the keys into a single direction object, then a vector is literally exactly what you want:

(Using a Point, works just the same, use applicable coord system)


public Point convertDirection(boolean left, boolean right, boolean top, boolean bottom) {
    int x = left ? -1 : 0;
    x += right ? 1 : 0;
    int y = up ? -1 : 0;
    y += down ? 1 : 0;
    return new Point(x, y);
}

Could also do an enum:


public enum Direction {
    N, S, E, W, NE, NW, SE, SW;
}

[quote]Why can’t this just be: (although still kinda hacky)… As for the second part of your code, I’m not even sure what it’s doing.
[/quote]
Let me explain. Okay so at first I had the version with less if statements, and then I was worried for people glitching through walls, so I hastily added inner if statements hoping that maybe it would recheck the collision and know to back up. For the integer system, it does the directioning but uses integers instead of an enum (don’t worry I wrote the system down on paper).

[quote]I doubt anyone will be able to help you until you clean up your code
[/quote]
I will clean up my code today, I was just hastily nesting if statements in the hopes that I could cause the wall glitches to cease.

Tonight I will change my polling to

 while (Keyboard.next ())

and clean up my code and post the cleaned up version.

I hope you don’t get the idea that this messiness is how I usually code…

CopyableCougar4

Hi

Rayvolution: So i rewrote the collision system and I think I solved my problem :slight_smile: All I had to do was take out the direction part (I realized it was unnecessary) and add some more enhanced collision detection and wall glitching hasn’t been seen since :slight_smile:

Code if anybody wants to see the final code:
[icode]
public void handleMovement(float speed){

	if(System.nanoTime() - stamp < 500000)
		return;
	stamp = System.nanoTime();
	// handle the coordinates
	Keyboard.poll();
	float x = 0.0f;
	float y = 0.0f;
	if (Keyboard.isKeyDown(Keyboard.KEY_W)) {
		y = speed;
    }
	if (Keyboard.isKeyDown(Keyboard.KEY_S)) {
		y = -speed;
    }
	if (Keyboard.isKeyDown(Keyboard.KEY_A)) {
		x = speed;
    }
	if (Keyboard.isKeyDown(Keyboard.KEY_D)) {
		x = -speed;
    }
    // check current position
	if(!Collisions.isCollision()){
		// move forward
		camera.addToPosition(x, y);
		if(Collisions.isCollision()){
			// back up
			camera.addToPosition(-x, -y);
		}
	} else {
		// try backing up
		camera.addToPosition(-x, -y);
		if(Collisions.isCollision()){
			// backing up collided
			camera.addToPosition(x, y);
		}
	}
	
}

[/icode]