feat(objects/room): RoomTileMap accuracy & adjustements

This commit is contained in:
Walid 2023-07-23 17:41:57 +01:00
parent f82de52fda
commit c217245058
Signed by: Walidoux
GPG Key ID: CCF21881FE8BEBAF
3 changed files with 284 additions and 332 deletions

14
TODO.md Normal file
View File

@ -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`

View File

@ -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)
}
}

View File

@ -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<Tile | Stair> = [];
/**
* Infos related to the door tile.
*
* @member {ITileInfo}
* @private
*/
private _doorTile!: ITileInfo;
private _tiles: Array<Tile | Stair> = []
/**
* 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
}
}