import { GAME_HEIGHT, GAME_WIDTH, TILE_SIZE } from "../constants.js"; import { GameObject } from "./game-object.js"; export class Sprite extends GameObject { constructor({ image, x = 0, y = 0, width = 0, height = 0 }) { super({ x, y, height, width }); this.image = image; this.imageWidth = this.image.width; this.imageHeight = this.image.height; } render(ctx, sourceX, sourceY) { ctx.drawImage( this.image, this.x, this.y, this.width, this.height, sourceX, sourceY, this.width, this.height ); } } export class SpriteSheet extends GameObject { constructor({ imageId, x = 0, y = 0, tileWidth = 16, tileHeight = 16, offsetX = 0, offsetY = 0, }) { super({ x, y }); this.image = document.getElementById(imageId); this.imageWidth = this.image.width; this.imageHeight = this.image.height; this.tileWidth = tileWidth; this.tileHeight = tileHeight; this.offsetX = offsetX; this.offsetY = offsetY; this.sprites = this._getSprites(); } _getSprites() { const sprites = []; for (let row = 0; row < this.imageHeight; row += this.tileHeight) { for (let col = 0; col < this.imageWidth; col += this.tileHeight) { sprites.push( new Sprite({ image: this.image, x: col + this.offsetX, y: row + this.offsetY, width: this.tileWidth, height: this.tileHeight, }) ); } } return sprites; } } export class Player extends GameObject { constructor({ gameObjects = [], x = 0, y = 0, speed = 1, ...args }) { super({ x, y, gameObjects, ...args }); this.speed = speed; this.keys = [ { key: "ArrowUp", pressed: false, value: [0, -1] }, { key: "ArrowDown", pressed: false, value: [0, 1] }, { key: "ArrowLeft", pressed: false, value: [-1, 0] }, { key: "ArrowRight", pressed: false, value: [1, 0] }, ]; this.availableKeys = this.keys.reduce( (acc, item) => ({ ...acc, [item.key]: item }), {} ); this.eventEmitter.on("levelChanged", (...args) => { this.x = x; this.y = y; }); } update(delta) { this.keys.forEach((item) => { if (item.pressed) { this.moveCharacter(...item.value, delta); } }); } onKeyPressed(key) { if (!this.availableKeys[key]) return; this.availableKeys[key].pressed = true; } onKeyReleased(key) { if (!this.availableKeys[key]) return; this.availableKeys[key].pressed = false; } render(ctx, ...args) { const [x, y] = args; const [spriteSheet] = this.gameObjects; const [item] = spriteSheet.sprites; item.render(ctx, this.x - x, this.y - y); } moveCharacter(dx, dy, delta) { const speed = Math.floor(delta * this.speed * 100); this.x = this.x + dx * speed; this.y = this.y + dy * speed; // TODO: Check for collisions and stop movement if needed } }