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

View file

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

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 {
/**
* 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 = {}) {
const { x = 0, y = 0, gameObjects = [] } = options;
const {
x = 0,
y = 0,
width = 0,
height = 0,
debug = false,
gameObjects = [],
} = options;
this.x = x;
this.y = y;
this.width = width;
this.height = height;
this.gameObjects = gameObjects;
this.debug = debug;
}
async load() {
@ -47,6 +49,9 @@ export class GameObject {
}
onMouseClick(elementId) {
if (elementId === "debug") {
this.debug = !this.debug;
}
this.gameObjects.forEach((item) => {
item.onMouseClick(elementId);
});

View file

@ -1,6 +1,6 @@
export { Camera } from "./camera.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 { MapManagement } from "./map-management.js";
export { Map } from "./map.js";

View file

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

View file

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