From c217245058e90974ca21aaf71ffc3daa02c0a86a Mon Sep 17 00:00:00 2001 From: Walidoux Date: Sun, 23 Jul 2023 17:41:57 +0100 Subject: [PATCH] feat(objects/room): RoomTileMap accuracy & adjustements --- TODO.md | 14 ++ src/objects/rooms/RoomTileMap.ts | 285 +++++++++++----------- src/objects/rooms/RoomVisualization.ts | 317 ++++++++++--------------- 3 files changed, 284 insertions(+), 332 deletions(-) create mode 100644 TODO.md diff --git a/TODO.md b/TODO.md new file mode 100644 index 0000000..d1460fb --- /dev/null +++ b/TODO.md @@ -0,0 +1,14 @@ +# ๐Ÿ To-do's + +## Rooms + +- [ ] Jaaj + +## ๐Ÿ› Patch Notes + +- Door walls: In order for the game to render the top-front wall of a door, it needs to make sure that the tile is actually a door in the first place, then it needs to check if the two neighboor tiles have walls too. +- Duplicate doors: If it appears to be more than one door in a single room the game logic will pick the first one in a concurrent way. + +## ๐Ÿงน Refactors + +- Look for `hasWall` method that has O(nยฒ) loop conditionals, and fix enum `WallType` type condition in `RoomTileMap` diff --git a/src/objects/rooms/RoomTileMap.ts b/src/objects/rooms/RoomTileMap.ts index 943d222..b27436e 100644 --- a/src/objects/rooms/RoomTileMap.ts +++ b/src/objects/rooms/RoomTileMap.ts @@ -1,7 +1,7 @@ -import type { IPosition2D, ITileInfo, TileMap } from '../../types/Room'; -import { WallType } from '../../enums/WallType'; -import { StairType } from '../../enums/StairType'; -import { Direction } from '../../enums/Direction'; +import type { IPosition2D, ITileInfo, TileMap } from '../../types/Room' +import { WallType } from '../../enums/WallType' +import { StairType } from '../../enums/StairType' +import { Direction } from '../../enums/Direction' /** * RoomTileMap class that manage all the things about the room model. @@ -16,14 +16,14 @@ export class RoomTileMap { * @member {TileMap} * @private */ - private readonly _tileMap: TileMap; + private readonly _tileMap: TileMap /** * @param {string} [tileMap] - The room tile map string that need to be parsed. */ constructor(tileMap: string) { /** Parse the tile map string to convert it into a matrix */ - this._tileMap = this._parse(tileMap); + this._tileMap = this._parse(tileMap) } /** @@ -34,11 +34,11 @@ export class RoomTileMap { * @private */ private _parse(tileMap: string): TileMap { - tileMap = tileMap.replace(/ /g, ''); - tileMap = tileMap.replace(/\n\n/g, '\n'); + tileMap = tileMap.replace(/ /g, '') + tileMap = tileMap.replace(/\n\n/g, '\n') return tileMap.split(/\r?\n/).map((line) => { - return line.split(''); - }); + return line.split('') + }) } /** @@ -49,7 +49,7 @@ export class RoomTileMap { * @public */ public get tileMap(): TileMap { - return this._tileMap; + return this._tileMap } /** @@ -65,7 +65,7 @@ export class RoomTileMap { this._tileMap[position.y] === undefined || this._tileMap[position.y][position.x] === undefined ? 'x' - : this._tileMap[position.y][position.x]; + : this._tileMap[position.y][position.x] } /** @@ -76,8 +76,8 @@ export class RoomTileMap { * @public */ public getTileHeight(position: IPosition2D): number { - const tile = this.getTile(position); - return tile === 'x' ? 0 : isNaN(Number(tile)) ? tile.charCodeAt(0) - 96 + 9 : Number(tile); + const tile = this.getTile(position) + return tile === 'x' ? 0 : isNaN(Number(tile)) ? tile.charCodeAt(0) - 96 + 9 : Number(tile) } /** @@ -94,7 +94,7 @@ export class RoomTileMap { height: this.getTileHeight(position), stairType: this._getStairType(position), wallType: this._getWallType(position) - }; + } } /** @@ -105,16 +105,26 @@ export class RoomTileMap { * @private */ private _getWallType(position: IPosition2D): WallType | undefined { - const topLeftTile: IPosition2D = { x: position.x - 1, y: position.y - 1 }; - const topTile: IPosition2D = { x: position.x, y: position.y - 1 }; - const midLeftTile: IPosition2D = { x: position.x - 1, y: position.y }; + const tiles = { + topLeft: { x: position.x - 1, y: position.y - 1 }, + leftMid: { x: position.x, y: position.y - 1 }, + topMid: { x: position.x - 1, y: position.y } + } - if (this.isDoor(position)) return; + if (this.isDoor(position)) return - if (!this.isTile(topLeftTile) && !this.isTile(topTile) && !this.isTile(midLeftTile) && this.isTile(position)) - return WallType.CORNER_WALL; - if (!this.isTile(midLeftTile) && this.isTile(position)) return WallType.LEFT_WALL; - if (!this.isTile(topTile) && this.isTile(position)) return WallType.RIGHT_WALL; + if (this.isDoor({ ...position, x: position.x - 1 })) return WallType.DOOR_WALL + + if ( + !this.isTile(tiles.topLeft) && + !this.isTile(tiles.leftMid) && + !this.isTile(tiles.topMid) && + this.isTile(position) + ) + return WallType.CORNER_WALL + if (!this.isTile(tiles.topMid) && this.isTile(position) && !this.hasWall('x', position)) return WallType.LEFT_WALL + if (!this.isTile(tiles.leftMid) && this.isTile(position) && !this.hasWall('x', { ...position, y: position.y - 1 })) + return WallType.RIGHT_WALL } /** @@ -125,89 +135,89 @@ export class RoomTileMap { * @private */ private _getStairType(position: IPosition2D): { type: StairType; direction: Direction } | undefined { - const topLeftTile: IPosition2D = { x: position.x - 1, y: position.y - 1 }; - const topTile: IPosition2D = { x: position.x, y: position.y - 1 }; - const topRightTile: IPosition2D = { x: position.x + 1, y: position.y - 1 }; - - const midLeftTile: IPosition2D = { x: position.x - 1, y: position.y }; - const midRightTile: IPosition2D = { x: position.x + 1, y: position.y }; - - const botLeftTile: IPosition2D = { x: position.x - 1, y: position.y + 1 }; - const botTile: IPosition2D = { x: position.x, y: position.y + 1 }; - const botRightTile: IPosition2D = { x: position.x + 1, y: position.y + 1 }; + const tiles = { + topLeft: { x: position.x - 1, y: position.y - 1 }, + topMid: { x: position.x, y: position.y - 1 }, + topRight: { x: position.x + 1, y: position.y - 1 }, + midLeft: { x: position.x - 1, y: position.y }, + midRight: { x: position.x + 1, y: position.y }, + botLeft: { x: position.x - 1, y: position.y + 1 }, + botMid: { x: position.x, y: position.y + 1 }, + botRight: { x: position.x + 1, y: position.y + 1 } + } if ( this.isTile(position) && - this.isTile(topRightTile) && - this._getTileDifference(topRightTile, position) === 1 && - this._getTileDifference(midRightTile, position) === 1 && - this._getTileDifference(topTile, position) === 1 + this.isTile(tiles.topRight) && + this._getTileDifference(tiles.topRight, position) === 1 && + this._getTileDifference(tiles.midRight, position) === 1 && + this._getTileDifference(tiles.topMid, position) === 1 ) - return { type: StairType.INNER_CORNER_STAIR, direction: Direction.NORTH_EAST }; + return { type: StairType.INNER_CORNER_STAIR, direction: Direction.NORTH_EAST } if ( this.isTile(position) && - this.isTile(botRightTile) && - this._getTileDifference(botRightTile, position) === 1 && - this._getTileDifference(midRightTile, position) === 1 && - this._getTileDifference(botTile, position) === 1 + this.isTile(tiles.botRight) && + this._getTileDifference(tiles.botRight, position) === 1 && + this._getTileDifference(tiles.midRight, position) === 1 && + this._getTileDifference(tiles.botMid, position) === 1 ) - return { type: StairType.INNER_CORNER_STAIR, direction: Direction.SOUTH_EAST }; + return { type: StairType.INNER_CORNER_STAIR, direction: Direction.SOUTH_EAST } if ( this.isTile(position) && - this.isTile(botLeftTile) && - this._getTileDifference(botLeftTile, position) === 1 && - this._getTileDifference(midLeftTile, position) === 1 && - this._getTileDifference(botTile, position) === 1 + this.isTile(tiles.botLeft) && + this._getTileDifference(tiles.botLeft, position) === 1 && + this._getTileDifference(tiles.midLeft, position) === 1 && + this._getTileDifference(tiles.botMid, position) === 1 ) - return { type: StairType.INNER_CORNER_STAIR, direction: Direction.SOUTH_WEST }; + return { type: StairType.INNER_CORNER_STAIR, direction: Direction.SOUTH_WEST } if ( this.isTile(position) && - this.isTile(topLeftTile) && - this._getTileDifference(topLeftTile, position) === 1 && - this._getTileDifference(midLeftTile, position) === 1 && - this._getTileDifference(topTile, position) === 1 + this.isTile(tiles.topLeft) && + this._getTileDifference(tiles.topLeft, position) === 1 && + this._getTileDifference(tiles.midLeft, position) === 1 && + this._getTileDifference(tiles.topMid, position) === 1 ) - return { type: StairType.INNER_CORNER_STAIR, direction: Direction.NORTH_WEST }; - if (this.isTile(position) && this.isTile(topTile) && this._getTileDifference(topTile, position) === 1) - return { type: StairType.STAIR, direction: Direction.NORTH }; + return { type: StairType.INNER_CORNER_STAIR, direction: Direction.NORTH_WEST } + if (this.isTile(position) && this.isTile(tiles.topMid) && this._getTileDifference(tiles.topMid, position) === 1) + return { type: StairType.STAIR, direction: Direction.NORTH } if ( this.isTile(position) && - this.isTile(topRightTile) && - this._getTileDifference(topRightTile, position) === 1 && - this._getTileDifference(midRightTile, position) === 0 && - this._getTileDifference(topTile, position) === 0 + this.isTile(tiles.topRight) && + this._getTileDifference(tiles.topRight, position) === 1 && + this._getTileDifference(tiles.midRight, position) === 0 && + this._getTileDifference(tiles.topMid, position) === 0 ) - return { type: StairType.OUTER_CORNER_STAIR, direction: Direction.NORTH_EAST }; - if (this.isTile(position) && this.isTile(midRightTile) && this._getTileDifference(midRightTile, position) === 1) - return { type: StairType.STAIR, direction: Direction.EAST }; + return { type: StairType.OUTER_CORNER_STAIR, direction: Direction.NORTH_EAST } + if (this.isTile(position) && this.isTile(tiles.midRight) && this._getTileDifference(tiles.midRight, position) === 1) + return { type: StairType.STAIR, direction: Direction.EAST } if ( this.isTile(position) && - this.isTile(botRightTile) && - this._getTileDifference(botRightTile, position) === 1 && - this._getTileDifference(midRightTile, position) === 0 && - this._getTileDifference(botTile, position) === 0 + this.isTile(tiles.botRight) && + this._getTileDifference(tiles.botRight, position) === 1 && + this._getTileDifference(tiles.midRight, position) === 0 && + this._getTileDifference(tiles.botMid, position) === 0 ) - return { type: StairType.OUTER_CORNER_STAIR, direction: Direction.SOUTH_EAST }; - if (this.isTile(position) && this.isTile(botTile) && this._getTileDifference(botTile, position) === 1) - return { type: StairType.STAIR, direction: Direction.SOUTH }; + return { type: StairType.OUTER_CORNER_STAIR, direction: Direction.SOUTH_EAST } + if (this.isTile(position) && this.isTile(tiles.botMid) && this._getTileDifference(tiles.botMid, position) === 1) + return { type: StairType.STAIR, direction: Direction.SOUTH } if ( this.isTile(position) && - this.isTile(botLeftTile) && - this._getTileDifference(botLeftTile, position) === 1 && - this._getTileDifference(midLeftTile, position) === 0 && - this._getTileDifference(botTile, position) === 0 + this.isTile(tiles.botLeft) && + this._getTileDifference(tiles.botLeft, position) === 1 && + this._getTileDifference(tiles.midLeft, position) === 0 && + this._getTileDifference(tiles.botMid, position) === 0 ) - return { type: StairType.OUTER_CORNER_STAIR, direction: Direction.SOUTH_WEST }; - if (this.isTile(position) && this.isTile(midLeftTile) && this._getTileDifference(midLeftTile, position) === 1) - return { type: StairType.STAIR, direction: Direction.WEST }; + return { type: StairType.OUTER_CORNER_STAIR, direction: Direction.SOUTH_WEST } + if (this.isTile(position) && this.isTile(tiles.midLeft) && this._getTileDifference(tiles.midLeft, position) === 1) + return { type: StairType.STAIR, direction: Direction.WEST } if ( this.isTile(position) && - this.isTile(topLeftTile) && - this._getTileDifference(topLeftTile, position) === 1 && - this._getTileDifference(midLeftTile, position) === 0 && - this._getTileDifference(topTile, position) === 0 + this.isTile(tiles.topLeft) && + this._getTileDifference(tiles.topLeft, position) === 1 && + this._getTileDifference(tiles.midLeft, position) === 0 && + this._getTileDifference(tiles.topMid, position) === 0 ) - return { type: StairType.OUTER_CORNER_STAIR, direction: Direction.NORTH_WEST }; + return { type: StairType.OUTER_CORNER_STAIR, direction: Direction.NORTH_WEST } } /** @@ -219,7 +229,7 @@ export class RoomTileMap { * @private */ private _getTileDifference(position1: IPosition2D, position2: IPosition2D): number { - return Number(this.getTileHeight(position1)) - Number(this.getTileHeight(position2)); + return Number(this.getTileHeight(position1)) - Number(this.getTileHeight(position2)) } /** @@ -230,7 +240,7 @@ export class RoomTileMap { * @public */ public isTile(position: IPosition2D): boolean { - return this.getTile(position) !== 'x'; + return this.getTile(position) !== 'x' } /** @@ -241,23 +251,23 @@ export class RoomTileMap { * @public */ public isDoor(position: IPosition2D): boolean { - const topLeftTile: IPosition2D = { x: position.x - 1, y: position.y - 1 }; - const topTile: IPosition2D = { x: position.x, y: position.y - 1 }; - - const midLeftTile: IPosition2D = { x: position.x - 1, y: position.y }; - const midTile: IPosition2D = { x: position.x, y: position.y }; - - const botLeftTile: IPosition2D = { x: position.x - 1, y: position.y + 1 }; - const botTile: IPosition2D = { x: position.x, y: position.y + 1 }; + const tiles = { + topLeft: { x: position.x - 1, y: position.y - 1 }, + topMid: { x: position.x, y: position.y - 1 }, + midLeft: { x: position.x - 1, y: position.y }, + mid: { x: position.x, y: position.y }, + botLeft: { x: position.x - 1, y: position.y + 1 }, + botMid: { x: position.x, y: position.y + 1 } + } return ( - !this.isTile(topTile) && - !this.isTile(topLeftTile) && - !this.isTile(midLeftTile) && - !this.isTile(botLeftTile) && - !this.isTile(botTile) && - this.isTile(midTile) - ); + !this.isTile(tiles.topMid) && + !this.isTile(tiles.topLeft) && + !this.isTile(tiles.midLeft) && + !this.isTile(tiles.botLeft) && + !this.isTile(tiles.botMid) && + this.isTile(tiles.mid) + ) } /** @@ -267,59 +277,66 @@ export class RoomTileMap { * @public */ public get maxZ(): number { - let z = 0; + let z = 0 + for (let y = 0; y < this._tileMap.length; y++) { for (let x = 0; x < this._tileMap[y].length; x++) { - const height = this.getTileHeight({ x, y }); - if (height > z) z = height; + const height = this.getTileHeight({ x, y }) + if (height > z) z = height } } - return z; + + return z } /** * Indicate if the given tile position have a left or a right wall. * * @param {IPosition2D} [position] - The given tile position that we wan't to check if it have walls. - * @return {{ x: boolean, y: boolean }} + * @return { x: boolean, y: boolean } * @public */ - public hasWall(position: IPosition2D): { x: boolean; y: boolean } { - // TODO: Integrate it in _getWallType() - let wallX = false; - let wallY = false; - for (let i = position.y - 1; i >= 0; i--) { - const wall: WallType | undefined = this._getWallType({ x: position.x, y: i }); - if (wall) { - if (wall === WallType.RIGHT_WALL || wall === (WallType.CORNER_WALL as WallType)) { - wallY = true; + public hasWall(axis: keyof IPosition2D, position: IPosition2D): boolean { + const handleXAxis = (coordinates: IPosition2D): boolean => { + let wallX = false + + for (let i = coordinates.x - 1; i >= 0; i--) { + const wall = this._getWallType({ x: i, y: coordinates.y }) + + if (wall === WallType.LEFT_WALL || wall === WallType.CORNER_WALL) wallX = true + + for (let j = coordinates.y - 1; j >= 0; j--) { + const wall2 = this._getWallType({ x: i, y: j }) + + if (wall2 === WallType.RIGHT_WALL || wall2 === WallType.CORNER_WALL) wallX = true } } - for (let j = position.x - 1; j >= 0; j--) { - const wall2: WallType | undefined = this._getWallType({ x: j, y: i }); - if (wall2) { - if (wall2 === WallType.LEFT_WALL || wall2 === (WallType.CORNER_WALL as WallType)) { - wallY = true; + + return wallX + } + + const handleYAxis = (coordinates: IPosition2D): boolean => { + let wallY = false + + for (let i = coordinates.y - 1; i >= 0; i--) { + const wall = this._getWallType({ x: coordinates.x, y: i }) + + if (wall != null) { + if (wall === WallType.RIGHT_WALL || wall === WallType.CORNER_WALL) wallY = true + } + + for (let j = coordinates.x - 1; j >= 0; j--) { + const wall2 = this._getWallType({ x: j, y: i }) + if (wall2 != null) { + if (wall2 === WallType.LEFT_WALL || wall2 === WallType.CORNER_WALL) wallY = true } } } + + return wallY } - for (let i = position.x - 1; i >= 0; i--) { - const wall: WallType | undefined = this._getWallType({ x: i, y: position.y }); - if (wall) { - if (wall === WallType.LEFT_WALL || wall === (WallType.CORNER_WALL as WallType)) { - wallX = true; - } - } - for (let j = position.y - 1; j >= 0; j--) { - const wall2: WallType | undefined = this._getWallType({ x: i, y: j }); - if (wall2) { - if (wall2 === WallType.RIGHT_WALL || wall2 === (WallType.CORNER_WALL as WallType)) { - wallX = true; - } - } - } - } - return { x: wallX, y: wallY }; + + if (axis === 'x') return handleXAxis(position) + else return handleYAxis(position) } } diff --git a/src/objects/rooms/RoomVisualization.ts b/src/objects/rooms/RoomVisualization.ts index 722b0ec..108112b 100644 --- a/src/objects/rooms/RoomVisualization.ts +++ b/src/objects/rooms/RoomVisualization.ts @@ -1,15 +1,16 @@ -import { Container, Ticker } from 'pixi.js'; +import { Container, Ticker } from 'pixi.js' -import type { Room } from './Room'; -import type { IPosition3D, ITileInfo } from '../../types/Room'; -import { Tile } from './parts/Tile'; -import { Wall } from './parts/Wall'; -import { Stair } from './parts/Stair'; -import { WallType } from '../../enums/WallType'; -import type { StairType } from '../../enums/StairType'; -import { Cursor } from './parts/Cursor'; -import { RoomObjectLayer } from './layers/RoomObjectLayer'; -import { RoomPartLayer } from './layers/RoomPartLayer'; +import type { Room } from './Room' +import type { IPosition3D, ITileInfo } from '../../types/Room' +import { Tile } from './parts/Tile' +import { Wall } from './parts/Wall' +import { Stair } from './parts/Stair' +import { WallType } from '../../enums/WallType' +import { Cursor } from './parts/Cursor' +import { RoomObjectLayer } from './layers/RoomObjectLayer' +import { RoomPartLayer } from './layers/RoomPartLayer' +import type { RoomPart } from './parts/RoomPart' +import type { EventManager } from '../interactions/EventManager' /** * RoomView class that manage all the rendering part of the room. @@ -24,7 +25,7 @@ export class RoomVisualization extends Container { * @member {Room} * @private */ - private readonly _room: Room; + private readonly _room: Room /** * The container that will contains all the objects like avatars or furnitures. @@ -32,7 +33,7 @@ export class RoomVisualization extends Container { * @member {RoomObjectLayer} * @private */ - private readonly _objectLayer: RoomObjectLayer; + private readonly _objectLayer: RoomObjectLayer /** * The container that will contains all the parts like tiles, walls and stairs. @@ -40,7 +41,7 @@ export class RoomVisualization extends Container { * @member {RoomPartLayer} * @private */ - private readonly _partLayer: RoomPartLayer; + private readonly _partLayer: RoomPartLayer /** * List containing all the walls instances. @@ -48,7 +49,7 @@ export class RoomVisualization extends Container { * @member {Wall} * @private */ - private _walls: Wall[] = []; + private _walls: Wall[] = [] /** * List containing all the tiles and stairs instances. @@ -56,15 +57,7 @@ export class RoomVisualization extends Container { * @member {Tile | Stair} * @private */ - private _tiles: Array = []; - - /** - * Infos related to the door tile. - * - * @member {ITileInfo} - * @private - */ - private _doorTile!: ITileInfo; + private _tiles: Array = [] /** * The room tile cursor instance. @@ -72,7 +65,7 @@ export class RoomVisualization extends Container { * @member {Cursor} * @private */ - private _cursor!: Cursor; + private _cursor!: Cursor /** * The room animation ticker instance that will manage all the objects animations @@ -80,24 +73,24 @@ export class RoomVisualization extends Container { * @member {Ticker} * @private */ - private readonly _animationTicker = new Ticker(); + private readonly _animationTicker = new Ticker() /** * @param {Room} [room] - The room instance that we want to visualize. */ constructor(room: Room) { - super(); + super() - this._room = room; - this._objectLayer = new RoomObjectLayer(this._room); - this._partLayer = new RoomPartLayer(this._room); + this._room = room + this._objectLayer = new RoomObjectLayer(this._room) + this._partLayer = new RoomPartLayer(this._room) /** Start the animation ticker */ - this._animationTicker.maxFPS = 4; - this._animationTicker.start(); + this._animationTicker.maxFPS = 4 + this._animationTicker.start() /** Render everything */ - this._draw(); + this._draw() } /** @@ -107,18 +100,19 @@ export class RoomVisualization extends Container { * @private */ private _draw(): void { - this._destroyParts(); - this._destroyCursor(); + this._destroyParts() + this._destroyCursor() + + let doorsCount = 0 for (let y = 0; y < this._room.tileMap.tileMap.length; y++) { for (let x = 0; x < this._room.tileMap.tileMap[y].length; x++) { - const tileInfo = this._room.tileMap.getTileInfo({ x, y }); + const tileInfo = this._room.tileMap.getTileInfo({ x, y }) - // todo: avoid duplicate tile doors - if (tileInfo.door && this._doorTile != null) tileInfo.door = false; - if (tileInfo.door && this._doorTile == null) this._doorTile = tileInfo; + if (tileInfo.door) doorsCount++ + if (doorsCount > 1) tileInfo.door = false - this._createPart(tileInfo, { x, y, z: tileInfo.height }); + this._createPart(tileInfo, { x, y, z: tileInfo.height }) } } } @@ -130,9 +124,11 @@ export class RoomVisualization extends Container { * @private */ private _destroyParts(): void { - [...this._tiles, ...this._walls].forEach((part) => part.destroy()); - this._tiles = []; - this._walls = []; + ;[...this._tiles, ...this._walls].forEach((part) => { + return part.destroy() + }) + this._tiles = [] + this._walls = [] } /** @@ -142,7 +138,7 @@ export class RoomVisualization extends Container { * @private */ public update(): void { - this._draw(); + this._draw() } /** @@ -154,39 +150,81 @@ export class RoomVisualization extends Container { * @private */ private _createPart(tileInfo: ITileInfo, position: IPosition3D): void { - if (tileInfo.wallType !== null || tileInfo.door) { + if (tileInfo.wallType != null) { if ( tileInfo.wallType === WallType.CORNER_WALL && - !this._room.tileMap.hasWall(position).x && - !this._room.tileMap.hasWall(position).y + !this._room.tileMap.hasWall('x', position) && + !this._room.tileMap.hasWall('y', position) ) { - this._createWall(position, WallType.CORNER_WALL); - this._createWall(position, WallType.LEFT_WALL); - this._createWall(position, WallType.RIGHT_WALL); - } else if (tileInfo.wallType === WallType.CORNER_WALL && !this._room.tileMap.hasWall(position).x) { - this._createWall(position, WallType.LEFT_WALL); - } else if (tileInfo.wallType === WallType.CORNER_WALL && !this._room.tileMap.hasWall(position).y) { - this._createWall(position, WallType.RIGHT_WALL); + this._createWall(position, WallType.CORNER_WALL) + this._createWall(position, WallType.LEFT_WALL) + this._createWall(position, WallType.RIGHT_WALL) + } else if (tileInfo.wallType === WallType.CORNER_WALL && !this._room.tileMap.hasWall('x', position)) { + this._createWall(position, WallType.LEFT_WALL) + } else if (tileInfo.wallType === WallType.CORNER_WALL && !this._room.tileMap.hasWall('y', position)) { + this._createWall(position, WallType.RIGHT_WALL) } - if (tileInfo.wallType === WallType.LEFT_WALL && !this._room.tileMap.hasWall(position).y) - this._createWall(position, WallType.LEFT_WALL); - if (tileInfo.wallType === WallType.RIGHT_WALL && !this._room.tileMap.hasWall(position).y) - this._createWall(position, WallType.RIGHT_WALL); + if (tileInfo.wallType === WallType.LEFT_WALL) this._createWall(position, WallType.LEFT_WALL) + if (tileInfo.wallType === WallType.RIGHT_WALL) this._createWall(position, WallType.RIGHT_WALL) - if (tileInfo.door) this._createWall(position, WallType.DOOR_WALL); + if (tileInfo.door) this._createWall(position, WallType.DOOR_WALL) } if (tileInfo.stairType != null) { - position.direction = tileInfo.stairType.direction; - this._createStair(position, tileInfo.stairType.type); - } else if (tileInfo.door) { - this._createDoor(position); - } else if (tileInfo.tile) { - this._createTile(position, tileInfo); + position.direction = tileInfo.stairType.direction + + const stair = new Stair(this._room, { + position, + material: this._room.floorMaterial, + thickness: this._room.floorThickness, + type: tileInfo.stairType.type + }) + + this._createTile(stair, this._partLayer.tiles) + this._tiles.push(stair) + } else if (tileInfo.tile || tileInfo.door) { + const tile = new Tile( + this._room, + { + position, + material: this._room.floorMaterial, + thickness: !tileInfo.door ? this._room.floorThickness : undefined + }, + !tileInfo.door ? tileInfo : undefined + ) + + this._createTile(tile, this._partLayer.tiles) + this._tiles.push(tile) } } + /** + * Creates a (tile|stair|door). + * + * @param {RoomPart} [part] - The room (tile|stair|door)'s position. + * @param {EventManager} [eventManager] + * @return {void} + * @private + */ + private _createTile(part: RoomPart, eventManager: EventManager): void { + part.onPointerDown = (event) => eventManager.onPointerDown != null && eventManager.onPointerDown(event) + part.onPointerUp = (event) => eventManager.onPointerUp != null && eventManager.onPointerUp(event) + part.onPointerMove = (event) => eventManager.onPointerMove != null && eventManager.onPointerMove(event) + part.onDoubleClick = (event) => eventManager.onDoubleClick != null && eventManager.onDoubleClick(event) + part.onPointerOut = (event) => { + if (eventManager.onPointerOut != null) eventManager.onPointerOut(event) + this._destroyCursor() + } + + part.onPointerOver = (event) => { + if (eventManager.onPointerOver != null) eventManager.onPointerOver(event) + this._createCursor(part._position) + } + + this.addChild(part) + } + /** * Destroy the current cursor and draw a new one at the new position. * @@ -195,15 +233,17 @@ export class RoomVisualization extends Container { * @private */ private _createCursor(position: IPosition3D): void { + this._destroyCursor() + if (this._cursor != null) { - this._cursor.visible = true; - return this._cursor.moveTo(position); + this._cursor.visible = true + return this._cursor.moveTo(position) } - this._destroyCursor(); - const cursor = new Cursor(this._room, { position }); - this.addChild(cursor); - this._cursor = cursor; + const cursor = new Cursor(this._room, { position }) + + this.addChild(cursor) + this._cursor = cursor } /** @@ -213,84 +253,7 @@ export class RoomVisualization extends Container { * @private */ private _destroyCursor(): void { - if (this._cursor != null) this._cursor.visible = false; - } - - /** - * Create a tile. - * - * @param {IPosition3D} [position] - The tile position. - * @param {ITileInfo} [tileInfo] - * @return {void} - * @private - */ - private _createTile(position: IPosition3D, tileInfo: ITileInfo): void { - const tile = new Tile( - this._room, - { position, material: this._room.floorMaterial, thickness: this._room.floorThickness }, - tileInfo - ); - - /** Register interactions */ - tile.onPointerDown = (event) => { - if (this._partLayer.tiles.onPointerDown != null) this._partLayer.tiles.onPointerDown(event); - }; - tile.onPointerUp = (event) => { - if (this._partLayer.tiles.onPointerUp != null) this._partLayer.tiles.onPointerUp(event); - }; - tile.onPointerMove = (event) => { - if (this._partLayer.tiles.onPointerMove != null) this._partLayer.tiles.onPointerMove(event); - }; - tile.onPointerOut = (event) => { - if (this._partLayer.tiles.onPointerOut != null) this._partLayer.tiles.onPointerOut(event); - this._destroyCursor(); - }; - tile.onPointerOver = (event) => { - if (this._partLayer.tiles.onPointerOver != null) this._partLayer.tiles.onPointerOver(event); - this._createCursor(position); - }; - tile.onDoubleClick = (event) => { - if (this._partLayer.tiles.onDoubleClick != null) this._partLayer.tiles.onDoubleClick(event); - }; - - this.addChild(tile); - this._tiles.push(tile); - } - - /** - * Create a door. - * - * @param {IPosition3D} [position] - The door position. - * @return {void} - * @private - */ - private _createDoor(position: IPosition3D): void { - const tile = new Tile(this._room, { position, material: this._room.floorMaterial }); - - /** Register interactions */ - tile.onPointerDown = (event) => { - if (this._partLayer.tiles.onPointerDown != null) this._partLayer.tiles.onPointerDown(event); - }; - tile.onPointerUp = (event) => { - if (this._partLayer.tiles.onPointerUp != null) this._partLayer.tiles.onPointerUp(event); - }; - tile.onPointerMove = (event) => { - if (this._partLayer.tiles.onPointerMove != null) this._partLayer.tiles.onPointerMove(event); - }; - tile.onPointerOut = (event) => { - if (this._partLayer.tiles.onPointerOut != null) this._partLayer.tiles.onPointerOut(event); - this._destroyCursor(); - }; - tile.onPointerOver = (event) => { - if (this._partLayer.tiles.onPointerOver != null) this._partLayer.tiles.onPointerOver(event); - this._createCursor(position); - }; - tile.onDoubleClick = (event) => { - if (this._partLayer.tiles.onDoubleClick != null) this._partLayer.tiles.onDoubleClick(event); - }; - - this.addChild(tile); - this._tiles.push(tile); + if (this._cursor != null) this._cursor.visible = false } /** @@ -308,54 +271,12 @@ export class RoomVisualization extends Container { thickness: this._room.wallThickness, height: this._room.wallHeight, type - }); + }) // todo!(): register event interactions for walls */ - this.addChild(wall); - this._walls.push(wall); - } - - /** - * Create stairs. - * - * @param {IPosition3D} [position] - The stairs position. - * @param {StairType} [type] - The stairs type. - * @return {void} - * @private - */ - private _createStair(position: IPosition3D, type: StairType): void { - const stair = new Stair(this._room, { - position, - material: this._room.floorMaterial, - thickness: this._room.floorThickness, - type - }); - - /** Register interactions */ - stair.onPointerDown = (event) => { - if (this._partLayer.tiles.onPointerDown != null) this._partLayer.tiles.onPointerDown(event); - }; - stair.onPointerUp = (event) => { - if (this._partLayer.tiles.onPointerUp != null) this._partLayer.tiles.onPointerUp(event); - }; - stair.onPointerMove = (event) => { - if (this._partLayer.tiles.onPointerMove != null) this._partLayer.tiles.onPointerMove(event); - }; - stair.onPointerOut = (event) => { - if (this._partLayer.tiles.onPointerOut != null) this._partLayer.tiles.onPointerOut(event); - this._destroyCursor(); - }; - stair.onPointerOver = (event) => { - if (this._partLayer.tiles.onPointerOver != null) this._partLayer.tiles.onPointerOver(event); - this._createCursor(position); - }; - stair.onDoubleClick = (event) => { - if (this._partLayer.tiles.onDoubleClick != null) this._partLayer.tiles.onDoubleClick(event); - }; - - this.addChild(stair); - this._tiles.push(stair); + this.addChild(wall) + this._walls.push(wall) } /** @@ -366,7 +287,7 @@ export class RoomVisualization extends Container { * @public */ public get room(): Room { - return this._room; + return this._room } /** @@ -377,7 +298,7 @@ export class RoomVisualization extends Container { * @public */ public get objectLayer(): RoomObjectLayer { - return this._objectLayer; + return this._objectLayer } /** @@ -388,7 +309,7 @@ export class RoomVisualization extends Container { * @public */ public get partLayer(): RoomPartLayer { - return this._partLayer; + return this._partLayer } /** @@ -399,6 +320,6 @@ export class RoomVisualization extends Container { * @public */ public get animationTicker(): Ticker { - return this._animationTicker; + return this._animationTicker } }