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) => {
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>
</template>
<script setup lang="ts" async>
<script setup lang="ts">
import config from '@/config'
import 'phaser'
import { ref, onBeforeUnmount } from 'vue'
@ -34,8 +34,8 @@ import Hotkeys from '@/components/gui/Hotkeys.vue'
import Chat from '@/components/gui/Chat.vue'
import Inventory from '@/components/gui/UserPanel.vue'
import Effects from '@/components/Effects.vue'
import { loadAssets } from '@/composables/zoneComposable'
import Minimap from '@/components/gui/Minimap.vue'
import AwaitLoaderPlugin from 'phaser3-rex-plugins/plugins/awaitloader-plugin'
const assetManager = useAssetManager
const gameStore = useGameStore()
@ -46,7 +46,16 @@ const gameConfig = {
width: window.innerWidth,
height: window.innerHeight,
type: Phaser.AUTO, // AUTO, CANVAS, WEBGL, HEADLESS
resolution: 5
resolution: 5,
plugins: {
global: [
{
key: 'rexAwaitLoader',
plugin: AwaitLoaderPlugin,
start: true
}
]
}
}
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
/**
@ -111,13 +120,27 @@ const preloadScene = async (scene: Phaser.Scene) => {
scene.load.image('blank_tile', '/assets/zone/blank_tile.png')
scene.load.image('waypoint', '/assets/waypoint.png')
/**
* Load the assets into the Phaser scene
*/
await loadAssets(scene)
scene.load.rexAwait(async (successCallback: any, failureCallback: any) => {
/**
* Load the assets into the Phaser 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
* 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 { useGameStore } from '@/stores/gameStore'
const gameStore = useGameStore();
const assetManager = useAssetManager;
const gameStore = useGameStore()
const assetManager = useAssetManager
const isLoaded = ref(false)
async function getAssets() {
@ -40,26 +40,17 @@ async function getAssets() {
async function loadAssetsIntoAssetManager(assets: ServerAsset[]): Promise<void> {
for (const asset of assets) {
// 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
if (!existingAsset || new Date(asset.updatedAt) > new Date(existingAsset.updatedAt)) {
// Check if the asset is already loaded, if so, delete it
if (existingAsset) {
await assetManager.deleteAsset(asset.key);
await assetManager.deleteAsset(asset.key)
}
// Add the asset to the asset manager
await assetManager.addAsset(
asset.key,
asset.url,
asset.group,
asset.updatedAt,
asset.frameCount,
asset.frameWidth,
asset.frameHeight
);
await assetManager.addAsset(asset.key, asset.url, asset.group, asset.updatedAt, asset.frameCount, asset.frameWidth, asset.frameHeight)
}
}
}
@ -75,4 +66,4 @@ onMounted(async () => {
isLoaded.value = true
}
})
</script>
</script>

View File

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