forked from noxious/client
Minor improvements, more work on dynamic asset loading
This commit is contained in:
parent
70fb732051
commit
7db2ba322c
@ -8,7 +8,7 @@ import { useZoneEditorStore } from '@/stores/zoneEditorStore'
|
|||||||
import { Image, useScene } from 'phavuer'
|
import { Image, useScene } from 'phavuer'
|
||||||
import { getTile, tileToWorldX, tileToWorldY } from '@/composables/zoneComposable'
|
import { getTile, tileToWorldX, tileToWorldY } from '@/composables/zoneComposable'
|
||||||
import { uuidv4 } from '@/utilities'
|
import { uuidv4 } from '@/utilities'
|
||||||
import { onBeforeMount, onBeforeUnmount } from 'vue'
|
import { onMounted, onUnmounted } from 'vue'
|
||||||
|
|
||||||
const scene = useScene()
|
const scene = useScene()
|
||||||
const zoneEditorStore = useZoneEditorStore()
|
const zoneEditorStore = useZoneEditorStore()
|
||||||
@ -102,14 +102,14 @@ function eraser(pointer: Phaser.Input.Pointer) {
|
|||||||
zoneEditorStore.zone.zoneEventTiles = zoneEditorStore.zone.zoneEventTiles.filter((eventTile) => eventTile.id !== existingEventTile.id)
|
zoneEditorStore.zone.zoneEventTiles = zoneEditorStore.zone.zoneEventTiles.filter((eventTile) => eventTile.id !== existingEventTile.id)
|
||||||
}
|
}
|
||||||
|
|
||||||
onBeforeMount(() => {
|
onMounted(() => {
|
||||||
scene.input.on(Phaser.Input.Events.POINTER_DOWN, pencil)
|
scene.input.on(Phaser.Input.Events.POINTER_DOWN, pencil)
|
||||||
scene.input.on(Phaser.Input.Events.POINTER_MOVE, pencil)
|
scene.input.on(Phaser.Input.Events.POINTER_MOVE, pencil)
|
||||||
scene.input.on(Phaser.Input.Events.POINTER_DOWN, eraser)
|
scene.input.on(Phaser.Input.Events.POINTER_DOWN, eraser)
|
||||||
scene.input.on(Phaser.Input.Events.POINTER_MOVE, eraser)
|
scene.input.on(Phaser.Input.Events.POINTER_MOVE, eraser)
|
||||||
})
|
})
|
||||||
|
|
||||||
onBeforeUnmount(() => {
|
onUnmounted(() => {
|
||||||
scene.input.off(Phaser.Input.Events.POINTER_DOWN, pencil)
|
scene.input.off(Phaser.Input.Events.POINTER_DOWN, pencil)
|
||||||
scene.input.off(Phaser.Input.Events.POINTER_MOVE, pencil)
|
scene.input.off(Phaser.Input.Events.POINTER_MOVE, pencil)
|
||||||
scene.input.off(Phaser.Input.Events.POINTER_DOWN, eraser)
|
scene.input.off(Phaser.Input.Events.POINTER_DOWN, eraser)
|
||||||
|
@ -10,7 +10,7 @@ import { Image, useScene } from 'phavuer'
|
|||||||
import { useZoneEditorStore } from '@/stores/zoneEditorStore'
|
import { useZoneEditorStore } from '@/stores/zoneEditorStore'
|
||||||
import type { ZoneObject } from '@/types'
|
import type { ZoneObject } from '@/types'
|
||||||
import SelectedZoneObject from '@/components/gameMaster/zoneEditor/partials/SelectedZoneObject.vue'
|
import SelectedZoneObject from '@/components/gameMaster/zoneEditor/partials/SelectedZoneObject.vue'
|
||||||
import { onBeforeMount, onBeforeUnmount, ref, watch } from 'vue'
|
import { onMounted, onUnmounted, ref, watch } from 'vue'
|
||||||
|
|
||||||
const scene = useScene()
|
const scene = useScene()
|
||||||
const zoneEditorStore = useZoneEditorStore()
|
const zoneEditorStore = useZoneEditorStore()
|
||||||
@ -155,14 +155,14 @@ function deleteZoneObject(id: string) {
|
|||||||
selectedZoneObject.value = null
|
selectedZoneObject.value = null
|
||||||
}
|
}
|
||||||
|
|
||||||
onBeforeMount(() => {
|
onMounted(() => {
|
||||||
scene.input.on(Phaser.Input.Events.POINTER_DOWN, pencil)
|
scene.input.on(Phaser.Input.Events.POINTER_DOWN, pencil)
|
||||||
scene.input.on(Phaser.Input.Events.POINTER_MOVE, pencil)
|
scene.input.on(Phaser.Input.Events.POINTER_MOVE, pencil)
|
||||||
scene.input.on(Phaser.Input.Events.POINTER_DOWN, eraser)
|
scene.input.on(Phaser.Input.Events.POINTER_DOWN, eraser)
|
||||||
scene.input.on(Phaser.Input.Events.POINTER_MOVE, eraser)
|
scene.input.on(Phaser.Input.Events.POINTER_MOVE, eraser)
|
||||||
})
|
})
|
||||||
|
|
||||||
onBeforeUnmount(() => {
|
onUnmounted(() => {
|
||||||
scene.input.off(Phaser.Input.Events.POINTER_DOWN, pencil)
|
scene.input.off(Phaser.Input.Events.POINTER_DOWN, pencil)
|
||||||
scene.input.off(Phaser.Input.Events.POINTER_MOVE, pencil)
|
scene.input.off(Phaser.Input.Events.POINTER_MOVE, pencil)
|
||||||
scene.input.off(Phaser.Input.Events.POINTER_DOWN, eraser)
|
scene.input.off(Phaser.Input.Events.POINTER_DOWN, eraser)
|
||||||
|
@ -7,7 +7,7 @@ import config from '@/config'
|
|||||||
import { useScene } from 'phavuer'
|
import { useScene } from 'phavuer'
|
||||||
import { useGameStore } from '@/stores/gameStore'
|
import { useGameStore } from '@/stores/gameStore'
|
||||||
import { useZoneEditorStore } from '@/stores/zoneEditorStore'
|
import { useZoneEditorStore } from '@/stores/zoneEditorStore'
|
||||||
import { onBeforeMount, onBeforeUnmount } from 'vue'
|
import { onMounted, onUnmounted } from 'vue'
|
||||||
import { createTileArray, getTile, placeTile, setLayerTiles } from '@/composables/zoneComposable'
|
import { createTileArray, getTile, placeTile, setLayerTiles } from '@/composables/zoneComposable'
|
||||||
import Controls from '@/components/utilities/Controls.vue'
|
import Controls from '@/components/utilities/Controls.vue'
|
||||||
|
|
||||||
@ -123,7 +123,7 @@ function paint(pointer: Phaser.Input.Pointer) {
|
|||||||
zoneEditorStore.zone.tiles = createTileArray(zoneTilemap.width, zoneTilemap.height, zoneEditorStore.selectedTile.id)
|
zoneEditorStore.zone.tiles = createTileArray(zoneTilemap.width, zoneTilemap.height, zoneEditorStore.selectedTile.id)
|
||||||
}
|
}
|
||||||
|
|
||||||
onBeforeMount(() => {
|
onMounted(() => {
|
||||||
if (!zoneEditorStore.zone?.tiles) {
|
if (!zoneEditorStore.zone?.tiles) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -134,7 +134,7 @@ onBeforeMount(() => {
|
|||||||
scene.input.on(Phaser.Input.Events.POINTER_DOWN, paint)
|
scene.input.on(Phaser.Input.Events.POINTER_DOWN, paint)
|
||||||
})
|
})
|
||||||
|
|
||||||
onBeforeUnmount(() => {
|
onUnmounted(() => {
|
||||||
scene.input.off(Phaser.Input.Events.POINTER_MOVE, pencil)
|
scene.input.off(Phaser.Input.Events.POINTER_MOVE, pencil)
|
||||||
scene.input.off(Phaser.Input.Events.POINTER_MOVE, eraser)
|
scene.input.off(Phaser.Input.Events.POINTER_MOVE, eraser)
|
||||||
scene.input.off(Phaser.Input.Events.POINTER_DOWN, paint)
|
scene.input.off(Phaser.Input.Events.POINTER_DOWN, paint)
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { useGameStore } from '@/stores/gameStore'
|
import { useGameStore } from '@/stores/gameStore'
|
||||||
import Modal from '@/components/utilities/Modal.vue'
|
import Modal from '@/components/utilities/Modal.vue'
|
||||||
import { onBeforeMount, onBeforeUnmount, watch } from 'vue'
|
import { onBeforeMount, onBeforeUnmount, onMounted, onUnmounted, watch } from 'vue'
|
||||||
|
|
||||||
const gameStore = useGameStore()
|
const gameStore = useGameStore()
|
||||||
|
|
||||||
@ -34,7 +34,7 @@ function setupNotificationListener(connection: any) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
onBeforeMount(() => {
|
onMounted(() => {
|
||||||
const connection = gameStore.connection
|
const connection = gameStore.connection
|
||||||
if (connection) {
|
if (connection) {
|
||||||
setupNotificationListener(connection)
|
setupNotificationListener(connection)
|
||||||
@ -49,7 +49,7 @@ onBeforeMount(() => {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
onBeforeUnmount(() => {
|
onUnmounted(() => {
|
||||||
const connection = gameStore.connection
|
const connection = gameStore.connection
|
||||||
if (connection) {
|
if (connection) {
|
||||||
connection.off('notification')
|
connection.off('notification')
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { useGameStore } from '@/stores/gameStore'
|
import { useGameStore } from '@/stores/gameStore'
|
||||||
import { useZoneStore } from '@/stores/zoneStore'
|
import { useZoneStore } from '@/stores/zoneStore'
|
||||||
import { onBeforeUnmount, ref, onBeforeMount } from 'vue'
|
import { ref, onUnmounted, onMounted } from 'vue'
|
||||||
import type { Character as CharacterT, Zone as ZoneT, ExtendedCharacter as ExtendedCharacterT } from '@/types'
|
import type { Character as CharacterT, Zone as ZoneT, ExtendedCharacter as ExtendedCharacterT } from '@/types'
|
||||||
import ZoneTiles from '@/components/zone/ZoneTiles.vue'
|
import ZoneTiles from '@/components/zone/ZoneTiles.vue'
|
||||||
import ZoneObjects from '@/components/zone/ZoneObjects.vue'
|
import ZoneObjects from '@/components/zone/ZoneObjects.vue'
|
||||||
@ -51,15 +51,15 @@ gameStore.connection!.on('character:move', (data: ExtendedCharacterT) => {
|
|||||||
zoneStore.updateCharacter(data)
|
zoneStore.updateCharacter(data)
|
||||||
})
|
})
|
||||||
|
|
||||||
onBeforeMount(async () => {
|
onMounted(async () => {
|
||||||
|
// Emit zone:character:join event to server and wait for response, then set zone and characters
|
||||||
gameStore!.connection!.emit('zone:character:join', async (response: zoneLoadData) => {
|
gameStore!.connection!.emit('zone:character:join', async (response: zoneLoadData) => {
|
||||||
// Set zone and characters
|
|
||||||
zoneStore.setZone(response.zone)
|
zoneStore.setZone(response.zone)
|
||||||
zoneStore.setCharacters(response.characters)
|
zoneStore.setCharacters(response.characters)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
onBeforeUnmount(() => {
|
onUnmounted(() => {
|
||||||
zoneStore.reset()
|
zoneStore.reset()
|
||||||
gameStore.connection!.off('zone:character:teleport')
|
gameStore.connection!.off('zone:character:teleport')
|
||||||
gameStore.connection!.off('zone:character:join')
|
gameStore.connection!.off('zone:character:join')
|
||||||
|
@ -6,17 +6,34 @@
|
|||||||
import config from '@/config'
|
import config from '@/config'
|
||||||
import { useScene } from 'phavuer'
|
import { useScene } from 'phavuer'
|
||||||
import { useZoneStore } from '@/stores/zoneStore'
|
import { useZoneStore } from '@/stores/zoneStore'
|
||||||
import { onBeforeMount, onBeforeUnmount } from 'vue'
|
import { onBeforeUnmount } from 'vue'
|
||||||
import { setLayerTiles } from '@/composables/zoneComposable'
|
import { setLayerTiles, loadZoneTileTexture } from '@/composables/zoneComposable'
|
||||||
import Controls from '@/components/utilities/Controls.vue'
|
import Controls from '@/components/utilities/Controls.vue'
|
||||||
|
|
||||||
const emit = defineEmits(['tilemap:create'])
|
const emit = defineEmits(['tilemap:create'])
|
||||||
|
|
||||||
const zoneStore = useZoneStore()
|
const zoneStore = useZoneStore()
|
||||||
const scene = useScene()
|
const scene = useScene()
|
||||||
|
|
||||||
|
const tilesFromZone = zoneStore.zone?.tiles
|
||||||
|
const uniqueTiles = new Set(tilesFromZone.flat().filter(Boolean))
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @TODO fix this
|
||||||
|
*/
|
||||||
|
for (const tile of uniqueTiles) {
|
||||||
|
console.log(tile)
|
||||||
|
await loadZoneTileTexture(scene, tile, new Date())
|
||||||
|
}
|
||||||
|
|
||||||
const zoneTilemap = createTilemap()
|
const zoneTilemap = createTilemap()
|
||||||
const tiles = createTileLayer()
|
const tiles = createTileLayer()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A Tilemap is a container for Tilemap data.
|
||||||
|
* This isn't a display object, rather, it holds data about the map and allows you to add tilesets and tilemap layers to it.
|
||||||
|
* A map can have one or more tilemap layers, which are the display objects that actually render the tiles.
|
||||||
|
*/
|
||||||
function createTilemap() {
|
function createTilemap() {
|
||||||
const zoneData = new Phaser.Tilemaps.MapData({
|
const zoneData = new Phaser.Tilemaps.MapData({
|
||||||
width: zoneStore.zone?.width,
|
width: zoneStore.zone?.width,
|
||||||
@ -31,6 +48,9 @@ function createTilemap() {
|
|||||||
return tilemap
|
return tilemap
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A Tileset is a combination of a single image containing the tiles and a container for data about each tile.
|
||||||
|
*/
|
||||||
function createTileLayer() {
|
function createTileLayer() {
|
||||||
const tilesFromZone = zoneStore.zone?.tiles || []
|
const tilesFromZone = zoneStore.zone?.tiles || []
|
||||||
const uniqueTiles = new Set(tilesFromZone.flat().filter(Boolean))
|
const uniqueTiles = new Set(tilesFromZone.flat().filter(Boolean))
|
||||||
@ -49,12 +69,7 @@ function createTileLayer() {
|
|||||||
return layer
|
return layer
|
||||||
}
|
}
|
||||||
|
|
||||||
onBeforeMount(() => {
|
setLayerTiles(zoneTilemap, tiles, zoneStore.zone?.tiles)
|
||||||
if (!zoneStore.zone?.tiles) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
setLayerTiles(zoneTilemap, tiles, zoneStore.zone.tiles)
|
|
||||||
})
|
|
||||||
|
|
||||||
onBeforeUnmount(() => {
|
onBeforeUnmount(() => {
|
||||||
zoneTilemap.destroyLayer('tiles')
|
zoneTilemap.destroyLayer('tiles')
|
||||||
|
@ -3,14 +3,9 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref, onMounted, computed } from 'vue'
|
import { ref, computed } from 'vue'
|
||||||
import { Image, useScene } from 'phavuer'
|
import { Image, useScene } from 'phavuer'
|
||||||
import {
|
import { calculateIsometricDepth, loadZoneObjectTexture, tileToWorldX, tileToWorldY } from '@/composables/zoneComposable'
|
||||||
calculateIsometricDepth,
|
|
||||||
loadZoneObjectTexture,
|
|
||||||
tileToWorldX,
|
|
||||||
tileToWorldY
|
|
||||||
} from '@/composables/zoneComposable'
|
|
||||||
import type { ZoneObject } from '@/types'
|
import type { ZoneObject } from '@/types'
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
@ -31,7 +26,6 @@ const imageProps = computed(() => ({
|
|||||||
originX: Number(props.zoneObject.object.originY)
|
originX: Number(props.zoneObject.object.originY)
|
||||||
}))
|
}))
|
||||||
|
|
||||||
onMounted(() => {
|
|
||||||
loadZoneObjectTexture(scene, props.zoneObject.object.id, props.zoneObject.object.updatedAt)
|
loadZoneObjectTexture(scene, props.zoneObject.object.id, props.zoneObject.object.updatedAt)
|
||||||
.then((loaded) => {
|
.then((loaded) => {
|
||||||
isTextureLoaded.value = loaded
|
isTextureLoaded.value = loaded
|
||||||
@ -39,5 +33,4 @@ onMounted(() => {
|
|||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
console.error('Error loading texture:', error)
|
console.error('Error loading texture:', error)
|
||||||
})
|
})
|
||||||
})
|
|
||||||
</script>
|
</script>
|
||||||
|
@ -52,6 +52,8 @@ export function placeTile(zone: Tilemap, layer: TilemapLayer, x: number, y: numb
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function setLayerTiles(zone: Tilemap, layer: TilemapLayer, tiles: string[][]) {
|
export function setLayerTiles(zone: Tilemap, layer: TilemapLayer, tiles: string[][]) {
|
||||||
|
if (!tiles) return
|
||||||
|
|
||||||
tiles.forEach((row: string[], y: number) => {
|
tiles.forEach((row: string[], y: number) => {
|
||||||
row.forEach((tile: string, x: number) => {
|
row.forEach((tile: string, x: number) => {
|
||||||
placeTile(zone, layer, x, y, tile)
|
placeTile(zone, layer, x, y, tile)
|
||||||
@ -71,6 +73,33 @@ export const calculateIsometricDepth = (x: number, y: number, width: number = 0,
|
|||||||
return baseDepth + (width + height) / (2 * config.tile_size.x)
|
return baseDepth + (width + height) / (2 * config.tile_size.x)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function loadZoneTileTexture(scene: Phaser.Scene, textureId: string, updatedAt: Date): Promise<boolean> {
|
||||||
|
const assetManager = useAssetManager
|
||||||
|
|
||||||
|
// Check if the texture is already loaded in Phaser
|
||||||
|
if (scene.textures.exists(textureId)) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
let assetData = await assetManager.getAsset(textureId)
|
||||||
|
|
||||||
|
if (!assetData) {
|
||||||
|
await assetManager.downloadAsset(textureId, `/assets/tiles/${textureId}.png`, 'tiles', updatedAt)
|
||||||
|
assetData = await assetManager.getAsset(textureId)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (assetData) {
|
||||||
|
return new Promise<boolean>((resolve) => {
|
||||||
|
scene.textures.addBase64(textureId, assetData.data)
|
||||||
|
scene.textures.once(`addtexture-${textureId}`, () => {
|
||||||
|
resolve(true)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
export async function loadZoneObjectTexture(scene: Phaser.Scene, textureId: string, updatedAt: Date): Promise<boolean> {
|
export async function loadZoneObjectTexture(scene: Phaser.Scene, textureId: string, updatedAt: Date): Promise<boolean> {
|
||||||
const assetManager = useAssetManager
|
const assetManager = useAssetManager
|
||||||
|
|
||||||
|
@ -83,24 +83,24 @@ function preloadScene(scene: Phaser.Scene) {
|
|||||||
* We're using rex-await-loader to load assets asynchronously
|
* We're using rex-await-loader to load assets asynchronously
|
||||||
* Phaser does not support this out of the box, so we're using this plugin
|
* Phaser does not support this out of the box, so we're using this plugin
|
||||||
*/
|
*/
|
||||||
scene.load.rexAwait(async function (successCallback) {
|
// scene.load.rexAwait(async function (successCallback) {
|
||||||
await assetManager.getAssetsByGroup('tiles').then((assets) => {
|
// await assetManager.getAssetsByGroup('tiles').then((assets) => {
|
||||||
assets.forEach((asset) => {
|
// assets.forEach((asset) => {
|
||||||
if (scene.load.textureManager.exists(asset.key)) return
|
// if (scene.load.textureManager.exists(asset.key)) return
|
||||||
scene.textures.addBase64(asset.key, asset.data)
|
// scene.textures.addBase64(asset.key, asset.data)
|
||||||
})
|
// })
|
||||||
})
|
// })
|
||||||
|
//
|
||||||
// Load objects
|
// // Load objects
|
||||||
await assetManager.getAssetsByGroup('objects').then((assets) => {
|
// await assetManager.getAssetsByGroup('objects').then((assets) => {
|
||||||
assets.forEach((asset) => {
|
// assets.forEach((asset) => {
|
||||||
if (scene.load.textureManager.exists(asset.key)) return
|
// if (scene.load.textureManager.exists(asset.key)) return
|
||||||
scene.textures.addBase64(asset.key, asset.data)
|
// scene.textures.addBase64(asset.key, asset.data)
|
||||||
})
|
// })
|
||||||
})
|
// })
|
||||||
|
//
|
||||||
successCallback()
|
// successCallback()
|
||||||
})
|
// })
|
||||||
}
|
}
|
||||||
|
|
||||||
function createScene(scene: Phaser.Scene) {
|
function createScene(scene: Phaser.Scene) {
|
||||||
@ -108,15 +108,15 @@ function createScene(scene: Phaser.Scene) {
|
|||||||
* Create sprite animations
|
* Create sprite animations
|
||||||
* This is done here because phaser forces us to
|
* This is done here because phaser forces us to
|
||||||
*/
|
*/
|
||||||
assetManager.getAssetsByGroup('sprite_animations').then((assets) => {
|
// assetManager.getAssetsByGroup('sprite_animations').then((assets) => {
|
||||||
assets.forEach((asset) => {
|
// assets.forEach((asset) => {
|
||||||
scene.anims.create({
|
// scene.anims.create({
|
||||||
key: asset.key,
|
// key: asset.key,
|
||||||
frameRate: 7,
|
// frameRate: 7,
|
||||||
frames: scene.anims.generateFrameNumbers(asset.key, { start: 0, end: asset.frameCount! - 1 }),
|
// frames: scene.anims.generateFrameNumbers(asset.key, { start: 0, end: asset.frameCount! - 1 }),
|
||||||
repeat: -1
|
// repeat: -1
|
||||||
})
|
// })
|
||||||
})
|
// })
|
||||||
})
|
// })
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user