I have a collision detection for terrain setup (non-terrain is handled with a quadtree I implemented apart from this) and I was wondering how others have done it compared to mine and what I could learn from people's critiques here.
My map is stored in a 2D array of "GameSquare"s
public class GameSquare extends GameObject {
private char tileLetter = 'W';
private int row, col;
}
public boolean isPassable() {
return tileLetter != 'W';
}
The Player
My player class gets track of the player in pixels. The speed and X,Y positions are all in exact pixels. I divide those measures by the width or height of the tile graphics I use and truncate it; in order to find the corresponding array cell that the player is in. In order to do collision detection I wrote a method that takes a cardinal direction, the players current collision box, and a distance which is usually their speed.
The cardinal direction is an enum that has methods for the adjX and adjY.
For example; East would return adjX() = 1 and adjY() = 0 whereas
SouthEast would return adjX() = 1 and adjY() = 1 <-- Positive because this is the movement in a 2D array.
The Collision Check
public int canMove(Direction dir, Rectangle collisionBox, int distance) {
int goodToGo = 0;
// Check each 'step' of our attempted movement from 1 - distance(ie speed)
for(int i = 1; i <= distance; i++) {
// Assemble suggested new position bounds to check, ie corners of suggested movement
HashSet<Vector2f> cornerPoints = new HashSet<Vector2f>();
cornerPoints.add( new Vector2f(collisionBox.getMinX()+dir.adjX()*i, collisionBox.getMinY()+dir.adjY()*i) );
cornerPoints.add( new Vector2f(collisionBox.getMaxX()+dir.adjX()*i, collisionBox.getMinY()+dir.adjY()*i) );
cornerPoints.add( new Vector2f(collisionBox.getMinX()+dir.adjX()*i, collisionBox.getMaxY()+dir.adjY()*i) );
cornerPoints.add( new Vector2f(collisionBox.getMaxX()+dir.adjX()*i, collisionBox.getMaxY()+dir.adjY()*i) );
// Check each corner of this step
for( Vector2f point : cornerPoints ) {
// Out of bounds check
if( point.y < 0 || point.y > this.dungeonHeight*ratioRow ||
point.x < 0 || point.x > this.dungeonWidth*ratioCol ) {
return goodToGo;
}
// Figure out what map square this point falls on
int checkX = (int) (point.x / ratioCol);
int checkY = (int) (point.y / ratioRow);
// If that's a wall square... no go, we're done here, return the number of steps that
// were OKed so far
if( this.dungeon[checkY][checkX].getTileLetter('W') ) {
return goodToGo;
}
}
// If this step, i, didn't have any conflicts on any of the proposed new corners, then
// increment our ongoing count of how many steps are OK to take
goodToGo++;
}
return goodToGo;
}
I know blocks of code are kind of a bitch but any feedback or just shared attempts at 2D collision detection in Slick/Java are very appreciated.