Collision Detection
Author |
Message |
goober69
|
Posted: Wed Jun 11, 2008 9:41 pm Post subject: Collision Detection |
|
|
Heres my situation. I have a game where a small red dot (16x16) is controlled by the user, and he/she must navigate it through a maze. Problem is I need to implement collision detection so that the red ball cannot pass through walls. This is what I have:
code: |
public void COLLISION(){
for(int i = 0; i < 225; i++){
//UPWARD COLLISION//
if(MY-2<Coordinates[i][1]+32 && Coordinates[i][2] == 1){
up = false;
}
//DOWNWARD COLLISION//
if(MY+18>Coordinates[i][1] && Coordinates[i][2] == 1){
down = false;
}
//LEFT COLLISION//
if(MX+18>Coordinates[i][0] && Coordinates[i][2] == 1){
left = false;
}
//RIGHT COLLISION//
if(MX-2<Coordinates[i][0]+32 && Coordinates[i][2] == 1){
right = false;
}
}
}
|
This collision checking method is called every time BEFORE the image is moved in any direction, and it sets up, down, etc. boolean values to false if the user's ball will hit a boundary in the specific direction. The boolean values are then set to true again afterward so the next time around they will allow movement unless a collision is immenent. The red ball will not move at all, indicating that all the booleans are being set to false :S Any takers?
ps. The reason for the 225 long for loop is because I have a 225 tile large map loaded onto the screen (15x15 of 32x32 pixel images) and I want to check collision for all of em. |
|
|
|
|
|
Sponsor Sponsor
|
|
|
DemonWasp
|
Posted: Thu Jun 12, 2008 8:26 am Post subject: Re: Collision Detection |
|
|
First, check that up down left and right are getting set to true before you call this function (or ideally, right at the top of the function). As I recall, Java automatically initializes boolean primitives to false, so if you never set them to true, they'll be false.
If that doesn't work, please explain exactly what's represented in Coordinates[][]. I'm a little confused as to why you're always comparing Coordinates[i][2] == 1. Your logic could be better given as:
Java: |
public void collision(){ // by convention, methods are always lower-camel-case in Java
for(int i = 0; i < 225; i++){
//UPWARD COLLISION//
if(Coordinates[i][2] == 1){
if(MY-2<Coordinates[i][1]+32){
up = false;
}
//DOWNWARD COLLISION//
if(MY+18>Coordinates[i][1]){
down = false;
}
//LEFT COLLISION//
if(MX+18>Coordinates[i][0]){
left = false;
}
//RIGHT COLLISION//
if(MX-2<Coordinates[i][0]+32){
right = false;
}
}
}
}
|
Also worth considering is changing things from hard-coded "magic numbers" to using constants. Instead of having +32 and +18 and -2 all throughout your code, consider using:
Java: |
public static final int mapGridSize = 32;
public static final int playerDotSize = 16;
public static final int paddingSize = 2;
|
That should let you express:
Java: |
MX-2<Coordinates[i][0]+32
|
as the much more self-documenting
Java: |
MX-paddingSize < Coordinates[i][0]+mapGridSize
|
It also really really helps if your grid size or player size or padding size ever changes. Instead of changing everything, everywhere, you can just change one variable (or better yet, auto-detect the size of the grid based on the input images). |
|
|
|
|
|
goober69
|
Posted: Thu Jun 12, 2008 9:42 am Post subject: Re: Collision Detection |
|
|
Hey thanks for the response man, I'll definetly implement your idea for using constants, and ahh my bad, should have exlained how the Coordinates[][] 2d array is used. The first dimention (i think thats what its called, the first []) is the tile that is being examined, element [0] in the second dimention is the Tiles X coordinate, element [1] is it's Y, and element [2] is set to 1 if the tile is solid, and 0 if the tile is a ground tile (user can move over it). |
|
|
|
|
|
DemonWasp
|
Posted: Thu Jun 12, 2008 3:31 pm Post subject: RE:Collision Detection |
|
|
In that case, you probably want to use non-magic-numbers for your array values as well:
Java: |
public static final int MAP_GRID_GROUND = 0;
public static final int MAP_GRID_IMPASSABLE = 1;
|
Your array would probably be better formulated in one of many different ways, depending on what exactly you're storing in Coordinates[][]. If you're storing EVERY square of your map, then you really only need one value for each square - either GROUND or IMPASSABLE. You can determine the X and Y coordinates with a little arithmetic.
If, however, you're storing only IMPASSABLE sections (i.e. the default is ground, and Coordinates[][] holds only areas where the player can't go), then you don't need to store the type - just X and Y locations.
In either case, some more intelligent commenting:
Java: |
public void collision(){
for(int i = 0; i < 225; i++){
if(Coordinates[i][2] == MAP_GRID_IMPASSABLE){ // Only check for collisions with impassable sections of the map
...
...
}
}
|
Minor nitpick: it's "dimension", not "dimention", though I see where you're coming from there.
If the hint to set your up/down/left/right variables to true beforehand didn't do what you wanted, try the following: add a simple System.out.println("UP denied!"); statement to right where you set up to be false (and the same for down/left/right). Then you can check to see that it's actually this method that's the problem. |
|
|
|
|
|
goober69
|
Posted: Thu Jun 12, 2008 5:21 pm Post subject: Re: Collision Detection |
|
|
Alright, thanks again for the reply. I checked the method with system.out.print, and yup its the logic in the method thats the problem. I ran through all the variables in my coordinates array, and they all seem fine, the solid tiles are 1's and the passable ones are 0's... I'm currently working with the advice you gave me and trying to fix the problem, will post back soon with results... |
|
|
|
|
|
DemonWasp
|
Posted: Thu Jun 12, 2008 9:19 pm Post subject: RE:Collision Detection |
|
|
*facepalm* I think I may see your problem.
Consider this, where . is ground, X is impassable, and ! is your player:
code: |
..X..
.....
X.!.X
.....
..X..
|
Let's, for convenience, label the X's according to their clock positions - #3, #6, #9 and #12.
Now trace through your code. Note that the ! is below #12, so it triggers the second IF, and isn't allowed to move downwards. The ! is above #6, so that triggers the first IF, and you can't move upwards.
Similarly, this will prevent us from moving left (blocked by #3) or right (blocked by #9).
There is no simple solution to this with the code you have (though we can use your existing data structure of Coordinates[][]). The easiest way is to determine WHERE the player WOULD move to (x and y), and figure out if that position is allowed. If it is, then move them there; if it isn't, then there's a collision, and you shouldn't move the player. |
|
|
|
|
|
|
|