import Field from "./Field.js"; import Tileset from "./Tileset.js"; import TilorswiftEvent from "./events/TilorswiftEvent.js"; export default class Terrain { constructor(tileset, tilesX, tilesY, backgroundColor = 'black') { this.tileset = tileset; this.fields = []; this.tilesX = tilesX; this.tilesY = tilesY; this.entranceTileX = undefined; this.entranceTileY = undefined; this.targetTileX = undefined; this.targetTileY = undefined; this.backgroundColor = backgroundColor; this.htmlElement = document.createElement('table'); this.brushTileIndex = 0; this.init(); } init() { this.htmlElement.id = 'level'; this.htmlElement.style.backgroundColor = this.backgroundColor; this.htmlElement.style.width = this.tileset.getTileWidth() * this.tilesX + 'px'; this.htmlElement.style.height = this.tileset.getTileHeight() * this.tilesY + 'px'; for (let r = 0; r < this.tilesY; r++) { this._insertRow(); } window.addEventListener( TilorswiftEvent.BUTTON_TILE_CLICKED, (event) => { this.brushTileIndex = event.button.index; } ) } getElement() { return this.htmlElement; } getTileset() { return this.tileset; } getWidth() { return this.tilesX * this.tilest.getTileWidth(); } getHeight() { return this.tilesY * this.tilest.getTileHeight(); } addRows(index, quantity = 1) { for (let q = 0; q < quantity; q++) { this._insertRow(index); this.tilesY++; } this.htmlElement.style.height = this.tileset.getTileHeight() * this.tilesY + 'px'; } _insertRow(index = undefined) { let row = []; let tr = document.createElement('tr'); for (let col = 0; col < this.tilesX; col++) { let field = new Field(this.tileset); let td = field.getElement(); row.push(field); tr.appendChild(td); } if (index === undefined || index >= this.tilesY - 1) { this.fields.push(row); this.htmlElement.appendChild(tr); } else { this.fields = this.fields.slice(0, index).concat(row).concat(this.fields.slice(index)); this.htmlElement.insertBefore(tr, this.htmlElement.childNodes[index]); } } addColumns(index, quantity = 1) { for (let c = 0; c < quantity; c++) { this._insertColumn(index); this.tilesX++; } this.htmlElement.style.width = this.tileset.getTileWidth() * this.tilesX + 'px'; } _insertColumn(index = undefined) { if (index === undefined || index > this.tilesX - 1) { index = this.tilesX; } for (let y = 0; y < this.tilesY; y++) { let field = new Field(this.tileset); this.fields[y] = this.fields[y].slice(0, index).concat(field).concat(this.fields[y].slice(index)); let htmlRow = this.htmlElement.childNodes[y]; htmlRow.insertBefore(field.getElement(), htmlRow.childNodes[index]); } } setFieldIndex(x, y, index) { this.fields[y][x].setIndex(index); } setEntrancePoint(tileX, tileY) { if (this.fields[tileY][tileX].index === -1) { if (this.entranceTileX !== undefined && this.entranceTileY !== undefined) { this.fields[this.entranceTileY][this.entranceTileX].setEntrancePoint(false); } this.entranceTileX = tileX; this.entranceTileY = tileY; this.fields[tileY][tileX].setEntrancePoint(true); } } setTargetPoint(tileX, tileY) { if (this.fields[tileY][tileX].index === -1) { if (this.targetTileX !== undefined && this.targetTileY !== undefined) { this.fields[this.targetTileY][this.targetTileX].setTargetPoint(false); } this.targetTileX = tileX; this.targetTileY = tileY; this.fields[tileY][tileX].setTargetPoint(true); } } getFieldCoordinates(field) { for (let y = 0; y < this.fields.length; y++) { for (let x = 0; x < this.fields[y].length; x++) { if (this.fields[y][x] === field) { return {x: x, y: y}; } } } return undefined; } hasEntrancePoint() { return this.entranceTileX !== undefined && this.entranceTileY !== undefined; } hasTargetPoint() { return this.targetTileX !== undefined && this.targetTileY !== undefined; } static createFromJson(terrainData) { let imageTileset = new Image(); imageTileset.src = terrainData.tileset; let tileset = new Tileset(imageTileset, terrainData.tiles, terrainData.scale); let terrain = new Terrain(tileset, terrainData.columns, terrainData.rows, terrainData.backgroundColor); for (let y = 0; y < terrainData.rows; y++) { for (let x = 0; x < terrainData.columns; x++) { terrain.setFieldIndex(x, y, terrainData.matrix[y][x]); if (x === terrainData.startX && y === terrainData.startY) { terrain.setEntrancePoint(x, y); } else if (x === terrainData.targetX && y === terrainData.targetY) { terrain.setTargetPoint(x, y); } } } return terrain; } }