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) => {
|
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()
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
@ -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
|
||||||
|
@ -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
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -75,4 +66,4 @@ onMounted(async () => {
|
|||||||
isLoaded.value = true
|
isLoaded.value = true
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
@ -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()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user