diff --git a/index.js b/index.js index 8c59081..0e0a732 100644 --- a/index.js +++ b/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"); diff --git a/modules/game-objects/camera.js b/modules/game-objects/camera.js index 24cacb5..064ab0f 100644 --- a/modules/game-objects/camera.js +++ b/modules/game-objects/camera.js @@ -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 ); } diff --git a/modules/game-objects/debug.js b/modules/game-objects/debug.js deleted file mode 100644 index 0bf82a7..0000000 --- a/modules/game-objects/debug.js +++ /dev/null @@ -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(); - } - } -} diff --git a/modules/game-objects/fps-counter.js b/modules/game-objects/fps-counter.js new file mode 100644 index 0000000..3d4b266 --- /dev/null +++ b/modules/game-objects/fps-counter.js @@ -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); + } +} diff --git a/modules/game-objects/game-object.js b/modules/game-objects/game-object.js index 73d1713..932f923 100644 --- a/modules/game-objects/game-object.js +++ b/modules/game-objects/game-object.js @@ -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); }); diff --git a/modules/game-objects/index.js b/modules/game-objects/index.js index 582f133..fbeecb0 100644 --- a/modules/game-objects/index.js +++ b/modules/game-objects/index.js @@ -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"; diff --git a/modules/game-objects/map-management.js b/modules/game-objects/map-management.js index 99263ff..fd4c952 100644 --- a/modules/game-objects/map-management.js +++ b/modules/game-objects/map-management.js @@ -19,6 +19,7 @@ export class MapManagement extends GameObject { } onMouseClick(elementId) { + super.onMouseClick(elementId); if ( !this.elementsId.includes(elementId) || this.selected.elementId === elementId diff --git a/modules/game-objects/map.js b/modules/game-objects/map.js index c12209e..6bf6eff 100644 --- a/modules/game-objects/map.js +++ b/modules/game-objects/map.js @@ -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;