public class CollisionComponent {
float x, y;
/*
* This here is a collision array
* I know, wtf right?
* He'eres the idea.
* I need to test for verticle and horizontal collision seperatly.
* If i don't then my game will ignore one for the other. This causes
* falls through floors and stuff. With collision being an array
* I can have one function return two values intead of two functions
* returning one value each.
*/
public void checkTouching(Entity entity, editor.MapComponent map ){
entity.collision[0] = 0;
entity.collision[1] = 0;
/*
* Entity is falling, check bottom side collision
*/
if (entity.verticleVelocity > 0.0f){
bottom (entity, map);
if (entity.collision[0] == 1){
entity.Y = ((map.rowIndex * map.tileHeight) - entity.Height) ;
entity.verticleVelocity = 0.0f;
}
}
/*
* Entity is rising, check top side for collision
*/
else if (entity.verticleVelocity < 0.0f){
top (entity, map);
if (entity.collision[0] == 2){
entity.Y = ((map.rowIndex + 1) * map.tileHeight);
entity.verticleVelocity = 0.0f;
}
}
/*
* Entity is moving right, check right for collision
*/
if (entity.Velocity > 0.0f){
right(entity, map);
if (entity.collision[1] == 3){
entity.X = ( ((map.columnIndex ) * map.tileWidth) - entity.Width) ;
}
}
/*
* Entity is moving left, check left for collision
*/
else if (entity.Velocity < 0.0f){
left(entity, map);
if (entity.collision[1] == 4){
entity.X = ((map.columnIndex + 1) * map.tileWidth);
}
}
}
public void bottom(Entity entity, editor.MapComponent map){
/*
* calculate which tile the bottom of entity is in
*/
map.rowIndex = (int) ((entity.Y + entity.Height ) / map.tileHeight);
for (float x = (entity.X); x <= ((entity.X) + entity.Width); x += map.tileWidth){
map.columnIndex = (int) (x / map.tileWidth); // the (int) casts the entity.x float into an int so I can do the calculation
map.selectedTile = map.map[map.rowIndex][map.columnIndex];
if( map.selectedTile == 1){
entity.collision[0] = 1;
}
}
/*
* this copy pasta code is horrible I know ..... same as above
* it's actually kind of meta now as I just copy pasta'd the
* copy pasta code for each side of the sprite....
*/
map.columnIndex = (int) (( (entity.X ) + entity.Width) / map.tileWidth);
map.selectedTile = map.map[map.rowIndex][map.columnIndex];
if( map.selectedTile == 1){
entity.collision[0] = 1;
}
}
public void top(Entity entity, editor.MapComponent map){
/*
* calculate which tile the top of entity is in
*/
map.rowIndex = (int) ((entity.Y ) / map.tileHeight);
for (float x = (entity.X); x <= ((entity.X ) + entity.Width); x += map.tileWidth){
map.columnIndex = (int) (x / map.tileWidth); // the (int) casts the entity.x float into an int so I can do the calculation
map.selectedTile = map.map[map.rowIndex][map.columnIndex];
if( map.selectedTile == 1){
entity.collision[0] = 2;
}
}
/*
* this copy pasta code is horrible I know ..... same as above
* it's actually kind of meta now as I just copy pasta'd the
* copy pasta code for each side of the sprite....
*/
map.columnIndex = (int) (( (entity.X) + entity.Width) / map.tileWidth);
map.selectedTile = map.map[map.rowIndex][map.columnIndex];
if( map.selectedTile == 1){
entity.collision[0] = 2;
}
}
public void right(Entity entity, editor.MapComponent map){
/*
* calculate which tile the right of entity is in
*/
map.columnIndex = (int) ((entity.X + entity.Width ) / map.tileWidth);
for (float y = (entity.Y) ; y <= ((entity.Y ) + entity.Height); y += map.tileHeight){
map.rowIndex = (int) ( (y) / map.tileHeight); // the (int) casts the entity.x float into an int so I can do the calculation
map.selectedTile = map.map[map.rowIndex][map.columnIndex];
if( map.selectedTile == 1){
entity.collision[1] = 3;
}
}
/*
* this copy pasta code is horrible I know ..... same as above
* it's actually kind of meta now as I just copy pasta'd the
* copy pasta code for each side of the sprite....
*/
map.rowIndex = (int) (((entity.Y) + entity.Height) / map.tileHeight);
map.selectedTile = map.map[map.rowIndex][map.columnIndex];
if( map.selectedTile == 1){
entity.collision[1] = 3;
}
}
public void left(Entity entity, editor.MapComponent map){
/*
* calculate which tile the right of entity is in
*/
map.columnIndex = (int) ((entity.X) / map.tileWidth);
for (float y = (entity.Y) ; y <= ((entity.Y ) + entity.Height); y += map.tileHeight){
map.rowIndex = (int) ((y) / map.tileHeight); // the (int) casts the entity.x float into an int so I can do the calculation
map.selectedTile = map.map[map.rowIndex][map.columnIndex];
if( map.selectedTile == 1){
entity.collision[1] = 4;
}
}
/*
* this copy pasta code is horrible I know ..... same as above
* it's actually kind of meta now as I just copy pasta'd the
* copy pasta code for each side of the sprite....
*/
map.rowIndex = (int) (( (entity.Y) + entity.Height) / map.tileHeight);
map.selectedTile = map.map[map.rowIndex][map.columnIndex];
if( map.selectedTile == 1){
entity.collision[1] = 4;
}
}
}
It is rough I know. I hold the collision results in a 2d array. The first index hold vertical collision(0 for not, 1 for collision on bottom, 2 for collision on top), and I use the second index for the horizontal collision. I test verticle collision first and move the sprite if collision was true. I then test horizontal collision and so blah blah. The rest of my code basically works by polling input (which only changes velocity), applying physics (which applies the velocity to the sprite's position), then testing collision and finally updating the screen. I've included all my source if you want to look at it, but the collision code should be enough.
Any ideas where I'm going wrong here? I think this collision code should work.