Java 2D is actually a really good place to begin to learn before moving on to something else.
This is how I render only what is on screen…
When you create your map, pass it the width and height of your screen to determine how many tiles to render at a time, i.e…
public TileMap(int screenWidth, int screenHeight) {
rowsToRender = screenHeight / tileSize + 2;
colsToRender = screenWidth / tileSize + 2;
}
Notice that you add an extra two tiles, this is just a safety buffer so you don’t see tiles appearing and disappearing as you walk. Now say if you are telling your tile map where the player is (the position variable in the below), then you can render only the tiles immediately surrounding the player using a render loop similar to the below.
public void render(Graphics2D g) {
int rowOffset = -position.intY() % tileSize;
int colOffset = -position.intX() % tileSize;
String mapString;
int row, col;
for (int r = 0; r < rowsToRender; r++) {
for (int c = 0; c < colsToRender; c++) {
row = r + position.intY() / tileSize;
col = c + position.intX() / tileSize;
if (isTileOutOfBounds(row, col))
break;
// if ((mapString = mapArray[row][col]).equals("NA"))
continue;
// row = charToInt(mapString.charAt(0));
// col = charToInt(mapString.charAt(1));
g.drawImage(tiles[row][col].tile, c * tileSize + colOffset, r * tileSize + rowOffset, null);
}
}
}
In this method, the row and col offset describe how far along the current tile you are on, without this, the player will jump from tile to tile instead of moving smoothly across it, you can see it added to the draw method at the bottom of the loop. The loop will now render the number of rows / cols that we set in the constructor.
The commented-out lines are relevant to how I build and read my maps and will be different for you…
I hope this helps!