SOURCE / PINNED RELEASE
Made of little things.
Browser Side Quest
- Release
- b9d42f5768e4…
- Author-recorded commit
- c267690145fa…
- License
- LICENSE
- Author’s source reference
- nostr://npub1ye5ptcxfyyxl5vjvdjar2ua3f0hynkjzpx552mu5snj3qmx5pzjscpknpr/wss%3A%2F%2Fgit.shakespeare.diy%2F/browser-side-quest
Archive hash verified: 6d4b90b8a5f328f7…. The source-to-build association is the author’s claim; it has not been independently rebuilt.
// Port of BrowserQuest client/js/camera.js (MPL-2.0).
// gridW/gridH come from the renderer's frame fit instead of the fixed 15x7 / 30x14.
import type { Entity } from './entity.js';
export class Camera {
x = 0;
y = 0;
gridX = 0;
gridY = 0;
constructor(
public gridW: number,
public gridH: number,
) {}
setPosition(x: number, y: number): void {
this.x = x;
this.y = y;
this.gridX = Math.floor(x / 16);
this.gridY = Math.floor(y / 16);
}
setGridPosition(x: number, y: number): void {
this.gridX = x;
this.gridY = y;
this.x = x * 16;
this.y = y * 16;
}
lookAt(entity: Entity): void {
const x = Math.round(entity.x - Math.floor(this.gridW / 2) * 16);
const y = Math.round(entity.y - Math.floor(this.gridH / 2) * 16);
this.setPosition(x, y);
}
forEachVisiblePosition(callback: (x: number, y: number) => void, extra = 0): void {
const maxY = this.gridY + this.gridH + extra * 2;
const maxX = this.gridX + this.gridW + extra * 2;
for (let y = this.gridY - extra; y < maxY; y += 1) {
for (let x = this.gridX - extra; x < maxX; x += 1) callback(x, y);
}
}
isVisible(entity: Entity): boolean {
return this.isVisiblePosition(entity.gridX, entity.gridY);
}
isVisiblePosition(x: number, y: number): boolean {
return y >= this.gridY && y < this.gridY + this.gridH && x >= this.gridX && x < this.gridX + this.gridW;
}
/** Snap the view by whole screens, keeping a one-tile overlap on each edge. */
focusEntity(entity: Entity): void {
const w = this.gridW - 2;
const h = this.gridH - 2;
const x = Math.floor((entity.gridX - 1) / w) * w;
const y = Math.floor((entity.gridY - 1) / h) * h;
this.setGridPosition(x, y);
}
}
