feat(#8): improve debug

This commit is contained in:
Juan Sebastián Montoya 2024-09-14 18:38:50 -05:00
parent 4e2905cf96
commit 731a32303a
8 changed files with 84 additions and 88 deletions

View file

@ -2,7 +2,7 @@ import { GAME_HEIGHT, GAME_WIDTH } from "./modules/constants.js";
import { import {
Camera, Camera,
CanvasResizer, CanvasResizer,
Debug, FpsCounter,
GameObject, GameObject,
MapManagement, MapManagement,
} from "./modules/game-objects/index.js"; } from "./modules/game-objects/index.js";
@ -30,10 +30,10 @@ class Game extends GameObject {
percentage: 0.9, percentage: 0.9,
}); });
const camera = new Camera({ const camera = new Camera({
mapManagement: new MapManagement({ maps: maps }), gameObjects: [new MapManagement({ maps: maps })],
}); });
const debug = new Debug({ debug: false }); const fpsCounter = new FpsCounter({ debug: false });
this.gameObjects = [canvasResizer, camera, debug]; this.gameObjects = [canvasResizer, camera, fpsCounter];
this.canvas = canvas; this.canvas = canvas;
this.ctx = this.canvas.getContext("2d"); this.ctx = this.canvas.getContext("2d");

View file

@ -1,12 +1,10 @@
import { TILE_SIZE } from "../constants.js"; import { TILE_SIZE } from "../constants.js";
import { GameObject } from "./game-object.js"; import { GameObject } from "./game-object.js";
import { MapManagement } from "./map-management.js";
export class Camera extends GameObject { export class Camera extends GameObject {
constructor({ mapManagement, x = 0, y = 0, width = 160, height = 120 }) { constructor({ gameObjects = [], x = 0, y = 0, width = 160, height = 120 }) {
super({ x, y }); super({ x, y });
this.mapManagement = mapManagement; this.gameObjects = gameObjects;
this.gameObjects = [mapManagement];
this.x = x; this.x = x;
this.y = y; this.y = y;
this.width = width; this.width = width;
@ -48,19 +46,14 @@ export class Camera extends GameObject {
} }
moveCamera(dx, dy, delta) { moveCamera(dx, dy, delta) {
const { levelConfig } = this.mapManagement.selected; const [item] = this.gameObjects;
const layer = levelConfig.layers[0]; const { height, width } = item.selected ?? item;
const { height, width } = layer;
const floorX = dx > 0 ? Math.floor : Math.ceil;
const floorY = dy > 0 ? Math.floor : Math.ceil;
this.x = Math.min( this.x = Math.min(
Math.max(this.x + floorX(dx * (delta * 100)), 0), Math.max(this.x + dx * Math.floor(delta * 100), 0),
width * TILE_SIZE - this.width width * TILE_SIZE - this.width
); );
this.y = Math.min( this.y = Math.min(
Math.max(this.y + floorY(dy * (delta * 100)), 0), Math.max(this.y + dy * Math.floor(delta * 100), 0),
height * TILE_SIZE - this.height height * TILE_SIZE - this.height
); );
} }

View file

@ -1,48 +0,0 @@
import { COLS, ROWS, TILE_SIZE } from "../constants.js";
import { createCanvas } from "../utils.js";
import { GameObject } from "./game-object.js";
export class Debug extends GameObject {
constructor({ debug = false }) {
super();
this.debug = debug;
this.fps = 0;
}
toggle() {
this.debug = !this.debug;
}
update(delta) {
this.fps = Math.floor(1 / delta);
}
get grid() {
if (this._grid) {
return this._grid;
}
const { ctx, canvas } = createCanvas(COLS * TILE_SIZE, ROWS * TILE_SIZE);
for (let row = 0; row < ROWS; row++) {
for (let col = 0; col < COLS; col++) {
ctx.strokeRect(col * TILE_SIZE, row * TILE_SIZE, TILE_SIZE, TILE_SIZE);
}
}
return (this._grid = canvas);
}
render(ctx) {
if (!this.debug) {
return;
}
ctx.drawImage(this.grid, 0, 0);
ctx.fillStyle = "Red";
ctx.font = "normal 16pt Arial";
ctx.fillText(this.fps + " fps", 10, 26);
}
onMouseClick(elementId) {
if (elementId === "debug") {
this.toggle();
}
}
}

View file

@ -0,0 +1,21 @@
import { GameObject } from "./game-object.js";
export class FpsCounter extends GameObject {
constructor({ debug = false }) {
super({ debug });
this.fps = 0;
}
update(delta) {
this.fps = Math.floor(1 / delta);
}
render(ctx) {
if (!this.debug) {
return;
}
ctx.fillStyle = "Red";
ctx.font = "normal 12pt Arial";
ctx.fillText(this.fps + " fps", 5, 15);
}
}

View file

@ -1,17 +1,19 @@
export class GameObject { export class GameObject {
/**
* Initializes a new instance of the GameObject class.
*
* @param {Object} options - An object containing the initial properties of the game object.
* @param {number} [options.x=0] - The initial x-coordinate of the game object.
* @param {number} [options.y=0] - The initial y-coordinate of the game object.
* @param {GameObject[]} [options.gameObjects=[]] - An array of child game objects.
*/
constructor(options = {}) { constructor(options = {}) {
const { x = 0, y = 0, gameObjects = [] } = options; const {
x = 0,
y = 0,
width = 0,
height = 0,
debug = false,
gameObjects = [],
} = options;
this.x = x; this.x = x;
this.y = y; this.y = y;
this.width = width;
this.height = height;
this.gameObjects = gameObjects; this.gameObjects = gameObjects;
this.debug = debug;
} }
async load() { async load() {
@ -47,6 +49,9 @@ export class GameObject {
} }
onMouseClick(elementId) { onMouseClick(elementId) {
if (elementId === "debug") {
this.debug = !this.debug;
}
this.gameObjects.forEach((item) => { this.gameObjects.forEach((item) => {
item.onMouseClick(elementId); item.onMouseClick(elementId);
}); });

View file

@ -1,6 +1,6 @@
export { Camera } from "./camera.js"; export { Camera } from "./camera.js";
export { CanvasResizer } from "./canvas-resizer.js"; export { CanvasResizer } from "./canvas-resizer.js";
export { Debug } from "./debug.js"; export { FpsCounter } from "./fps-counter.js";
export { GameObject } from "./game-object.js"; export { GameObject } from "./game-object.js";
export { MapManagement } from "./map-management.js"; export { MapManagement } from "./map-management.js";
export { Map } from "./map.js"; export { Map } from "./map.js";

View file

@ -19,6 +19,7 @@ export class MapManagement extends GameObject {
} }
onMouseClick(elementId) { onMouseClick(elementId) {
super.onMouseClick(elementId);
if ( if (
!this.elementsId.includes(elementId) || !this.elementsId.includes(elementId) ||
this.selected.elementId === elementId this.selected.elementId === elementId

View file

@ -3,39 +3,56 @@ import { createCanvas } from "../utils.js";
import { GameObject } from "./game-object.js"; import { GameObject } from "./game-object.js";
export class Map extends GameObject { export class Map extends GameObject {
constructor({ name, imageId, elementId, selected = false }) { constructor({ name, imageId, elementId, selected = false, debug = false }) {
super(); super({ debug });
this.name = name; this.name = name;
this.imageId = imageId; this.imageId = imageId;
this.image = document.getElementById(imageId); this.image = document.getElementById(imageId);
this.width = this.image.width; this.imageWidth = this.image.width;
this.imageHeight = this.image.height;
this.selected = selected; this.selected = selected;
this.elementId = elementId; this.elementId = elementId;
this.debug = debug;
} }
async load() { async load() {
const levelConfig = await fetch("/resources/" + this.name + ".json"); const levelConfig = await fetch("/resources/" + this.name + ".json");
this.levelConfig = await levelConfig.json(); this.levelConfig = await levelConfig.json();
const layer = this.levelConfig.layers[0];
const { data, height, width } = layer;
this.width = width;
this.height = height;
this.data = data;
} }
get level() { get level() {
if (this._level) { if (this._level) {
return this._level; return this._level;
} }
const levelConfig = this.levelConfig; const { ctx, canvas } = createCanvas(
const layer = levelConfig.layers[0]; this.width * TILE_SIZE,
const { data, height, width } = layer; this.height * TILE_SIZE
const { ctx, canvas } = createCanvas(width * TILE_SIZE, height * TILE_SIZE); );
for (let row = 0; row < height; row++) { for (let row = 0; row < this.height; row++) {
for (let col = 0; col < width; col++) { for (let col = 0; col < this.width; col++) {
if (row < 0 || col < 0 || row >= height || col >= width) continue; if (row < 0 || col < 0 || row >= this.height || col >= this.width)
continue;
const tile = data[row * width + col] - 1; if (this.debug) {
ctx.strokeRect(
col * TILE_SIZE,
row * TILE_SIZE,
TILE_SIZE,
TILE_SIZE
);
}
const tile = this.data[row * this.width + col] - 1;
ctx.drawImage( ctx.drawImage(
this.image, this.image,
(tile * TILE_SIZE) % this.width, (tile * TILE_SIZE) % this.imageWidth,
Math.floor((tile * TILE_SIZE) / this.width) * TILE_SIZE, Math.floor((tile * TILE_SIZE) / this.imageWidth) * TILE_SIZE,
TILE_SIZE, TILE_SIZE,
TILE_SIZE, TILE_SIZE,
col * TILE_SIZE, col * TILE_SIZE,
@ -49,6 +66,13 @@ export class Map extends GameObject {
return (this._level = canvas); return (this._level = canvas);
} }
onMouseClick(elementId) {
if (elementId === "debug") {
this.debug = !this.debug;
this._level = null;
}
}
render(ctx, sourceX, sourceY, width, height) { render(ctx, sourceX, sourceY, width, height) {
if (!this.levelConfig || !this.selected) { if (!this.levelConfig || !this.selected) {
return; return;