mirror of
https://github.com/unanmed/HumanBreak.git
synced 2025-01-31 23:29:27 +08:00
feat: 构建版本加载
This commit is contained in:
parent
684fba1475
commit
4d5f14e8a5
@ -601,18 +601,18 @@ core.prototype._init_others = function () {
|
|||||||
);
|
);
|
||||||
core.bigmap.tempCanvas = document.createElement('canvas').getContext('2d');
|
core.bigmap.tempCanvas = document.createElement('canvas').getContext('2d');
|
||||||
core.bigmap.cacheCanvas = document.createElement('canvas').getContext('2d');
|
core.bigmap.cacheCanvas = document.createElement('canvas').getContext('2d');
|
||||||
core.loadImage('materials', 'fog', function (name, img) {
|
// core.loadImage('materials', 'fog', function (name, img) {
|
||||||
core.animateFrame.weather.fog = img;
|
// core.animateFrame.weather.fog = img;
|
||||||
});
|
// });
|
||||||
core.loadImage('materials', 'cloud', function (name, img) {
|
// core.loadImage('materials', 'cloud', function (name, img) {
|
||||||
core.animateFrame.weather.cloud = img;
|
// core.animateFrame.weather.cloud = img;
|
||||||
});
|
// });
|
||||||
core.loadImage('materials', 'sun', function (name, img) {
|
// core.loadImage('materials', 'sun', function (name, img) {
|
||||||
core.animateFrame.weather.sun = img;
|
// core.animateFrame.weather.sun = img;
|
||||||
});
|
// });
|
||||||
core.loadImage('materials', 'keyboard', function (name, img) {
|
// core.loadImage('materials', 'keyboard', function (name, img) {
|
||||||
core.material.images.keyboard = img;
|
// core.material.images.keyboard = img;
|
||||||
});
|
// });
|
||||||
// 记录存档编号
|
// 记录存档编号
|
||||||
core.saves.saveIndex = core.getLocalStorage('saveIndex', 1);
|
core.saves.saveIndex = core.getLocalStorage('saveIndex', 1);
|
||||||
core.control.getSaveIndexes(function (indexes) {
|
core.control.getSaveIndexes(function (indexes) {
|
||||||
|
@ -215,15 +215,6 @@ function main() {
|
|||||||
|
|
||||||
this.__VERSION__ = '2.10.0';
|
this.__VERSION__ = '2.10.0';
|
||||||
this.__VERSION_CODE__ = 510;
|
this.__VERSION_CODE__ = 510;
|
||||||
|
|
||||||
this.timestamp = 0;
|
|
||||||
|
|
||||||
// 远程资源地址,在线游戏中,塔本体不包含任何资源,只包含源码,从而可以降低游戏本体的体积并平均分担资源包体积
|
|
||||||
// 从而可以优化加载并避免网站发布的大小限制
|
|
||||||
this.RESOURCE_TYPE = 'dev';
|
|
||||||
this.RESOURCE_URL = '';
|
|
||||||
this.RESOURCE_SYMBOL = '';
|
|
||||||
this.RESOURCE_INDEX = {};
|
|
||||||
}
|
}
|
||||||
// >>>> body end
|
// >>>> body end
|
||||||
|
|
||||||
@ -336,7 +327,7 @@ main.prototype.loadAsync = async function (mode, callback) {
|
|||||||
const mainData = data_a1e2fb4a_e986_4524_b0da_9b7ba7c0874d.main;
|
const mainData = data_a1e2fb4a_e986_4524_b0da_9b7ba7c0874d.main;
|
||||||
Object.assign(main, mainData);
|
Object.assign(main, mainData);
|
||||||
|
|
||||||
main.importFonts(main.fonts);
|
// main.importFonts(main.fonts);
|
||||||
|
|
||||||
// 加载核心js代码
|
// 加载核心js代码
|
||||||
if (main.useCompress) {
|
if (main.useCompress) {
|
||||||
@ -496,7 +487,6 @@ main.prototype.importFonts = function (fonts) {
|
|||||||
font +
|
font +
|
||||||
'"; src: url("project/fonts/' +
|
'"; src: url("project/fonts/' +
|
||||||
font +
|
font +
|
||||||
(main.pluginUseCompress ? '-' + main.timestamp : '') +
|
|
||||||
'.ttf") format("truetype"); }';
|
'.ttf") format("truetype"); }';
|
||||||
});
|
});
|
||||||
style.innerHTML = html;
|
style.innerHTML = html;
|
||||||
|
@ -8,12 +8,12 @@ import rollupBabel from '@rollup/plugin-babel';
|
|||||||
import terser from '@rollup/plugin-terser';
|
import terser from '@rollup/plugin-terser';
|
||||||
import resolve from '@rollup/plugin-node-resolve';
|
import resolve from '@rollup/plugin-node-resolve';
|
||||||
import commonjs from '@rollup/plugin-commonjs';
|
import commonjs from '@rollup/plugin-commonjs';
|
||||||
import { splitResorce } from './resource.js';
|
import { splitResource } from './resource.js';
|
||||||
import compressing from 'compressing';
|
import compressing from 'compressing';
|
||||||
|
|
||||||
const type = process.argv[2];
|
const type = process.argv[2];
|
||||||
const map = false;
|
const map = false;
|
||||||
const resorce = type !== 'dev';
|
const resorce = true;
|
||||||
const compress = type === 'dist';
|
const compress = type === 'dist';
|
||||||
|
|
||||||
(async function () {
|
(async function () {
|
||||||
@ -115,14 +115,6 @@ const compress = type === 'dist';
|
|||||||
})()
|
})()
|
||||||
)
|
)
|
||||||
]);
|
]);
|
||||||
await Promise.all([
|
|
||||||
...fonts.map(v => {
|
|
||||||
return fs.rename(
|
|
||||||
`./dist/project/fonts/${v}.ttf`,
|
|
||||||
`./dist/project/fonts/${v}-${timestamp}.ttf`
|
|
||||||
);
|
|
||||||
})
|
|
||||||
]);
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.log('字体压缩失败');
|
console.log('字体压缩失败');
|
||||||
console.log(e);
|
console.log(e);
|
||||||
@ -133,7 +125,7 @@ const compress = type === 'dist';
|
|||||||
await fs.remove('./dist/project/plugin.min.js');
|
await fs.remove('./dist/project/plugin.min.js');
|
||||||
|
|
||||||
const build = await rollup.rollup({
|
const build = await rollup.rollup({
|
||||||
input: 'src/plugin/game/index.js',
|
input: 'src/game/index.ts',
|
||||||
plugins: [
|
plugins: [
|
||||||
typescript({
|
typescript({
|
||||||
sourceMap: false
|
sourceMap: false
|
||||||
@ -163,12 +155,7 @@ const compress = type === 'dist';
|
|||||||
// 4. 压缩main.js
|
// 4. 压缩main.js
|
||||||
try {
|
try {
|
||||||
// 先获取不能压缩的部分
|
// 先获取不能压缩的部分
|
||||||
const main = (await fs.readFile('./public/main.js', 'utf-8'))
|
const main = await fs.readFile('./public/main.js', 'utf-8');
|
||||||
.replace(
|
|
||||||
/this.pluginUseCompress\s*=\s*false\;/,
|
|
||||||
'this.pluginUseCompress = true;'
|
|
||||||
)
|
|
||||||
.replace('this.timestamp = 0', `this.timestamp = ${timestamp};`);
|
|
||||||
|
|
||||||
const endIndex = main.indexOf('// >>>> body end');
|
const endIndex = main.indexOf('// >>>> body end');
|
||||||
const nonCompress = main.slice(0, endIndex);
|
const nonCompress = main.slice(0, endIndex);
|
||||||
@ -190,7 +177,11 @@ const compress = type === 'dist';
|
|||||||
|
|
||||||
// 6. 资源分离
|
// 6. 资源分离
|
||||||
if (resorce) {
|
if (resorce) {
|
||||||
await splitResorce(type);
|
await splitResource();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!compress) {
|
||||||
|
await fs.copy('./script/template/启动服务.exe', './dist/启动服务.exe');
|
||||||
}
|
}
|
||||||
|
|
||||||
// 7. 压缩
|
// 7. 压缩
|
||||||
|
@ -1,297 +1,236 @@
|
|||||||
import fs from 'fs-extra';
|
import fs, { Stats } from 'fs-extra';
|
||||||
import { uniqueSymbol } from './utils.js';
|
import JSZip from 'jszip';
|
||||||
import { resolve } from 'path';
|
import { formatSize, uniqueSymbol } from './utils.js';
|
||||||
import motaConfig from '../mota.config.js';
|
|
||||||
import compressing from 'compressing';
|
|
||||||
|
|
||||||
const SYMBOL = uniqueSymbol();
|
// 资源拆分模块,可以加快在线加载速度
|
||||||
const MAX_SIZE = 100 * (1 << 20) - 20 * (1 << 10);
|
|
||||||
const sourceIndex: Record<string, string> = {};
|
|
||||||
const toMove: Stats[] = [];
|
|
||||||
const all = [
|
|
||||||
'bgms',
|
|
||||||
'sounds',
|
|
||||||
'autotiles',
|
|
||||||
'images',
|
|
||||||
'materials',
|
|
||||||
'tilesets',
|
|
||||||
'animates',
|
|
||||||
'fonts'
|
|
||||||
];
|
|
||||||
|
|
||||||
type Stats = fs.Stats & { name?: string };
|
type ResourceType =
|
||||||
|
| 'text'
|
||||||
|
| 'buffer'
|
||||||
|
| 'image'
|
||||||
|
| 'material'
|
||||||
|
| 'audio'
|
||||||
|
| 'json'
|
||||||
|
| 'zip';
|
||||||
|
interface CompressedLoadListItem {
|
||||||
|
type: ResourceType;
|
||||||
|
name: string;
|
||||||
|
usage: string;
|
||||||
|
}
|
||||||
|
type CompressedLoadList = Record<string, CompressedLoadListItem[]>;
|
||||||
|
|
||||||
export async function splitResorce(type: string) {
|
interface MainData {
|
||||||
await fs.ensureDir('./dist-resource');
|
main: {
|
||||||
await fs.emptyDir('./dist-resource');
|
images: string[];
|
||||||
await readySplit();
|
tilesets: string[];
|
||||||
|
animates: string[];
|
||||||
await zipResource();
|
sounds: string[];
|
||||||
await split(type === 'dist' ? MAX_SIZE : void 0);
|
fonts: string[];
|
||||||
|
};
|
||||||
await endSplit(type);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async function readySplit() {
|
/** 单包大小,2M */
|
||||||
await fs.ensureDir('./_temp');
|
const SPLIT_SIZE = 2 ** 20 * 2;
|
||||||
await fs.emptyDir('./_temp');
|
|
||||||
await fs.ensureDir('./_temp/origin');
|
|
||||||
await copyAll();
|
|
||||||
}
|
|
||||||
|
|
||||||
async function endSplit(type: string) {
|
export async function splitResource() {
|
||||||
await rewriteMain(type);
|
const splitResult: CompressedLoadList = {};
|
||||||
await fs.emptyDir('./_temp');
|
let now: CompressedLoadListItem[] = [];
|
||||||
await fs.rmdir('./_temp');
|
let totalSize: number = 0;
|
||||||
}
|
let nowZip: JSZip = new JSZip();
|
||||||
|
|
||||||
async function zipResource() {
|
await fs.ensureDir('./dist/resource/');
|
||||||
const zip = motaConfig.zip;
|
await fs.emptyDir('./dist/resource');
|
||||||
if (!zip) return;
|
|
||||||
for await (const [name, files] of Object.entries(zip)) {
|
|
||||||
const stream = new compressing.zip.Stream();
|
|
||||||
const dirs: string[] = [];
|
|
||||||
|
|
||||||
for await (const file of files) {
|
const pushItem = async (
|
||||||
if (/^.+\/\*$/.test(file)) {
|
type: ResourceType,
|
||||||
const dir = file.split('/')[0];
|
name: string,
|
||||||
dirs.push(dir);
|
usage: string,
|
||||||
await fs.copy(`./_temp/origin/${dir}`, `./_temp/${dir}`);
|
file: Stats,
|
||||||
} else if (file.startsWith('!')) {
|
content: any
|
||||||
const dir = file.slice(1);
|
) => {
|
||||||
await fs.remove(`./_temp/${dir}`);
|
totalSize += file.size;
|
||||||
} else {
|
|
||||||
const [dir, name] = file.split('/');
|
if (totalSize > SPLIT_SIZE) {
|
||||||
if (dirs.includes(dir)) dirs.push(dir);
|
if (file.size > SPLIT_SIZE) {
|
||||||
await fs.ensureDir(`./_temp/${dir}`);
|
const symbol = uniqueSymbol() + `.h5data`;
|
||||||
await fs.copyFile(
|
console.warn(
|
||||||
`./_temp/origin/${dir}/${name}`,
|
`file ${type}/${name}(${formatSize(
|
||||||
`./_temp/${dir}/${name}`
|
file.size
|
||||||
|
)}) is larger than split limit (${formatSize(
|
||||||
|
SPLIT_SIZE
|
||||||
|
)}), single zip will be generated.`
|
||||||
);
|
);
|
||||||
|
splitResult['resource/' + symbol] = [{ type, name, usage }];
|
||||||
|
const zip = new JSZip();
|
||||||
|
addZippedFile(zip, type, name, content);
|
||||||
|
await writeZip(zip, `./dist/resource/${symbol}`, file.size);
|
||||||
|
totalSize -= file.size;
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
const symbol = uniqueSymbol() + `.h5data`;
|
||||||
|
splitResult['resource/' + symbol] = now;
|
||||||
|
await writeZip(
|
||||||
|
nowZip,
|
||||||
|
`./dist/resource/${symbol}`,
|
||||||
|
totalSize - file.size
|
||||||
|
);
|
||||||
|
nowZip = new JSZip();
|
||||||
|
totalSize = 0;
|
||||||
|
now = [];
|
||||||
|
await pushItem(type, name, usage, file, content);
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
|
now.push({ type, name, usage });
|
||||||
dirs.forEach(v => stream.addEntry(`./_temp/${v}`));
|
addZippedFile(nowZip, type, name, content);
|
||||||
const dest = fs.createWriteStream(`./_temp/${name}`);
|
|
||||||
await new Promise<void>(res =>
|
|
||||||
stream.pipe(dest).on('finish', () => {
|
|
||||||
res();
|
|
||||||
})
|
|
||||||
);
|
|
||||||
const stat = await fs.stat(`./_temp/${name}`);
|
|
||||||
toMove.push({ ...stat, name: `./_temp/${name}` });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async function getRemainReource() {
|
|
||||||
const zip = motaConfig.zip;
|
|
||||||
if (!zip) return;
|
|
||||||
const values = Object.values(zip);
|
|
||||||
for await (const one of all) {
|
|
||||||
if (values.some(v => v.includes(`${one}/*`))) continue;
|
|
||||||
const list = await fs.readdir(`./_temp/origin/${one}`);
|
|
||||||
for await (const name of list) {
|
|
||||||
if (!values.some(vv => vv.includes(`${one}/${name}`))) {
|
|
||||||
const stat = await fs.stat(`./_temp/origin/${one}/${name}`);
|
|
||||||
toMove.push({
|
|
||||||
...stat,
|
|
||||||
name: `./_temp/origin/${one}/${name}`
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
toMove.sort((a, b) => {
|
|
||||||
if (a.name?.endsWith('.zip') && b.name?.endsWith('.zip')) {
|
|
||||||
return b.size - a.size;
|
|
||||||
}
|
|
||||||
if (a.name?.endsWith('.zip')) return -1;
|
|
||||||
if (b.name?.endsWith('.zip')) return 1;
|
|
||||||
return b.size - a.size;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
async function split(max?: number) {
|
|
||||||
await getRemainReource();
|
|
||||||
|
|
||||||
const doSplit = async (index: string | number) => {
|
|
||||||
const base =
|
|
||||||
typeof index === 'string' ? index : `./dist-resource/${index}`;
|
|
||||||
|
|
||||||
await fs.ensureDir(base);
|
|
||||||
await generatePublishStructure(
|
|
||||||
base,
|
|
||||||
typeof index === 'string' ? 0 : index
|
|
||||||
);
|
|
||||||
|
|
||||||
let size = (await fs.stat(base)).size;
|
|
||||||
// 计算出要移动多少资源
|
|
||||||
const res = (() => {
|
|
||||||
if (!max) return toMove.splice(0, toMove.length);
|
|
||||||
let remain = max - size;
|
|
||||||
for (let i = 0; i < toMove.length; i++) {
|
|
||||||
const ele = toMove[i];
|
|
||||||
remain -= ele.size;
|
|
||||||
if (remain <= 0) {
|
|
||||||
return toMove.splice(0, i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return toMove.splice(0, toMove.length);
|
|
||||||
})();
|
|
||||||
|
|
||||||
if (base.endsWith('dist')) {
|
|
||||||
await fs.ensureDir(resolve(base, 'resource'));
|
|
||||||
}
|
|
||||||
|
|
||||||
// 执行移动
|
|
||||||
await Promise.all(
|
|
||||||
res.map(async v => {
|
|
||||||
if (!v.name) return;
|
|
||||||
// 压缩包
|
|
||||||
if (v.name.endsWith('.zip')) {
|
|
||||||
const [, , name] = v.name.split('/');
|
|
||||||
const split = name.split('.');
|
|
||||||
const target = `${split
|
|
||||||
.slice(0, -1)
|
|
||||||
.join('.')}-${SYMBOL}.${split.at(-1)}`;
|
|
||||||
if (base.endsWith('dist')) {
|
|
||||||
await fs.ensureDir(resolve(base, 'resource/zip'));
|
|
||||||
return fs.copyFile(
|
|
||||||
v.name,
|
|
||||||
resolve(base, 'resource', 'zip', target)
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
await fs.ensureDir(resolve(base, 'zip'));
|
|
||||||
return fs.copyFile(
|
|
||||||
v.name,
|
|
||||||
resolve(base, 'zip', target)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 非压缩包
|
|
||||||
if (!v.name.endsWith('.zip')) {
|
|
||||||
const [, , , type, name] = v.name.split('/');
|
|
||||||
const split = name.split('.');
|
|
||||||
const target = `${split
|
|
||||||
.slice(0, -1)
|
|
||||||
.join('.')}-${SYMBOL}.${split.at(-1)}`;
|
|
||||||
if (base.endsWith('dist')) {
|
|
||||||
await fs.ensureDir(resolve(base, 'resource', type));
|
|
||||||
} else {
|
|
||||||
await fs.ensureDir(resolve(base, type));
|
|
||||||
}
|
|
||||||
if (base.endsWith('dist')) {
|
|
||||||
return fs.copyFile(
|
|
||||||
v.name,
|
|
||||||
resolve(base, 'resource', type, target)
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
return fs.copyFile(v.name, resolve(base, type, target));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
);
|
|
||||||
|
|
||||||
// 标记资源索引
|
|
||||||
res.forEach(v => {
|
|
||||||
if (!v.name) return;
|
|
||||||
// 压缩包
|
|
||||||
if (v.name.endsWith('.zip')) {
|
|
||||||
const [, , name] = v.name.split('/');
|
|
||||||
sourceIndex[`zip.${name}`] = index.toString();
|
|
||||||
}
|
|
||||||
// 非压缩包
|
|
||||||
if (!v.name.endsWith('.zip')) {
|
|
||||||
const [, , , type, name] = v.name.split('/');
|
|
||||||
sourceIndex[`${type}.${name}`] = index.toString();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
if (toMove.length > 0) {
|
|
||||||
await doSplit(typeof index === 'string' ? 0 : index + 1);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
await doSplit('dist');
|
|
||||||
}
|
|
||||||
|
|
||||||
async function copyAll() {
|
const writeZip = (zip: JSZip, name: string, size: number) => {
|
||||||
await Promise.all(
|
return new Promise<void>(res => {
|
||||||
all.map(v => {
|
zip.generateNodeStream({ type: 'nodebuffer', streamFiles: true })
|
||||||
return fs.move(`./dist/project/${v}`, `./_temp/origin/${v}`);
|
.pipe(fs.createWriteStream(name))
|
||||||
})
|
.once('finish', function () {
|
||||||
);
|
console.log(
|
||||||
}
|
`Generated ${name}. Unzipped size: ${formatSize(size)}`
|
||||||
|
);
|
||||||
|
res();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
async function rewriteMain(type: string) {
|
const addZippedFile = (
|
||||||
const main = await fs.readFile('./dist/main.js', 'utf-8');
|
zip: JSZip,
|
||||||
const res = main
|
type: ResourceType,
|
||||||
.replace(
|
name: string,
|
||||||
/this\.RESOURCE_TYPE\s*\=\s*.*;/,
|
content: any
|
||||||
`this.RESOURCE_TYPE = '${type}';`
|
) => {
|
||||||
)
|
zip.file(`${type}/${name}`, content);
|
||||||
.replace(
|
};
|
||||||
/this\.RESOURCE_URL\s*\=\s*'.*'/,
|
|
||||||
`this.RESOURCE_URL = '/games/${motaConfig.resourceName}'`
|
|
||||||
)
|
|
||||||
.replace(
|
|
||||||
/this\.RESOURCE_SYMBOL\s*\=\s*'.*'/,
|
|
||||||
`this.RESOURCE_SYMBOL = '${SYMBOL}'`
|
|
||||||
)
|
|
||||||
.replace(
|
|
||||||
/this\.RESOURCE_INDEX\s*\=\s*\{.*\}/,
|
|
||||||
`this.RESOURCE_INDEX = ${JSON.stringify(sourceIndex, void 0, 8)}`
|
|
||||||
);
|
|
||||||
await fs.writeFile('./dist/main.js', res, 'utf-8');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
const file = await fs.readFile('./dist/project/data.js', 'utf-8');
|
||||||
* 生成可发布目录
|
const data = JSON.parse(file.split('\n').slice(1).join('')) as MainData;
|
||||||
*/
|
|
||||||
async function generatePublishStructure(dir: string, index: number) {
|
|
||||||
await fs.ensureDir(resolve(dir, 'libs'));
|
|
||||||
await fs.ensureDir(resolve(dir, 'libs/thirdparty'));
|
|
||||||
await fs.ensureDir(resolve(dir, 'project'));
|
|
||||||
await Promise.all(
|
|
||||||
all.map(v => {
|
|
||||||
fs.ensureDir(resolve(dir, 'project', v));
|
|
||||||
fs.emptyDir(resolve(dir, 'project', v));
|
|
||||||
})
|
|
||||||
);
|
|
||||||
|
|
||||||
if (!dir.endsWith('dist')) {
|
// images
|
||||||
await fs.writeFile(
|
for (const image of data.main.images) {
|
||||||
resolve(dir, 'project/icons.js'),
|
const path = `./dist/project/images/${image}`;
|
||||||
`var icons_4665ee12_3a1f_44a4_bea3_0fccba634dc1 =
|
const stat = await fs.stat(path);
|
||||||
{"autotile": {}}
|
await pushItem('image', image, 'image', stat, await fs.readFile(path));
|
||||||
`,
|
}
|
||||||
'utf-8'
|
|
||||||
);
|
|
||||||
await fs.writeFile(
|
|
||||||
resolve(dir, 'project/floors/none.js'),
|
|
||||||
'"none"',
|
|
||||||
'utf-8'
|
|
||||||
);
|
|
||||||
await fs.writeFile(resolve(dir, 'libs/none.js'), '"none"', 'utf-8');
|
|
||||||
|
|
||||||
await fs.copyFile('./script/template/main.js', resolve(dir, 'main.js'));
|
// tileset
|
||||||
const data = await fs.readFile('./script/template/data.js', 'utf-8');
|
for (const tileset of data.main.tilesets) {
|
||||||
await fs.writeFile(
|
const path = `./dist/project/tilesets/${tileset}`;
|
||||||
resolve(dir, 'project/data.js'),
|
const stat = await fs.stat(path);
|
||||||
data.replace('@name', `${motaConfig.resourceName}${index}`)
|
await pushItem(
|
||||||
);
|
'image',
|
||||||
|
tileset,
|
||||||
await fs.copyFile(
|
'tileset',
|
||||||
'./script/template/lz-string.min.js',
|
stat,
|
||||||
resolve(dir, 'libs/thirdparty/lz-string.min.js')
|
await fs.readFile(path)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
await Promise.all(
|
// animates
|
||||||
['animates', 'images', 'materials', 'sounds', 'tilesets'].map(v => {
|
for (const ani of data.main.animates) {
|
||||||
fs.copyFile(
|
const path = `./dist/project/animates/${ani}.animate`;
|
||||||
'./script/template/.h5data',
|
const stat = await fs.stat(path);
|
||||||
resolve(dir, `project/${v}/${v}.h5data`)
|
await pushItem(
|
||||||
);
|
'text',
|
||||||
})
|
ani + '.animate',
|
||||||
|
'animate',
|
||||||
|
stat,
|
||||||
|
await fs.readFile(path, 'utf-8')
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// sounds
|
||||||
|
for (const sound of data.main.sounds) {
|
||||||
|
const path = `./dist/project/sounds/${sound}`;
|
||||||
|
const stat = await fs.stat(path);
|
||||||
|
await pushItem('audio', sound, 'sound', stat, await fs.readFile(path));
|
||||||
|
}
|
||||||
|
|
||||||
|
// fonts
|
||||||
|
for (const font of data.main.fonts) {
|
||||||
|
const path = `./dist/project/fonts/${font}.ttf`;
|
||||||
|
const stat = await fs.stat(path);
|
||||||
|
await pushItem(
|
||||||
|
'buffer',
|
||||||
|
font + '.ttf',
|
||||||
|
'font',
|
||||||
|
stat,
|
||||||
|
await fs.readFile(path)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// autotiles
|
||||||
|
const autotiles = await fs.readdir('./dist/project/autotiles');
|
||||||
|
for (const a of autotiles) {
|
||||||
|
const path = `./dist/project/autotiles/${a}`;
|
||||||
|
const stat = await fs.stat(path);
|
||||||
|
await pushItem('image', a, 'autotile', stat, await fs.readFile(path));
|
||||||
|
}
|
||||||
|
|
||||||
|
// materials
|
||||||
|
const materials = await fs.readdir('./dist/project/materials');
|
||||||
|
for (const m of materials) {
|
||||||
|
const path = `./dist/project/materials/${m}`;
|
||||||
|
const stat = await fs.stat(path);
|
||||||
|
await pushItem(
|
||||||
|
'material',
|
||||||
|
m,
|
||||||
|
'material',
|
||||||
|
stat,
|
||||||
|
await fs.readFile(path)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const symbol = uniqueSymbol() + `.h5data`;
|
||||||
|
splitResult['resource/' + symbol] = now;
|
||||||
|
await writeZip(nowZip, `./dist/resource/${symbol}`, totalSize);
|
||||||
|
|
||||||
|
// 添加资源映射
|
||||||
|
await fs.writeFile(
|
||||||
|
'./dist/loadList.json',
|
||||||
|
JSON.stringify(splitResult),
|
||||||
|
'utf-8'
|
||||||
|
);
|
||||||
|
|
||||||
|
// 删除原资源
|
||||||
|
await fs.emptyDir('./dist/project/images');
|
||||||
|
await fs.emptyDir('./dist/project/tilesets');
|
||||||
|
await fs.emptyDir('./dist/project/animates');
|
||||||
|
await fs.emptyDir('./dist/project/fonts');
|
||||||
|
await fs.emptyDir('./dist/project/materials');
|
||||||
|
await fs.emptyDir('./dist/project/sounds');
|
||||||
|
await fs.emptyDir('./dist/project/autotiles');
|
||||||
|
// 然后加入填充内容
|
||||||
|
await fs.copy(
|
||||||
|
'./script/template/.h5data',
|
||||||
|
'./dist/project/images/images.h5data'
|
||||||
|
);
|
||||||
|
await fs.copy(
|
||||||
|
'./script/template/.h5data',
|
||||||
|
'./dist/project/tilesets/tilesets.h5data'
|
||||||
|
);
|
||||||
|
await fs.copy(
|
||||||
|
'./script/template/.h5data',
|
||||||
|
'./dist/project/animates/animates.h5data'
|
||||||
|
);
|
||||||
|
await fs.copy(
|
||||||
|
'./script/template/.h5data',
|
||||||
|
'./dist/project/fonts/fonts.h5data'
|
||||||
|
);
|
||||||
|
await fs.copy(
|
||||||
|
'./script/template/.h5data',
|
||||||
|
'./dist/project/materials/materials.h5data'
|
||||||
|
);
|
||||||
|
await fs.copy(
|
||||||
|
'./script/template/.h5data',
|
||||||
|
'./dist/project/sounds/sounds.h5data'
|
||||||
|
);
|
||||||
|
await fs.copy(
|
||||||
|
'./script/template/.h5data',
|
||||||
|
'./dist/project/autotiles/autotiles.h5data'
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
BIN
script/template/启动服务.exe
Normal file
BIN
script/template/启动服务.exe
Normal file
Binary file not shown.
@ -26,6 +26,29 @@ interface ResourceMap {
|
|||||||
zip: ZipResource;
|
zip: ZipResource;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface CompressedLoadListItem {
|
||||||
|
type: keyof ResourceType;
|
||||||
|
name: string;
|
||||||
|
usage: string;
|
||||||
|
}
|
||||||
|
type CompressedLoadList = Record<string, CompressedLoadListItem[]>;
|
||||||
|
|
||||||
|
const types: Record<keyof ResourceType, JSZip.OutputType> = {
|
||||||
|
text: 'string',
|
||||||
|
buffer: 'arraybuffer',
|
||||||
|
image: 'blob',
|
||||||
|
material: 'blob',
|
||||||
|
audio: 'arraybuffer',
|
||||||
|
json: 'string',
|
||||||
|
zip: 'arraybuffer'
|
||||||
|
};
|
||||||
|
|
||||||
|
const base = import.meta.env.DEV ? '/' : '';
|
||||||
|
|
||||||
|
function toURL(uri: string) {
|
||||||
|
return import.meta.env.DEV ? uri : `${import.meta.env.BASE_URL}${uri}`;
|
||||||
|
}
|
||||||
|
|
||||||
export abstract class Resource<T = any> extends Disposable<string> {
|
export abstract class Resource<T = any> extends Disposable<string> {
|
||||||
type = 'none';
|
type = 'none';
|
||||||
|
|
||||||
@ -92,7 +115,7 @@ export class ImageResource extends Resource<HTMLImageElement> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
resolveURI(): string {
|
resolveURI(): string {
|
||||||
return `/${findURL(this.uri)}`;
|
return toURL(`${base}${findURL(this.uri)}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -107,7 +130,7 @@ export class MaterialResource extends ImageResource {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override resolveURI(): string {
|
override resolveURI(): string {
|
||||||
return `/project/materials/${findURL(this.uri)}`;
|
return toURL(`${base}project/materials/${findURL(this.uri)}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -136,7 +159,7 @@ export class TextResource extends Resource<string> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
resolveURI(): string {
|
resolveURI(): string {
|
||||||
return `/${findURL(this.uri)}`;
|
return toURL(`${base}${findURL(this.uri)}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -164,7 +187,7 @@ export class BufferResource extends Resource<ArrayBuffer> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
resolveURI(): string {
|
resolveURI(): string {
|
||||||
return `/${findURL(this.uri)}`;
|
return toURL(`${base}${findURL(this.uri)}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -190,7 +213,7 @@ export class JSONResource<T = any> extends Resource<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
resolveURI(): string {
|
resolveURI(): string {
|
||||||
return `/${findURL(this.uri)}`;
|
return toURL(`${base}${findURL(this.uri)}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -217,7 +240,7 @@ export class AudioResource extends Resource<HTMLAudioElement> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
resolveURI(): string {
|
resolveURI(): string {
|
||||||
return `/project/bgms/${findURL(this.uri)}`;
|
return toURL(`${base}project/bgms/${findURL(this.uri)}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -228,7 +251,7 @@ export class ZipResource extends Resource<JSZip> {
|
|||||||
* 注意后缀名不要是zip,不然有的浏览器会触发下载,而不是加载
|
* 注意后缀名不要是zip,不然有的浏览器会触发下载,而不是加载
|
||||||
*/
|
*/
|
||||||
constructor(uri: string) {
|
constructor(uri: string) {
|
||||||
super(uri);
|
super(uri, 'zip');
|
||||||
this.type = 'zip';
|
this.type = 'zip';
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -249,7 +272,7 @@ export class ZipResource extends Resource<JSZip> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
resolveURI(): string {
|
resolveURI(): string {
|
||||||
return `/${findURL(this.uri)}`;
|
return toURL(`${base}${findURL(this.uri)}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -289,7 +312,7 @@ interface LoadEvent<T extends keyof ResourceType> extends EmitableEvent {
|
|||||||
now: number,
|
now: number,
|
||||||
total: number
|
total: number
|
||||||
) => void;
|
) => void;
|
||||||
load: (resource: ResourceMap[T]) => void;
|
load: (resource: ResourceMap[T]) => void | Promise<void>;
|
||||||
loadStart: (resource: ResourceMap[T]) => void;
|
loadStart: (resource: ResourceMap[T]) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -371,14 +394,14 @@ export class LoadTask<
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
this.emit('loadStart', this.resource);
|
this.emit('loadStart', this.resource);
|
||||||
load.then(() => {
|
return load.then(async value => {
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
LoadTask.loadedTaskList.add(this);
|
LoadTask.loadedTaskList.add(this);
|
||||||
this.loaded = totalByte;
|
this.loaded = totalByte;
|
||||||
LoadTask.loadedTask++;
|
LoadTask.loadedTask++;
|
||||||
this.emit('load', this.resource);
|
await Promise.all(this.emit('load', this.resource));
|
||||||
|
return value;
|
||||||
});
|
});
|
||||||
return load;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -493,7 +516,7 @@ export function loadDefaultResource() {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
// tilseset
|
// tileset
|
||||||
data.main.tilesets.forEach(v => {
|
data.main.tilesets.forEach(v => {
|
||||||
const res = LoadTask.add('image', `image/project/tilesets/${v}`);
|
const res = LoadTask.add('image', `image/project/tilesets/${v}`);
|
||||||
res.once('load', res => {
|
res.once('load', res => {
|
||||||
@ -563,4 +586,112 @@ export function loadDefaultResource() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function loadCompressedResource() {}
|
export async function loadCompressedResource() {
|
||||||
|
const data = await axios.get(toURL('loadList.json'), {
|
||||||
|
responseType: 'text'
|
||||||
|
});
|
||||||
|
const list: CompressedLoadList = JSON.parse(data.data);
|
||||||
|
|
||||||
|
const d = data_a1e2fb4a_e986_4524_b0da_9b7ba7c0874d;
|
||||||
|
// 对于bgm,直接按照原来的方式加载即可
|
||||||
|
d.main.bgms.forEach(v => {
|
||||||
|
const res = LoadTask.add('audio', `audio/${v}`);
|
||||||
|
Mota.r(() => {
|
||||||
|
res.once('loadStart', res => {
|
||||||
|
Mota.require('var', 'bgm').add(`bgms.${v}`, res.resource!);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
// 对于区域内容,按照zip格式进行加载,然后解压处理
|
||||||
|
const autotiles: Partial<Record<AllIdsOf<'autotile'>, HTMLImageElement>> =
|
||||||
|
{};
|
||||||
|
const materialImages = core.materials.slice() as SelectKey<
|
||||||
|
MaterialImages,
|
||||||
|
HTMLImageElement
|
||||||
|
>[];
|
||||||
|
materialImages.push('keyboard');
|
||||||
|
const weathers: (keyof Weather)[] = ['fog', 'cloud', 'sun'];
|
||||||
|
|
||||||
|
Object.entries(list).forEach(v => {
|
||||||
|
const [uri, list] = v;
|
||||||
|
const res = LoadTask.add('zip', `zip/${uri}`);
|
||||||
|
|
||||||
|
res.once('load', resource => {
|
||||||
|
const res = resource.resource;
|
||||||
|
if (!res) return;
|
||||||
|
list.forEach(async v => {
|
||||||
|
const { type, name, usage } = v;
|
||||||
|
const asyncType = types[type];
|
||||||
|
const value = await res
|
||||||
|
.file(`${type}/${name}`)
|
||||||
|
?.async(asyncType);
|
||||||
|
|
||||||
|
if (!value) return;
|
||||||
|
|
||||||
|
// 图片类型的资源
|
||||||
|
if (type === 'image') {
|
||||||
|
const img = value as Blob;
|
||||||
|
const image = new Image();
|
||||||
|
image.src = URL.createObjectURL(img);
|
||||||
|
image.addEventListener('load', () => {
|
||||||
|
image.setAttribute('_width', image.width.toString());
|
||||||
|
image.setAttribute('_height', image.height.toString());
|
||||||
|
});
|
||||||
|
|
||||||
|
// 图片
|
||||||
|
if (usage === 'image') {
|
||||||
|
core.material.images.images[name as ImageIds] = image;
|
||||||
|
} else if (usage === 'tileset') {
|
||||||
|
// 额外素材
|
||||||
|
core.material.images.tilesets[name] = image;
|
||||||
|
} else if (usage === 'autotile') {
|
||||||
|
// 自动元件
|
||||||
|
autotiles[name.slice(0, -4) as AllIdsOf<'autotile'>] =
|
||||||
|
image;
|
||||||
|
const loading = Mota.require('var', 'loading');
|
||||||
|
loading.addAutotileLoaded();
|
||||||
|
loading.onAutotileLoaded(autotiles);
|
||||||
|
core.material.images.autotile[
|
||||||
|
name.slice(0, -4) as AllIdsOf<'autotile'>
|
||||||
|
] = image;
|
||||||
|
}
|
||||||
|
} else if (type === 'material') {
|
||||||
|
const img = value as Blob;
|
||||||
|
const image = new Image();
|
||||||
|
image.src = URL.createObjectURL(img);
|
||||||
|
image.addEventListener('load', () => {
|
||||||
|
image.setAttribute('_width', image.width.toString());
|
||||||
|
image.setAttribute('_height', image.height.toString());
|
||||||
|
});
|
||||||
|
|
||||||
|
// material
|
||||||
|
if (materialImages.some(v => name === v + '.png')) {
|
||||||
|
// @ts-ignore
|
||||||
|
core.material.images[
|
||||||
|
name.slice(0, -4) as SelectKey<
|
||||||
|
MaterialImages,
|
||||||
|
HTMLImageElement
|
||||||
|
>
|
||||||
|
] = image;
|
||||||
|
} else if (weathers.some(v => name === v + '.png')) {
|
||||||
|
// @ts-ignore
|
||||||
|
core.animateFrame.weather[v] = image;
|
||||||
|
} else {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (usage === 'font') {
|
||||||
|
const font = value as ArrayBuffer;
|
||||||
|
document.fonts.add(new FontFace(name.slice(0, -4), font));
|
||||||
|
} else if (usage === 'sound') {
|
||||||
|
const sound = value as ArrayBuffer;
|
||||||
|
Mota.require('var', 'sound').add(`sounds.${name}`, sound);
|
||||||
|
} else if (usage === 'animate') {
|
||||||
|
const ani = value as string;
|
||||||
|
core.material.animates[name.slice(0, -8) as AnimationIds] =
|
||||||
|
core.loader._loadAnimate(ani);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
@ -394,7 +394,7 @@ function handleAudioSetting<T extends number | boolean>(
|
|||||||
) {
|
) {
|
||||||
if (key === 'bgmEnabled') {
|
if (key === 'bgmEnabled') {
|
||||||
bgm.disable = !n;
|
bgm.disable = !n;
|
||||||
core.checkBgm();
|
if (core.isPlaying()) core.checkBgm();
|
||||||
} else if (key === 'bgmVolume') {
|
} else if (key === 'bgmVolume') {
|
||||||
bgm.volume = (n as number) / 100;
|
bgm.volume = (n as number) / 100;
|
||||||
} else if (key === 'soundEnabled') {
|
} else if (key === 'soundEnabled') {
|
||||||
|
2
src/types/core.d.ts
vendored
2
src/types/core.d.ts
vendored
@ -101,6 +101,8 @@ type MaterialImages = {
|
|||||||
keyboard: HTMLImageElement;
|
keyboard: HTMLImageElement;
|
||||||
|
|
||||||
hero: HTMLImageElement;
|
hero: HTMLImageElement;
|
||||||
|
|
||||||
|
icons: HTMLImageElement;
|
||||||
};
|
};
|
||||||
|
|
||||||
interface Material {
|
interface Material {
|
||||||
|
@ -10,11 +10,13 @@
|
|||||||
@touchstart="touchStart(one.id)"
|
@touchstart="touchStart(one.id)"
|
||||||
>
|
>
|
||||||
<span class="danmaku-info">
|
<span class="danmaku-info">
|
||||||
<like-filled
|
<span
|
||||||
class="danmaku-like-icon"
|
class="danmaku-like-icon"
|
||||||
:liked="likedMap[one.id] < 0"
|
:liked="likedMap[one.id] < 0"
|
||||||
@click="postLike(one)"
|
@click="postLike(one)"
|
||||||
/>
|
>
|
||||||
|
<like-filled />
|
||||||
|
</span>
|
||||||
<span class="danmaku-like-num">{{
|
<span class="danmaku-like-num">{{
|
||||||
Math.abs(likedMap[one.id])
|
Math.abs(likedMap[one.id])
|
||||||
}}</span>
|
}}</span>
|
||||||
|
@ -7,21 +7,27 @@
|
|||||||
@click="openTool('css')"
|
@click="openTool('css')"
|
||||||
>CSS</span
|
>CSS</span
|
||||||
>
|
>
|
||||||
<font-colors-outlined
|
<span
|
||||||
class="danmaku-tool"
|
class="danmaku-tool"
|
||||||
:open="fillOpened"
|
:open="fillOpened"
|
||||||
@click="openTool('fillColor')"
|
@click="openTool('fillColor')"
|
||||||
/>
|
>
|
||||||
<highlight-outlined
|
<font-colors-outlined />
|
||||||
|
</span>
|
||||||
|
<span
|
||||||
class="danmaku-tool"
|
class="danmaku-tool"
|
||||||
:open="strokeOpened"
|
:open="strokeOpened"
|
||||||
@click="openTool('strokeColor')"
|
@click="openTool('strokeColor')"
|
||||||
/>
|
>
|
||||||
<meh-outlined
|
<highlight-outlined />
|
||||||
|
</span>
|
||||||
|
<span
|
||||||
class="danmaku-tool"
|
class="danmaku-tool"
|
||||||
:open="iconOpened"
|
:open="iconOpened"
|
||||||
@click="openTool('icon')"
|
@click="openTool('icon')"
|
||||||
/>
|
>
|
||||||
|
<meh-outlined />
|
||||||
|
</span>
|
||||||
<div id="danmaku-input-div">
|
<div id="danmaku-input-div">
|
||||||
<a-input
|
<a-input
|
||||||
id="danmaku-input-input"
|
id="danmaku-input-input"
|
||||||
@ -33,11 +39,13 @@
|
|||||||
@pressEnter="inputEnter()"
|
@pressEnter="inputEnter()"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<send-outlined
|
<span
|
||||||
class="danmaku-tool danmaku-post"
|
class="danmaku-tool danmaku-post"
|
||||||
:posting="posting"
|
:posting="posting"
|
||||||
@click="send()"
|
@click="send()"
|
||||||
/>
|
>
|
||||||
|
<send-outlined />
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<Transition name="danmaku">
|
<Transition name="danmaku">
|
||||||
<div v-if="cssOpened" id="danmaku-css">
|
<div v-if="cssOpened" id="danmaku-css">
|
||||||
|
@ -26,7 +26,11 @@
|
|||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { onMounted, ref } from 'vue';
|
import { onMounted, ref } from 'vue';
|
||||||
import { loadDefaultResource, LoadTask } from '@/core/common/resource';
|
import {
|
||||||
|
loadCompressedResource,
|
||||||
|
loadDefaultResource,
|
||||||
|
LoadTask
|
||||||
|
} from '@/core/common/resource';
|
||||||
import { GameUi } from '@/core/main/custom/ui';
|
import { GameUi } from '@/core/main/custom/ui';
|
||||||
import { formatSize } from '@/plugin/utils';
|
import { formatSize } from '@/plugin/utils';
|
||||||
import { logger } from '@/core/common/logger';
|
import { logger } from '@/core/common/logger';
|
||||||
@ -48,32 +52,32 @@ const totalTask = ref(0);
|
|||||||
|
|
||||||
let loadDiv: HTMLDivElement;
|
let loadDiv: HTMLDivElement;
|
||||||
|
|
||||||
loadDefaultResource();
|
onMounted(async () => {
|
||||||
|
if (import.meta.env.DEV) loadDefaultResource();
|
||||||
|
else await loadCompressedResource();
|
||||||
|
|
||||||
LoadTask.onProgress(() => {
|
LoadTask.onProgress(() => {
|
||||||
const loadingNum = [...LoadTask.taskList].filter(v => v.loading).length;
|
const loadingNum = [...LoadTask.taskList].filter(v => v.loading).length;
|
||||||
|
|
||||||
loadedByte.value = LoadTask.loadedByte;
|
loadedByte.value = LoadTask.loadedByte;
|
||||||
loadedPercent.value = parseFloat(
|
loadedPercent.value = parseFloat(
|
||||||
((LoadTask.loadedByte / LoadTask.totalByte) * 100).toFixed(2)
|
((LoadTask.loadedByte / LoadTask.totalByte) * 100).toFixed(2)
|
||||||
);
|
);
|
||||||
loading.value = loadingNum;
|
loading.value = loadingNum;
|
||||||
loaded.value = LoadTask.loadedTask;
|
loaded.value = LoadTask.loadedTask;
|
||||||
totalByte.value = LoadTask.totalByte;
|
totalByte.value = LoadTask.totalByte;
|
||||||
totalTask.value = LoadTask.totalTask;
|
totalTask.value = LoadTask.totalTask;
|
||||||
});
|
});
|
||||||
|
|
||||||
LoadTask.load().then(async () => {
|
LoadTask.load().then(async () => {
|
||||||
core.loader._loadMaterials_afterLoad();
|
core.loader._loadMaterials_afterLoad();
|
||||||
core._afterLoadResources(props.callback);
|
core._afterLoadResources(props.callback);
|
||||||
logger.log(`Resource load end.`);
|
logger.log(`Resource load end.`);
|
||||||
loadDiv.style.opacity = '0';
|
loadDiv.style.opacity = '0';
|
||||||
await sleep(1000);
|
await sleep(1000);
|
||||||
fixedUi.close(props.num);
|
fixedUi.close(props.num);
|
||||||
fixedUi.open('start');
|
fixedUi.open('start');
|
||||||
});
|
});
|
||||||
|
|
||||||
onMounted(() => {
|
|
||||||
loadDiv = document.getElementById('load') as HTMLDivElement;
|
loadDiv = document.getElementById('load') as HTMLDivElement;
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<div id="start">
|
<div id="start">
|
||||||
<div id="start-div">
|
<div id="start-div">
|
||||||
<img id="background" src="/project/images/bg.jpg" />
|
<img id="background" :src="bg.src" />
|
||||||
<div id="start-main">
|
<div id="start-main">
|
||||||
<div id="title">人类:开天辟地</div>
|
<div id="title">人类:开天辟地</div>
|
||||||
<div id="settings">
|
<div id="settings">
|
||||||
@ -80,6 +80,8 @@ const props = defineProps<{
|
|||||||
ui: GameUi;
|
ui: GameUi;
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
|
const bg = core.material.images.images['bg.jpg'];
|
||||||
|
|
||||||
let startdiv: HTMLDivElement;
|
let startdiv: HTMLDivElement;
|
||||||
let start: HTMLDivElement;
|
let start: HTMLDivElement;
|
||||||
let main: HTMLDivElement;
|
let main: HTMLDivElement;
|
||||||
|
@ -20,10 +20,7 @@
|
|||||||
>
|
>
|
||||||
<span id="status-lv">{{ lvName }}</span>
|
<span id="status-lv">{{ lvName }}</span>
|
||||||
<div id="status-skill" class="status-item">
|
<div id="status-skill" class="status-item">
|
||||||
<img
|
<img :src="imgs['skill.png'].src" class="status-icon" />
|
||||||
src="/project/images/skill.png"
|
|
||||||
class="status-icon"
|
|
||||||
/>
|
|
||||||
<span>{{ skill }}</span>
|
<span>{{ skill }}</span>
|
||||||
<span
|
<span
|
||||||
v-if="has(spring)"
|
v-if="has(spring)"
|
||||||
@ -33,7 +30,7 @@
|
|||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
<div id="status-hp" class="status-item">
|
<div id="status-hp" class="status-item">
|
||||||
<img src="/project/images/hp.png" class="status-icon" />
|
<img :src="imgs['hp.png'].src" class="status-icon" />
|
||||||
<span class="status-item-bold">{{
|
<span class="status-item-bold">{{
|
||||||
format(hero.hp!)
|
format(hero.hp!)
|
||||||
}}</span>
|
}}</span>
|
||||||
@ -50,10 +47,7 @@
|
|||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
<div id="status-atk" class="status-item">
|
<div id="status-atk" class="status-item">
|
||||||
<img
|
<img :src="imgs['atk.png'].src" class="status-icon" />
|
||||||
src="/project/images/atk.png"
|
|
||||||
class="status-icon"
|
|
||||||
/>
|
|
||||||
<span class="status-item-bold">{{
|
<span class="status-item-bold">{{
|
||||||
format(hero.atk!)
|
format(hero.atk!)
|
||||||
}}</span>
|
}}</span>
|
||||||
@ -64,28 +58,19 @@
|
|||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
<div id="status-def" class="status-item status-item-bold">
|
<div id="status-def" class="status-item status-item-bold">
|
||||||
<img
|
<img :src="imgs['def.png'].src" class="status-icon" />
|
||||||
src="/project/images/def.png"
|
|
||||||
class="status-icon"
|
|
||||||
/>
|
|
||||||
<span>{{ format(hero.def!) }}</span>
|
<span>{{ format(hero.def!) }}</span>
|
||||||
</div>
|
</div>
|
||||||
<div id="status-mdef" class="status-item status-item-bold">
|
<div id="status-mdef" class="status-item status-item-bold">
|
||||||
<img src="/project/images/IQ.png" class="status-icon" />
|
<img :src="imgs['IQ.png'].src" class="status-icon" />
|
||||||
<span>{{ format(hero.mdef!) }}</span>
|
<span>{{ format(hero.mdef!) }}</span>
|
||||||
</div>
|
</div>
|
||||||
<div id="status-money" class="status-item status-item-bold">
|
<div id="status-money" class="status-item status-item-bold">
|
||||||
<img
|
<img :src="imgs['money.png'].src" class="status-icon" />
|
||||||
src="/project/images/money.png"
|
|
||||||
class="status-icon"
|
|
||||||
/>
|
|
||||||
<span>{{ format(hero.money!) }}</span>
|
<span>{{ format(hero.money!) }}</span>
|
||||||
</div>
|
</div>
|
||||||
<div id="status-exp" class="status-item status-item-bold">
|
<div id="status-exp" class="status-item status-item-bold">
|
||||||
<img
|
<img :src="imgs['exp.png'].src" class="status-icon" />
|
||||||
src="/project/images/exp.png"
|
|
||||||
class="status-icon"
|
|
||||||
/>
|
|
||||||
<span>{{ format(up) }}</span>
|
<span>{{ format(up) }}</span>
|
||||||
</div>
|
</div>
|
||||||
<div id="status-key" class="status-item status-item-bold">
|
<div id="status-key" class="status-item status-item-bold">
|
||||||
@ -143,8 +128,8 @@ import { has } from '@/plugin/utils';
|
|||||||
|
|
||||||
let main: HTMLDivElement;
|
let main: HTMLDivElement;
|
||||||
|
|
||||||
const items = core.flags.statusBarItems;
|
const imgs = core.material.images.images;
|
||||||
const icons = core.statusBar.icons;
|
|
||||||
const skillTree = Mota.Plugin.require('skillTree_g');
|
const skillTree = Mota.Plugin.require('skillTree_g');
|
||||||
|
|
||||||
const width = ref(
|
const width = ref(
|
||||||
|
@ -40,7 +40,6 @@ export default defineConfig({
|
|||||||
'lz-string',
|
'lz-string',
|
||||||
'chart.js',
|
'chart.js',
|
||||||
'mutate-animate',
|
'mutate-animate',
|
||||||
'three',
|
|
||||||
'@vueuse/core'
|
'@vueuse/core'
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user