mirror of
https://github.com/unanmed/HumanBreak.git
synced 2025-02-28 17:37: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 {
|
class SoundController {
|
||||||
add(uri: string, data: ArrayBuffer) {}
|
add(uri: string, data: ArrayBuffer) {}
|
||||||
|
@ -3,7 +3,7 @@ export {};
|
|||||||
declare global {
|
declare global {
|
||||||
interface AncTe {}
|
interface AncTe {}
|
||||||
interface Window {
|
interface Window {
|
||||||
ancTe: AncTe;
|
readonly ancTe: AncTe;
|
||||||
}
|
}
|
||||||
const ancTe: AncTe;
|
const ancTe: AncTe;
|
||||||
}
|
}
|
||||||
|
@ -1,10 +1,9 @@
|
|||||||
import resource from '../../data/resource.json';
|
import resource from '../../data/resource.json';
|
||||||
import { Resource, ResourceType } from './resource';
|
import { NonZipResource, Resource, getTypeByResource } from './resource';
|
||||||
|
|
||||||
const info = resource as ResourceInfo[];
|
const info = resource as ResourceInfo[];
|
||||||
|
|
||||||
export interface ResourceInfo {
|
export interface ResourceInfo {
|
||||||
floor: [FloorIds, FloorIds][];
|
|
||||||
includes: string[];
|
includes: string[];
|
||||||
zip: boolean;
|
zip: boolean;
|
||||||
zippedName?: string;
|
zippedName?: string;
|
||||||
@ -13,13 +12,15 @@ export interface ResourceInfo {
|
|||||||
export function readyAllResource() {
|
export function readyAllResource() {
|
||||||
info.forEach(v => {
|
info.forEach(v => {
|
||||||
if (v.zip) {
|
if (v.zip) {
|
||||||
const res = new Resource(`zip.${v.zippedName}`, 'zip');
|
const id = `zip.${v.zippedName}`;
|
||||||
ancTe.resource.push([[`zip.${v.zippedName}`, res]]);
|
ancTe.zipResource.push([[id, new Resource(id, 'zip')]]);
|
||||||
} else {
|
} else {
|
||||||
const res: [string, Resource][] = v.includes.map(v => {
|
const res: [string, Resource<NonZipResource>][] = v.includes.map(
|
||||||
const type = v.split('.')[0];
|
v => {
|
||||||
return [v, new Resource(v, type as ResourceType)];
|
const type = getTypeByResource(v);
|
||||||
});
|
return [v, new Resource(v, type as NonZipResource)];
|
||||||
|
}
|
||||||
|
);
|
||||||
ancTe.resource.push(res);
|
ancTe.resource.push(res);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -15,6 +15,7 @@ interface ResourceData {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export type ResourceType = keyof ResourceData;
|
export type ResourceType = keyof ResourceData;
|
||||||
|
export type NonZipResource = Exclude<ResourceType, 'zip'>;
|
||||||
|
|
||||||
export class Resource<
|
export class Resource<
|
||||||
T extends ResourceType = ResourceType
|
T extends ResourceType = ResourceType
|
||||||
@ -33,22 +34,46 @@ export class Resource<
|
|||||||
/** 资源数据 */
|
/** 资源数据 */
|
||||||
resource?: ResourceData[T];
|
resource?: ResourceData[T];
|
||||||
|
|
||||||
constructor(resource: string, type: T) {
|
constructor(resource: string, format: T) {
|
||||||
super(resource);
|
super(resource);
|
||||||
this.data = this.resolveUrl(resource);
|
this.data = this.resolveUrl(resource);
|
||||||
this.format = type;
|
this.format = format;
|
||||||
this.resStr = resource;
|
this.resStr = resource;
|
||||||
|
|
||||||
this.on('active', this.load);
|
this.once('active', this.load);
|
||||||
this.on('load', this.onload);
|
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') {
|
if (this.type === 'fonts') {
|
||||||
document.fonts.add(new FontFace(this.name, v as ArrayBuffer));
|
document.fonts.add(new FontFace(this.name, v as ArrayBuffer));
|
||||||
} else if (this.type === 'sounds') {
|
} else if (this.type === 'sounds') {
|
||||||
ancTe.sound.add(this.resStr, v as ArrayBuffer);
|
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() {
|
protected load() {
|
||||||
|
if (this.loaded) {
|
||||||
|
throw new Error(`Cannot load one resource twice.`);
|
||||||
|
}
|
||||||
const data = this.data;
|
const data = this.data;
|
||||||
if (!data) {
|
if (!data) {
|
||||||
throw new Error(`Unexpected null of url in loading resource.`);
|
throw new Error(`Unexpected null of url in loading resource.`);
|
||||||
@ -92,6 +120,7 @@ export class Resource<
|
|||||||
this.request = new Promise(res => {
|
this.request = new Promise(res => {
|
||||||
const img = new Image();
|
const img = new Image();
|
||||||
img.src = data;
|
img.src = data;
|
||||||
|
this.emit('loadstart', img);
|
||||||
img.addEventListener('load', () => {
|
img.addEventListener('load', () => {
|
||||||
this.resource = img;
|
this.resource = img;
|
||||||
this.loaded = true;
|
this.loaded = true;
|
||||||
@ -103,6 +132,7 @@ export class Resource<
|
|||||||
this.request = new Promise(res => {
|
this.request = new Promise(res => {
|
||||||
const audio = new Audio();
|
const audio = new Audio();
|
||||||
audio.src = data;
|
audio.src = data;
|
||||||
|
this.emit('loadstart', audio);
|
||||||
audio.addEventListener('load', () => {
|
audio.addEventListener('load', () => {
|
||||||
this.resource = audio;
|
this.resource = audio;
|
||||||
this.loaded = true;
|
this.loaded = true;
|
||||||
@ -115,6 +145,7 @@ export class Resource<
|
|||||||
this.format === 'text' ||
|
this.format === 'text' ||
|
||||||
this.format === 'arraybuffer'
|
this.format === 'arraybuffer'
|
||||||
) {
|
) {
|
||||||
|
this.emit('loadstart');
|
||||||
this.request = axios
|
this.request = axios
|
||||||
.get(data, { responseType: this.format })
|
.get(data, { responseType: this.format })
|
||||||
.then(v => {
|
.then(v => {
|
||||||
@ -124,6 +155,7 @@ export class Resource<
|
|||||||
return v;
|
return v;
|
||||||
});
|
});
|
||||||
} else if (this.format === 'zip') {
|
} else if (this.format === 'zip') {
|
||||||
|
this.emit('loadstart');
|
||||||
this.request = axios
|
this.request = axios
|
||||||
.get(data, { responseType: 'arraybuffer' })
|
.get(data, { responseType: 'arraybuffer' })
|
||||||
.then(v => {
|
.then(v => {
|
||||||
@ -147,6 +179,25 @@ export class Resource<
|
|||||||
return this.resource ?? null;
|
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 {
|
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) {
|
active(key: string[] | string) {
|
||||||
const keys = ensureArray(key);
|
const keys = ensureArray(key);
|
||||||
keys.forEach(v => this.get(v)?.active());
|
keys.forEach(v => this.get(v)?.active());
|
||||||
@ -183,7 +234,7 @@ class ResourceStore extends Map<string, Resource> {
|
|||||||
keys.forEach(v => this.get(v)?.destroy());
|
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) {
|
if (data instanceof Array) {
|
||||||
for (const [key, res] of data) {
|
for (const [key, res] of data) {
|
||||||
if (this.has(key)) {
|
if (this.has(key)) {
|
||||||
@ -201,13 +252,41 @@ class ResourceStore extends Map<string, Resource> {
|
|||||||
): Promise<ResourceData[T] | null> {
|
): Promise<ResourceData[T] | null> {
|
||||||
return this.get(key)?.getData() ?? 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 {
|
declare global {
|
||||||
interface AncTe {
|
interface AncTe {
|
||||||
/** 游戏资源 */
|
/** 游戏资源 */
|
||||||
resource: ResourceStore;
|
resource: ResourceStore<Exclude<ResourceType, 'zip'>>;
|
||||||
|
zipResource: ResourceStore<'zip'>;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ancTe.resource = new ResourceStore();
|
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": [],
|
"includes": [],
|
||||||
"zip": false
|
"zip": false
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user