1
0
forked from noxious/client

MVP Dexie loader

This commit is contained in:
Dennis Postma 2024-10-21 18:35:36 +02:00
parent 715fe5c318
commit 347fc0e1e8
4 changed files with 74 additions and 112 deletions

View File

@ -87,47 +87,3 @@ export const sortByIsometricDepth = <T extends { positionX: number; positionY: n
export const clearAssets = (scene: Phaser.Scene) => { export const clearAssets = (scene: Phaser.Scene) => {
scene.load.destroy() scene.load.destroy()
} }
export const loadAssets = (scene: Phaser.Scene): Promise<void> => {
return new Promise((resolve) => {
let assetManager = useAssetManager
let addedLoad = false
assetManager.getAssetsByGroup('tiles').then((assets) => {
assets.forEach((asset) => {
if (scene.load.textureManager.exists(asset.key)) return
addedLoad = true
scene.textures.addBase64(asset.key, asset.data)
})
})
assetManager.getAssetsByGroup('objects').then((assets) => {
assets.forEach((asset) => {
if (scene.load.textureManager.exists(asset.key)) return
addedLoad = true
scene.textures.addBase64(asset.key, asset.data)
})
})
assetManager.getAssetsByGroup('sprites').then((assets) => {
assets.forEach((asset) => {
if (scene.load.textureManager.exists(asset.key)) return
let img = new Image();
img.onload = () => {
scene.textures.addSpriteSheet(asset.key, img, { frameWidth: asset.frameWidth ?? 0, frameHeight: asset.frameHeight ?? 0 })
};
img.src = asset.data;
addedLoad = true
})
})
if (addedLoad) {
scene.load.start()
scene.load.on(Phaser.Loader.Events.COMPLETE, () => {
resolve()
})
} else {
resolve()
}
})
}

View File

@ -19,7 +19,7 @@
</div> </div>
</template> </template>
<script setup lang="ts" async> <script setup lang="ts">
import config from '@/config' import config from '@/config'
import 'phaser' import 'phaser'
import { ref, onBeforeUnmount } from 'vue' import { ref, onBeforeUnmount } from 'vue'
@ -34,8 +34,8 @@ import Hotkeys from '@/components/gui/Hotkeys.vue'
import Chat from '@/components/gui/Chat.vue' import Chat from '@/components/gui/Chat.vue'
import Inventory from '@/components/gui/UserPanel.vue' import Inventory from '@/components/gui/UserPanel.vue'
import Effects from '@/components/Effects.vue' import Effects from '@/components/Effects.vue'
import { loadAssets } from '@/composables/zoneComposable'
import Minimap from '@/components/gui/Minimap.vue' import Minimap from '@/components/gui/Minimap.vue'
import AwaitLoaderPlugin from 'phaser3-rex-plugins/plugins/awaitloader-plugin'
const assetManager = useAssetManager const assetManager = useAssetManager
const gameStore = useGameStore() const gameStore = useGameStore()
@ -46,7 +46,16 @@ const gameConfig = {
width: window.innerWidth, width: window.innerWidth,
height: window.innerHeight, height: window.innerHeight,
type: Phaser.AUTO, // AUTO, CANVAS, WEBGL, HEADLESS type: Phaser.AUTO, // AUTO, CANVAS, WEBGL, HEADLESS
resolution: 5 resolution: 5,
plugins: {
global: [
{
key: 'rexAwaitLoader',
plugin: AwaitLoaderPlugin,
start: true
}
]
}
} }
const createGame = (game: Phaser.Game) => { const createGame = (game: Phaser.Game) => {
@ -67,7 +76,7 @@ const createGame = (game: Phaser.Game) => {
} }
} }
const preloadScene = async (scene: Phaser.Scene) => { function preloadScene(scene: Phaser.Scene) {
isLoaded.value = false isLoaded.value = false
/** /**
@ -111,13 +120,27 @@ const preloadScene = async (scene: Phaser.Scene) => {
scene.load.image('blank_tile', '/assets/zone/blank_tile.png') scene.load.image('blank_tile', '/assets/zone/blank_tile.png')
scene.load.image('waypoint', '/assets/waypoint.png') scene.load.image('waypoint', '/assets/waypoint.png')
/** scene.load.rexAwait(async (successCallback: any, failureCallback: any) => {
* Load the assets into the Phaser scene /**
*/ * Load the assets into the Phaser scene
await loadAssets(scene) */
await assetManager.getAssetsByGroup('tiles').then((assets) => {
assets.forEach((asset) => {
scene.textures.addBase64(asset.key, asset.data)
})
})
await assetManager.getAssetsByGroup('objects').then((assets) => {
assets.forEach((asset) => {
scene.textures.addBase64(asset.key, asset.data)
})
})
successCallback()
})
} }
const createScene = async (scene: Phaser.Scene) => { const 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

View File

@ -20,8 +20,8 @@ import type { AssetT as ServerAsset } from '@/types'
import { useAssetManager } from '@/utilities/assets' import { useAssetManager } from '@/utilities/assets'
import { useGameStore } from '@/stores/gameStore' import { useGameStore } from '@/stores/gameStore'
const gameStore = useGameStore(); const gameStore = useGameStore()
const assetManager = useAssetManager; const assetManager = useAssetManager
const isLoaded = ref(false) const isLoaded = ref(false)
async function getAssets() { async function getAssets() {
@ -40,26 +40,17 @@ async function getAssets() {
async function loadAssetsIntoAssetManager(assets: ServerAsset[]): Promise<void> { async function loadAssetsIntoAssetManager(assets: ServerAsset[]): Promise<void> {
for (const asset of assets) { for (const asset of assets) {
// Check if the asset is already loaded // Check if the asset is already loaded
const existingAsset = await assetManager.getAsset(asset.key); const existingAsset = await assetManager.getAsset(asset.key)
// Check if the asset needs to be updated // Check if the asset needs to be updated
if (!existingAsset || new Date(asset.updatedAt) > new Date(existingAsset.updatedAt)) { if (!existingAsset || new Date(asset.updatedAt) > new Date(existingAsset.updatedAt)) {
// Check if the asset is already loaded, if so, delete it // Check if the asset is already loaded, if so, delete it
if (existingAsset) { if (existingAsset) {
await assetManager.deleteAsset(asset.key); await assetManager.deleteAsset(asset.key)
} }
// Add the asset to the asset manager // Add the asset to the asset manager
await assetManager.addAsset( await assetManager.addAsset(asset.key, asset.url, asset.group, asset.updatedAt, asset.frameCount, asset.frameWidth, asset.frameHeight)
asset.key,
asset.url,
asset.group,
asset.updatedAt,
asset.frameCount,
asset.frameWidth,
asset.frameHeight
);
} }
} }
} }

View File

@ -1,101 +1,93 @@
import config from '@/config'; import config from '@/config'
import Dexie from 'dexie'; import Dexie from 'dexie'
interface Asset { interface Asset {
key: string; key: string
data: Blob; data: Blob
group: string; group: string
updatedAt: Date; updatedAt: Date
frameCount?: number; frameCount?: number
frameWidth?: number; frameWidth?: number
frameHeight?: number; frameHeight?: number
} }
interface AssetWithUrl extends Omit<Asset, 'data'> { interface AssetWithUrl extends Omit<Asset, 'data'> {
data: string; data: string
} }
class AssetManager extends Dexie { class AssetManager extends Dexie {
assets!: Dexie.Table<Asset, string>; assets!: Dexie.Table<Asset, string>
constructor() { constructor() {
super('AssetManager'); super('AssetManager')
this.version(1).stores({ this.version(1).stores({
assets: 'key, group' assets: 'key, group'
}); })
} }
async getAssetCount(): Promise<number> { async getAssetCount(): Promise<number> {
try { try {
const count = await this.assets.count(); const count = await this.assets.count()
return count; return count
} catch (error) { } catch (error) {
console.error('Failed to get asset count:', error); console.error('Failed to get asset count:', error)
return 0; return 0
} }
} }
async addAsset( async addAsset(key: string, url: string, group: string, updatedAt: Date, frameCount?: number, frameWidth?: number, frameHeight?: number): Promise<void> {
key: string,
url: string,
group: string,
updatedAt: Date,
frameCount?: number,
frameWidth?: number,
frameHeight?: number
): Promise<void> {
try { try {
const response = await fetch(config.server_endpoint + url); const response = await fetch(config.server_endpoint + url)
const blob = await response.blob(); const blob = await response.blob()
await this.assets.put({ key, data: blob, group, updatedAt, frameCount, frameWidth, frameHeight }); await this.assets.put({ key, data: blob, group, updatedAt, frameCount, frameWidth, frameHeight })
} catch (error) { } catch (error) {
console.error(`Failed to add asset ${key}:`, error); console.error(`Failed to add asset ${key}:`, error)
} }
} }
async getAsset(key: string): Promise<AssetWithUrl | null> { async getAsset(key: string): Promise<AssetWithUrl | null> {
try { try {
const asset = await this.assets.get(key); const asset = await this.assets.get(key)
if (asset) { if (asset) {
return { return {
...asset, ...asset,
data: URL.createObjectURL(asset.data) data: URL.createObjectURL(asset.data)
}; }
} }
} catch (error) { } catch (error) {
console.error(`Failed to retrieve asset ${key}:`, error); console.error(`Failed to retrieve asset ${key}:`, error)
} }
return null; return null
} }
async getAssetsByGroup(group: string): Promise<AssetWithUrl[]> { async getAssetsByGroup(group: string): Promise<AssetWithUrl[]> {
try { try {
const assets = await this.assets.where('group').equals(group).toArray(); const assets = await this.assets.where('group').equals(group).toArray()
return assets.map(asset => ({ return assets.map((asset) => ({
...asset, ...asset,
data: URL.createObjectURL(asset.data) data: URL.createObjectURL(asset.data)
})); }))
} catch (error) { } catch (error) {
console.error(`Failed to retrieve assets for group ${group}:`, error); console.error(`Failed to retrieve assets for group ${group}:`, error)
return []; return []
} }
} }
async clearAssets(): Promise<void> { async clearAssets(): Promise<void> {
try { try {
await this.assets.clear(); await this.assets.clear()
} catch (error) { } catch (error) {
console.error('Failed to clear assets:', error); console.error('Failed to clear assets:', error)
} }
} }
async deleteAsset(key: string): Promise<void> { async deleteAsset(key: string): Promise<void> {
try { try {
await this.assets.delete(key); await this.assets.delete(key)
} catch (error) { } catch (error) {
console.error(`Failed to delete asset ${key}:`, error); console.error(`Failed to delete asset ${key}:`, error)
} }
} }
} }
export const useAssetManager = new AssetManager(); export const useAssetManager = new AssetManager()