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 {
|
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");
|
||||||
|
|
|
@ -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
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 {
|
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);
|
||||||
});
|
});
|
||||||
|
|
|
@ -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";
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Loading…
Reference in a new issue