Skip to content

Commit

Permalink
refactor(client): optimize all draws
Browse files Browse the repository at this point in the history
  • Loading branch information
Veradictus committed Sep 25, 2023
1 parent 2cdf4ce commit e633c79
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 34 deletions.
8 changes: 2 additions & 6 deletions packages/client/src/renderer/camera.ts
Original file line number Diff line number Diff line change
Expand Up @@ -360,12 +360,8 @@ export default class Camera {
offset = 2,
offsetRight = offset
): void {
for (let y = this.gridY - offset, maxY = y + this.gridHeight + offsetRight; y < maxY; y++)
for (
let x = this.gridX - offset, maxX = x + this.gridWidth + offsetRight;
x < maxX;
x++
) {
for (let y = this.gridY - offset; y < this.gridY + this.gridHeight + offsetRight; y++)
for (let x = this.gridX - offset; x < this.gridX + this.gridWidth + offsetRight; x++) {
if (x < 0 || y < 0 || x >= this.width || y >= this.height) continue;
callback(x, y);
}
Expand Down
28 changes: 23 additions & 5 deletions packages/client/src/renderer/canvas.ts
Original file line number Diff line number Diff line change
Expand Up @@ -95,11 +95,26 @@ export default class Canvas extends Renderer {
// Sets the view according to the camera.
this.updateDrawingView();

// Iterate through all the visible tiles and draw them.
this.forEachVisibleTile(
(tile: ClientTile, index: number) => this.parseTile(tile, index),
2
);
/**
* I made a decision to sacrifice legibility to maximize performance. We avoid using
* `forEachVisiblePosition` so that we do not make a ridiculous amount of callbacks
* for each tile. We do the iteration through the visible tiles using a for loop and
* all within one function.
*/

for (let y = this.camera.gridY - 2; y < this.camera.gridY + this.camera.gridHeight; y++)
for (
let x = this.camera.gridX - 2;
x < this.camera.gridX + this.camera.gridWidth;
x++
) {
// Prevent out of bounds coordinates.
if (this.map.isOutOfBounds(x, y)) continue;

let index = x + y * this.map.width;

this.parseTile(this.map.data[index], index);
}

this.saveFrame();
this.restoreDrawing();
Expand Down Expand Up @@ -469,6 +484,9 @@ export default class Canvas extends Renderer {
*/

private parseTile(tile: ClientTile, index: number): void {
// Ignore empty tiles.
if (tile === 0) return;

// Check for transformed tiles and draw them.
if ((tile as TransformedTile).tileId)
return this.drawVisibleTile(tile as TransformedTile, index);
Expand Down
23 changes: 0 additions & 23 deletions packages/client/src/renderer/renderer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1784,29 +1784,6 @@ export default class Renderer {
//
}

/**
* Iterates through all the indexes and extracts the tile data at that
* specified index by iterating through each tile array (if present) or
* returning the tile data from the map.
* @param callback Returns a region tile object containing rendering information
* such as tileId, x, y, and flip flags. The index is the positioning in the map.
* @param offset How much to look outside the visible camera proportions.
*/

protected forEachVisibleTile(
callback: (data: ClientTile, index: number) => void,
offset = 0
): void {
this.forEachVisibleIndex((index) => {
let indexData = this.map.data[index];

if (indexData === 0) return;

if (Array.isArray(indexData)) for (let data of indexData) callback(data, index);
else callback(indexData, index);
}, offset);
}

/**
* Iterates through all the indexes in the current camera view. The offset
* is used to look `offset` amount of tiles outside the camera view.
Expand Down

0 comments on commit e633c79

Please sign in to comment.