There are a few tile-based collision detection questions out there, but none seemed to suit my need.
I guess I really would like to know why this method for collision detection isn't working.
It updates in a tick() method, but I've also tried updating it in the initializing method. The checkCollisions() starts in a player class, and I'm simply using the returned boolean value to check whether the player can move in that direction or not.
public Boolean checkCollision(Player player, Screen screen, Level level)
{
boolean collides = false;
for(int i = 0; i < level.tiles.length; i++)
{
if(player.getBounds().intersects(level.getBounds(level, i)) && Tile.tiles[i].id == 1)
{
collides = true;
}
}
return collides;
}
And it's simply an if statement in the tick() method:
if(input.right)
{
if(Ash.checkCollision(Ash, screen, level) == false && (dirFacing == 2 || dirFacing == 4))
{
xScroll++;
}
if(deltaMS > 16)
{
dirFacing = 2;
}
if(deltaMS <= 16)
{
dirFacing = 4;
}
}
Here's my getBounds for the tiles (I stuck it in my Level class because the tiles are created there):
public int getX(int i)
{
return tileX[i];
}
public int getY(int i)
{
return tileY[i];
}
public Rectangle getBounds(Level level, int i)
{
return new Rectangle(getX(i), getY(i), 16, 16);
}
And I'm trying this method to find the tile's coordinates so I can draw each rectangle for each tile:
public void setTileCoords(int[] tiles)
{
int sum = 0;
for(int i = 0; i < tiles.length; i++)
{
tileX[i] += sum;
tileY[i] += sum;
sum += 16;
}
}
Now I feel it's the way I'm rendering the map, since when I try to expand the map to 32 by 32 pixels (which will render 32 by 32 tiles on screen) it sticks with the 16 by 16 tiles but keeps my little rocky outcrop in the top right corner of the map...
Here's my level class where I do some extreme rendering/arrays of tile coordinates:
public class Level
{
int w;
int h;
public int[] tiles;
public int[] tileX;
public int[] tileY;
public Level(int w, int h)
{
this.w = w;
this.h = h;
tiles = new int[w * h];
tileX = new int[Tile.tiles.length];
tileY = new int[Tile.tiles.length];
setTileCoords(tiles);
loadMap(0, 0, 0, 0);
}
public void renderBkgrd(int xScroll, int yScroll, Screen screen)
{
//Bitshifting: 10101000 >> 4 = 1010
int xo = xScroll >> 4;
int yo = yScroll >> 4;
int w = (screen.w + 15) >> 4;
int h = (screen.h + 15) >> 4;
screen.setOffs(xScroll, yScroll);
for(int y = yo; y <= h + yo; y++)
{
for(int x = xo; x <= w + xo; x++)
{
getTile(x, y).render(x, y, screen);
}
}
screen.setOffs(0, 0);
}
public Tile getTile(int x, int y)
{
if(x < 0 || y < 0 || x >= w || y >= h) return Tile.rockTile;
return Tile.tiles[tiles[x + y * w]];
}
//Takes tile and offsets.
public void loadMap(int x0, int y0, int x1, int y1)
{
Sprite sprite = SpritesManage.Map1[x0][y0];
for(int y = 0; y < sprite.h; y++)
{
for(int x = 0; x < sprite.w; x++)
{
if(sprite.pixels[x + y * sprite.h] == -9276814)
{
tiles[x + x1 + (y + y1) * h] = Tile.rockTile.id;
}
if(sprite.pixels[x + y * sprite.h] == -11731200)
{
tiles[x + x1 + (y + y1) * h] = Tile.grassTile.id;
}
}
}
}
public void setTileCoords(int[] tiles)
{
int sumX = 0;
int sumY = 0;
for(int y = 0; y < Tile.tiles.length; y++)
{
tileY[y] += sumY;
for(int x = 0; x < Tile.tiles.length; x++)
{
tileX[x] = sumX;
sumX += 16;
}
sumX = 0;
sumY += 16;
}
}
public int getX(int i)
{
return tileX[i];
}
public int getY(int i)
{
return tileY[i];
}
public Rectangle getBounds(Level level, int i)
{
return new Rectangle(getX(i), getY(i), 16, 16);
}
}