mirror of
https://github.com/unanmed/HumanBreak.git
synced 2025-04-28 10:13:25 +08:00
图片加载
This commit is contained in:
parent
2e0770ae71
commit
e947a1e6e8
@ -19,7 +19,11 @@ function core() {
|
|||||||
this.__HALF_SIZE__ = Math.floor(this.__SIZE__ / 2);
|
this.__HALF_SIZE__ = Math.floor(this.__SIZE__ / 2);
|
||||||
this.material = {
|
this.material = {
|
||||||
animates: {},
|
animates: {},
|
||||||
images: {},
|
images: {
|
||||||
|
images: {},
|
||||||
|
autotile: {},
|
||||||
|
tilesets: {}
|
||||||
|
},
|
||||||
bgms: {},
|
bgms: {},
|
||||||
sounds: {},
|
sounds: {},
|
||||||
items: {},
|
items: {},
|
||||||
|
@ -115,6 +115,7 @@ loader.prototype._load_async = function (callback) {
|
|||||||
// ----- 加载资源文件 ------ //
|
// ----- 加载资源文件 ------ //
|
||||||
|
|
||||||
loader.prototype._loadMaterials_sync = function (callback) {
|
loader.prototype._loadMaterials_sync = function (callback) {
|
||||||
|
callback();
|
||||||
this._setStartLoadTipText('正在加载资源文件...');
|
this._setStartLoadTipText('正在加载资源文件...');
|
||||||
this.loadImages(
|
this.loadImages(
|
||||||
'materials',
|
'materials',
|
||||||
@ -122,7 +123,6 @@ loader.prototype._loadMaterials_sync = function (callback) {
|
|||||||
core.material.images,
|
core.material.images,
|
||||||
function () {
|
function () {
|
||||||
core.loader._loadMaterials_afterLoad();
|
core.loader._loadMaterials_afterLoad();
|
||||||
callback();
|
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
@ -154,14 +154,7 @@ loader.prototype._loadMaterials_afterLoad = function () {
|
|||||||
// ------ 加载使用的图片 ------ //
|
// ------ 加载使用的图片 ------ //
|
||||||
|
|
||||||
loader.prototype._loadExtraImages_sync = function (callback) {
|
loader.prototype._loadExtraImages_sync = function (callback) {
|
||||||
core.material.images.images = {};
|
callback();
|
||||||
this._setStartLoadTipText('正在加载图片文件...');
|
|
||||||
core.loadImages(
|
|
||||||
'images',
|
|
||||||
core.images,
|
|
||||||
core.material.images.images,
|
|
||||||
callback
|
|
||||||
);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
loader.prototype._loadExtraImages_async = function (onprogress, onfinished) {
|
loader.prototype._loadExtraImages_async = function (onprogress, onfinished) {
|
||||||
@ -196,15 +189,7 @@ loader.prototype._loadExtraImages_async = function (onprogress, onfinished) {
|
|||||||
// ------ 加载自动元件 ------ //
|
// ------ 加载自动元件 ------ //
|
||||||
|
|
||||||
loader.prototype._loadAutotiles_sync = function (callback) {
|
loader.prototype._loadAutotiles_sync = function (callback) {
|
||||||
core.material.images.autotile = {};
|
callback();
|
||||||
var keys = Object.keys(core.material.icons.autotile);
|
|
||||||
var autotiles = {};
|
|
||||||
|
|
||||||
this._setStartLoadTipText('正在加载自动元件...');
|
|
||||||
this.loadImages('autotiles', keys, autotiles, function () {
|
|
||||||
core.loader._loadAutotiles_afterLoad(keys, autotiles);
|
|
||||||
callback();
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
loader.prototype._loadAutotiles_async = function (onprogress, onfinished) {
|
loader.prototype._loadAutotiles_async = function (onprogress, onfinished) {
|
||||||
@ -224,30 +209,12 @@ loader.prototype._loadAutotiles_async = function (onprogress, onfinished) {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
loader.prototype._loadAutotiles_afterLoad = function (keys, autotiles) {
|
loader.prototype._loadAutotiles_afterLoad = function (keys, autotiles) {};
|
||||||
// autotile需要保证顺序
|
|
||||||
keys.forEach(function (v) {
|
|
||||||
core.material.images.autotile[v] = autotiles[v];
|
|
||||||
});
|
|
||||||
|
|
||||||
setTimeout(function () {
|
|
||||||
core.maps._makeAutotileEdges();
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
// ------ 加载额外素材 ------ //
|
// ------ 加载额外素材 ------ //
|
||||||
|
|
||||||
loader.prototype._loadTilesets_sync = function (callback) {
|
loader.prototype._loadTilesets_sync = function (callback) {
|
||||||
core.material.images.tilesets = {};
|
callback();
|
||||||
this._setStartLoadTipText('正在加载额外素材...');
|
|
||||||
this.loadImages(
|
|
||||||
'tilesets',
|
|
||||||
core.tilesets,
|
|
||||||
core.material.images.tilesets,
|
|
||||||
function () {
|
|
||||||
callback();
|
|
||||||
}
|
|
||||||
);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
loader.prototype._loadTilesets_async = function (onprogress, onfinished) {
|
loader.prototype._loadTilesets_async = function (onprogress, onfinished) {
|
||||||
@ -266,26 +233,7 @@ loader.prototype._loadTilesets_async = function (onprogress, onfinished) {
|
|||||||
// ------ 实际加载一系列图片 ------ //
|
// ------ 实际加载一系列图片 ------ //
|
||||||
|
|
||||||
loader.prototype.loadImages = function (dir, names, toSave, callback) {
|
loader.prototype.loadImages = function (dir, names, toSave, callback) {
|
||||||
if (!names || names.length == 0) {
|
return callback();
|
||||||
if (callback) callback();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
var items = 0;
|
|
||||||
for (var i = 0; i < names.length; i++) {
|
|
||||||
this.loadImage(dir, names[i], function (id, image) {
|
|
||||||
core.loader._setStartLoadTipText('正在加载图片 ' + id + '...');
|
|
||||||
if (toSave[id] !== undefined) {
|
|
||||||
if (image != null) toSave[id] = image;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
toSave[id] = image;
|
|
||||||
items++;
|
|
||||||
core.loader._setStartProgressVal(items * (100 / names.length));
|
|
||||||
if (items == names.length) {
|
|
||||||
if (callback) callback();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
loader.prototype.loadImage = function (dir, imgName, callback) {
|
loader.prototype.loadImage = function (dir, imgName, callback) {
|
||||||
|
@ -336,10 +336,15 @@ main.prototype.loadAsync = async function (mode, callback) {
|
|||||||
// 加载核心js代码
|
// 加载核心js代码
|
||||||
if (main.useCompress) {
|
if (main.useCompress) {
|
||||||
await main.loadScript(`libs/libs.min.js?v=${main.version}`);
|
await main.loadScript(`libs/libs.min.js?v=${main.version}`);
|
||||||
|
main.loading.emit('coreLoaded');
|
||||||
} else {
|
} else {
|
||||||
await Promise.all(
|
await Promise.all(
|
||||||
main.loadList.map(v =>
|
main.loadList.map(v =>
|
||||||
main.loadScript(`libs/${v}.js?v=${main.version}`)
|
main.loadScript(`libs/${v}.js?v=${main.version}`).then(vv => {
|
||||||
|
if (v === 'core') {
|
||||||
|
main.loading.emit('coreLoaded');
|
||||||
|
}
|
||||||
|
})
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -398,6 +403,8 @@ main.prototype.loadAsync = async function (mode, callback) {
|
|||||||
coreData[t] = main[t];
|
coreData[t] = main[t];
|
||||||
});
|
});
|
||||||
await core.init(coreData, callback);
|
await core.init(coreData, callback);
|
||||||
|
main.loading.emit('coreInit');
|
||||||
|
|
||||||
core.resize();
|
core.resize();
|
||||||
|
|
||||||
main.core = core;
|
main.core = core;
|
||||||
|
@ -5,16 +5,19 @@ export interface EmitableEvent {
|
|||||||
interface Listener<T extends (...params: any) => any> {
|
interface Listener<T extends (...params: any) => any> {
|
||||||
fn: T;
|
fn: T;
|
||||||
once?: boolean;
|
once?: boolean;
|
||||||
|
immediate?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface ListenerOptions {
|
interface ListenerOptions {
|
||||||
once: boolean;
|
once: boolean;
|
||||||
|
immediate: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class EventEmitter<T extends EmitableEvent = {}> {
|
export class EventEmitter<T extends EmitableEvent = {}> {
|
||||||
private events: {
|
private events: {
|
||||||
[P in keyof T]?: Listener<T[P]>[];
|
[P in keyof T]?: Listener<T[P]>[];
|
||||||
} = {};
|
} = {};
|
||||||
|
private emitted: (keyof T)[] = [];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 监听某个事件
|
* 监听某个事件
|
||||||
@ -27,6 +30,16 @@ export class EventEmitter<T extends EmitableEvent = {}> {
|
|||||||
fn: T[K],
|
fn: T[K],
|
||||||
options?: Partial<ListenerOptions>
|
options?: Partial<ListenerOptions>
|
||||||
) {
|
) {
|
||||||
|
if (options?.immediate && this.emitted.includes(event)) {
|
||||||
|
fn();
|
||||||
|
if (!options.once) {
|
||||||
|
this.events[event] ??= [];
|
||||||
|
this.events[event]?.push({
|
||||||
|
fn
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
this.events[event] ??= [];
|
this.events[event] ??= [];
|
||||||
this.events[event]?.push({
|
this.events[event]?.push({
|
||||||
fn,
|
fn,
|
||||||
@ -60,6 +73,9 @@ export class EventEmitter<T extends EmitableEvent = {}> {
|
|||||||
* @param params 传入的参数
|
* @param params 传入的参数
|
||||||
*/
|
*/
|
||||||
emit<K extends keyof T>(event: K, ...params: Parameters<T[K]>) {
|
emit<K extends keyof T>(event: K, ...params: Parameters<T[K]>) {
|
||||||
|
if (!this.emitted.includes(event)) {
|
||||||
|
this.emitted.push(event);
|
||||||
|
}
|
||||||
const events = (this.events[event] ??= []);
|
const events = (this.events[event] ??= []);
|
||||||
for (let i = 0; i < events.length; i++) {
|
for (let i = 0; i < events.length; i++) {
|
||||||
const e = events[i];
|
const e = events[i];
|
||||||
|
@ -3,8 +3,6 @@ import { SoundController } from './audio/sound';
|
|||||||
import { readyAllResource } from './loader/load';
|
import { readyAllResource } from './loader/load';
|
||||||
import { ResourceStore, ResourceType } from './loader/resource';
|
import { ResourceStore, ResourceType } from './loader/resource';
|
||||||
|
|
||||||
export {};
|
|
||||||
|
|
||||||
declare global {
|
declare global {
|
||||||
interface AncTe {
|
interface AncTe {
|
||||||
sound: SoundController;
|
sound: SoundController;
|
||||||
|
@ -1,6 +1,15 @@
|
|||||||
import resource from '../../data/resource.json';
|
import resource from '../../data/resource.json';
|
||||||
|
import { has } from '../../plugin/utils';
|
||||||
|
import { EmitableEvent, EventEmitter } from '../common/eventEmitter';
|
||||||
import { Resource, getTypeByResource } from './resource';
|
import { Resource, getTypeByResource } from './resource';
|
||||||
|
|
||||||
|
interface GameLoadEvent extends EmitableEvent {
|
||||||
|
coreLoaded: () => void;
|
||||||
|
autotileLoaded: () => void;
|
||||||
|
coreInit: () => void;
|
||||||
|
materialLoaded: () => void;
|
||||||
|
}
|
||||||
|
|
||||||
const info = resource;
|
const info = resource;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -32,3 +41,79 @@ export function readyAllResource() {
|
|||||||
});
|
});
|
||||||
ancTe.resource.forEach(v => v.active());
|
ancTe.resource.forEach(v => v.active());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class GameLoading extends EventEmitter<GameLoadEvent> {
|
||||||
|
private autotileLoaded: number = 0;
|
||||||
|
private autotileNum?: number;
|
||||||
|
private autotileListened: boolean = false;
|
||||||
|
|
||||||
|
private materialsNum: number = main.materials.length;
|
||||||
|
private materialsLoaded: number = 0;
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
this.on(
|
||||||
|
'coreInit',
|
||||||
|
() => {
|
||||||
|
this.autotileNum = Object.keys(
|
||||||
|
core.material.icons.autotile
|
||||||
|
).length;
|
||||||
|
},
|
||||||
|
{ immediate: true }
|
||||||
|
);
|
||||||
|
this.on('materialLoaded', () => {
|
||||||
|
core.loader._loadMaterials_afterLoad();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
addMaterialLoaded() {
|
||||||
|
this.once('coreInit', () => {
|
||||||
|
this.materialsLoaded++;
|
||||||
|
if (this.materialsLoaded === this.materialsNum) {
|
||||||
|
this.emit('materialLoaded');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
addAutotileLoaded() {
|
||||||
|
this.once('coreInit', () => {
|
||||||
|
this.autotileLoaded++;
|
||||||
|
if (this.autotileLoaded === this.autotileNum) {
|
||||||
|
this.emit('autotileLoaded');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 当自动原件加载完毕时
|
||||||
|
* @param autotiles 自动原件数组
|
||||||
|
*/
|
||||||
|
onAutotileLoaded(
|
||||||
|
autotiles: Partial<Record<AllIdsOf<'autotile'>, HTMLImageElement>>
|
||||||
|
) {
|
||||||
|
if (this.autotileListened) return;
|
||||||
|
this.autotileListened = true;
|
||||||
|
this.on('autotileLoaded', () => {
|
||||||
|
const keys = Object.keys(
|
||||||
|
core.material.icons.autotile
|
||||||
|
) as AllIdsOf<'autotile'>[];
|
||||||
|
|
||||||
|
keys.forEach(v => {
|
||||||
|
core.material.images.autotile[v] = autotiles[v]!;
|
||||||
|
});
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
core.maps._makeAutotileEdges();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const loading = new GameLoading();
|
||||||
|
|
||||||
|
declare global {
|
||||||
|
interface Main {
|
||||||
|
loading: EventEmitter<GameLoadEvent>;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
main.loading = loading;
|
||||||
|
@ -4,6 +4,7 @@ import { ensureArray } from '../../plugin/utils';
|
|||||||
import { has } from '../../plugin/utils';
|
import { has } from '../../plugin/utils';
|
||||||
import JSZip from 'jszip';
|
import JSZip from 'jszip';
|
||||||
import { EmitableEvent, EventEmitter } from '../common/eventEmitter';
|
import { EmitableEvent, EventEmitter } from '../common/eventEmitter';
|
||||||
|
import { loading } from './load';
|
||||||
|
|
||||||
interface ResourceData {
|
interface ResourceData {
|
||||||
image: HTMLImageElement;
|
image: HTMLImageElement;
|
||||||
@ -17,6 +18,8 @@ interface ResourceData {
|
|||||||
export type ResourceType = keyof ResourceData;
|
export type ResourceType = keyof ResourceData;
|
||||||
export type NonZipResource = Exclude<ResourceType, 'zip'>;
|
export type NonZipResource = Exclude<ResourceType, 'zip'>;
|
||||||
|
|
||||||
|
const autotiles: Partial<Record<AllIdsOf<'autotile'>, HTMLImageElement>> = {};
|
||||||
|
|
||||||
export class Resource<
|
export class Resource<
|
||||||
T extends ResourceType = ResourceType
|
T extends ResourceType = ResourceType
|
||||||
> extends Disposable<string> {
|
> extends Disposable<string> {
|
||||||
@ -59,6 +62,42 @@ export class Resource<
|
|||||||
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.uri, v as ArrayBuffer);
|
ancTe.sound.add(this.uri, v as ArrayBuffer);
|
||||||
|
} else if (this.type === 'images') {
|
||||||
|
const name = `${this.name}${this.ext}` as ImageIds;
|
||||||
|
loading.on(
|
||||||
|
'coreLoaded',
|
||||||
|
() => {
|
||||||
|
core.material.images.images[name] = v as HTMLImageElement;
|
||||||
|
},
|
||||||
|
{ immediate: true }
|
||||||
|
);
|
||||||
|
} else if (this.type === 'materials') {
|
||||||
|
const name = this.name as SelectKey<
|
||||||
|
MaterialImages,
|
||||||
|
HTMLImageElement
|
||||||
|
>;
|
||||||
|
|
||||||
|
loading.on(
|
||||||
|
'coreLoaded',
|
||||||
|
() => {
|
||||||
|
core.material.images[name] = v;
|
||||||
|
},
|
||||||
|
{ immediate: true }
|
||||||
|
);
|
||||||
|
} else if (this.type === 'autotiles') {
|
||||||
|
const name = this.name as AllIdsOf<'autotile'>;
|
||||||
|
autotiles[name] = v;
|
||||||
|
loading.addAutotileLoaded();
|
||||||
|
loading.onAutotileLoaded(autotiles);
|
||||||
|
} else if (this.type === 'tilesets') {
|
||||||
|
const name = `${this.name}${this.ext}`;
|
||||||
|
loading.on(
|
||||||
|
'coreLoaded',
|
||||||
|
() => {
|
||||||
|
core.material.images.tilesets[name] = v;
|
||||||
|
},
|
||||||
|
{ immediate: true }
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 资源加载类型处理
|
// 资源加载类型处理
|
||||||
|
2
src/types/core.d.ts
vendored
2
src/types/core.d.ts
vendored
@ -810,7 +810,7 @@ type CoreStatusBarElements = {
|
|||||||
readonly [key: string]: HTMLElement;
|
readonly [key: string]: HTMLElement;
|
||||||
};
|
};
|
||||||
|
|
||||||
type Materails = [
|
type Materials = [
|
||||||
'animates',
|
'animates',
|
||||||
'enemys',
|
'enemys',
|
||||||
'items',
|
'items',
|
||||||
|
2
src/types/loader.d.ts
vendored
2
src/types/loader.d.ts
vendored
@ -64,6 +64,8 @@ interface Loader {
|
|||||||
* @param name 要释放的bgm的id或名称
|
* @param name 要释放的bgm的id或名称
|
||||||
*/
|
*/
|
||||||
freeBgm(name: BgmIds | NameMapIn<BgmIds>): void;
|
freeBgm(name: BgmIds | NameMapIn<BgmIds>): void;
|
||||||
|
|
||||||
|
_loadMaterials_afterLoad(): void;
|
||||||
}
|
}
|
||||||
|
|
||||||
declare const loader: new () => Loader;
|
declare const loader: new () => Loader;
|
||||||
|
2
src/types/map.d.ts
vendored
2
src/types/map.d.ts
vendored
@ -1376,6 +1376,8 @@ interface Maps {
|
|||||||
* @param doCallback 是否执行该动画的回调函数
|
* @param doCallback 是否执行该动画的回调函数
|
||||||
*/
|
*/
|
||||||
stopAnimate(id?: number, doCallback?: boolean): void;
|
stopAnimate(id?: number, doCallback?: boolean): void;
|
||||||
|
|
||||||
|
_makeAutotileEdges(): void;
|
||||||
}
|
}
|
||||||
|
|
||||||
declare const maps: new () => Maps;
|
declare const maps: new () => Maps;
|
||||||
|
Loading…
Reference in New Issue
Block a user