The important thing to remember is that you’re working with multiple coordinate systems.
x * TILE_SIZE
and y * TILE_SIZE
are screen coordinates.
mapx
and mapy
are map offsets in world coordinates.
Then % TILE_SIZE
is used to get the player’s offset within a tile (sort of),
which is then used to offset the rendered representation of the world (the map is not the territory).
You could try working out the numbers on paper (maybe with a calculator) to see how they behave.
Often just stepping through the code manually makes it easier to understand, and that’s probably the closest you can get tp being able to do that.
You could also try this:
constexpr uint8_t TILE_SIZE = 16;
void drawworld()
{
const int tileswide = WIDTH / TILE_SIZE + 1;
const int tilestall = HEIGHT / TILE_SIZE + 1;
for (int y = 0; y < tilestall; y++)
{
for (int x = 0; x < tileswide; x++)
{
const int tilex = x - mapx / TILE_SIZE;
const int tiley = y - mapy / TILE_SIZE;
if (tilex >= 0 && tiley >= 0 && tilex < WORLD_WIDTH && tiley < WORLD_HEIGHT)
{
Sprites::drawOverwrite(x * TILE_SIZE + mapx % TILE_SIZE, y * TILE_SIZE + mapy % TILE_SIZE, tiles, world[tiley][tilex]);
}
}
}
arduboy.fillRect(0, 0, 48, 8, BLACK);
arduboy.setCursor(0, 0);
// Map coordinates
arduboy.print(mapx);
arduboy.print(',');
arduboy.print(mapy);
arduboy.print('\n');
// Map coordinate remainder
arduboy.print(mapx % TILE_SIZE);
arduboy.print(',');
arduboy.print(mapy % TILE_SIZE);
arduboy.print('\n');
// Render coordinate without modulo
arduboy.print(1 * TILE_SIZE + mapx);
arduboy.print(',');
arduboy.print(1 * TILE_SIZE + mapy % TILE_SIZE);
arduboy.print('\n');
// Render coordinate with modulo
arduboy.print(1 * TILE_SIZE + mapx % TILE_SIZE);
arduboy.print(',');
arduboy.print(1 * TILE_SIZE + mapy % TILE_SIZE);
arduboy.print('\n');
}
Smasher.hex (26.4 KB)
Hopefully you’ll be able to see that not using the modulo increases the size indefinitely, while using the modulo just provides the 0 to -15 offset (the player’s offset into the tile they’re currently on).