mirror of
https://github.com/unanmed/HumanBreak.git
synced 2025-02-28 09:27:07 +08:00
压缩文件的加载
This commit is contained in:
parent
80ce3b1a31
commit
069ee0613b
1
idea.md
1
idea.md
@ -41,6 +41,7 @@
|
||||
- 宝物目标设定
|
||||
- 每个怪物加一个怪物说明
|
||||
- 歌词展示系统
|
||||
- 小地图显示框,可以选择是否显示剩余怪物数量等
|
||||
|
||||
### 第二章 智慧
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
export class MotaAudio {}
|
||||
export class SoundEffect {}
|
||||
|
||||
class SoundController {
|
||||
add(uri: string, data: ArrayBuffer) {}
|
||||
|
@ -3,7 +3,7 @@ export {};
|
||||
declare global {
|
||||
interface AncTe {}
|
||||
interface Window {
|
||||
ancTe: AncTe;
|
||||
readonly ancTe: AncTe;
|
||||
}
|
||||
const ancTe: AncTe;
|
||||
}
|
||||
|
@ -1,10 +1,9 @@
|
||||
import resource from '../../data/resource.json';
|
||||
import { Resource, ResourceType } from './resource';
|
||||
import { NonZipResource, Resource, getTypeByResource } from './resource';
|
||||
|
||||
const info = resource as ResourceInfo[];
|
||||
|
||||
export interface ResourceInfo {
|
||||
floor: [FloorIds, FloorIds][];
|
||||
includes: string[];
|
||||
zip: boolean;
|
||||
zippedName?: string;
|
||||
@ -13,13 +12,15 @@ export interface ResourceInfo {
|
||||
export function readyAllResource() {
|
||||
info.forEach(v => {
|
||||
if (v.zip) {
|
||||
const res = new Resource(`zip.${v.zippedName}`, 'zip');
|
||||
ancTe.resource.push([[`zip.${v.zippedName}`, res]]);
|
||||
const id = `zip.${v.zippedName}`;
|
||||
ancTe.zipResource.push([[id, new Resource(id, 'zip')]]);
|
||||
} else {
|
||||
const res: [string, Resource][] = v.includes.map(v => {
|
||||
const type = v.split('.')[0];
|
||||
return [v, new Resource(v, type as ResourceType)];
|
||||
});
|
||||
const res: [string, Resource<NonZipResource>][] = v.includes.map(
|
||||
v => {
|
||||
const type = getTypeByResource(v);
|
||||
return [v, new Resource(v, type as NonZipResource)];
|
||||
}
|
||||
);
|
||||
ancTe.resource.push(res);
|
||||
}
|
||||
});
|
||||
|
@ -15,6 +15,7 @@ interface ResourceData {
|
||||
}
|
||||
|
||||
export type ResourceType = keyof ResourceData;
|
||||
export type NonZipResource = Exclude<ResourceType, 'zip'>;
|
||||
|
||||
export class Resource<
|
||||
T extends ResourceType = ResourceType
|
||||
@ -33,22 +34,46 @@ export class Resource<
|
||||
/** 资源数据 */
|
||||
resource?: ResourceData[T];
|
||||
|
||||
constructor(resource: string, type: T) {
|
||||
constructor(resource: string, format: T) {
|
||||
super(resource);
|
||||
this.data = this.resolveUrl(resource);
|
||||
this.format = type;
|
||||
this.format = format;
|
||||
this.resStr = resource;
|
||||
|
||||
this.on('active', this.load);
|
||||
this.on('load', this.onload);
|
||||
this.once('active', this.load);
|
||||
this.once('load', this.onLoad);
|
||||
this.once('loadstart', this.onLoadStart);
|
||||
}
|
||||
|
||||
protected onload(v: ResourceData[T]) {
|
||||
protected onLoadStart(v?: ResourceData[T]) {
|
||||
if (this.format === 'bgm') {
|
||||
// bgm 单独处理,因为它可以边播放边加载
|
||||
}
|
||||
}
|
||||
|
||||
protected onLoad(v: ResourceData[T]) {
|
||||
// 资源类型处理
|
||||
if (this.type === 'fonts') {
|
||||
document.fonts.add(new FontFace(this.name, v as ArrayBuffer));
|
||||
} else if (this.type === 'sounds') {
|
||||
ancTe.sound.add(this.resStr, v as ArrayBuffer);
|
||||
}
|
||||
|
||||
// 资源加载类型处理
|
||||
if (this.format === 'zip') {
|
||||
(this.resource as ZippedResource).once('ready', data => {
|
||||
data.forEach((path, file) => {
|
||||
const [base, name] = path.split(/(\/|\\)/);
|
||||
const id = `${base}.${name}`;
|
||||
const type = getTypeByResource(id) as NonZipResource;
|
||||
const format = getZipFormatByType(type);
|
||||
ancTe.resource.set(
|
||||
id,
|
||||
new Resource(id, type).setData(file.async(format))
|
||||
);
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -84,6 +109,9 @@ export class Resource<
|
||||
* 加载资源
|
||||
*/
|
||||
protected load() {
|
||||
if (this.loaded) {
|
||||
throw new Error(`Cannot load one resource twice.`);
|
||||
}
|
||||
const data = this.data;
|
||||
if (!data) {
|
||||
throw new Error(`Unexpected null of url in loading resource.`);
|
||||
@ -92,6 +120,7 @@ export class Resource<
|
||||
this.request = new Promise(res => {
|
||||
const img = new Image();
|
||||
img.src = data;
|
||||
this.emit('loadstart', img);
|
||||
img.addEventListener('load', () => {
|
||||
this.resource = img;
|
||||
this.loaded = true;
|
||||
@ -103,6 +132,7 @@ export class Resource<
|
||||
this.request = new Promise(res => {
|
||||
const audio = new Audio();
|
||||
audio.src = data;
|
||||
this.emit('loadstart', audio);
|
||||
audio.addEventListener('load', () => {
|
||||
this.resource = audio;
|
||||
this.loaded = true;
|
||||
@ -115,6 +145,7 @@ export class Resource<
|
||||
this.format === 'text' ||
|
||||
this.format === 'arraybuffer'
|
||||
) {
|
||||
this.emit('loadstart');
|
||||
this.request = axios
|
||||
.get(data, { responseType: this.format })
|
||||
.then(v => {
|
||||
@ -124,6 +155,7 @@ export class Resource<
|
||||
return v;
|
||||
});
|
||||
} else if (this.format === 'zip') {
|
||||
this.emit('loadstart');
|
||||
this.request = axios
|
||||
.get(data, { responseType: 'arraybuffer' })
|
||||
.then(v => {
|
||||
@ -147,6 +179,25 @@ export class Resource<
|
||||
return this.resource ?? null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置资源数据,不再需要加载
|
||||
* @param data 数据
|
||||
*/
|
||||
protected setData(data: ResourceData[T] | Promise<ResourceData[T]>) {
|
||||
if (data instanceof Promise) {
|
||||
data.then(v => {
|
||||
this.loaded = true;
|
||||
this.resource = v;
|
||||
this.emit('load', v);
|
||||
});
|
||||
} else {
|
||||
this.loaded = true;
|
||||
this.resource = data;
|
||||
this.emit('load', data);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
interface ZippedEvent extends EmitableEvent {
|
||||
@ -167,7 +218,7 @@ export class ZippedResource extends EventEmitter<ZippedEvent> {
|
||||
}
|
||||
}
|
||||
|
||||
class ResourceStore extends Map<string, Resource> {
|
||||
class ResourceStore<T extends ResourceType> extends Map<string, Resource<T>> {
|
||||
active(key: string[] | string) {
|
||||
const keys = ensureArray(key);
|
||||
keys.forEach(v => this.get(v)?.active());
|
||||
@ -183,7 +234,7 @@ class ResourceStore extends Map<string, Resource> {
|
||||
keys.forEach(v => this.get(v)?.destroy());
|
||||
}
|
||||
|
||||
push(data: [string, Resource][] | Record<string, Resource>): void {
|
||||
push(data: [string, Resource<T>][] | Record<string, Resource<T>>): void {
|
||||
if (data instanceof Array) {
|
||||
for (const [key, res] of data) {
|
||||
if (this.has(key)) {
|
||||
@ -201,13 +252,41 @@ class ResourceStore extends Map<string, Resource> {
|
||||
): Promise<ResourceData[T] | null> {
|
||||
return this.get(key)?.getData() ?? null;
|
||||
}
|
||||
|
||||
getDataSync<T extends ResourceType = ResourceType>(
|
||||
key: string
|
||||
): ResourceData[T] | null {
|
||||
return this.get(key)?.resource ?? null;
|
||||
}
|
||||
}
|
||||
|
||||
declare global {
|
||||
interface AncTe {
|
||||
/** 游戏资源 */
|
||||
resource: ResourceStore;
|
||||
resource: ResourceStore<Exclude<ResourceType, 'zip'>>;
|
||||
zipResource: ResourceStore<'zip'>;
|
||||
}
|
||||
}
|
||||
|
||||
ancTe.resource = new ResourceStore();
|
||||
ancTe.zipResource = new ResourceStore();
|
||||
|
||||
console.log(JSZip.external.Promise);
|
||||
|
||||
export function getTypeByResource(resource: string): ResourceType {
|
||||
const type = resource.split('.')[0];
|
||||
|
||||
if (type === 'zip') return 'zip';
|
||||
else if (type === 'bgms') return 'bgm';
|
||||
else if (['images', 'autotiles', 'materials', 'tilesets'].includes(type)) {
|
||||
return 'image';
|
||||
} else if (['sounds', 'fonts'].includes(type)) return 'arraybuffer';
|
||||
else if (type === 'animates') return 'json';
|
||||
|
||||
return 'arraybuffer';
|
||||
}
|
||||
|
||||
export function getZipFormatByType(type: ResourceType): 'arraybuffer' | 'text' {
|
||||
if (type === 'text' || type === 'json') return 'text';
|
||||
else return 'arraybuffer';
|
||||
}
|
||||
|
@ -1,6 +1,5 @@
|
||||
[
|
||||
{
|
||||
"floor": [],
|
||||
"includes": [],
|
||||
"zip": false
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user