forked from noxious/client
MVP Dexie loader
This commit is contained in:
parent
715fe5c318
commit
347fc0e1e8
@ -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()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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()
|
||||
|
Loading…
x
Reference in New Issue
Block a user