插件完全ts化

This commit is contained in:
unanmed 2023-05-02 15:37:38 +08:00
parent b2cb89a7f6
commit 2e7e64b399
32 changed files with 147 additions and 112 deletions

View File

@ -29,6 +29,9 @@
"@babel/cli": "^7.21.0", "@babel/cli": "^7.21.0",
"@babel/core": "^7.21.4", "@babel/core": "^7.21.4",
"@babel/preset-env": "^7.21.4", "@babel/preset-env": "^7.21.4",
"@rollup/plugin-babel": "^6.0.3",
"@rollup/plugin-terser": "^0.4.1",
"@rollup/plugin-typescript": "^11.1.0",
"@types/babel__core": "^7.20.0", "@types/babel__core": "^7.20.0",
"@types/fontmin": "^0.9.0", "@types/fontmin": "^0.9.0",
"@types/fs-extra": "^9.0.13", "@types/fs-extra": "^9.0.13",

View File

@ -5,6 +5,9 @@ specifiers:
'@babel/cli': ^7.21.0 '@babel/cli': ^7.21.0
'@babel/core': ^7.21.4 '@babel/core': ^7.21.4
'@babel/preset-env': ^7.21.4 '@babel/preset-env': ^7.21.4
'@rollup/plugin-babel': ^6.0.3
'@rollup/plugin-terser': ^0.4.1
'@rollup/plugin-typescript': ^11.1.0
'@types/babel__core': ^7.20.0 '@types/babel__core': ^7.20.0
'@types/fontmin': ^0.9.0 '@types/fontmin': ^0.9.0
'@types/fs-extra': ^9.0.13 '@types/fs-extra': ^9.0.13
@ -49,6 +52,9 @@ devDependencies:
'@babel/cli': 7.21.0_@babel+core@7.21.4 '@babel/cli': 7.21.0_@babel+core@7.21.4
'@babel/core': 7.21.4 '@babel/core': 7.21.4
'@babel/preset-env': 7.21.4_@babel+core@7.21.4 '@babel/preset-env': 7.21.4_@babel+core@7.21.4
'@rollup/plugin-babel': 6.0.3_mthsuwq2qd2jauekjxjmmazyii
'@rollup/plugin-terser': 0.4.1_rollup@3.20.2
'@rollup/plugin-typescript': 11.1.0_e7tciabaay7z2i5ycjdzz3zl6i
'@types/babel__core': 7.20.0 '@types/babel__core': 7.20.0
'@types/fontmin': 0.9.0 '@types/fontmin': 0.9.0
'@types/fs-extra': 9.0.13 '@types/fs-extra': 9.0.13
@ -1622,6 +1628,60 @@ packages:
rimraf: 3.0.2 rimraf: 3.0.2
dev: true dev: true
/@rollup/plugin-babel/6.0.3_mthsuwq2qd2jauekjxjmmazyii:
resolution: {integrity: sha512-fKImZKppa1A/gX73eg4JGo+8kQr/q1HBQaCGKECZ0v4YBBv3lFqi14+7xyApECzvkLTHCifx+7ntcrvtBIRcpg==}
engines: {node: '>=14.0.0'}
peerDependencies:
'@babel/core': ^7.0.0
'@types/babel__core': ^7.1.9
rollup: ^1.20.0||^2.0.0||^3.0.0
peerDependenciesMeta:
'@types/babel__core':
optional: true
rollup:
optional: true
dependencies:
'@babel/core': 7.21.4
'@babel/helper-module-imports': 7.21.4
'@rollup/pluginutils': 5.0.2_rollup@3.20.2
'@types/babel__core': 7.20.0
rollup: 3.20.2
dev: true
/@rollup/plugin-terser/0.4.1_rollup@3.20.2:
resolution: {integrity: sha512-aKS32sw5a7hy+fEXVy+5T95aDIwjpGHCTv833HXVtyKMDoVS7pBr5K3L9hEQoNqbJFjfANPrNpIXlTQ7is00eA==}
engines: {node: '>=14.0.0'}
peerDependencies:
rollup: ^2.x || ^3.x
peerDependenciesMeta:
rollup:
optional: true
dependencies:
rollup: 3.20.2
serialize-javascript: 6.0.1
smob: 0.0.6
terser: 5.16.9
dev: true
/@rollup/plugin-typescript/11.1.0_e7tciabaay7z2i5ycjdzz3zl6i:
resolution: {integrity: sha512-86flrfE+bSHB69znnTV6kVjkncs2LBMhcTCyxWgRxLyfXfQrxg4UwlAqENnjrrxnSNS/XKCDJCl8EkdFJVHOxw==}
engines: {node: '>=14.0.0'}
peerDependencies:
rollup: ^2.14.0||^3.0.0
tslib: '*'
typescript: '>=3.7.0'
peerDependenciesMeta:
rollup:
optional: true
tslib:
optional: true
dependencies:
'@rollup/pluginutils': 5.0.2_rollup@3.20.2
resolve: 1.22.3
rollup: 3.20.2
typescript: 4.9.5
dev: true
/@rollup/pluginutils/5.0.2_rollup@3.20.2: /@rollup/pluginutils/5.0.2_rollup@3.20.2:
resolution: {integrity: sha512-pTd9rIsP92h+B6wWwFbW8RkZv4hiR/xKsqre4SIuAOaOEQRxi0lqLke9k2/7WegC85GgUs9pjmOjCUi3In4vwA==} resolution: {integrity: sha512-pTd9rIsP92h+B6wWwFbW8RkZv4hiR/xKsqre4SIuAOaOEQRxi0lqLke9k2/7WegC85GgUs9pjmOjCUi3In4vwA==}
engines: {node: '>=14.0.0'} engines: {node: '>=14.0.0'}
@ -3798,6 +3858,12 @@ packages:
engines: {node: '>=10'} engines: {node: '>=10'}
dev: true dev: true
/randombytes/2.1.0:
resolution: {integrity: sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==}
dependencies:
safe-buffer: 5.2.1
dev: true
/read-pkg-up/8.0.0: /read-pkg-up/8.0.0:
resolution: {integrity: sha512-snVCqPczksT0HS2EC+SxUndvSzn6LRCwpfSvLrIfR5BKDQQZMaI6jPRC9dYvYFDRAuFEAnkwww8kBBNE/3VvzQ==} resolution: {integrity: sha512-snVCqPczksT0HS2EC+SxUndvSzn6LRCwpfSvLrIfR5BKDQQZMaI6jPRC9dYvYFDRAuFEAnkwww8kBBNE/3VvzQ==}
engines: {node: '>=12'} engines: {node: '>=12'}
@ -4020,6 +4086,12 @@ packages:
lru-cache: 6.0.0 lru-cache: 6.0.0
dev: true dev: true
/serialize-javascript/6.0.1:
resolution: {integrity: sha512-owoXEFjWRllis8/M1Q+Cw5k8ZH40e3zhp/ovX+Xr/vi1qj6QesbyXXViFbpNvWvPNAD62SutwEXavefrLJWj7w==}
dependencies:
randombytes: 2.1.0
dev: true
/set-blocking/2.0.0: /set-blocking/2.0.0:
resolution: {integrity: sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==} resolution: {integrity: sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==}
dev: true dev: true
@ -4042,6 +4114,10 @@ packages:
engines: {node: '>= 6.0.0', npm: '>= 3.0.0'} engines: {node: '>= 6.0.0', npm: '>= 3.0.0'}
dev: true dev: true
/smob/0.0.6:
resolution: {integrity: sha512-V21+XeNni+tTyiST1MHsa84AQhT1aFZipzPpOFAVB8DkHzwJyjjAmt9bgwnuZiZWnIbMo2duE29wybxv/7HWUw==}
dev: true
/socks-proxy-agent/7.0.0: /socks-proxy-agent/7.0.0:
resolution: {integrity: sha512-Fgl0YPZ902wEsAyiQ+idGd1A7rSFx/ayC1CQVMw5P+EQx2V0SgpGtf6OKFhVjPflPUl9YMmEOnmfjCdMUsygww==} resolution: {integrity: sha512-Fgl0YPZ902wEsAyiQ+idGd1A7rSFx/ayC1CQVMw5P+EQx2V0SgpGtf6OKFhVjPflPUl9YMmEOnmfjCdMUsygww==}
engines: {node: '>= 10'} engines: {node: '>= 10'}

View File

@ -44,11 +44,6 @@ control.prototype._init = function () {
); );
this.registerAnimationFrame('weather', true, this._animationFrame_weather); this.registerAnimationFrame('weather', true, this._animationFrame_weather);
this.registerAnimationFrame('tip', true, this._animateFrame_tip); this.registerAnimationFrame('tip', true, this._animateFrame_tip);
this.registerAnimationFrame(
'parallelDo',
false,
this._animationFrame_parallelDo
);
// --- 注册系统的天气 // --- 注册系统的天气
this.registerWeather( this.registerWeather(
'rain', 'rain',
@ -479,10 +474,6 @@ control.prototype._animateFrame_tip = function (timestamp) {
} }
}; };
control.prototype._animationFrame_parallelDo = function (timestamp) {
core.control.controldata.parallelDo(timestamp);
};
// ------ 标题界面的处理 ------ // // ------ 标题界面的处理 ------ //
////// 显示游戏开始界面 ////// ////// 显示游戏开始界面 //////

View File

@ -343,10 +343,7 @@ core.prototype._loadPlugin = async function () {
if (main.pluginUseCompress) { if (main.pluginUseCompress) {
await main.loadScript(`project/plugin.min.js?v=${main.version}`); await main.loadScript(`project/plugin.min.js?v=${main.version}`);
} else { } else {
await main.loadScript( await main.loadScript(`src/plugin/game/index.js`, true);
`project/plugin/index.js?v=${main.version}`,
true
);
} }
}; };

View File

@ -1018,15 +1018,6 @@ events.prototype.pushBox = function (data) {
if (data.event.id == 'box') core.removeBlock(data.x, data.y); if (data.event.id == 'box') core.removeBlock(data.x, data.y);
else core.setBlock('flower', data.x, data.y); else core.setBlock('flower', data.x, data.y);
// 勇士前进一格,然后触发推箱子后事件 // 勇士前进一格,然后触发推箱子后事件
core.insertAction([
{ type: 'moveAction' },
{ type: 'function', function: 'function() { core.afterPushBox(); }' }
]);
};
////// 推箱子后的事件 //////
events.prototype.afterPushBox = function () {
return this.eventdata.afterPushBox();
}; };
events.prototype._sys_ski = function (data, callback) { events.prototype._sys_ski = function (data, callback) {

View File

@ -484,19 +484,6 @@ var functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a = {
} }
if (todo.length > 0) core.insertAction(todo, x, y); if (todo.length > 0) core.insertAction(todo, x, y);
},
afterPushBox: function () {
// 推箱子后的事件
if (core.searchBlock('box').length == 0) {
// 可以通过if语句来进行开门操作
/*
if (core.status.floorId=='xxx') { // 在某个楼层
core.insertAction([ // 插入一条事件
{"type": "openDoor", "loc": [x,y]} // 开门
])
}
*/
}
} }
}, },
enemys: { enemys: {
@ -1906,23 +1893,6 @@ var functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a = {
return true; return true;
} }
return false; return false;
},
parallelDo: function (timestamp) {
// 并行事件处理,可以在这里写任何需要并行处理的脚本或事件
// 该函数将被系统反复执行每次执行间隔视浏览器或设备性能而定一般约为16.6ms一次
// 参数timestamp为“从游戏资源加载完毕到当前函数执行时”的时间差以毫秒为单位
// 检查当前是否处于游戏开始状态
if (!core.isPlaying()) return;
// 执行当前楼层的并行事件处理
if (core.status.floorId) {
try {
eval(core.floors[core.status.floorId].parallelDo);
} catch (e) {
console.error(e);
}
}
} }
}, },
ui: { ui: {

View File

@ -1,35 +0,0 @@
///<reference path="../../../src/types/core.d.ts" />
/**
* 计算需要计算伤害的方向
* @param {number} x
* @param {number} y
* @param {FloorIds} floorId
*/
export function getNeedCalculateDir(x, y, floorId) {}
/**
* 获得怪物属性
* @param {EnemyIds | Partial<Enemy>} enemy
* @param {Partial<HeroStatus>?} hero
* @param {number?} x
* @param {number?} y
* @param {FloorIds?} floorId
*/
export function getEnemyInfo(enemy, hero, x, y, floorId) {}
/**
* 获得怪物伤害
* @param {EnemyIds | Partial<Enemy>} enemy
* @param {Partial<HeroStatus>?} hero
* @param {number?} x
* @param {number?} y
* @param {FloorIds?} floorId
*/
export function getDamageInfo(enemy, hero, x, y, floorId) {}
/**
* 计算地图伤害与光环效果
* @param {FloorIds} floorId
*/
export function checkBlock(floorId) {}

View File

@ -41,9 +41,11 @@ next();
const listenedFloors = []; const listenedFloors = [];
const listenedPlugins = []; const listenedPlugins = [];
const pluginBase = 'public/plugin/game';
const hasPlugin = (function () { const hasPlugin = (function () {
try { try {
fss.readdirSync('./project/plugin'); fss.readdirSync(pluginBase);
return true; return true;
} catch { } catch {
return false; return false;
@ -339,7 +341,7 @@ async function watch() {
}); });
// 脚本编辑 热重载 // 脚本编辑 热重载
const scripts = await extract('project/functions.js', 'project/plugins.js'); const scripts = await extract('project/functions.js');
scripts.forEach(v => { scripts.forEach(v => {
const dir = path.resolve(__dirname, v); const dir = path.resolve(__dirname, v);
const type = v.split('/').at(-1).slice(0, -3); const type = v.split('/').at(-1).slice(0, -3);
@ -351,9 +353,11 @@ async function watch() {
// 插件热重载 // 插件热重载
if (hasPlugin) { if (hasPlugin) {
const plugins = await extract('project/plugin/*.js'); const plugins = (await extract('../src/plugin/game/*.js')).concat(
await extract('../src/plugin/game/*.ts')
);
plugins.forEach(v => { plugins.forEach(v => {
watchOnePlugin(v.slice(15)); watchOnePlugin(v.slice(19));
}); });
} }
@ -390,9 +394,9 @@ function testWatchFloor(url) {
*/ */
function testWatchPlugin(url) { function testWatchPlugin(url) {
if (!hasPlugin) return; if (!hasPlugin) return;
if (/project(\/|\\)plugin(\/|\\).*\.js/.test(url)) { if (/src(\/|\\)plugin(\/|\\)game(\/|\\).*\.(js|ts)/.test(url)) {
const f = url.slice(15); const f = url.slice(19);
if (!listenedFloors.includes(f.slice(0, -3))) { if (!listenedPlugins.includes(f.slice(0, -3))) {
watchOnePlugin(f); watchOnePlugin(f);
} }
} }
@ -419,15 +423,19 @@ function watchOneFloor(file) {
* @param {string} file 要监听的文件 * @param {string} file 要监听的文件
*/ */
function watchOnePlugin(file) { function watchOnePlugin(file) {
if (!/.*\.js/.test(file)) return; if (!/.*\.(js|ts)/.test(file)) return;
const f = file.slice(0, -3); const f = file.slice(0, -3);
listenedPlugins.push(file.slice(0, -3)); listenedPlugins.push(file.slice(0, -3));
fss.watchFile(`project/plugin/${file}`, { interval: 500 }, () => { fss.watchFile(
const plugin = f; path.resolve(__dirname, `../src/plugin/game/${file}`),
if (hotReloadData.includes(`@@plugin:${plugin}`)) return; { interval: 500 },
hotReloadData += `@@plugin:${plugin}`; () => {
console.log(`plugin hot reload: ${plugin}`); const plugin = f;
}); if (hotReloadData.includes(`@@plugin:${plugin}`)) return;
hotReloadData += `@@plugin:${plugin}`;
console.log(`plugin hot reload: ${plugin}`);
}
);
} }
/** /**

View File

@ -4,6 +4,9 @@ import fse from 'fs-extra';
import Fontmin from 'fontmin'; import Fontmin from 'fontmin';
import * as babel from '@babel/core'; import * as babel from '@babel/core';
import * as rollup from 'rollup'; import * as rollup from 'rollup';
import typescript from '@rollup/plugin-typescript';
import rollupBabel from '@rollup/plugin-babel';
import terser from '@rollup/plugin-terser';
(async function () { (async function () {
const timestamp = Date.now(); const timestamp = Date.now();
@ -113,18 +116,31 @@ import * as rollup from 'rollup';
// 3. 压缩js插件 // 3. 压缩js插件
try { try {
await fse.remove('./dist/project/plugin.min.js');
const build = await rollup.rollup({ const build = await rollup.rollup({
input: 'public/project/plugin/index.js' input: 'src/plugin/game/index.js',
plugins: [
typescript({
sourceMap: false
}),
rollupBabel({
babelHelpers: 'bundled',
sourceType: 'module'
}),
terser()
]
}); });
const code = await build.generate({ await build.write({
format: 'iife', format: 'iife',
name: 'CorePlugin' name: 'CorePlugin',
file: './dist/project/plugin.min.js'
}); });
const compressed = babel.transformSync(code.output[0].code)?.code!;
await fs.writeFile('./dist/project/plugin.min.js', compressed, 'utf-8');
await fse.remove('./dist/project/plugin/'); await fse.remove('./dist/project/plugin/');
} catch (e) { } catch (e) {
console.log(e);
console.log('压缩插件失败'); console.log('压缩插件失败');
} }

View File

@ -0,0 +1,9 @@
///<reference path="../../../src/types/core.d.ts" />
export class EnemyCollection {}
export class Enemy {}
core.plugin.damage = {
Enemy
};

View File

@ -59,7 +59,9 @@ export {};
) )
return; return;
// 首先重新加载main.floors对应的楼层 // 首先重新加载main.floors对应的楼层
await import(`/project/floors/${data}.js?v=${Date.now()}`); await import(
/* @vite-ignore */ `./project/floors/${data}.js?v=${Date.now()}`
);
// 然后写入core.floors并解析 // 然后写入core.floors并解析
core.floors[data] = main.floors[data]; core.floors[data] = main.floors[data];
const floor = core.loadFloor(data); const floor = core.loadFloor(data);
@ -127,7 +129,7 @@ export {};
async function reloadPlugin(data) { async function reloadPlugin(data) {
// 直接import就完事了 // 直接import就完事了
await import(`/project/plugin/${data}.js?v=${Date.now()}`); await import(/* @vite-ignore */ `./src/plugin/game/${data}.js`);
console.log(`plugin hot reload: ${data}.js`); console.log(`plugin hot reload: ${data}.js`);
} }

View File

@ -17,6 +17,7 @@ import * as study from './study.js';
import * as towerBoss from './towerBoss.js'; import * as towerBoss from './towerBoss.js';
import * as utils from './utils.js'; import * as utils from './utils.js';
import * as chase from './chase.js'; import * as chase from './chase.js';
import * as damage from './damage';
export { export {
halo, halo,
@ -30,5 +31,6 @@ export {
study, study,
towerBoss, towerBoss,
utils, utils,
chase chase,
damage
}; };

View File

@ -92,7 +92,7 @@ export function useDrag(
target.addEventListener('mouseup', mouseUp as EventListener); target.addEventListener('mouseup', mouseUp as EventListener);
target.addEventListener('touchend', touchUp as EventListener); target.addEventListener('touchend', touchUp as EventListener);
} }
dragFnMap.set(fn, [mouseFn, touchFn, mouseUp, touchUp]); dragFnMap.set(fn, [mouseUp, touchUp]);
} }
/** /**
@ -103,8 +103,6 @@ export function cancelGlobalDrag(fn: DragFn): void {
const fns = dragFnMap.get(fn); const fns = dragFnMap.get(fn);
dragFnMap.delete(fn); dragFnMap.delete(fn);
if (!fns) return; if (!fns) return;
document.removeEventListener('mousemove', fns[0]);
document.removeEventListener('touchmove', fns[1]);
document.removeEventListener('mouseup', fns[0]); document.removeEventListener('mouseup', fns[0]);
document.removeEventListener('touchend', fns[1]); document.removeEventListener('touchend', fns[1]);
} }

View File

@ -30,6 +30,7 @@ interface PluginDeclaration
hero: GamePluginHeroRealStatus; hero: GamePluginHeroRealStatus;
replay: PluginReplay; replay: PluginReplay;
chase: PluginChase; chase: PluginChase;
damage: PluginDamage;
skills: Record<Chapter, Skill[]>; skills: Record<Chapter, Skill[]>;
skillEffects: SkillEffects; skillEffects: SkillEffects;
@ -456,6 +457,12 @@ interface Skill {
effect: string[]; effect: string[];
} }
interface PluginDamage {
Enemy: new () => DamageEnemy;
}
interface DamageEnemy {}
type Forward<T> = { type Forward<T> = {
[K in keyof T as T[K] extends Function [K in keyof T as T[K] extends Function
? K extends `_${string}` ? K extends `_${string}`