I'm toying with creating a tile-based 2D java game engine. I can render the "local" area without issues(I.E. deciding which local tiles to render). The problem came when I introduced floating point locations. I want my "camera" location to be a double. My thought was "I'll multiply the double by the tilesize, round it, and get a pixel approximation". That doesn't work, for one reason or another. The code below is the most functional code I've been able to construct. It works almost entirely correctly except around the 0,0 area it skips tiles(?) and it looks hackish and the code's overall hideous. Is there some easier method I'm missing here, is there an example I can examine?
private HashMap<Integer, HashMap<Integer, Tile>> tiles = new HashMap<>(); // Tiles stored here
public double cameraX = 0, cameraY = 0; // Camera location(centered on screen)
private final int TILE_SIZE = 100; // Size of tiles
private final int TILE_BUFFER = 5; // Buffer of tiles to be rendered/loaded around screen
private int screenTileWidth = 0, screenTileHeight = 0; // Tiles that fit onto the screen
@Override
public void render(Graphics g) {
// Calculate tile width/height of screen
int screenWidth = this.screenTileWidth + (TILE_BUFFER * 2), screenHeight = this.screenTileHeight
+ (TILE_BUFFER * 2);
// Supposedly the offsets from the camera's location to be applied to the rest of the tile locations
int locOffsetX = (int) Math.round((cameraX % 1) * TILE_SIZE);
int locOffsetY = (int) Math.round((cameraY % 1) * TILE_SIZE);
// Big mess of "eww" hackish stuff to fix negatives messing with things
if (cameraX >= 0 && locOffsetX >= 0) {
locOffsetX *= -1;
}
if (cameraX < 0 && locOffsetX < 0) {
locOffsetX *= -1;
}
if (cameraY >= 0 && locOffsetY >= 0) {
locOffsetY *= -1;
}
if (cameraY < 0 && locOffsetY < 0) {
locOffsetY *= -1;
}
// Base offsets to center tile
int offsetX = ((GameEngine.g.getWidth() / 2) - (screenTileWidth / 2)
* TILE_SIZE)
+ locOffsetX;
int offsetY = ((GameEngine.g.getHeight() / 2) - (screenTileHeight / 2)
* TILE_SIZE)
+ locOffsetY;
// Loop through loaded tiles(x/y tile coord)
for (int x = (int) (Math.floor(cameraX) - (screenWidth / 2)); x < Math
.floor(cameraX) + (screenWidth / 2); x++) {
for (int y = (int) (Math.floor(cameraY) - (screenHeight / 2)); y < Math
.floor(cameraY) + (screenHeight / 2); y++) {
// The screen-relative tile coord
int sx = (int) (x - Math.floor(cameraX));
int sy = (int) (y - Math.floor(cameraY));
// Tile pixel location
int locX = sx * TILE_SIZE + offsetX;
int locY = sy * TILE_SIZE + offsetY;
// Draw box/location info
g.setColor(Color.RED);
g.drawRect(locX, locY, TILE_SIZE, TILE_SIZE);
g.drawString(x + ", " + y, locX + 10, locY + 20);
}
}
}