mirror of
https://github.com/duckietm/Nitro-Cool-UI.git
synced 2025-06-21 22:36:58 +00:00
🆙 FloorEditor allow tile selection - Beta 1
This will allow you to select a field of tiles. Still need the buttons fixed, but hee it is beta 1
This commit is contained in:
parent
e493428dc9
commit
31e047e803
@ -3,15 +3,18 @@ import { ActionSettings } from './ActionSettings';
|
|||||||
import { FloorAction, HEIGHT_SCHEME, MAX_NUM_TILE_PER_AXIS, TILE_SIZE } from './Constants';
|
import { FloorAction, HEIGHT_SCHEME, MAX_NUM_TILE_PER_AXIS, TILE_SIZE } from './Constants';
|
||||||
import { imageBase64, spritesheet } from './FloorplanResource';
|
import { imageBase64, spritesheet } from './FloorplanResource';
|
||||||
import { Tile } from './Tile';
|
import { Tile } from './Tile';
|
||||||
import { getScreenPositionForTile } from './Utils';
|
import { getScreenPositionForTile, getTileFromScreenPosition } from './Utils';
|
||||||
|
|
||||||
export class FloorplanEditor
|
export class FloorplanEditor {
|
||||||
{
|
|
||||||
private static _INSTANCE: FloorplanEditor = null;
|
private static _INSTANCE: FloorplanEditor = null;
|
||||||
|
|
||||||
public static readonly TILE_BLOCKED = 'r_blocked';
|
public static readonly TILE_BLOCKED = 'r_blocked';
|
||||||
public static readonly TILE_DOOR = 'r_door';
|
public static readonly TILE_DOOR = 'r_door';
|
||||||
|
|
||||||
|
private _squareSelectMode: boolean = false; // Mode flag (name remains for compatibility)
|
||||||
|
private _selectionStart: NitroPoint = null;
|
||||||
|
private _selectionEnd: NitroPoint = null;
|
||||||
|
|
||||||
private _tilemap: Tile[][];
|
private _tilemap: Tile[][];
|
||||||
private _width: number;
|
private _width: number;
|
||||||
private _height: number;
|
private _height: number;
|
||||||
@ -23,22 +26,20 @@ export class FloorplanEditor
|
|||||||
|
|
||||||
private _image: HTMLImageElement;
|
private _image: HTMLImageElement;
|
||||||
|
|
||||||
constructor()
|
constructor() {
|
||||||
{
|
|
||||||
const width = TILE_SIZE * MAX_NUM_TILE_PER_AXIS + 20;
|
const width = TILE_SIZE * MAX_NUM_TILE_PER_AXIS + 20;
|
||||||
const height = (TILE_SIZE * MAX_NUM_TILE_PER_AXIS) / 2 + 100;
|
const height = (TILE_SIZE * MAX_NUM_TILE_PER_AXIS) / 2 + 100;
|
||||||
|
|
||||||
const canvas = document.createElement('canvas');
|
const canvas = document.createElement('canvas');
|
||||||
|
|
||||||
canvas.height = height;
|
canvas.height = height;
|
||||||
canvas.width = width;
|
canvas.width = width;
|
||||||
|
|
||||||
canvas.style.touchAction = 'none';
|
canvas.style.touchAction = 'none';
|
||||||
|
|
||||||
|
canvas.oncontextmenu = (e) => { e.preventDefault(); };
|
||||||
|
|
||||||
this._renderer = canvas.getContext('2d');
|
this._renderer = canvas.getContext('2d');
|
||||||
|
|
||||||
this._image = new Image();
|
this._image = new Image();
|
||||||
|
|
||||||
this._image.src = imageBase64;
|
this._image.src = imageBase64;
|
||||||
|
|
||||||
this._tilemap = [];
|
this._tilemap = [];
|
||||||
@ -50,62 +51,75 @@ export class FloorplanEditor
|
|||||||
this._actionSettings = new ActionSettings();
|
this._actionSettings = new ActionSettings();
|
||||||
}
|
}
|
||||||
|
|
||||||
public onPointerRelease(): void
|
public setSquareSelectMode(enabled: boolean): void {
|
||||||
{
|
this._squareSelectMode = enabled;
|
||||||
this._isPointerDown = false;
|
if (!enabled) {
|
||||||
|
this._selectionStart = null;
|
||||||
|
this._selectionEnd = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public get squareSelectMode(): boolean {
|
||||||
|
return this._squareSelectMode;
|
||||||
}
|
}
|
||||||
|
|
||||||
public onPointerDown(event: PointerEvent): void
|
public onPointerRelease(): void {
|
||||||
{
|
this._isPointerDown = false;
|
||||||
if(event.button === 2) return;
|
if (this._squareSelectMode && this._selectionStart) {
|
||||||
|
this.finalizeSquareSelection();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public onPointerDown(event: PointerEvent): void {
|
||||||
|
if (this._squareSelectMode) {
|
||||||
|
event.preventDefault();
|
||||||
|
const location = new NitroPoint(event.offsetX, event.offsetY);
|
||||||
|
const [tileX, tileY] = getTileFromScreenPosition(location.x, location.y);
|
||||||
|
const roundedX = Math.floor(tileX);
|
||||||
|
const roundedY = Math.floor(tileY);
|
||||||
|
this._selectionStart = new NitroPoint(roundedX, roundedY);
|
||||||
|
this._selectionEnd = new NitroPoint(roundedX, roundedY);
|
||||||
|
this._isPointerDown = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (event.button === 2) return;
|
||||||
const location = new NitroPoint(event.offsetX, event.offsetY);
|
const location = new NitroPoint(event.offsetX, event.offsetY);
|
||||||
|
|
||||||
this._isPointerDown = true;
|
this._isPointerDown = true;
|
||||||
|
|
||||||
this.tileHitDetection(location, true);
|
this.tileHitDetection(location, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public onPointerMove(event: PointerEvent): void
|
public onPointerMove(event: PointerEvent): void {
|
||||||
{
|
if (!this._isPointerDown) return;
|
||||||
if(!this._isPointerDown) return;
|
if (this._squareSelectMode && this._selectionStart) {
|
||||||
|
const location = new NitroPoint(event.offsetX, event.offsetY);
|
||||||
|
const [tileX, tileY] = getTileFromScreenPosition(location.x, location.y);
|
||||||
|
this._selectionEnd.x = Math.floor(tileX);
|
||||||
|
this._selectionEnd.y = Math.floor(tileY);
|
||||||
|
this.renderTiles();
|
||||||
|
// Optionally, you could add a temporary overlay here if desired.
|
||||||
|
return;
|
||||||
|
}
|
||||||
const location = new NitroPoint(event.offsetX, event.offsetY);
|
const location = new NitroPoint(event.offsetX, event.offsetY);
|
||||||
this.tileHitDetection(location, false);
|
this.tileHitDetection(location, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
private tileHitDetection(tempPoint: NitroPoint, isClick: boolean = false): boolean
|
private tileHitDetection(tempPoint: NitroPoint, isClick: boolean = false): boolean {
|
||||||
{
|
|
||||||
const mousePositionX = Math.floor(tempPoint.x);
|
const mousePositionX = Math.floor(tempPoint.x);
|
||||||
const mousePositionY = Math.floor(tempPoint.y);
|
const mousePositionY = Math.floor(tempPoint.y);
|
||||||
|
|
||||||
const width = TILE_SIZE;
|
const width = TILE_SIZE;
|
||||||
const height = TILE_SIZE / 2;
|
const height = TILE_SIZE / 2;
|
||||||
|
for (let y = 0; y < this._tilemap.length; y++) {
|
||||||
for(let y = 0; y < this._tilemap.length; y++)
|
for (let x = 0; x < this.tilemap[y].length; x++) {
|
||||||
{
|
const [tileStartX, tileStartY] = getScreenPositionForTile(x, y);
|
||||||
for(let x = 0; x < this.tilemap[y].length; x++)
|
|
||||||
{
|
|
||||||
const [ tileStartX, tileStartY ] = getScreenPositionForTile(x, y);
|
|
||||||
|
|
||||||
const centreX = tileStartX + (width / 2);
|
const centreX = tileStartX + (width / 2);
|
||||||
const centreY = tileStartY + (height / 2);
|
const centreY = tileStartY + (height / 2);
|
||||||
|
|
||||||
const dx = Math.abs(mousePositionX - centreX);
|
const dx = Math.abs(mousePositionX - centreX);
|
||||||
const dy = Math.abs(mousePositionY - centreY);
|
const dy = Math.abs(mousePositionY - centreY);
|
||||||
|
const solution = (dx / (width * 0.5) + dy / (height * 0.5) <= 1);
|
||||||
const solution = (dx / (width * 0.5) + dy / (height * 0.5) <= 1); //todo: improve this
|
if (solution) {
|
||||||
|
if (this._isPointerDown) {
|
||||||
if(solution)
|
if (isClick) {
|
||||||
{
|
|
||||||
if(this._isPointerDown)
|
|
||||||
{
|
|
||||||
if(isClick)
|
|
||||||
{
|
|
||||||
this.onClick(x, y);
|
this.onClick(x, y);
|
||||||
}
|
} else if (this._lastUsedTile.x !== x || this._lastUsedTile.y !== y) {
|
||||||
else if(this._lastUsedTile.x !== x || this._lastUsedTile.y !== y)
|
|
||||||
{
|
|
||||||
this._lastUsedTile.x = x;
|
this._lastUsedTile.x = x;
|
||||||
this._lastUsedTile.y = y;
|
this._lastUsedTile.y = y;
|
||||||
this.onClick(x, y);
|
this.onClick(x, y);
|
||||||
@ -118,21 +132,16 @@ export class FloorplanEditor
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private onClick(x: number, y: number, render: boolean = true, force: boolean = false): void
|
private onClick(x: number, y: number, render: boolean = true, force: boolean = false): void {
|
||||||
{
|
|
||||||
const tile = this._tilemap[y][x];
|
const tile = this._tilemap[y][x];
|
||||||
// When forcing, treat background ('x') as index 0.
|
|
||||||
let currentHeightIndex = (tile.height === 'x' && force) ? 0 : HEIGHT_SCHEME.indexOf(tile.height);
|
let currentHeightIndex = (tile.height === 'x' && force) ? 0 : HEIGHT_SCHEME.indexOf(tile.height);
|
||||||
let futureHeightIndex = 0;
|
let futureHeightIndex = 0;
|
||||||
|
switch (this._actionSettings.currentAction) {
|
||||||
switch(this._actionSettings.currentAction)
|
|
||||||
{
|
|
||||||
case FloorAction.DOOR:
|
case FloorAction.DOOR:
|
||||||
if (!force && tile.height !== 'x')
|
if (!force && tile.height !== 'x') {
|
||||||
{
|
|
||||||
this._doorLocation.x = x;
|
this._doorLocation.x = x;
|
||||||
this._doorLocation.y = y;
|
this._doorLocation.y = y;
|
||||||
if(render) this.renderTiles();
|
if (render) this.renderTiles();
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
case FloorAction.UP:
|
case FloorAction.UP:
|
||||||
@ -150,58 +159,51 @@ export class FloorplanEditor
|
|||||||
futureHeightIndex = 0;
|
futureHeightIndex = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
if (futureHeightIndex === -1) return;
|
||||||
if(futureHeightIndex === -1) return;
|
if (currentHeightIndex === futureHeightIndex) return;
|
||||||
if(currentHeightIndex === futureHeightIndex) return;
|
if (!force && futureHeightIndex > 0) {
|
||||||
|
|
||||||
// Only update _width and _height if not forcing.
|
|
||||||
if (!force && futureHeightIndex > 0)
|
|
||||||
{
|
|
||||||
if ((x + 1) > this._width) this._width = x + 1;
|
if ((x + 1) > this._width) this._width = x + 1;
|
||||||
if ((y + 1) > this._height) this._height = y + 1;
|
if ((y + 1) > this._height) this._height = y + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
const newHeight = HEIGHT_SCHEME[futureHeightIndex];
|
const newHeight = HEIGHT_SCHEME[futureHeightIndex];
|
||||||
if (!newHeight) return;
|
if (!newHeight) return;
|
||||||
|
|
||||||
this._tilemap[y][x].height = newHeight;
|
this._tilemap[y][x].height = newHeight;
|
||||||
|
if (render) this.renderTiles();
|
||||||
if(render) this.renderTiles();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public renderTiles(): void
|
public renderTiles(): void {
|
||||||
{
|
|
||||||
this.clearCanvas();
|
this.clearCanvas();
|
||||||
|
for (let y = 0; y < this._tilemap.length; y++) {
|
||||||
for(let y = 0; y < this._tilemap.length; y++)
|
for (let x = 0; x < this.tilemap[y].length; x++) {
|
||||||
{
|
|
||||||
for(let x = 0; x < this.tilemap[y].length; x++)
|
|
||||||
{
|
|
||||||
const tile = this.tilemap[y][x];
|
const tile = this.tilemap[y][x];
|
||||||
let assetName = tile.height;
|
let assetName = tile.height;
|
||||||
|
if (this._doorLocation.x === x && this._doorLocation.y === y)
|
||||||
if(this._doorLocation.x === x && this._doorLocation.y === y)
|
|
||||||
assetName = FloorplanEditor.TILE_DOOR;
|
assetName = FloorplanEditor.TILE_DOOR;
|
||||||
|
if (tile.isBlocked) assetName = FloorplanEditor.TILE_BLOCKED;
|
||||||
if(tile.isBlocked) assetName = FloorplanEditor.TILE_BLOCKED;
|
|
||||||
|
|
||||||
if ((tile.height === 'x' || tile.height === 'X') && tile.isBlocked) assetName = 'x';
|
if ((tile.height === 'x' || tile.height === 'X') && tile.isBlocked) assetName = 'x';
|
||||||
|
const [positionX, positionY] = getScreenPositionForTile(x, y);
|
||||||
const [ positionX, positionY ] = getScreenPositionForTile(x, y);
|
|
||||||
|
|
||||||
const asset = spritesheet.frames[assetName];
|
const asset = spritesheet.frames[assetName];
|
||||||
|
if (asset === undefined) {
|
||||||
if (asset === undefined)
|
console.warn(`Asset "${assetName}" not found in spritesheet.`);
|
||||||
{
|
|
||||||
console.warn(`Asset "${ assetName }" not found in spritesheet.`);
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
this.renderer.drawImage(this._image, asset.frame.x, asset.frame.y, asset.frame.w, asset.frame.h,
|
||||||
|
positionX, positionY, asset.frame.w, asset.frame.h);
|
||||||
|
|
||||||
this.renderer.drawImage(this._image, asset.frame.x, asset.frame.y, asset.frame.w, asset.frame.h, positionX, positionY, asset.frame.w, asset.frame.h);
|
// While dragging in selection mode, overlay green on tiles within the selection region.
|
||||||
|
if (this._squareSelectMode && this._isPointerDown && this._selectionStart && this._selectionEnd) {
|
||||||
|
const selMinX = Math.min(this._selectionStart.x, this._selectionEnd.x);
|
||||||
|
const selMaxX = Math.max(this._selectionStart.x, this._selectionEnd.x);
|
||||||
|
const selMinY = Math.min(this._selectionStart.y, this._selectionEnd.y);
|
||||||
|
const selMaxY = Math.max(this._selectionStart.y, this._selectionEnd.y);
|
||||||
|
if (x >= selMinX && x <= selMaxX && y >= selMinY && y <= selMaxY) {
|
||||||
|
this.renderer.fillStyle = 'rgba(0, 255, 0, 0.3)';
|
||||||
|
this.renderer.fillRect(positionX, positionY, asset.frame.w, asset.frame.h);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// If the tile is selected, draw a semi-transparent blue overlay.
|
if (tile.selected) {
|
||||||
if (tile.selected)
|
|
||||||
{
|
|
||||||
this.renderer.fillStyle = 'rgba(0, 0, 255, 0.3)';
|
this.renderer.fillStyle = 'rgba(0, 0, 255, 0.3)';
|
||||||
this.renderer.fillRect(positionX, positionY, asset.frame.w, asset.frame.h);
|
this.renderer.fillRect(positionX, positionY, asset.frame.w, asset.frame.h);
|
||||||
}
|
}
|
||||||
@ -209,37 +211,53 @@ export class FloorplanEditor
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public toggleSelectAll(): void
|
// Toggle select all (always selects)
|
||||||
{
|
public toggleSelectAll(): void {
|
||||||
|
|
||||||
const newState = true;
|
const newState = true;
|
||||||
|
for (let y = 0; y < this._tilemap.length; y++) {
|
||||||
|
for (let x = 0; x < this._tilemap[y].length; x++) {
|
||||||
for (let y = 0; y < this._tilemap.length; y++)
|
|
||||||
{
|
|
||||||
for (let x = 0; x < this._tilemap[y].length; x++)
|
|
||||||
{
|
|
||||||
this._tilemap[y][x].selected = newState;
|
this._tilemap[y][x].selected = newState;
|
||||||
this.onClick(x, y, false, true);
|
this.onClick(x, y, false, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this.recalcActiveArea();
|
this.recalcActiveArea();
|
||||||
this.renderTiles();
|
this.renderTiles();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private finalizeSquareSelection(): void {
|
||||||
|
const startX = Math.floor(this._selectionStart.x);
|
||||||
|
const startY = Math.floor(this._selectionStart.y);
|
||||||
|
const endX = Math.floor(this._selectionEnd.x);
|
||||||
|
const endY = Math.floor(this._selectionEnd.y);
|
||||||
|
const minX = Math.min(startX, endX);
|
||||||
|
const maxX = Math.max(startX, endX);
|
||||||
|
const minY = Math.min(startY, endY);
|
||||||
|
const maxY = Math.max(startY, endY);
|
||||||
|
this.selectSquareField(minX, minY, maxX, maxY);
|
||||||
|
this._selectionStart = null;
|
||||||
|
this._selectionEnd = null;
|
||||||
|
this.renderTiles();
|
||||||
|
}
|
||||||
|
|
||||||
// New helper method to recalculate active area dimensions.
|
private selectSquareField(x1: number, y1: number, x2: number, y2: number): void {
|
||||||
private recalcActiveArea(): void
|
for (let y = y1; y <= y2; y++) {
|
||||||
{
|
for (let x = x1; x <= x2; x++) {
|
||||||
|
if (this._tilemap[y] && this._tilemap[y][x]) {
|
||||||
|
this._tilemap[y][x].selected = true;
|
||||||
|
this.onClick(x, y, false, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.recalcActiveArea();
|
||||||
|
this.renderTiles();
|
||||||
|
}
|
||||||
|
|
||||||
|
private recalcActiveArea(): void {
|
||||||
this._width = 0;
|
this._width = 0;
|
||||||
this._height = 0;
|
this._height = 0;
|
||||||
for (let y = 0; y < this._tilemap.length; y++)
|
for (let y = 0; y < this._tilemap.length; y++) {
|
||||||
{
|
for (let x = 0; x < this._tilemap[y].length; x++) {
|
||||||
for (let x = 0; x < this._tilemap[y].length; x++)
|
if (this._tilemap[y][x].height !== 'x') {
|
||||||
{
|
|
||||||
if (this._tilemap[y][x].height !== 'x')
|
|
||||||
{
|
|
||||||
if ((x + 1) > this._width) this._width = x + 1;
|
if ((x + 1) > this._width) this._width = x + 1;
|
||||||
if ((y + 1) > this._height) this._height = y + 1;
|
if ((y + 1) > this._height) this._height = y + 1;
|
||||||
}
|
}
|
||||||
@ -247,124 +265,81 @@ export class FloorplanEditor
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public setTilemap(map: string, blockedTiles: boolean[][]): void
|
public setTilemap(map: string, blockedTiles: boolean[][]): void {
|
||||||
{
|
|
||||||
this._tilemap = [];
|
this._tilemap = [];
|
||||||
const roomMapStringSplit = map.split('\r');
|
const roomMapStringSplit = map.split('\r');
|
||||||
|
|
||||||
let width = 0;
|
let width = 0;
|
||||||
let height = roomMapStringSplit.length;
|
let height = roomMapStringSplit.length;
|
||||||
|
for (let y = 0; y < height; y++) {
|
||||||
// find the map width, height
|
|
||||||
for(let y = 0; y < height; y++)
|
|
||||||
{
|
|
||||||
const originalRow = roomMapStringSplit[y];
|
const originalRow = roomMapStringSplit[y];
|
||||||
|
if (originalRow.length === 0) {
|
||||||
if(originalRow.length === 0)
|
|
||||||
{
|
|
||||||
roomMapStringSplit.splice(y, 1);
|
roomMapStringSplit.splice(y, 1);
|
||||||
height = roomMapStringSplit.length;
|
height = roomMapStringSplit.length;
|
||||||
y--;
|
y--;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
if (originalRow.length > width) {
|
||||||
if(originalRow.length > width)
|
|
||||||
{
|
|
||||||
width = originalRow.length;
|
width = originalRow.length;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// fill map with room heightmap tiles
|
for (let y = 0; y < height; y++) {
|
||||||
for(let y = 0; y < height; y++)
|
|
||||||
{
|
|
||||||
this._tilemap[y] = [];
|
this._tilemap[y] = [];
|
||||||
const rowString = roomMapStringSplit[y];
|
const rowString = roomMapStringSplit[y];
|
||||||
|
for (let x = 0; x < width; x++) {
|
||||||
for(let x = 0; x < width; x++)
|
|
||||||
{
|
|
||||||
const blocked = (blockedTiles[y] && blockedTiles[y][x]) || false;
|
const blocked = (blockedTiles[y] && blockedTiles[y][x]) || false;
|
||||||
|
|
||||||
const char = rowString[x];
|
const char = rowString[x];
|
||||||
if(((!(char === 'x')) && (!(char === 'X')) && char))
|
if ((!(char === 'x')) && (!(char === 'X')) && char) {
|
||||||
{
|
|
||||||
this._tilemap[y][x] = new Tile(char, blocked);
|
this._tilemap[y][x] = new Tile(char, blocked);
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
this._tilemap[y][x] = new Tile('x', blocked);
|
this._tilemap[y][x] = new Tile('x', blocked);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
for (let x = width; x < MAX_NUM_TILE_PER_AXIS; x++) {
|
||||||
for(let x = width; x < MAX_NUM_TILE_PER_AXIS; x++)
|
|
||||||
{
|
|
||||||
this.tilemap[y][x] = new Tile('x', false);
|
this.tilemap[y][x] = new Tile('x', false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
for (let y = height; y < MAX_NUM_TILE_PER_AXIS; y++) {
|
||||||
// fill remaining map with empty tiles
|
if (!this.tilemap[y]) this.tilemap[y] = [];
|
||||||
for(let y = height; y < MAX_NUM_TILE_PER_AXIS; y++)
|
for (let x = 0; x < MAX_NUM_TILE_PER_AXIS; x++) {
|
||||||
{
|
|
||||||
if(!this.tilemap[y]) this.tilemap[y] = [];
|
|
||||||
for(let x = 0; x < MAX_NUM_TILE_PER_AXIS; x++)
|
|
||||||
{
|
|
||||||
this.tilemap[y][x] = new Tile('x', false);
|
this.tilemap[y][x] = new Tile('x', false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this._width = width;
|
this._width = width;
|
||||||
this._height = height;
|
this._height = height;
|
||||||
}
|
}
|
||||||
|
|
||||||
public getCurrentTilemapString(): string
|
public getCurrentTilemapString(): string {
|
||||||
{
|
|
||||||
const highestTile = this._tilemap[this._height - 1][this._width - 1];
|
const highestTile = this._tilemap[this._height - 1][this._width - 1];
|
||||||
|
if (highestTile.height === 'x') {
|
||||||
if(highestTile.height === 'x')
|
|
||||||
{
|
|
||||||
this._width = -1;
|
this._width = -1;
|
||||||
this._height = -1;
|
this._height = -1;
|
||||||
|
for (let y = MAX_NUM_TILE_PER_AXIS - 1; y >= 0; y--) {
|
||||||
for(let y = MAX_NUM_TILE_PER_AXIS - 1; y >= 0; y--)
|
if (!this._tilemap[y]) continue;
|
||||||
{
|
for (let x = MAX_NUM_TILE_PER_AXIS - 1; x >= 0; x--) {
|
||||||
if(!this._tilemap[y]) continue;
|
if (!this._tilemap[y][x]) continue;
|
||||||
|
|
||||||
for(let x = MAX_NUM_TILE_PER_AXIS - 1; x >= 0; x--)
|
|
||||||
{
|
|
||||||
if(!this._tilemap[y][x]) continue;
|
|
||||||
|
|
||||||
const tile = this._tilemap[y][x];
|
const tile = this._tilemap[y][x];
|
||||||
|
if (tile.height !== 'x') {
|
||||||
if(tile.height !== 'x')
|
if ((x + 1) > this._width)
|
||||||
{
|
|
||||||
if((x + 1) > this._width)
|
|
||||||
this._width = x + 1;
|
this._width = x + 1;
|
||||||
|
if ((y + 1) > this._height)
|
||||||
if((y + 1) > this._height)
|
|
||||||
this._height = y + 1;
|
this._height = y + 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const rows = [];
|
const rows = [];
|
||||||
|
for (let y = 0; y < this._height; y++) {
|
||||||
for(let y = 0; y < this._height; y++)
|
|
||||||
{
|
|
||||||
const row = [];
|
const row = [];
|
||||||
|
for (let x = 0; x < this._width; x++) {
|
||||||
for(let x = 0; x < this._width; x++)
|
|
||||||
{
|
|
||||||
const tile = this._tilemap[y][x];
|
const tile = this._tilemap[y][x];
|
||||||
row[x] = tile.height;
|
row[x] = tile.height;
|
||||||
}
|
}
|
||||||
|
|
||||||
rows[y] = row.join('');
|
rows[y] = row.join('');
|
||||||
}
|
}
|
||||||
|
|
||||||
return rows.join('\r');
|
return rows.join('\r');
|
||||||
}
|
}
|
||||||
|
|
||||||
public clear(): void
|
public clear(): void {
|
||||||
{
|
|
||||||
this._tilemap = [];
|
this._tilemap = [];
|
||||||
this._doorLocation.set(-1, -1);
|
this._doorLocation.set(-1, -1);
|
||||||
this._width = 0;
|
this._width = 0;
|
||||||
@ -375,44 +350,35 @@ export class FloorplanEditor
|
|||||||
this.clearCanvas();
|
this.clearCanvas();
|
||||||
}
|
}
|
||||||
|
|
||||||
public clearCanvas(): void
|
public clearCanvas(): void {
|
||||||
{
|
|
||||||
this.renderer.fillStyle = '#000000';
|
this.renderer.fillStyle = '#000000';
|
||||||
this.renderer.fillRect(0, 0, this._renderer.canvas.width, this._renderer.canvas.height);
|
this.renderer.fillRect(0, 0, this._renderer.canvas.width, this._renderer.canvas.height);
|
||||||
}
|
}
|
||||||
|
|
||||||
public get renderer(): CanvasRenderingContext2D
|
public get renderer(): CanvasRenderingContext2D {
|
||||||
{
|
|
||||||
return this._renderer;
|
return this._renderer;
|
||||||
}
|
}
|
||||||
|
|
||||||
public get tilemap(): Tile[][]
|
public get tilemap(): Tile[][] {
|
||||||
{
|
|
||||||
return this._tilemap;
|
return this._tilemap;
|
||||||
}
|
}
|
||||||
|
|
||||||
public get doorLocation(): NitroPoint
|
public get doorLocation(): NitroPoint {
|
||||||
{
|
|
||||||
return this._doorLocation;
|
return this._doorLocation;
|
||||||
}
|
}
|
||||||
|
|
||||||
public set doorLocation(value: NitroPoint)
|
public set doorLocation(value: NitroPoint) {
|
||||||
{
|
|
||||||
this._doorLocation = value;
|
this._doorLocation = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
public get actionSettings(): ActionSettings
|
public get actionSettings(): ActionSettings {
|
||||||
{
|
|
||||||
return this._actionSettings;
|
return this._actionSettings;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static get instance(): FloorplanEditor
|
public static get instance(): FloorplanEditor {
|
||||||
{
|
if (!FloorplanEditor._INSTANCE) {
|
||||||
if(!FloorplanEditor._INSTANCE)
|
|
||||||
{
|
|
||||||
FloorplanEditor._INSTANCE = new FloorplanEditor();
|
FloorplanEditor._INSTANCE = new FloorplanEditor();
|
||||||
}
|
}
|
||||||
|
|
||||||
return FloorplanEditor._INSTANCE;
|
return FloorplanEditor._INSTANCE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -141,6 +141,10 @@ export const FloorplanOptionsView: FC<{}> = props =>
|
|||||||
<LayoutGridItem onClick={ event => FloorplanEditor.instance.toggleSelectAll() }>
|
<LayoutGridItem onClick={ event => FloorplanEditor.instance.toggleSelectAll() }>
|
||||||
<i className="icon icon-set-select" />
|
<i className="icon icon-set-select" />
|
||||||
</LayoutGridItem>
|
</LayoutGridItem>
|
||||||
|
<LayoutGridItem itemActive={ FloorplanEditor.instance.squareSelectMode } onClick={ event => {
|
||||||
|
FloorplanEditor.instance.setSquareSelectMode(!FloorplanEditor.instance.squareSelectMode);}
|
||||||
|
}><i className="icon icon-set-select" />
|
||||||
|
</LayoutGridItem>
|
||||||
</Flex>
|
</Flex>
|
||||||
</Column>
|
</Column>
|
||||||
<Column alignItems="center" size={ 4 }>
|
<Column alignItems="center" size={ 4 }>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user