mirror of
https://github.com/unanmed/HumanBreak.git
synced 2025-02-28 17:37:07 +08:00
资源加载,bgm和音效播放
This commit is contained in:
parent
6f59ea51ac
commit
5aed6393a2
@ -16,11 +16,25 @@ export default defineConfig({
|
||||
'resource.zip': [
|
||||
'autotiles/*',
|
||||
'tilesets/*',
|
||||
'materials/*',
|
||||
'images/*',
|
||||
'animates/*',
|
||||
'sounds/*',
|
||||
'fonts/*'
|
||||
],
|
||||
'weather.zip': [
|
||||
'materials/fog.png',
|
||||
'materials/cloud.png',
|
||||
'materials/sun.png'
|
||||
],
|
||||
'materials.zip': [
|
||||
'materials/animates.png',
|
||||
'materials/enemy48.png',
|
||||
'materials/enemys.png',
|
||||
'materials/icons.png',
|
||||
'materials/items.png',
|
||||
'materials/npc48.png',
|
||||
'materials/npcs.png',
|
||||
'materials/terrains.png'
|
||||
]
|
||||
}
|
||||
});
|
||||
|
@ -636,6 +636,13 @@ return '{' + [
|
||||
|
||||
|
||||
mainStyle_m
|
||||
: '主要样式设置:' '标题界面背景图:' EvalString BGNL? Newline
|
||||
'竖屏标题界面背景图:' EvalString BGNL? Newline
|
||||
'标题样式;可写 display: none 隐藏标题' EvalString BGNL? Newline
|
||||
'标题按钮样式:' EvalString BGNL? Newline
|
||||
'横屏状态栏背景;url(...) 0 0/100% 100% no-repeat 可将图片拉伸自适配' BGNL? Newline EvalString BGNL? Newline
|
||||
'竖屏状态栏背景:' EvalString BGNL? Newline
|
||||
'竖屏工具栏背景:' EvalString BGNL? Newline
|
||||
'楼层切换样式:' EvalString BGNL? Newline
|
||||
'状态栏颜色' ColorString Colour '边框颜色' ColorString Colour BGNL? Newline
|
||||
'选中框颜色' ColorString Colour '全局字体' EvalString BEND
|
||||
@ -645,7 +652,14 @@ tooltip : 主要样式设置
|
||||
default : ["project/images/bg.jpg", "project/images/bg.jpg", "color: white", "background-color: #32369F; opacity: 0.85; color: #FFFFFF; border: #FFFFFF 2px solid; caret-color: #FFD700;", "url(project/materials/ground.png) repeat", "url(project/materials/ground.png) repeat", "url(project/materials/ground.png) repeat", "background-color: black; color: white", "255,255,255,1", "rgba(255,255,255,1)", "204,204,204,1", "rgba(204,204,204,1)", "255,215,0,1", "rgba(255,215,0,1)", "Verdana"]
|
||||
helpUrl : /_docs/#/instruction
|
||||
var code = {
|
||||
floorChangingStyle: EvalString_0,
|
||||
startBackground: EvalString_0,
|
||||
startVerticalBackground: EvalString_1,
|
||||
startLogoStyle: EvalString_2,
|
||||
startButtonsStyle: EvalString_3,
|
||||
statusLeftBackground: EvalString_4,
|
||||
statusTopBackground: EvalString_5,
|
||||
toolsBackground: EvalString_6,
|
||||
floorChangingStyle: EvalString_7,
|
||||
statusBarColor: JSON.parse('['+ColorString_0+']'),
|
||||
borderColor: JSON.parse('['+ColorString_1+']'),
|
||||
selectColor: JSON.parse('['+ColorString_2+']'),
|
||||
|
@ -277,7 +277,7 @@ span#hard {
|
||||
box-sizing: border-box;
|
||||
-moz-box-sizing: border-box;
|
||||
-webkit-box-sizing: border-box;
|
||||
background: url(project/materials/ground.png) repeat;
|
||||
background: black;
|
||||
z-index: 185;
|
||||
display: none;
|
||||
top: 0;
|
||||
|
@ -56,6 +56,10 @@ const compress = type === 'dist';
|
||||
await fs.remove('./dist/_server');
|
||||
await fs.remove('./dist/editor.html');
|
||||
await fs.remove('./dist/server.cjs');
|
||||
|
||||
await fs.remove('./dist/project/materials/airwall.png');
|
||||
await fs.remove('./dist/project/materials/ground.png');
|
||||
await fs.remove('./dist/project/materials/icons_old.png');
|
||||
} catch {}
|
||||
|
||||
// 2. 压缩字体
|
||||
|
@ -254,7 +254,7 @@ async function writeFile(req: Request, res: Response) {
|
||||
if (name.endsWith('project/events.js')) doDeclaration('events', value);
|
||||
if (name.endsWith('project/items.js')) doDeclaration('items', value);
|
||||
if (name.endsWith('project/maps.js')) doDeclaration('maps', value);
|
||||
if (name.endsWith('project/data.js')) doDeclaration('data', value);
|
||||
if (name.endsWith('project/data.js')) writeDevResource(value);
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
res.end(
|
||||
@ -315,6 +315,44 @@ async function writeMultiFiles(req: Request, res: Response) {
|
||||
res.end();
|
||||
}
|
||||
|
||||
async function writeDevResource(data: string) {
|
||||
try {
|
||||
const buf = Buffer.from(data, 'base64');
|
||||
data = buf.toString('utf-8');
|
||||
const info = JSON.parse(data.split('\n').slice(1).join(''));
|
||||
const res: string[] = [];
|
||||
const icons = await fs.readFile('./public/project/icons.js', 'utf-8');
|
||||
const iconData = JSON.parse(icons.split('\n').slice(1).join(''));
|
||||
res.push(
|
||||
...info.main.animates.map((v: any) => `animates.${v}.animate`),
|
||||
...info.main.bgms.map((v: any) => `bgms.${v}`),
|
||||
...info.main.fonts.map((v: any) => `fonts.${v}.ttf`),
|
||||
...info.main.images.map((v: any) => `images.${v}`),
|
||||
...info.main.sounds.map((v: any) => `sounds.${v}`),
|
||||
...info.main.tilesets.map((v: any) => `tilesets.${v}`),
|
||||
...Object.keys(iconData.autotile).map(v => `autotiles.${v}.png`),
|
||||
...[
|
||||
'animates',
|
||||
'cloud',
|
||||
'enemy48',
|
||||
'enemys',
|
||||
'fog',
|
||||
'icons',
|
||||
'items',
|
||||
'keyboard',
|
||||
'npc48',
|
||||
'npcs',
|
||||
'sun',
|
||||
'terrains'
|
||||
].map(v => `materials.${v}.png`)
|
||||
);
|
||||
const text = JSON.stringify(res, void 0, 4);
|
||||
await fs.writeFile('./src/data/resource-dev.json', text, 'utf-8');
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 声明某种类型
|
||||
* @param {string} type 类型
|
||||
|
@ -44,6 +44,7 @@ export class AudioPlayer extends EventEmitter<AudioPlayerEvent> {
|
||||
async update(data: ArrayBuffer) {
|
||||
this.data = data;
|
||||
this.buffer = await ac.decodeAudioData(data);
|
||||
|
||||
this.emit('update', this.buffer);
|
||||
}
|
||||
|
||||
@ -61,9 +62,10 @@ export class AudioPlayer extends EventEmitter<AudioPlayerEvent> {
|
||||
* 播放音频
|
||||
*/
|
||||
play(when?: number, offset?: number, duration?: number) {
|
||||
if (!this.source) return;
|
||||
this.ready();
|
||||
this.source?.start(when, offset, duration);
|
||||
if (!this.source) return;
|
||||
|
||||
this.source.start(when, offset, duration);
|
||||
|
||||
const source = this.source;
|
||||
this.source?.addEventListener('ended', ev => {
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { has } from '../../plugin/utils';
|
||||
import { ResourceController } from '../loader/controller';
|
||||
|
||||
class BgmController extends ResourceController<HTMLAudioElement> {
|
||||
export class BgmController extends ResourceController<HTMLAudioElement> {
|
||||
playing?: BgmIds;
|
||||
|
||||
/**
|
||||
@ -27,6 +27,7 @@ class BgmController extends ResourceController<HTMLAudioElement> {
|
||||
const bgm = this.get(id);
|
||||
bgm.currentTime = when;
|
||||
bgm.play();
|
||||
this.playing = id;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -48,13 +49,6 @@ class BgmController extends ResourceController<HTMLAudioElement> {
|
||||
}
|
||||
|
||||
get(id: BgmIds) {
|
||||
return this.list[`bgm.${id}`];
|
||||
return this.list[`bgms.${id}`];
|
||||
}
|
||||
}
|
||||
|
||||
declare global {
|
||||
interface AncTe {
|
||||
bgm: BgmController;
|
||||
}
|
||||
}
|
||||
ancTe.bgm = new BgmController();
|
||||
|
@ -132,7 +132,10 @@ export class SoundEffect extends AudioPlayer {
|
||||
}
|
||||
}
|
||||
|
||||
class SoundController extends ResourceController<ArrayBuffer, SoundEffect> {
|
||||
export class SoundController extends ResourceController<
|
||||
ArrayBuffer,
|
||||
SoundEffect
|
||||
> {
|
||||
private seIndex: Record<number, SoundEffect> = {};
|
||||
|
||||
/**
|
||||
@ -196,10 +199,3 @@ class SoundController extends ResourceController<ArrayBuffer, SoundEffect> {
|
||||
return this.list[`sounds.${sound}`];
|
||||
}
|
||||
}
|
||||
|
||||
declare global {
|
||||
interface AncTe {
|
||||
sound: SoundController;
|
||||
}
|
||||
}
|
||||
ancTe.sound = new SoundController();
|
||||
|
@ -1,11 +1,32 @@
|
||||
import { BgmController } from './audio/bgm';
|
||||
import { SoundController } from './audio/sound';
|
||||
import { readyAllResource } from './loader/load';
|
||||
import { ResourceStore, ResourceType } from './loader/resource';
|
||||
|
||||
export {};
|
||||
|
||||
declare global {
|
||||
interface AncTe {}
|
||||
interface AncTe {
|
||||
sound: SoundController;
|
||||
/** 游戏资源 */
|
||||
resource: ResourceStore<Exclude<ResourceType, 'zip'>>;
|
||||
zipResource: ResourceStore<'zip'>;
|
||||
bgm: BgmController;
|
||||
}
|
||||
interface Window {
|
||||
readonly ancTe: AncTe;
|
||||
ancTe: AncTe;
|
||||
}
|
||||
const ancTe: AncTe;
|
||||
}
|
||||
// @ts-ignore
|
||||
window.ancTe = {};
|
||||
|
||||
function ready() {
|
||||
window.ancTe = {
|
||||
bgm: new BgmController(),
|
||||
resource: new ResourceStore(),
|
||||
zipResource: new ResourceStore(),
|
||||
sound: new SoundController()
|
||||
};
|
||||
|
||||
readyAllResource();
|
||||
}
|
||||
ready();
|
||||
|
@ -7,7 +7,7 @@ const info = resource;
|
||||
* 构建游戏包后的加载
|
||||
*/
|
||||
export function readyAllResource() {
|
||||
if (main.RESOURCE_TYPE === 'dev') return readyDevResource();
|
||||
/* @__PURE__ */ if (main.RESOURCE_TYPE === 'dev') return readyDevResource();
|
||||
info.resource.forEach(v => {
|
||||
const type = getTypeByResource(v);
|
||||
if (type === 'zip') {
|
||||
@ -21,4 +21,14 @@ export function readyAllResource() {
|
||||
/**
|
||||
* 开发时的加载
|
||||
*/
|
||||
function readyDevResource() {}
|
||||
/* @__PURE__ */ async function readyDevResource() {
|
||||
const loadData = (await import('../../data/resource-dev.json')).default;
|
||||
|
||||
loadData.forEach(v => {
|
||||
const type = getTypeByResource(v);
|
||||
if (type !== 'zip') {
|
||||
ancTe.resource.set(v, new Resource(v, type));
|
||||
}
|
||||
});
|
||||
ancTe.resource.forEach(v => v.active());
|
||||
}
|
||||
|
@ -37,12 +37,13 @@ export class Resource<
|
||||
constructor(resource: string, format: T) {
|
||||
super(resource);
|
||||
this.data = this.resolveUrl(resource);
|
||||
|
||||
this.format = format;
|
||||
this.uri = resource;
|
||||
|
||||
this.once('active', this.load);
|
||||
this.once('load', this.onLoad);
|
||||
this.once('loadstart', this.onLoadStart);
|
||||
this.once('active', () => this.load());
|
||||
this.once('load', v => this.onLoad(v));
|
||||
this.once('loadstart', v => this.onLoadStart(v));
|
||||
}
|
||||
|
||||
protected onLoadStart(v?: ResourceData[T]) {
|
||||
@ -242,7 +243,10 @@ export class ZippedResource extends EventEmitter<ZippedEvent> {
|
||||
}
|
||||
}
|
||||
|
||||
class ResourceStore<T extends ResourceType> extends Map<string, Resource<T>> {
|
||||
export 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());
|
||||
@ -301,14 +305,3 @@ export function getZipFormatByType(type: ResourceType): 'arraybuffer' | 'text' {
|
||||
if (type === 'text' || type === 'json') return 'text';
|
||||
else return 'arraybuffer';
|
||||
}
|
||||
|
||||
declare global {
|
||||
interface AncTe {
|
||||
/** 游戏资源 */
|
||||
resource: ResourceStore<Exclude<ResourceType, 'zip'>>;
|
||||
zipResource: ResourceStore<'zip'>;
|
||||
}
|
||||
}
|
||||
|
||||
ancTe.resource = new ResourceStore();
|
||||
ancTe.zipResource = new ResourceStore();
|
||||
|
145
src/data/resource-dev.json
Normal file
145
src/data/resource-dev.json
Normal file
@ -0,0 +1,145 @@
|
||||
[
|
||||
"animates.amazed.animate",
|
||||
"animates.angry.animate",
|
||||
"animates.angry2.animate",
|
||||
"animates.bulb.animate",
|
||||
"animates.emm.animate",
|
||||
"animates.explosion1.animate",
|
||||
"animates.explosion2.animate",
|
||||
"animates.explosion3.animate",
|
||||
"animates.explosion4.animate",
|
||||
"animates.fire.animate",
|
||||
"animates.focus.animate",
|
||||
"animates.fret.animate",
|
||||
"animates.hand.animate",
|
||||
"animates.ice.animate",
|
||||
"animates.jianji.animate",
|
||||
"animates.luv.animate",
|
||||
"animates.magicAtk.animate",
|
||||
"animates.stone.animate",
|
||||
"animates.sweat.animate",
|
||||
"animates.sweat2.animate",
|
||||
"animates.sword.animate",
|
||||
"animates.zone.animate",
|
||||
"bgms.beforeBoss.mp3",
|
||||
"bgms.cave.mp3",
|
||||
"bgms.escape.mp3",
|
||||
"bgms.grass.mp3",
|
||||
"bgms.mount.mp3",
|
||||
"bgms.plot1.mp3",
|
||||
"bgms.road.mp3",
|
||||
"bgms.title.mp3",
|
||||
"bgms.tower.mp3",
|
||||
"bgms.towerBoss.mp3",
|
||||
"bgms.towerBoss2.mp3",
|
||||
"bgms.towerBoss3.mp3",
|
||||
"bgms.winter.mp3",
|
||||
"bgms.winterTown.mp3",
|
||||
"fonts.normal.ttf",
|
||||
"images.IQ.png",
|
||||
"images.arrow.png",
|
||||
"images.atk.png",
|
||||
"images.bg.jpg",
|
||||
"images.boom.png",
|
||||
"images.botton.png",
|
||||
"images.cave2.jpg",
|
||||
"images.def.png",
|
||||
"images.exp.png",
|
||||
"images.hero1.png",
|
||||
"images.hero2.png",
|
||||
"images.hp.png",
|
||||
"images.money.png",
|
||||
"images.skill.png",
|
||||
"images.skill0.png",
|
||||
"images.skill1.png",
|
||||
"images.skill10.png",
|
||||
"images.skill11.png",
|
||||
"images.skill12.png",
|
||||
"images.skill13.png",
|
||||
"images.skill14.png",
|
||||
"images.skill2.png",
|
||||
"images.skill3.png",
|
||||
"images.skill4.png",
|
||||
"images.skill5.png",
|
||||
"images.skill6.png",
|
||||
"images.skill7.png",
|
||||
"images.skill8.png",
|
||||
"images.skill9.png",
|
||||
"images.title.jpg",
|
||||
"images.tower.jpg",
|
||||
"images.tower7.jpeg",
|
||||
"images.winskin.png",
|
||||
"images.winskin2.png",
|
||||
"images.winskin3.png",
|
||||
"sounds.008-System08.ogg",
|
||||
"sounds.015-Jump01.ogg",
|
||||
"sounds.050-Explosion03.ogg",
|
||||
"sounds.051-Explosion04.ogg",
|
||||
"sounds.087-Action02.ogg",
|
||||
"sounds.094-Attack06.ogg",
|
||||
"sounds.118-Fire02.ogg",
|
||||
"sounds.119-Fire03.ogg",
|
||||
"sounds.120-Ice01.ogg",
|
||||
"sounds.arrow.mp3",
|
||||
"sounds.attack.mp3",
|
||||
"sounds.bomb.mp3",
|
||||
"sounds.cancel.mp3",
|
||||
"sounds.centerFly.mp3",
|
||||
"sounds.chapter.mp3",
|
||||
"sounds.confirm.mp3",
|
||||
"sounds.cursor.mp3",
|
||||
"sounds.danger.mp3",
|
||||
"sounds.door.mp3",
|
||||
"sounds.drink.mp3",
|
||||
"sounds.electron.mp3",
|
||||
"sounds.equip.mp3",
|
||||
"sounds.error.mp3",
|
||||
"sounds.floor.mp3",
|
||||
"sounds.item.mp3",
|
||||
"sounds.jump.mp3",
|
||||
"sounds.load.mp3",
|
||||
"sounds.open_ui.mp3",
|
||||
"sounds.paper.mp3",
|
||||
"sounds.pickaxe.mp3",
|
||||
"sounds.quake.mp3",
|
||||
"sounds.recovery.mp3",
|
||||
"sounds.save.mp3",
|
||||
"sounds.shake.mp3",
|
||||
"sounds.shop.mp3",
|
||||
"sounds.thunder.mp3",
|
||||
"sounds.tree.mp3",
|
||||
"sounds.zone.mp3",
|
||||
"tilesets.magictower.png",
|
||||
"tilesets.043-Cave01.png",
|
||||
"tilesets.004-Mountain01.png",
|
||||
"tilesets.Map-Tower01.png",
|
||||
"tilesets.Caverna1.png",
|
||||
"tilesets.map-tower.png",
|
||||
"tilesets.winter1.png",
|
||||
"tilesets.snowTown.png",
|
||||
"tilesets.room.png",
|
||||
"autotiles.autotile.png",
|
||||
"autotiles.autotile1.png",
|
||||
"autotiles.autotile2.png",
|
||||
"autotiles.autotile3.png",
|
||||
"autotiles.autotile4.png",
|
||||
"autotiles.autotile5.png",
|
||||
"autotiles.autotile6.png",
|
||||
"autotiles.autotile7.png",
|
||||
"autotiles.autotile8.png",
|
||||
"autotiles.autotile9.png",
|
||||
"autotiles.autotile10.png",
|
||||
"autotiles.autotile11.png",
|
||||
"materials.animates.png",
|
||||
"materials.cloud.png",
|
||||
"materials.enemy48.png",
|
||||
"materials.enemys.png",
|
||||
"materials.fog.png",
|
||||
"materials.icons.png",
|
||||
"materials.items.png",
|
||||
"materials.keyboard.png",
|
||||
"materials.npc48.png",
|
||||
"materials.npcs.png",
|
||||
"materials.sun.png",
|
||||
"materials.terrains.png"
|
||||
]
|
@ -1,6 +1,9 @@
|
||||
{
|
||||
"resource": [
|
||||
"zip.resource.zip",
|
||||
"zip.weather.zip",
|
||||
"zip.materials.zip",
|
||||
"materials.keyboard.png",
|
||||
"bgms.tower.mp3",
|
||||
"bgms.cave.mp3",
|
||||
"bgms.mount.mp3",
|
||||
|
@ -4,6 +4,7 @@ import App2 from './App2.vue';
|
||||
import './styles.less';
|
||||
import 'ant-design-vue/dist/antd.dark.css';
|
||||
import './initPlugin';
|
||||
import './core/index';
|
||||
|
||||
createApp(App).mount('#root');
|
||||
createApp(App2).mount('#root2');
|
||||
|
@ -2,7 +2,7 @@ import { message } from 'ant-design-vue';
|
||||
import { MessageApi } from 'ant-design-vue/lib/message';
|
||||
import { isNil } from 'lodash-es';
|
||||
import { Animation, sleep, TimingFn } from 'mutate-animate';
|
||||
import { ComputedRef, ref } from 'vue';
|
||||
import { ref } from 'vue';
|
||||
import { EVENT_KEY_CODE_MAP } from './keyCodes';
|
||||
import axios from 'axios';
|
||||
import { decompressFromBase64 } from 'lz-string';
|
||||
@ -211,15 +211,13 @@ export async function doByInterval(
|
||||
interval: number,
|
||||
awaitFirst: boolean = false
|
||||
) {
|
||||
for await (const fn of funcs) {
|
||||
if (awaitFirst) {
|
||||
await sleep(interval);
|
||||
}
|
||||
for await (const fn of funcs) {
|
||||
fn();
|
||||
if (!awaitFirst) {
|
||||
await sleep(interval);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
6
src/types/loader.d.ts
vendored
6
src/types/loader.d.ts
vendored
@ -22,7 +22,11 @@ interface Loader {
|
||||
* @param imgName 图片名称
|
||||
* @param callback 加载完毕的回调函数
|
||||
*/
|
||||
loadImage(dir: string, imgName: string, callback?: () => void): void;
|
||||
loadImage(
|
||||
dir: string,
|
||||
imgName: string,
|
||||
callback?: (name: string, img: HTMLImageElement) => void
|
||||
): void;
|
||||
|
||||
/**
|
||||
* 从zip中加载一系列图片
|
||||
|
Loading…
Reference in New Issue
Block a user