refactor: plugins-fiveLayer

This commit is contained in:
unanmed 2024-02-04 21:18:02 +08:00
parent 9bb3803612
commit 216e8119c4
15 changed files with 597 additions and 373 deletions

View File

@ -277,6 +277,7 @@ core.prototype.init = async function (coreData, callback) {
this._forwardFuncs();
for (var key in coreData) core[key] = coreData[key];
await this._loadGameProcess();
await this._loadPluginAsync();
this._init_flags();
this._init_platform();
this._init_others();
@ -302,9 +303,9 @@ core.prototype.init = async function (coreData, callback) {
};
core.prototype.initSync = function (coreData, callback) {
this._loadGameProcessSync();
this._forwardFuncs();
for (var key in coreData) core[key] = coreData[key];
this._loadGameProcessSync();
this._init_flags();
this._init_platform();
this._init_others();
@ -314,6 +315,27 @@ core.prototype.initSync = function (coreData, callback) {
});
};
core.prototype._loadPluginAsync = async function () {
if (!main.useCompress) {
await main.loadScript(`project/plugins.js?v=${main.version}`);
} else {
await main.loadScript(`project/plugins.min.js?v=${main.version}`);
}
for (const [key, value] of Object.entries(
plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1
)) {
try {
value.call(plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1);
} catch (e) {
throw new Error(`Plugin '${key}' init fail. Error info: ${e}`);
}
}
};
core.prototype._loadPluginSync = function () {
main.loadMod('project', 'plugins', () => 0);
};
core.prototype._loadGameProcess = async function () {
// 加载游戏进程代码
if (main.pluginUseCompress) {

View File

@ -369,7 +369,73 @@ events.prototype.doSystemEvent = function (type, data, callback) {
////// 触发(x,y)点的事件 //////
events.prototype.trigger = function (x, y, callback) {
// see src/plugin/game/loopMap.js
var _executeCallback = function () {
// 因为trigger之后还有可能触发其他同步脚本比如阻激夹域检测
// 所以这里强制callback被异步触发
if (callback) {
setTimeout(callback, 1); // +1是为了录像检测系统
}
return;
};
if (core.status.gameOver) return _executeCallback();
if (core.status.event.id == 'action') {
core.insertAction(
{
type: 'function',
function:
'function () { core.events._trigger_inAction(' +
x +
',' +
y +
'); }',
async: true
},
null,
null,
null,
true
);
return _executeCallback();
}
if (core.status.event.id) return _executeCallback();
var block = core.getBlock(x, y);
if (block == null) return _executeCallback();
// 执行该点的脚本
if (block.event.script) {
core.clearRouteFolding();
try {
eval(block.event.script);
} catch (ee) {
console.error(ee);
}
}
// 碰触事件
if (block.event.event) {
core.clearRouteFolding();
core.insertAction(block.event.event, block.x, block.y);
// 不再执行该点的系统事件
return _executeCallback();
}
if (block.event.trigger && block.event.trigger != 'null') {
var noPass = block.event.noPass,
trigger = block.event.trigger;
if (noPass) core.clearAutomaticRouteNode(x, y);
// 转换楼层能否穿透
if (
trigger == 'changeFloor' &&
!noPass &&
this._trigger_ignoreChangeFloor(block)
)
return _executeCallback();
core.status.automaticRoute.moveDirectly = false;
this.doSystemEvent(trigger, block);
}
return _executeCallback();
};
events.prototype._trigger_inAction = function (x, y) {
@ -587,7 +653,7 @@ events.prototype._openDoor_animate = function (block, x, y, callback) {
////// 开一个门后触发的事件 //////
events.prototype.afterOpenDoor = function (doorId, x, y) {
// Deprecated. See hook#afterOpenDoor.
this.eventdata.afterOpenDoor(doorId, x, y);
};
events.prototype._sys_getItem = function (data, callback) {
@ -646,7 +712,7 @@ events.prototype.getItem = function (id, num, x, y, isGentleClick, callback) {
};
events.prototype.afterGetItem = function (id, x, y, isGentleClick) {
// Deprecated. See hook#afterGetItem
this.eventdata.afterGetItem(id, x, y, isGentleClick);
};
////// 获得面前的物品(轻按) //////
@ -686,7 +752,15 @@ events.prototype._getNextItem = function (direction, noRoute) {
};
events.prototype._sys_changeFloor = function (data, callback) {
// see src/plugin/game/loopMap.js
data = data.event.data;
var heroLoc = {};
if (data.loc) heroLoc = { x: data.loc[0], y: data.loc[1] };
if (data.direction) heroLoc.direction = data.direction;
if (core.status.event.id != 'action') core.status.event.id = null;
core.changeFloor(data.floorId, data.stair, heroLoc, data.time, function () {
core.replay();
if (callback) callback();
});
};
////// 楼层切换 //////

View File

@ -698,7 +698,44 @@ maps.prototype.getMapBlocksObj = function (floorId, noCache) {
////// 将背景前景层变成二维数组的形式 //////
maps.prototype._getBgFgMapArray = function (name, floorId, noCache) {
// see src/plugin/game/loopMap.js
floorId = floorId || core.status.floorId;
if (!floorId) return [];
var width = core.floors[floorId].width;
var height = core.floors[floorId].height;
if (!noCache && core.status[name + 'maps'][floorId])
return core.status[name + 'maps'][floorId];
var arr =
main.mode == 'editor' &&
!(window.editor && editor.uievent && editor.uievent.isOpen)
? core.cloneArray(editor[name + 'map'])
: null;
if (arr == null)
arr = core.cloneArray(core.floors[floorId][name + 'map'] || []);
for (var y = 0; y < height; ++y) {
if (arr[y] == null) arr[y] = Array(width).fill(0);
}
(core.getFlag('__' + name + 'v__', {})[floorId] || []).forEach(function (
one
) {
arr[one[1]][one[0]] = one[2] || 0;
});
(core.getFlag('__' + name + 'd__', {})[floorId] || []).forEach(function (
one
) {
arr[one[1]][one[0]] = 0;
});
if (main.mode == 'editor') {
for (var x = 0; x < width; x++) {
for (var y = 0; y < height; y++) {
arr[y][x] = arr[y][x].idnum || arr[y][x] || 0;
}
}
}
if (core.status[name + 'maps']) core.status[name + 'maps'][floorId] = arr;
return arr;
};
maps.prototype.getBgMapArray = function (floorId) {

View File

@ -5,7 +5,7 @@ function main() {
this.version = '2.A'; // 游戏版本号如果更改了游戏内容建议修改此version以免造成缓存问题。
this.useCompress = false; // 是否使用压缩文件
this.pluginUseCompress = false;
this.pluginUseCompress = false; // 是否是构建版样板,不用改动
// 当你即将发布你的塔时请使用“JS代码压缩工具”将所有js代码进行压缩然后将这里的useCompress改为true。
// 请注意只有useCompress是false时才会读取floors目录下的文件为true时会直接读取libs目录下的floors.min.js文件。
// 如果要进行剧本的修改请务必将其改成false。
@ -804,74 +804,74 @@ main.prototype.listen = function () {
};
////// 手机端的按钮1-7 //////
// main.statusBar.image.btn1.onclick = function (e) {
// e.stopPropagation();
// core.onkeyUp({
// keyCode: 49,
// altKey: core.getLocalStorage('altKey')
// });
// };
main.statusBar.image.btn1.onclick = function (e) {
e.stopPropagation();
core.onkeyUp({
keyCode: 49,
altKey: core.getLocalStorage('altKey')
});
};
// main.statusBar.image.btn2.onclick = function (e) {
// e.stopPropagation();
// core.onkeyUp({
// keyCode: 50,
// altKey: core.getLocalStorage('altKey')
// });
// };
main.statusBar.image.btn2.onclick = function (e) {
e.stopPropagation();
core.onkeyUp({
keyCode: 50,
altKey: core.getLocalStorage('altKey')
});
};
// main.statusBar.image.btn3.onclick = function (e) {
// e.stopPropagation();
// core.onkeyUp({
// keyCode: 51,
// altKey: core.getLocalStorage('altKey')
// });
// };
main.statusBar.image.btn3.onclick = function (e) {
e.stopPropagation();
core.onkeyUp({
keyCode: 51,
altKey: core.getLocalStorage('altKey')
});
};
// main.statusBar.image.btn4.onclick = function (e) {
// e.stopPropagation();
// core.onkeyUp({
// keyCode: 52,
// altKey: core.getLocalStorage('altKey')
// });
// };
main.statusBar.image.btn4.onclick = function (e) {
e.stopPropagation();
core.onkeyUp({
keyCode: 52,
altKey: core.getLocalStorage('altKey')
});
};
// main.statusBar.image.btn5.onclick = function (e) {
// e.stopPropagation();
// core.onkeyUp({
// keyCode: 53,
// altKey: core.getLocalStorage('altKey')
// });
// };
main.statusBar.image.btn5.onclick = function (e) {
e.stopPropagation();
core.onkeyUp({
keyCode: 53,
altKey: core.getLocalStorage('altKey')
});
};
// main.statusBar.image.btn6.onclick = function (e) {
// e.stopPropagation();
// core.onkeyUp({
// keyCode: 54,
// altKey: core.getLocalStorage('altKey')
// });
// };
main.statusBar.image.btn6.onclick = function (e) {
e.stopPropagation();
core.onkeyUp({
keyCode: 54,
altKey: core.getLocalStorage('altKey')
});
};
// main.statusBar.image.btn7.onclick = function (e) {
// e.stopPropagation();
// core.onkeyUp({
// keyCode: 55,
// altKey: core.getLocalStorage('altKey')
// });
// };
main.statusBar.image.btn7.onclick = function (e) {
e.stopPropagation();
core.onkeyUp({
keyCode: 55,
altKey: core.getLocalStorage('altKey')
});
};
// main.statusBar.image.btn8.onclick = function (e) {
// e.stopPropagation();
// if (core.getLocalStorage('altKey')) {
// core.removeLocalStorage('altKey');
// core.drawTip('Alt模式已关闭。');
// main.statusBar.image.btn8.style.filter = '';
// } else {
// core.setLocalStorage('altKey', true);
// core.drawTip('Alt模式已开启此模式下1~7按钮视为Alt+1~7。');
// main.statusBar.image.btn8.style.filter = 'sepia(1) contrast(1.5)';
// }
// };
main.statusBar.image.btn8.onclick = function (e) {
e.stopPropagation();
if (core.getLocalStorage('altKey')) {
core.removeLocalStorage('altKey');
core.drawTip('Alt模式已关闭。');
main.statusBar.image.btn8.style.filter = '';
} else {
core.setLocalStorage('altKey', true);
core.drawTip('Alt模式已开启此模式下1~7按钮视为Alt+1~7。');
main.statusBar.image.btn8.style.filter = 'sepia(1) contrast(1.5)';
}
};
window.onblur = function () {
if (core && core.control) {

View File

@ -254,6 +254,51 @@ var functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a = {
core.changeFloor(toId, stair, loc, null, callback);
return true;
},
afterGetItem: function () {
// 获得一个道具后触发的事件
// itemId获得的道具IDx和y是该道具所在的坐标
// isGentleClick是否是轻按触发的
const potionItems = [
'redPotion',
'bluePotion',
'yellowPotion',
'greenPotion'
];
if (potionItems.includes(itemId)) core.playSound('回血');
else core.playSound('获得道具');
const todo = [];
// 检查该点的获得道具后事件。
if (core.status.floorId == null) return;
const event =
core.floors[core.status.floorId].afterGetItem[`${x},${y}`];
if (
event &&
(event instanceof Array ||
!isGentleClick ||
!event.disableOnGentleClick)
) {
core.unshift(todo, event);
}
if (todo.length > 0) core.insertAction(todo, x, y);
},
afterOpenDoor: function () {
// 开一个门后触发的事件
const todo = [];
// 检查该点的获得开门后事件。
if (core.status.floorId == null) return;
const event =
core.floors[core.status.floorId].afterOpenDoor[`${x},${y}`];
if (event) core.unshift(todo, event);
if (todo.length > 0) core.insertAction(todo, x, y);
if (core.status.event.id == null) core.continueAutomaticRoute();
else core.clearContinueAutomaticRoute();
}
},
control: {

View File

@ -1,8 +1,229 @@
var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = {
init: function () {
// 这看不到插件插件全放到plugin文件夹里面了要看的话去 关于游戏 的开源地址里面看
// 直接把仓库clone下来或者下载zip都行
// 脚本编辑同理一部分在plugin里面
// 对于一部分的常用插件,样板已经内置,同时配有开关,可以在设置里面开关
// 以及那些只提供api的插件也是已经内置
// 这里内置的插件只有不容易开关的插件
this._afterLoadResources = function () {};
},
fiveLayer: function () {
// 注册插件
Mota.Plugin.register('fiveLayer_g', { init }, init);
// 创建新图层
function createCanvas(name, zIndex) {
if (!name) return;
var canvas = document.createElement('canvas');
canvas.id = name;
canvas.className = 'gameCanvas no-anti-aliasing';
// 编辑器模式下设置zIndex会导致加入的图层覆盖优先级过高
if (main.mode != 'editor') canvas.style.zIndex = zIndex || 0;
// 将图层插入进游戏内容
document.getElementById('gameDraw').appendChild(canvas);
var ctx = canvas.getContext('2d');
core.canvas[name] = ctx;
return canvas;
}
function init() {
var bg2Canvas = createCanvas('bg2', 20);
var fg2Canvas = createCanvas('fg2', 63);
// 大地图适配
core.bigmap.canvas = [
'bg2',
'fg2',
'bg',
'event',
'event2',
'fg',
'damage'
];
core.initStatus.bg2maps = {};
core.initStatus.fg2maps = {};
if (main.mode == 'editor') {
/*插入编辑器的图层 不做此步新增图层无法在编辑器显示*/
// 编辑器图层覆盖优先级 eui > efg > fg(前景层) > event2(48*32图块的事件层) > event(事件层) > bg(背景层)
// 背景层2(bg2) 插入事件层(event)之前(即bg与event之间)
document
.getElementById('mapEdit')
.insertBefore(bg2Canvas, document.getElementById('event'));
// 前景层2(fg2) 插入编辑器前景(efg)之前(即fg之后)
document
.getElementById('mapEdit')
.insertBefore(fg2Canvas, document.getElementById('ebm'));
// 原本有三个图层 从4开始添加
var num = 4;
// 新增图层存入editor.dom中
editor.dom.bg2c = core.canvas.bg2.canvas;
editor.dom.bg2Ctx = core.canvas.bg2;
editor.dom.fg2c = core.canvas.fg2.canvas;
editor.dom.fg2Ctx = core.canvas.fg2;
editor.dom.maps.push('bg2map', 'fg2map');
editor.dom.canvas.push('bg2', 'fg2');
// 创建编辑器上的按钮
var createCanvasBtn = name => {
// 电脑端创建按钮
var input = document.createElement('input');
// layerMod4/layerMod5
var id = 'layerMod' + num++;
// bg2map/fg2map
var value = name + 'map';
input.type = 'radio';
input.name = 'layerMod';
input.id = id;
input.value = value;
editor.dom[id] = input;
input.onchange = () => {
editor.uifunctions.setLayerMod(value);
};
return input;
};
var createCanvasBtn_mobile = name => {
// 手机端往选择列表中添加子选项
var input = document.createElement('option');
var id = 'layerMod' + num++;
var value = name + 'map';
input.name = 'layerMod';
input.value = value;
editor.dom[id] = input;
return input;
};
if (!editor.isMobile) {
var input = createCanvasBtn('bg2');
var input2 = createCanvasBtn('fg2');
// 获取事件层及其父节点
var child = document.getElementById('layerMod'),
parent = child.parentNode;
// 背景层2插入事件层前
parent.insertBefore(input, child);
// 不能直接更改背景层2的innerText 所以创建文本节点
var txt = document.createTextNode('背2');
// 插入事件层前(即新插入的背景层2前)
parent.insertBefore(txt, child);
// 向最后插入前景层2(即插入前景层后)
parent.appendChild(input2);
var txt2 = document.createTextNode('前2');
parent.appendChild(txt2);
} else {
var input = createCanvasBtn_mobile('bg2');
var input2 = createCanvasBtn_mobile('fg2');
// 手机端因为是选项 所以可以直接改innerText
input.innerText = '背景2';
input2.innerText = '前景2';
var parent = document.getElementById('layerMod');
parent.insertBefore(input, parent.children[1]);
parent.appendChild(input2);
}
}
maps.prototype._loadFloor_doNotCopy = function () {
return [
'firstArrive',
'eachArrive',
'blocks',
'parallelDo',
'map',
'bgmap',
'fgmap',
'bg2map',
'fg2map',
'events',
'changeFloor',
'afterBattle',
'afterGetItem',
'afterOpenDoor',
'cannotMove',
'enemy'
];
};
////// 绘制背景和前景层 //////
maps.prototype._drawBg_draw = function (
floorId,
toDrawCtx,
cacheCtx,
config
) {
config.ctx = cacheCtx;
core.maps._drawBg_drawBackground(floorId, config);
// ------ 调整这两行的顺序来控制是先绘制贴图还是先绘制背景图块;后绘制的覆盖先绘制的。
core.maps._drawFloorImages(
floorId,
config.ctx,
'bg',
null,
null,
config.onMap
);
core.maps._drawBgFgMap(floorId, 'bg', config);
if (config.onMap) {
core.drawImage(
toDrawCtx,
cacheCtx.canvas,
core.bigmap.v2 ? -32 : 0,
core.bigmap.v2 ? -32 : 0
);
core.clearMap('bg2');
core.clearMap(cacheCtx);
}
core.maps._drawBgFgMap(floorId, 'bg2', config);
if (config.onMap)
core.drawImage(
'bg2',
cacheCtx.canvas,
core.bigmap.v2 ? -32 : 0,
core.bigmap.v2 ? -32 : 0
);
config.ctx = toDrawCtx;
};
maps.prototype._drawFg_draw = function (
floorId,
toDrawCtx,
cacheCtx,
config
) {
config.ctx = cacheCtx;
// ------ 调整这两行的顺序来控制是先绘制贴图还是先绘制前景图块;后绘制的覆盖先绘制的。
core.maps._drawFloorImages(
floorId,
config.ctx,
'fg',
null,
null,
config.onMap
);
core.maps._drawBgFgMap(floorId, 'fg', config);
if (config.onMap) {
core.drawImage(
toDrawCtx,
cacheCtx.canvas,
core.bigmap.v2 ? -32 : 0,
core.bigmap.v2 ? -32 : 0
);
core.clearMap('fg2');
core.clearMap(cacheCtx);
}
core.maps._drawBgFgMap(floorId, 'fg2', config);
if (config.onMap)
core.drawImage(
'fg2',
cacheCtx.canvas,
core.bigmap.v2 ? -32 : 0,
core.bigmap.v2 ? -32 : 0
);
config.ctx = toDrawCtx;
};
////// 移动判定 //////
maps.prototype._generateMovableArray_arrays = function (floorId) {
return {
bgArray: this.getBgMapArray(floorId),
fgArray: this.getFgMapArray(floorId),
eventArray: this.getMapArray(floorId),
bg2Array: this._getBgFgMapArray('bg2', floorId),
fg2Array: this._getBgFgMapArray('fg2', floorId)
};
};
}
}
};

View File

@ -12,15 +12,39 @@ import {
mainSetting,
settingStorage
} from './main/setting';
import { KeyCode } from '@/plugin/keyCodes';
import { KeyCode, ScanCode } from '@/plugin/keyCodes';
import { status } from '@/plugin/ui/statusBar';
import './plugin';
import './package';
import { AudioPlayer } from './audio/audio';
import { CustomToolbar } from './main/custom/toolbar';
import { Hotkey } from './main/custom/hotkey';
import { Keyboard } from './main/custom/keyboard';
import {
Hotkey,
checkAssist,
isAssist,
unwarpBinary
} from './main/custom/hotkey';
import { Keyboard, generateKeyboardEvent } from './main/custom/keyboard';
import './main/layout';
import { MComponent, icon, m } from './main/layout';
import { createSettingComponents } from './main/init/settings';
import {
createToolbarComponents,
createToolbarEditorComponents
} from './main/init/toolbar';
import { VirtualKey } from './main/init/misc';
import * as utils from '@/plugin/utils';
import * as use from '@/plugin/use';
import * as mark from '@/plugin/mark';
import * as keyCodes from '@/plugin/keyCodes';
import { addAnimate, removeAnimate } from '@/plugin/animateController';
import * as bookTools from '@/plugin/ui/book';
import * as commonTools from '@/plugin/ui/common';
import * as equipboxTools from '@/plugin/ui/equipbox';
import * as fixedTools from '@/plugin/ui/fixed';
import * as flyTools from '@/plugin/ui/fly';
import * as statusBarTools from '@/plugin/ui/statusBar';
import * as toolboxTools from '@/plugin/ui/toolbox';
// ----- 类注册
Mota.register('class', 'AudioPlayer', AudioPlayer);
@ -36,8 +60,16 @@ Mota.register('class', 'SettingDisplayer', SettingDisplayer);
Mota.register('class', 'SoundController', SoundController);
Mota.register('class', 'SoundEffect', SoundEffect);
Mota.register('class', 'UiController', UiController);
Mota.register('class', 'MComponent', MComponent);
// ----- 函数注册
Mota.register('fn', 'm', m);
Mota.register('fn', 'icon', icon);
Mota.register('fn', 'unwrapBinary', unwarpBinary);
Mota.register('fn', 'checkAssist', checkAssist);
Mota.register('fn', 'isAssist', isAssist);
Mota.register('fn', 'generateKeyboardEvent', generateKeyboardEvent);
Mota.register('fn', 'addAnimate', addAnimate);
Mota.register('fn', 'removeAnimate', removeAnimate);
// ----- 变量注册
Mota.register('var', 'mainUi', mainUi);
Mota.register('var', 'fixedUi', fixedUi);
@ -46,7 +78,29 @@ Mota.register('var', 'sound', sound);
Mota.register('var', 'gameKey', gameKey);
Mota.register('var', 'mainSetting', mainSetting);
Mota.register('var', 'KeyCode', KeyCode);
Mota.register('var', 'ScanCode', ScanCode);
Mota.register('var', 'settingStorage', settingStorage);
Mota.register('var', 'status', status);
// ----- 模块注册
Mota.register('module', 'CustomComponents', {
createSettingComponents,
createToolbarComponents,
createToolbarEditorComponents
});
Mota.register('module', 'MiscComponents', {
VirtualKey
});
Mota.register('module', 'RenderUtils', utils);
Mota.register('module', 'Use', use);
Mota.register('module', 'Mark', mark);
Mota.register('module', 'KeyCodes', keyCodes);
Mota.register('module', 'UITools', {
book: bookTools,
common: commonTools,
equipbox: equipboxTools,
fixed: fixedTools,
fly: flyTools,
statusBar: statusBarTools,
toolbox: toolboxTools
});

View File

@ -27,6 +27,7 @@ import * as frag from '@/plugin/fx/frag';
import * as use from '@/plugin/use';
import * as gameCanvas from '@/plugin/fx/gameCanvas';
import * as smooth from '@/plugin/fx/smoothView';
import * as shader from './fx/shader';
Mota.Plugin.register('shadow_r', shadow, shadow.init);
Mota.Plugin.register('gameShadow_r', gameShadow, gameShadow.init);
@ -38,3 +39,4 @@ Mota.Plugin.register('frag_r', frag, frag.init);
Mota.Plugin.register('use_r', use);
Mota.Plugin.register('gameCanvas_r', gameCanvas);
Mota.Plugin.register('smooth_r', smooth, smooth.init);
Mota.Plugin.register('shader_r', shader);

View File

@ -7,8 +7,16 @@ import type {
IndexedEventEmitter
} from '@/core/common/eventEmitter';
import type { loading } from './game';
import type { Hotkey } from '@/core/main/custom/hotkey';
import type { Keyboard } from '@/core/main/custom/keyboard';
import type {
Hotkey,
unwarpBinary,
checkAssist,
isAssist
} from '@/core/main/custom/hotkey';
import type {
Keyboard,
generateKeyboardEvent
} from '@/core/main/custom/keyboard';
import type { CustomToolbar } from '@/core/main/custom/toolbar';
import type { Focus, GameUi, UiController } from '@/core/main/custom/ui';
import type { gameListener, hook } from './game';
@ -17,8 +25,25 @@ import type { GameStorage } from '@/core/main/storage';
import type { DamageEnemy, EnemyCollection } from './enemy/damage';
import type { specials } from './enemy/special';
import type { Range } from '@/plugin/game/range';
import type { KeyCode } from '@/plugin/keyCodes';
import type { KeyCode, ScanCode } from '@/plugin/keyCodes';
import type { Ref } from 'vue';
import type { MComponent, m, icon } from '@/core/main/layout';
import type { addAnimate, removeAnimate } from '@/plugin/animateController';
import type { createSettingComponents } from '@/core/main/init/settings';
import type {
createToolbarComponents,
createToolbarEditorComponents
} from '@/core/main/init/toolbar';
import type * as use from '@/plugin/use';
import type * as mark from '@/plugin/mark';
import type * as keyCodes from '@/plugin/keyCodes';
import type * as bookTools from '@/plugin/ui/book';
import type * as commonTools from '@/plugin/ui/common';
import type * as equipboxTools from '@/plugin/ui/equipbox';
import type * as fixedTools from '@/plugin/ui/fixed';
import type * as flyTools from '@/plugin/ui/fly';
import type * as statusBarTools from '@/plugin/ui/statusBar';
import type * as toolboxTools from '@/plugin/ui/toolbox';
import type * as battle from './enemy/battle';
import type * as hero from './hero';
@ -27,7 +52,7 @@ interface ClassInterface {
EventEmitter: typeof EventEmitter;
IndexedEventEmitter: typeof IndexedEventEmitter;
Disposable: typeof Disposable;
// 定义于渲染进程,录像中会进行polyfill但是不执行任何内容
// 定义于渲染进程,录像验证使用会报错
GameStorage: typeof GameStorage;
MotaSetting: typeof MotaSetting;
SettingDisplayer: typeof SettingDisplayer;
@ -41,7 +66,7 @@ interface ClassInterface {
SoundEffect: typeof SoundEffect;
SoundController: typeof SoundController;
BgmController: typeof BgmController;
// todo: 放到插件 ShaderEffect: typeof ShaderEffect;
MComponent: typeof MComponent;
// 定义于游戏进程,渲染进程依然可用
Range: typeof Range;
EnemyCollection: typeof EnemyCollection;
@ -52,11 +77,15 @@ type _IBattle = typeof battle;
type _IHero = typeof hero;
interface FunctionInterface extends _IBattle, _IHero {
// 定义于渲染进程录像中会进行polyfill但是不执行任何内容
readyAllResource(): void;
// 定义于游戏进程,渲染进程依然可用
// todo
// 定义于渲染进程,录像验证中会出错
m: typeof m;
icon: typeof icon;
unwrapBinary: typeof unwarpBinary;
checkAssist: typeof checkAssist;
isAssist: typeof isAssist;
generateKeyboardEvent: typeof generateKeyboardEvent;
addAnimate: typeof addAnimate;
removeAnimate: typeof removeAnimate;
}
interface VariableInterface {
@ -69,7 +98,7 @@ interface VariableInterface {
mainUi: UiController;
fixedUi: UiController;
KeyCode: typeof KeyCode;
// isMobile: boolean;
ScanCode: typeof ScanCode;
bgm: BgmController;
sound: SoundController;
settingStorage: GameStorage;
@ -79,7 +108,23 @@ interface VariableInterface {
enemySpecials: typeof specials;
}
interface ModuleInterface {}
interface ModuleInterface {
CustomComponents: {
createSettingComponents: typeof createSettingComponents;
createToolbarComponents: typeof createToolbarComponents;
createToolbarEditorComponents: typeof createToolbarEditorComponents;
};
Use: typeof use;
Mark: typeof mark;
KeyCodes: typeof keyCodes;
UITools: typeof bookTools &
typeof commonTools &
typeof equipboxTools &
typeof fixedTools &
typeof flyTools &
typeof statusBarTools &
typeof toolboxTools;
}
interface SystemInterfaceMap {
class: ClassInterface;
@ -516,7 +561,8 @@ function r<T = undefined>(
fn: (this: T, packages: PackageInterface) => void,
thisArg?: T
) {
if (!main.replayChecking) fn.call(thisArg as T, MPackage.requireAll());
if (!main.replayChecking || main.mode === 'editor')
fn.call(thisArg as T, MPackage.requireAll());
}
/**
@ -535,7 +581,7 @@ function rf<F extends (...params: any) => any, T>(
thisArg?: T
): (this: T, ...params: Parameters<F>) => ReturnType<F> | undefined {
// @ts-ignore
if (main.replayChecking) return () => {};
if (main.replayChecking || main.mode === 'editor') return () => {};
else {
return (...params) => {
return fn.call(thisArg, ...params);

View File

@ -1,8 +1,10 @@
import { loading } from '@/game/game';
const animation: ((time: number) => void)[] = [];
let animateTime = 0;
export default function init() {
loading.once('coreInit', () => {
core.registerAnimationFrame('animateController', true, time => {
if (time - animateTime <= core.values.animateSpeed) return;
for (const fn of animation) {
@ -10,8 +12,7 @@ export default function init() {
}
animateTime = core.animateFrame.animateTime;
});
return { addAnimate, removeAnimate };
}
});
/**
*

View File

@ -1,219 +0,0 @@
// @ts-nocheck
// 创建新图层
function createCanvas(name, zIndex) {
if (!name) return;
var canvas = document.createElement('canvas');
canvas.id = name;
canvas.className = 'gameCanvas no-anti-aliasing';
// 编辑器模式下设置zIndex会导致加入的图层覆盖优先级过高
if (main.mode != 'editor') canvas.style.zIndex = zIndex || 0;
// 将图层插入进游戏内容
document.getElementById('gameDraw').appendChild(canvas);
var ctx = canvas.getContext('2d');
core.canvas[name] = ctx;
return canvas;
}
export function init() {
var bg2Canvas = createCanvas('bg2', 20);
var fg2Canvas = createCanvas('fg2', 63);
// 大地图适配
core.bigmap.canvas = [
'bg2',
'fg2',
'bg',
'event',
'event2',
'fg',
'damage'
];
core.initStatus.bg2maps = {};
core.initStatus.fg2maps = {};
if (main.mode == 'editor') {
/*插入编辑器的图层 不做此步新增图层无法在编辑器显示*/
// 编辑器图层覆盖优先级 eui > efg > fg(前景层) > event2(48*32图块的事件层) > event(事件层) > bg(背景层)
// 背景层2(bg2) 插入事件层(event)之前(即bg与event之间)
document
.getElementById('mapEdit')
.insertBefore(bg2Canvas, document.getElementById('event'));
// 前景层2(fg2) 插入编辑器前景(efg)之前(即fg之后)
document
.getElementById('mapEdit')
.insertBefore(fg2Canvas, document.getElementById('ebm'));
// 原本有三个图层 从4开始添加
var num = 4;
// 新增图层存入editor.dom中
editor.dom.bg2c = core.canvas.bg2.canvas;
editor.dom.bg2Ctx = core.canvas.bg2;
editor.dom.fg2c = core.canvas.fg2.canvas;
editor.dom.fg2Ctx = core.canvas.fg2;
editor.dom.maps.push('bg2map', 'fg2map');
editor.dom.canvas.push('bg2', 'fg2');
// 创建编辑器上的按钮
var createCanvasBtn = name => {
// 电脑端创建按钮
var input = document.createElement('input');
// layerMod4/layerMod5
var id = 'layerMod' + num++;
// bg2map/fg2map
var value = name + 'map';
input.type = 'radio';
input.name = 'layerMod';
input.id = id;
input.value = value;
editor.dom[id] = input;
input.onchange = () => {
editor.uifunctions.setLayerMod(value);
};
return input;
};
var createCanvasBtn_mobile = name => {
// 手机端往选择列表中添加子选项
var input = document.createElement('option');
var id = 'layerMod' + num++;
var value = name + 'map';
input.name = 'layerMod';
input.value = value;
editor.dom[id] = input;
return input;
};
if (!editor.isMobile) {
var input = createCanvasBtn('bg2');
var input2 = createCanvasBtn('fg2');
// 获取事件层及其父节点
var child = document.getElementById('layerMod'),
parent = child.parentNode;
// 背景层2插入事件层前
parent.insertBefore(input, child);
// 不能直接更改背景层2的innerText 所以创建文本节点
var txt = document.createTextNode('背2');
// 插入事件层前(即新插入的背景层2前)
parent.insertBefore(txt, child);
// 向最后插入前景层2(即插入前景层后)
parent.appendChild(input2);
var txt2 = document.createTextNode('前2');
parent.appendChild(txt2);
} else {
var input = createCanvasBtn_mobile('bg2');
var input2 = createCanvasBtn_mobile('fg2');
// 手机端因为是选项 所以可以直接改innerText
input.innerText = '背景2';
input2.innerText = '前景2';
var parent = document.getElementById('layerMod');
parent.insertBefore(input, parent.children[1]);
parent.appendChild(input2);
}
}
maps.prototype._loadFloor_doNotCopy = function () {
return [
'firstArrive',
'eachArrive',
'blocks',
'parallelDo',
'map',
'bgmap',
'fgmap',
'bg2map',
'fg2map',
'events',
'changeFloor',
'afterBattle',
'afterGetItem',
'afterOpenDoor',
'cannotMove',
'enemy'
];
};
////// 绘制背景和前景层 //////
maps.prototype._drawBg_draw = function (
floorId,
toDrawCtx,
cacheCtx,
config
) {
config.ctx = cacheCtx;
core.maps._drawBg_drawBackground(floorId, config);
// ------ 调整这两行的顺序来控制是先绘制贴图还是先绘制背景图块;后绘制的覆盖先绘制的。
core.maps._drawFloorImages(
floorId,
config.ctx,
'bg',
null,
null,
config.onMap
);
core.maps._drawBgFgMap(floorId, 'bg', config);
if (config.onMap) {
core.drawImage(
toDrawCtx,
cacheCtx.canvas,
core.bigmap.v2 ? -32 : 0,
core.bigmap.v2 ? -32 : 0
);
core.clearMap('bg2');
core.clearMap(cacheCtx);
}
core.maps._drawBgFgMap(floorId, 'bg2', config);
if (config.onMap)
core.drawImage(
'bg2',
cacheCtx.canvas,
core.bigmap.v2 ? -32 : 0,
core.bigmap.v2 ? -32 : 0
);
config.ctx = toDrawCtx;
};
maps.prototype._drawFg_draw = function (
floorId,
toDrawCtx,
cacheCtx,
config
) {
config.ctx = cacheCtx;
// ------ 调整这两行的顺序来控制是先绘制贴图还是先绘制前景图块;后绘制的覆盖先绘制的。
core.maps._drawFloorImages(
floorId,
config.ctx,
'fg',
null,
null,
config.onMap
);
core.maps._drawBgFgMap(floorId, 'fg', config);
if (config.onMap) {
core.drawImage(
toDrawCtx,
cacheCtx.canvas,
core.bigmap.v2 ? -32 : 0,
core.bigmap.v2 ? -32 : 0
);
core.clearMap('fg2');
core.clearMap(cacheCtx);
}
core.maps._drawBgFgMap(floorId, 'fg2', config);
if (config.onMap)
core.drawImage(
'fg2',
cacheCtx.canvas,
core.bigmap.v2 ? -32 : 0,
core.bigmap.v2 ? -32 : 0
);
config.ctx = toDrawCtx;
};
////// 移动判定 //////
maps.prototype._generateMovableArray_arrays = function (floorId) {
return {
bgArray: this.getBgMapArray(floorId),
fgArray: this.getFgMapArray(floorId),
eventArray: this.getMapArray(floorId),
bg2Array: this._getBgFgMapArray('bg2', floorId),
fg2Array: this._getBgFgMapArray('fg2', floorId)
};
};
}

View File

@ -1,38 +1,24 @@
/* @__PURE__ */ import './dev/hotReload'; // 仅开发会用到
import * as fiveLayer from './fiveLayer';
/* @__PURE__ */ import './dev/hotReload.js'; // 仅开发会用到
import * as heroFourFrames from './fx/heroFourFrames';
import * as itemDetail from './fx/itemDetail';
import * as replay from './replay';
import * as ui from './ui';
import * as rewrite from './fx/rewrite';
import * as halo from './fx/halo';
import * as loopMap from './loopMap';
import * as removeMap from './removeMap';
import * as shop from './shop';
import * as skill from './skill';
import * as skillTree from './skillTree';
import * as study from './study';
import * as towerBoss from './towerBoss';
import * as utils from './utils';
import * as chase from './chase';
import * as remainEnemy from './enemy/remainEnemy';
import * as checkBlock from './enemy/checkblock';
Mota.Plugin.register('utils_g', utils);
Mota.Plugin.register('loopMap_g', loopMap, loopMap.init);
Mota.Plugin.register('shop_g', shop);
Mota.Plugin.register('replay_g', replay, replay.init);
Mota.Plugin.register('skillTree_g', skillTree);
Mota.Plugin.register('removeMap_g', removeMap);
Mota.Plugin.register('chase_g', chase);
Mota.Plugin.register('skill_g', skill);
Mota.Plugin.register('towerBoss_g', towerBoss);
Mota.Plugin.register('fiveLayer_g', fiveLayer, fiveLayer.init);
Mota.Plugin.register('heroFourFrames_g', heroFourFrames, heroFourFrames.init);
Mota.Plugin.register('rewrite_g', rewrite, rewrite.init);
Mota.Plugin.register('itemDetail_g', itemDetail, itemDetail.init);
Mota.Plugin.register('halo_g', halo);
Mota.Plugin.register('study_g', study);
Mota.Plugin.register('remainEnemy_g', remainEnemy);
Mota.Plugin.register('checkBlock_g', checkBlock, checkBlock.init);
// todo: 这几个不应该放到插件

View File

@ -1,7 +1,3 @@
import { upgradeSkill } from './skillTree';
const replayableSettings = ['autoSkill'];
let cliping = false;
let startIndex = 0;
@ -21,45 +17,6 @@ export function clip(...replace: string[]) {
}
export function init() {
// 注册修改设置的录像操作
core.registerReplayAction('settings', name => {
if (!name.startsWith('set:')) return false;
const [, setting, value] = name.split(':');
const v = eval(value);
if (typeof v !== 'boolean') return false;
if (!replayableSettings.includes(setting)) return false;
flags[setting] = v;
core.status.route.push(name);
core.replay();
return true;
});
core.registerReplayAction('upgradeSkill', name => {
if (!name.startsWith('skill:')) return false;
const skill = parseInt(name.slice(6));
upgradeSkill(skill);
core.status.route.push(name);
core.replay();
return true;
});
core.registerReplayAction('study', name => {
// todo
// if (!name.startsWith('study:')) return false;
// const [num, x, y] = name
// .slice(6)
// .split(',')
// .map(v => parseInt(v));
// if (!canStudySkill(num)) return false;
// const id = core.getBlockId(x, y);
// const enemy = core.getEnemyInfo(id, void 0, x, y);
// if (!enemy.special.includes(num)) return false;
// studySkill(enemy, num);
// core.status.route.push(name);
// core.replay();
return true;
});
// 商店
let shopOpened = false;
let openedShopId = '';

View File

@ -223,7 +223,7 @@ export enum KeyCode {
/**
* keyboardEvent.code
*/
export const enum ScanCode {
export enum ScanCode {
DependsOnKbLayout = -1,
None,
Hyper,

View File

@ -1,5 +1,3 @@
import { has } from '../utils';
interface ClsMap {
tools: '消耗道具';
constants: '永久道具';