Don't use Vue3 ref's for storing map data

This commit is contained in:
2024-09-18 20:55:37 +02:00
parent 43a59c8f7c
commit ddb0e8bf3a
4 changed files with 167 additions and 139 deletions

View File

@ -53,11 +53,11 @@ const assetStore = useAssetStore()
const { objectList, zone, selectedTile, selectedObject, selectedZoneObject, eraserMode, drawMode } = storeToRefs(zoneEditorStore)
const zoneTilemap = ref(createTilemap())
const tiles = ref(createTileLayer())
const zoneObjects = ref<ZoneObject[]>([])
const zoneEventTiles = ref<ZoneEventTile[]>([])
const tileArray = ref(createTileArray())
const zoneTilemap = createTilemap()
const tiles = createTileLayer()
let zoneObjects = <ZoneObject[]>[]
let zoneEventTiles = <ZoneEventTile[]>[]
let tileArray = createTileArray()
const shouldShowTeleportModal = computed(() => zoneEditorStore.tool === 'pencil' && drawMode.value === 'teleport')
@ -75,10 +75,10 @@ function createTilemap() {
}
function createTileLayer() {
const tilesetImages = assetStore.assets.filter((asset) => asset.group === 'tiles').map((asset, index) => zoneTilemap.value.addTilesetImage(asset.key, asset.key, config.tile_size.x, config.tile_size.y, 0, 0, index + 1, { x: 0, y: -config.tile_size.y }))
tilesetImages.push(zoneTilemap.value.addTilesetImage('blank_tile', 'blank_tile', config.tile_size.x, config.tile_size.y, 0, 0, 0, { x: 0, y: -config.tile_size.y }))
const tilesetImages = assetStore.assets.filter((asset) => asset.group === 'tiles').map((asset, index) => zoneTilemap.addTilesetImage(asset.key, asset.key, config.tile_size.x, config.tile_size.y, 0, 0, index + 1, { x: 0, y: -config.tile_size.y }))
tilesetImages.push(zoneTilemap.addTilesetImage('blank_tile', 'blank_tile', config.tile_size.x, config.tile_size.y, 0, 0, 0, { x: 0, y: -config.tile_size.y }))
const layer = zoneTilemap.value.createBlankLayer('tiles', tilesetImages as any, 0, config.tile_size.y) as Phaser.Tilemaps.TilemapLayer
const layer = zoneTilemap.createBlankLayer('tiles', tilesetImages as any, 0, config.tile_size.y) as Phaser.Tilemaps.TilemapLayer
layer.setDepth(0)
@ -86,14 +86,14 @@ function createTileLayer() {
}
function createTileArray() {
return Array.from({ length: zoneTilemap.value.height || 0 }, () => Array.from({ length: zoneTilemap.value.width || 0 }, () => 'blank_tile'))
return Array.from({ length: zoneTilemap.height || 0 }, () => Array.from({ length: zoneTilemap.width || 0 }, () => 'blank_tile'))
}
function getObjectImageProps(object: ZoneObject) {
return {
tint: selectedZoneObject.value?.id === object.id ? 0x00ff00 : 0xffffff,
x: tileToWorldX(zoneTilemap.value as any, object.positionX, object.positionY),
y: tileToWorldY(zoneTilemap.value as any, object.positionX, object.positionY),
x: tileToWorldX(zoneTilemap as any, object.positionX, object.positionY),
y: tileToWorldY(zoneTilemap as any, object.positionX, object.positionY),
texture: object.object.id,
originY: Number(object.object.originX),
originX: Number(object.object.originY)
@ -102,27 +102,27 @@ function getObjectImageProps(object: ZoneObject) {
function getEventTileImageProps(tile: ZoneEventTile) {
return {
x: tileToWorldX(zoneTilemap.value as any, tile.positionX, tile.positionY),
y: tileToWorldY(zoneTilemap.value as any, tile.positionX, tile.positionY),
x: tileToWorldX(zoneTilemap as any, tile.positionX, tile.positionY),
y: tileToWorldY(zoneTilemap as any, tile.positionX, tile.positionY),
texture: tile.type
}
}
function eraser(tile: Phaser.Tilemaps.Tile) {
if (eraserMode.value === 'tile') {
placeTile(zoneTilemap.value as Tilemap, tiles.value as TilemapLayer, tile.x, tile.y, 'blank_tile')
tileArray.value[tile.y][tile.x] = 'blank_tile'
placeTile(zoneTilemap as Tilemap, tiles as TilemapLayer, tile.x, tile.y, 'blank_tile')
tileArray[tile.y][tile.x] = 'blank_tile'
} else if (eraserMode.value === 'object') {
zoneObjects.value = zoneObjects.value.filter((object) => object.positionX !== tile.x || object.positionY !== tile.y)
zoneObjects = zoneObjects.filter((object) => object.positionX !== tile.x || object.positionY !== tile.y)
} else if (eraserMode.value === 'blocking tile' || eraserMode.value === 'teleport') {
zoneEventTiles.value = zoneEventTiles.value.filter((eventTile) => eventTile.positionX !== tile.x || eventTile.positionY !== tile.y || (eraserMode.value === 'teleport' && eventTile.type !== ZoneEventTileType.TELEPORT))
zoneEventTiles = zoneEventTiles.filter((eventTile) => eventTile.positionX !== tile.x || eventTile.positionY !== tile.y || (eraserMode.value === 'teleport' && eventTile.type !== ZoneEventTileType.TELEPORT))
}
}
function pencil(tile: Phaser.Tilemaps.Tile) {
if (drawMode.value === 'tile' && selectedTile.value) {
placeTile(zoneTilemap.value as Tilemap, tiles.value as TilemapLayer, tile.x, tile.y, selectedTile.value.id)
tileArray.value[tile.y][tile.x] = selectedTile.value.id
placeTile(zoneTilemap as Tilemap, tiles as TilemapLayer, tile.x, tile.y, selectedTile.value.id)
tileArray[tile.y][tile.x] = selectedTile.value.id
} else if (drawMode.value === 'object' && selectedObject.value) {
addZoneObject(tile)
} else if (drawMode.value === 'blocking tile' || drawMode.value === 'teleport') {
@ -132,7 +132,7 @@ function pencil(tile: Phaser.Tilemaps.Tile) {
function addZoneObject(tile: Phaser.Tilemaps.Tile) {
// Check if object already exists on position
const existingObject = zoneObjects.value.find((object) => object.positionX === tile.x && object.positionY === tile.y)
const existingObject = zoneObjects.find((object) => object.positionX === tile.x && object.positionY === tile.y)
if (existingObject) return
const newObject = {
@ -145,12 +145,12 @@ function addZoneObject(tile: Phaser.Tilemaps.Tile) {
positionX: tile.x,
positionY: tile.y
}
zoneObjects.value = [...new Set([...zoneObjects.value, newObject])]
zoneObjects = [...new Set([...zoneObjects, newObject])]
}
function addZoneEventTile(tile: Phaser.Tilemaps.Tile) {
// Check if event tile already exists on position
const existingEventTile = zoneEventTiles.value.find((eventTile) => eventTile.positionX === tile.x && eventTile.positionY === tile.y)
const existingEventTile = zoneEventTiles.find((eventTile) => eventTile.positionX === tile.x && eventTile.positionY === tile.y)
if (existingEventTile) return
const newEventTile = {
@ -169,25 +169,25 @@ function addZoneEventTile(tile: Phaser.Tilemaps.Tile) {
}
: undefined
}
zoneEventTiles.value = [...new Set([...zoneEventTiles.value, newEventTile])] as any
zoneEventTiles = [...new Set([...zoneEventTiles, newEventTile])] as any
}
function paint() {
if (!selectedTile.value) return
// Ensure tileArray is initialized with correct dimensions
if (!tileArray.value || tileArray.value.length !== zoneTilemap.value.height) {
tileArray.value = Array.from({ length: zoneTilemap.value.height }, () => Array.from({ length: zoneTilemap.value.width }, () => 'blank_tile'))
if (!tileArray || tileArray.length !== zoneTilemap.height) {
tileArray = Array.from({ length: zoneTilemap.height }, () => Array.from({ length: zoneTilemap.width }, () => 'blank_tile'))
}
// Set all tiles in the tilemap to the selected tile's id
for (let y = 0; y < zoneTilemap.value.height; y++) {
if (!tileArray.value[y]) {
tileArray.value[y] = Array(zoneTilemap.value.width).fill('blank_tile')
for (let y = 0; y < zoneTilemap.height; y++) {
if (!tileArray[y]) {
tileArray[y] = Array(zoneTilemap.width).fill('blank_tile')
}
for (let x = 0; x < zoneTilemap.value.width; x++) {
placeTile(zoneTilemap.value as Tilemap, tiles.value as TilemapLayer, x, y, selectedTile.value.id)
tileArray.value[y][x] = selectedTile.value.id
for (let x = 0; x < zoneTilemap.width; x++) {
placeTile(zoneTilemap as Tilemap, tiles as TilemapLayer, x, y, selectedTile.value.id)
tileArray[y][x] = selectedTile.value.id
}
}
}
@ -199,10 +199,10 @@ function save() {
name: zoneEditorStore.zoneSettings.name,
width: zoneEditorStore.zoneSettings.width,
height: zoneEditorStore.zoneSettings.height,
tiles: tileArray.value,
tiles: tileArray,
pvp: zone.value.pvp,
zoneEventTiles: zoneEventTiles.value.map(({ id, zoneId, type, positionX, positionY, teleport }) => ({ id, zoneId, type, positionX, positionY, teleport })),
zoneObjects: zoneObjects.value.map(({ id, zoneId, objectId, depth, positionX, positionY }) => ({ id, zoneId, objectId, depth, positionX, positionY }))
zoneEventTiles: zoneEventTiles.map(({ id, zoneId, type, positionX, positionY, teleport }) => ({ id, zoneId, type, positionX, positionY, teleport })),
zoneObjects: zoneObjects.map(({ id, zoneId, objectId, depth, positionX, positionY }) => ({ id, zoneId, objectId, depth, positionX, positionY }))
}
if (zoneEditorStore.isSettingsModalShown) {
@ -215,26 +215,26 @@ function save() {
}
function clear() {
for (let y = 0; y < zoneTilemap.value.height; y++) {
if (!tileArray.value[y]) {
tileArray.value[y] = Array(zoneTilemap.value.width).fill('blank_tile')
for (let y = 0; y < zoneTilemap.height; y++) {
if (!tileArray[y]) {
tileArray[y] = Array(zoneTilemap.width).fill('blank_tile')
}
for (let x = 0; x < zoneTilemap.value.width; x++) {
placeTile(zoneTilemap.value as Tilemap, tiles.value as TilemapLayer, x, y, 'blank_tile')
tileArray.value[y][x] = 'blank_tile'
for (let x = 0; x < zoneTilemap.width; x++) {
placeTile(zoneTilemap as Tilemap, tiles as TilemapLayer, x, y, 'blank_tile')
tileArray[y][x] = 'blank_tile'
}
}
zoneEventTiles.value = []
zoneObjects.value = []
zoneEventTiles = []
zoneObjects = []
}
function updateZoneObjectDepth(depth: number) {
zoneObjects.value = zoneObjects.value.map((object) => (object.id === selectedZoneObject.value?.id ? { ...object, depth } : object))
zoneObjects = zoneObjects.map((object) => (object.id === selectedZoneObject.value?.id ? { ...object, depth } : object))
}
function deleteZoneObject(objectId: string) {
zoneObjects.value = zoneObjects.value.filter((object) => object.id !== objectId)
zoneObjects = zoneObjects.filter((object) => object.id !== objectId)
}
function handleMove() {
@ -242,28 +242,28 @@ function handleMove() {
}
onBeforeMount(() => {
tileArray.value.forEach((row, y) => row.forEach((_, x) => placeTile(zoneTilemap.value, tiles.value, x, y, 'blank_tile')))
tileArray.forEach((row, y) => row.forEach((_, x) => placeTile(zoneTilemap, tiles, x, y, 'blank_tile')))
if (zone.value?.tiles) {
setAllTiles(zoneTilemap.value, tiles.value, zone.value.tiles)
tileArray.value = zone.value.tiles.map((row) => row.map((tileId) => tileId || 'blank_tile'))
setAllTiles(zoneTilemap, tiles, zone.value.tiles)
tileArray = zone.value.tiles.map((row) => row.map((tileId) => tileId || 'blank_tile'))
}
zoneEventTiles.value = zone.value?.zoneEventTiles ?? []
zoneObjects.value = sortByIsometricDepth(zone.value?.zoneObjects ?? [], zoneTilemap.value.width)
zoneEventTiles = zone.value?.zoneEventTiles ?? []
zoneObjects = sortByIsometricDepth(zone.value?.zoneObjects ?? [], zoneTilemap.width)
// Center camera
const centerY = (zoneTilemap.value.height * zoneTilemap.value.tileHeight) / 2
const centerX = (zoneTilemap.value.width * zoneTilemap.value.tileWidth) / 2
const centerY = (zoneTilemap.height * zoneTilemap.tileHeight) / 2
const centerX = (zoneTilemap.width * zoneTilemap.tileWidth) / 2
scene.cameras.main.centerOn(centerX, centerY)
})
onUnmounted(() => {
zoneEventTiles.value = []
zoneObjects.value = []
tiles.value?.destroy()
zoneTilemap.value?.removeAllLayers()
zoneTilemap.value?.destroy()
zoneEventTiles = []
zoneObjects = []
tiles?.destroy()
zoneTilemap?.removeAllLayers()
zoneTilemap?.destroy()
zoneEditorStore.reset()
})
@ -271,7 +271,7 @@ onUnmounted(() => {
watch(
objectList,
(newObjects) => {
zoneObjects.value = zoneObjects.value.map((zoneObject) => {
zoneObjects = zoneObjects.map((zoneObject) => {
const updatedObject = newObjects.find((obj) => obj.id === zoneObject.objectId)
if (updatedObject) {
return {