feat(#8): improve debug
This commit is contained in:
parent
4e2905cf96
commit
731a32303a
8 changed files with 84 additions and 88 deletions
8
index.js
8
index.js
|
@ -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");
|
||||
|
|
|
@ -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
|
||||
);
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
21
modules/game-objects/fps-counter.js
Normal file
21
modules/game-objects/fps-counter.js
Normal 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);
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
});
|
||||
|
|
|
@ -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";
|
||||
|
|
|
@ -19,6 +19,7 @@ export class MapManagement extends GameObject {
|
|||
}
|
||||
|
||||
onMouseClick(elementId) {
|
||||
super.onMouseClick(elementId);
|
||||
if (
|
||||
!this.elementsId.includes(elementId) ||
|
||||
this.selected.elementId === elementId
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue