refactor: 完全修改dom结构

This commit is contained in:
unanmed 2024-11-19 22:28:48 +08:00
parent 4e21f60696
commit b87a2b3e2f
32 changed files with 370 additions and 1902 deletions

View File

@ -4,7 +4,7 @@
<head> <head>
<meta http-equiv='content-type' content='text/html' charset='utf-8'> <meta http-equiv='content-type' content='text/html' charset='utf-8'>
<meta http-equiv='X-UA-Compatible' content='IE=Edge, chrome=1'> <meta http-equiv='X-UA-Compatible' content='IE=Edge, chrome=1'>
<meta name='author' content='ckcz123'> <meta name='author' content='AncTe'>
<meta name='viewport' <meta name='viewport'
content='width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=yes'> content='width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=yes'>
<title>HTML5魔塔</title> <title>HTML5魔塔</title>
@ -19,137 +19,16 @@
</head> </head>
<body> <body>
<div id='startImageBackgroundDiv'>
<div id='startImageDiv'></div>
<img id='startImageLogo' />
</div>
<div id="game">
<!-- injection --> <!-- injection -->
<div id='gameGroup'> <div id="game">
<p id='mainTips'>请稍候...</p> <div id="game-draw">
<div id='startPanel'>
<div id='startTop'>
<div id='startTopProgressBar'>
<div id='startTopProgress'></div>
</div>
<p id='startTopLoadTips'>资源即将开始加载</p>
<p id='startTopHint'>HTML5魔塔游戏平台享受更多魔塔游戏<br />https://h5mota.com/</p>
</div>
</div>
<div id='floorMsgGroup'>
<p id='logoLabel'></p>
<p id='versionLabel'></p>
<p id='floorNameLabel'></p>
</div>
<div id='statusBar' class="clearfix">
<div class="status" id="floorCol">
<img id="img-floor">
<p class='statusLabel statusText' id='floor'></p>
</div>
<div class="status" id="nameCol">
<img id="img-name">
<p class='statusLabel statusText' id='name'></p>
</div>
<div class="status" id="lvCol">
<img id="img-lv">
<p class='statusLabel statusText' id='lv'></p>
</div>
<div class="status" id='hpmaxCol'>
<img id="img-hpmax">
<p class='statusLabel statusText' id='hpmax'></p>
</div>
<div class="status" id='hpCol'>
<img id="img-hp">
<p class='statusLabel statusText' id='hp'></p>
</div>
<div class="status" id='manaCol'>
<img id="img-mana">
<p class='statusLabel statusText' id='mana'></p>
</div>
<div class="status" id='atkCol'>
<img id="img-atk">
<p class='statusLabel statusText' id='atk'></p>
</div>
<div class="status" id='defCol'>
<img id="img-def">
<p class='statusLabel statusText' id='def'></p>
</div>
<div class="status" id="mdefCol">
<img id="img-mdef">
<p class='statusLabel statusText' id='mdef'></p>
</div>
<div class="status" id="moneyCol">
<img id="img-money">
<p class='statusLabel statusText' id='money'></p>
</div>
<div class="status" id="expCol">
<img id="img-exp">
<p class='statusLabel statusText' id='exp'></p>
</div>
<div class="status" id="upCol">
<img id="img-up">
<p class='statusLabel statusText' id='up'></p>
</div>
<div class="status" id="skillCol">
<img id="img-skill">
<p class='statusLabel statusText' id='skill' style='font-style: normal'></p>
</div>
<div class="status" id='keyCol'>
<span class='statusLabel' id='yellowKey' style="color:#FFCCAA"></span>
<span class='statusLabel' id='blueKey' style="color:#AAAADD"></span>
<span class='statusLabel' id='redKey' style="color:#FF8888"></span>
<span class='statusLabel' id='greenKey' style="color:#88FF88"></span>
</div>
<div class="status" id='pzfCol'>
<span class='statusLabel' id='pickaxe' style="color: #BC6E27"></span>
<span class='statusLabel' id='bomb' style="color: #FA14B9"></span>
<span class='statusLabel' id='fly' style="color: #8DB600"></span>
</div>
<div class="status" id="debuffCol">
<span class='statusLabel' id='poison' style="color: #AFFCA8;"></span>
<span class='statusLabel' id='weak' style="color: #FECCD0;"></span>
<span class='statusLabel' id='curse' style="color: #C2F4E7;"></span>
</div>
<!-- 状态栏canvas化 -->
<canvas id="statusCanvas" style="position: absolute; left: 0; top: 0;"></canvas>
</div>
<div id="toolBar" class="clearfix">
<img class="tools" id='img-book'>
<img class="tools" id='img-fly'>
<img class="tools" id='img-toolbox'>
<img class="tools" id='img-keyboard'>
<img class="tools" id='img-shop'>
<img class="tools" id='img-save'>
<img class="tools" id='img-load'>
<img class="tools" id='img-settings'>
<img class="tools" id='img-btn1' style='display:none'>
<img class="tools" id='img-btn2' style='display:none'>
<img class="tools" id='img-btn3' style='display:none'>
<img class="tools" id='img-btn4' style='display:none'>
<img class="tools" id='img-btn5' style='display:none'>
<img class="tools" id='img-btn6' style='display:none'>
<img class="tools" id='img-btn7' style='display:none'>
<img class="tools" id='img-btn8' style='display:none'>
<p class="statusLabel tools" id="hard"></p>
</div>
<div id="gameDraw">
<div id="gif"></div>
<div id="gif2"></div>
<canvas class='gameCanvas draw-canvas hide' id='bg'></canvas>
<canvas class='gameCanvas draw-canvas hide' id='event'></canvas>
<canvas class='gameCanvas draw-canvas hide' id='hero'></canvas>
<canvas class='gameCanvas draw-canvas hide' id='event2'></canvas>
<canvas class='gameCanvas draw-canvas hide' id='fg'></canvas>
<canvas class='gameCanvas hide' id='damage'></canvas>
<canvas class='gameCanvas hide' id='animate'></canvas>
<canvas class='gameCanvas' id='curtain'></canvas> <canvas class='gameCanvas' id='curtain'></canvas>
<canvas class='gameCanvas' id='ui'></canvas> <canvas class='gameCanvas' id='ui'></canvas>
<canvas class='gameCanvas' id='data'>此浏览器不支持HTML5</canvas> <canvas class='gameCanvas' id='data'>此浏览器不支持HTML5</canvas>
<canvas id="render-main"></canvas>
<div id="next"></div> <div id="next"></div>
</div> </div>
</div> </div>
</div>
<div id='inputDiv'> <div id='inputDiv'>
<div id='inputDialog'> <div id='inputDialog'>
<p id="inputMessage">请输入文字...</p> <p id="inputMessage">请输入文字...</p>

View File

@ -763,26 +763,17 @@ actions.prototype._sys_onup = function (x, y, px, py) {
}; };
////// 获得点击事件相对左上角的坐标 ////// ////// 获得点击事件相对左上角的坐标 //////
actions.prototype._getClickLoc = function (x, y) { actions.prototype._getClickLoc = function (x, y, isClient = false) {
var statusBar = { x: 0, y: 0 }; var size = 32 * core.domStyle.scale;
var size = 32;
size = size * core.domStyle.scale;
if (core.domStyle.isVertical) { if (!isClient) {
statusBar.x = 3; return { x, y, size };
statusBar.y =
core.dom.statusBar.offsetHeight +
3 +
32 * core.values.statusCanvasRowsOnMobile;
} else { } else {
statusBar.x = core.dom.statusBar.offsetWidth + 3; const ele = core.dom.gameDraw;
statusBar.y = 3; const left = ele.offsetLeft;
const top = ele.offsetTop;
return { x: x - left, y: y - top, size };
} }
var left = core.dom.gameGroup.offsetLeft + statusBar.x;
var top = core.dom.gameGroup.offsetTop + statusBar.y;
var loc = { x: Math.max(x - left), y: Math.max(y - top, 0), size: size };
return loc;
}; };
////// 滑动鼠标滚轮时的操作 ////// ////// 滑动鼠标滚轮时的操作 //////

View File

@ -47,7 +47,6 @@ control.prototype._init = function () {
this.registerReplayAction('ignoreInput', this._replayAction_ignoreInput); this.registerReplayAction('ignoreInput', this._replayAction_ignoreInput);
this.registerReplayAction('no', this._replayAction_no); this.registerReplayAction('no', this._replayAction_no);
// --- 注册系统的resize // --- 注册系统的resize
this.registerResize('gameGroup', this._resize_gameGroup);
this.registerResize('canvas', this._resize_canvas); this.registerResize('canvas', this._resize_canvas);
}; };
@ -251,14 +250,10 @@ control.prototype.showStartAnimate = function (noAnimate, callback) {
Mota.r(() => { Mota.r(() => {
Mota.require('var', 'fixedUi').open('start'); Mota.require('var', 'fixedUi').open('start');
}); });
// core.hideWithAnimate(core.dom.startTop, 20, function () {
// core.control._showStartAnimate_finished(false, callback);
// });
}; };
control.prototype._showStartAnimate_resetDom = function () { control.prototype._showStartAnimate_resetDom = function () {
core.status.played = false; core.status.played = false;
core.dom.gameGroup.style.display = 'none';
core.clearStatus(); core.clearStatus();
core.clearMap('all'); core.clearMap('all');
// 重置音量 // 重置音量
@ -267,7 +262,6 @@ control.prototype._showStartAnimate_resetDom = function () {
}; };
control.prototype._showStartAnimate_finished = function (start, callback) { control.prototype._showStartAnimate_finished = function (start, callback) {
core.dom.startTop.style.display = 'none';
main.selectedButton = null; main.selectedButton = null;
if (start) core.startGame(); if (start) core.startGame();
if (callback) callback(); if (callback) callback();
@ -275,9 +269,7 @@ control.prototype._showStartAnimate_finished = function (start, callback) {
////// 隐藏游戏开始界面 ////// ////// 隐藏游戏开始界面 //////
control.prototype.hideStartAnimate = function (callback) { control.prototype.hideStartAnimate = function (callback) {
core.dom.startPanel.style.display = 'none';
callback?.(); callback?.();
// core.hideWithAnimate(core.dom.startPanel, 20, callback);
}; };
////// 游戏是否已经开始 ////// ////// 游戏是否已经开始 //////
@ -931,6 +923,7 @@ control.prototype.setHeroOpacity = function (
////// 设置画布偏移 ////// 设置画布偏移
control.prototype.setGameCanvasTranslate = function (canvas, x, y) { control.prototype.setGameCanvasTranslate = function (canvas, x, y) {
// Deprecated. Use RenderItem.transform instead.
var c = core.dom.gameCanvas[canvas]; var c = core.dom.gameCanvas[canvas];
x = x * core.domStyle.scale; x = x * core.domStyle.scale;
y = y * core.domStyle.scale; y = y * core.domStyle.scale;
@ -968,22 +961,7 @@ control.prototype.setGameCanvasTranslate = function (canvas, x, y) {
////// 加减画布偏移 ////// 加减画布偏移
control.prototype.addGameCanvasTranslate = function (x, y) { control.prototype.addGameCanvasTranslate = function (x, y) {
for (var ii = 0, canvas; (canvas = core.dom.gameCanvas[ii]); ii++) { // Deprecated. Use RenderItem.transform instead.
var id = canvas.getAttribute('id');
if (id == 'ui' || id == 'data') continue; // UI层和data层不移动
var offsetX = x,
offsetY = y;
if (core.bigmap.canvas.indexOf(id) >= 0) {
if (core.bigmap.v2) {
offsetX -= core.bigmap.offsetX - 32 * core.bigmap.posX + 32;
offsetY -= core.bigmap.offsetY - 32 * core.bigmap.posY + 32;
} else {
offsetX -= core.bigmap.offsetX;
offsetY -= core.bigmap.offsetY;
}
}
core.control.setGameCanvasTranslate(id, offsetX, offsetY);
}
}; };
////// 更新视野范围 ////// ////// 更新视野范围 //////
@ -2670,11 +2648,13 @@ control.prototype.getStatusLabel = function (name) {
////// 设置某个属性的增幅值 ////// ////// 设置某个属性的增幅值 //////
control.prototype.setBuff = function (name, value) { control.prototype.setBuff = function (name, value) {
core.status.hero.buff[name] ??= 1;
core.status.hero.buff[name] = value; core.status.hero.buff[name] = value;
}; };
////// 加减某个属性的增幅值 ////// ////// 加减某个属性的增幅值 //////
control.prototype.addBuff = function (name, value) { control.prototype.addBuff = function (name, value) {
core.status.hero.buff[name] ??= 1;
core.status.hero.buff[name] += value; core.status.hero.buff[name] += value;
}; };
@ -2893,9 +2873,11 @@ control.prototype.getMappedName = function (name) {
////// 更改天气效果 ////// ////// 更改天气效果 //////
control.prototype.setWeather = function (type, level) { control.prototype.setWeather = function (type, level) {
// Deprecated. Use WeatherController API instead. // Deprecated. Use WeatherController API instead.
Mota.r(() => {
const controller = Mota.require('module', 'Weather').controller; const controller = Mota.require('module', 'Weather').controller;
controller.clearWeather(); controller.clearWeather();
if (type !== null && type !== void 0) controller.activate(type, level); if (type !== null && type !== void 0) controller.activate(type, level);
});
}; };
////// 注册一个天气 ////// ////// 注册一个天气 //////
@ -3101,17 +3083,7 @@ control.prototype.setDisplayScale = function (delta) {
////// 清空状态栏 ////// ////// 清空状态栏 //////
control.prototype.clearStatusBar = function () { control.prototype.clearStatusBar = function () {
if (main.mode === 'editor') return; // Deprecated.
Object.keys(core.statusBar).forEach(function (e) {
if (core.statusBar[e].innerHTML != null) {
core.statusBar[e].innerHTML = '&nbsp;';
core.statusBar[e].removeAttribute('_style');
core.statusBar[e].removeAttribute('_value');
}
});
core.statusBar.image.book.style.opacity = 0.3;
if (!core.flags.equipboxButton)
core.statusBar.image.fly.style.opacity = 0.3;
}; };
////// 更新状态栏 ////// ////// 更新状态栏 //////
@ -3183,110 +3155,54 @@ control.prototype._doResize = function (obj) {
////// 屏幕分辨率改变后重新自适应 ////// ////// 屏幕分辨率改变后重新自适应 //////
control.prototype.resize = function () { control.prototype.resize = function () {
if (main.mode == 'editor') return; if (main.mode === 'editor') return;
var clientWidth = main.dom.body.clientWidth, const width = window.innerWidth;
clientHeight = main.dom.body.clientHeight; const height = window.innerHeight;
var BORDER = 3;
var extendToolbar = core.flags.extendToolbar;
var BAR_WIDTH = extendToolbar ? 0 : Math.round(core._PY_ * 0.31);
var horizontalMaxRatio = const auto = Mota.require('var', 'mainSetting').getValue('autoScale', true);
(clientHeight - 2 * BORDER - (extendToolbar ? BORDER : 0)) /
(core._PY_ + (extendToolbar ? 38 : 0));
if ( if (window.innerWidth >= 600) {
clientWidth - 3 * BORDER >= core._PX_ + BAR_WIDTH ||
(clientWidth > clientHeight && horizontalMaxRatio < 1)
) {
// 横屏 // 横屏
core.domStyle.isVertical = false; core.domStyle.isVertical = false;
core.domStyle.availableScale = []; core.domStyle.availableScale = [];
const maxScale = Math.min(width / core._PX_, height / core._PY_);
[1, 1.25, 1.5, 1.75, 2, 2.25, 2.5].forEach(function (v) { [1, 1.25, 1.5, 1.75, 2, 2.25, 2.5].forEach(function (v) {
if ( if (v < maxScale) {
clientWidth - 3 * BORDER >= v * (core._PX_ + BAR_WIDTH) &&
horizontalMaxRatio >= v
) {
core.domStyle.availableScale.push(v); core.domStyle.availableScale.push(v);
} }
}); });
if (core.domStyle.availableScale.indexOf(core.domStyle.scale) < 0) { if (!core.domStyle.availableScale.includes(core.domStyle.scale)) {
core.domStyle.scale = Math.min(1, horizontalMaxRatio); core.domStyle.scale = 1;
} }
core.dom.gameDraw.style.top = '0';
} else { } else {
// 竖屏 // 竖屏
core.domStyle.isVertical = true; core.domStyle.isVertical = true;
core.domStyle.scale = Math.min((clientWidth - 2 * BORDER) / core._PX_); core.domStyle.scale = window.innerWidth / core._PX_;
core.domStyle.availableScale = []; core.domStyle.availableScale = [];
extendToolbar = false; core.dom.gameDraw.style.top = '10vh';
BAR_WIDTH = Math.round(core._PX_ * 0.3);
} }
var statusCanvas = core.flags.statusCanvas, if (!core.domStyle.isVertical) {
statusCanvasRows = core.values.statusCanvasRowsOnMobile || 3; const height = window.innerHeight;
var col = statusCanvas ? statusCanvasRows : Math.ceil(5 / 3); const width = window.innerWidth;
const maxScale = Math.min(height / core._PY_, width / core._PX_);
const target = Number((Math.floor(maxScale * 4) / 4).toFixed(2));
core.domStyle.scale = target - 0.25;
}
var globalAttribute = const pw = core._PX_ * core.domStyle.scale;
core.status.globalAttribute || core.initStatus.globalAttribute; const ph = core._PY_ * core.domStyle.scale;
core.dom.gameDraw.style.width = `${pw}px`;
core.dom.gameDraw.style.height = `${ph}px`;
var obj = { this._doResize({});
clientWidth: clientWidth,
clientHeight: clientHeight,
BORDER: BORDER,
BAR_WIDTH: BAR_WIDTH,
TOOLBAR_HEIGHT: 38,
outerWidth: core._PX_ * core.domStyle.scale + 2 * BORDER,
outerHeight: core._PY_ * core.domStyle.scale + 2 * BORDER,
globalAttribute: globalAttribute,
border:
'3px ' + core.arrayToRGBA(globalAttribute.borderColor) + ' solid',
col: col,
statusBarHeightInVertical: core.domStyle.isVertical
? (32 * col + 6) * core.domStyle.scale + 2 * BORDER
: 0,
toolbarHeightInVertical: core.domStyle.isVertical
? 38 * core.domStyle.scale + 2 * BORDER
: 0,
extendToolbar: extendToolbar,
is15x15: false
};
this._doResize(obj);
this.setToolbarButton(); this.setToolbarButton();
core.updateStatusBar(); core.updateStatusBar();
}; };
control.prototype._resize_gameGroup = function (obj) { control.prototype._resize_gameGroup = function (obj) {
var gameGroup = core.dom.gameGroup; // Deprecated.
var totalWidth, totalHeight;
if (core.domStyle.isVertical) {
totalWidth = obj.outerWidth;
totalHeight =
obj.outerHeight +
obj.statusBarHeightInVertical +
obj.toolbarHeightInVertical;
} else {
totalWidth =
obj.outerWidth +
obj.BAR_WIDTH * core.domStyle.scale +
(obj.extendToolbar ? 0 : obj.BORDER);
totalHeight = obj.outerHeight;
}
gameGroup.style.width = totalWidth + 'px';
gameGroup.style.height = totalHeight + 'px';
gameGroup.style.left = (obj.clientWidth - totalWidth) / 2 + 'px';
gameGroup.style.top =
(obj.clientHeight - totalHeight) / 2 +
(core.domStyle.isVertical ? totalHeight / 8 : 0) +
'px';
// floorMsgGroup
var floorMsgGroup = core.dom.floorMsgGroup;
floorMsgGroup.style = obj.globalAttribute.floorChangingStyle;
floorMsgGroup.style.width = obj.outerWidth - 2 * obj.BORDER + 'px';
floorMsgGroup.style.height = totalHeight - 2 * obj.BORDER + 'px';
floorMsgGroup.style.fontSize = 16 * core.domStyle.scale + 'px';
// startPanel
core.dom.startPanel.style.fontSize = 16 * core.domStyle.scale + 'px';
}; };
control.prototype._resize_canvas = function (obj) { control.prototype._resize_canvas = function (obj) {
@ -3300,26 +3216,6 @@ control.prototype._resize_canvas = function (obj) {
core.resizeCanvas(ctx, core._PX_, core._PY_); core.resizeCanvas(ctx, core._PX_, core._PY_);
} }
core.dom.gif.style.width = innerWidth;
core.dom.gif.style.height = innerHeight;
core.dom.gif2.style.width = innerWidth;
core.dom.gif2.style.height = innerHeight;
core.dom.gameDraw.style.width = innerWidth;
core.dom.gameDraw.style.height = innerHeight;
core.dom.gameDraw.style.top = obj.statusBarHeightInVertical + 'px';
core.dom.gameDraw.style.right = 0;
core.dom.gameDraw.style.boxSizing = 'content-box';
// resize bigmap
core.bigmap.canvas.forEach(function (cn) {
var ratio = core.canvas[cn].canvas.hasAttribute('isHD')
? core.domStyle.scale * devicePixelRatio
: 1;
core.canvas[cn].canvas.style.width =
(core.canvas[cn].canvas.width / ratio) * core.domStyle.scale + 'px';
core.canvas[cn].canvas.style.height =
(core.canvas[cn].canvas.height / ratio) * core.domStyle.scale +
'px';
});
// resize dynamic canvas // resize dynamic canvas
if (!core.isPlaying()) { if (!core.isPlaying()) {
for (var name in core.dymCanvas) { for (var name in core.dymCanvas) {

View File

@ -111,7 +111,7 @@ function core() {
hdCanvas: ['damage', 'ui', 'data'] hdCanvas: ['damage', 'ui', 'data']
}; };
this.bigmap = { this.bigmap = {
canvas: ['bg', 'event', 'event2', 'fg', 'damage'], canvas: [],
offsetX: 0, // in pixel offsetX: 0, // in pixel
offsetY: 0, offsetY: 0,
posX: 0, // posX: 0, //
@ -376,8 +376,6 @@ core.prototype._init_flags = function () {
core.firstData = core.clone(core.data.firstData); core.firstData = core.clone(core.data.firstData);
this._init_sys_flags(); this._init_sys_flags();
core.dom.versionLabel.innerText = core.firstData.version;
core.dom.logoLabel.innerText = core.firstData.title;
document.title = core.firstData.title + ' - HTML5魔塔'; document.title = core.firstData.title + ' - HTML5魔塔';
(core.firstData.shops || []).forEach(function (t) { (core.firstData.shops || []).forEach(function (t) {
core.initStatus.shops[t.id] = t; core.initStatus.shops[t.id] = t;

View File

@ -24,7 +24,6 @@ events.prototype.resetGame = function (hero, hard, floorId, maps, values) {
////// 游戏开始事件 ////// ////// 游戏开始事件 //////
events.prototype.startGame = function (hard, seed, route, callback) { events.prototype.startGame = function (hard, seed, route, callback) {
hard = hard || ''; hard = hard || '';
core.dom.gameGroup.style.display = 'block';
if (!main.replayChecking) { if (!main.replayChecking) {
Mota.require('var', 'fixedUi').closeByName('start'); Mota.require('var', 'fixedUi').closeByName('start');
} }
@ -34,7 +33,6 @@ events.prototype.startGame = function (hard, seed, route, callback) {
// 无动画的开始游戏 // 无动画的开始游戏
if (core.flags.startUsingCanvas || route != null) { if (core.flags.startUsingCanvas || route != null) {
core.dom.startPanel.style.display = 'none';
this._startGame_start(hard, seed, route, callback); this._startGame_start(hard, seed, route, callback);
} else { } else {
core.hideStartAnimate(function () { core.hideStartAnimate(function () {
@ -62,7 +60,6 @@ events.prototype._startGame_start = function (hard, seed, route, callback) {
var todo = []; var todo = [];
if (core.flags.startUsingCanvas) { if (core.flags.startUsingCanvas) {
core.hideStatusBar(); core.hideStatusBar();
core.dom.musicBtn.style.display = 'block';
core.push(todo, core.firstData.startCanvas); core.push(todo, core.firstData.startCanvas);
} }
core.push(todo, { core.push(todo, {
@ -146,7 +143,6 @@ events.prototype.gameOver = function (ending, fromReplay, norank) {
if (!core.status.extraEvent) { if (!core.status.extraEvent) {
core.clearMap('all'); core.clearMap('all');
core.deleteAllCanvas(); core.deleteAllCanvas();
core.dom.gif2.innerHTML = '';
core.setWeather(); core.setWeather();
} }
core.ui.closePanel(); core.ui.closePanel();
@ -783,7 +779,6 @@ events.prototype.changeFloor = function (
floorId = info.floorId; floorId = info.floorId;
info.locked = core.status.lockControl; info.locked = core.status.lockControl;
core.dom.floorNameLabel.innerText = core.status.maps[floorId].title;
core.lockControl(); core.lockControl();
core.stopAutomaticRoute(); core.stopAutomaticRoute();
core.clearContinueAutomaticRoute(); core.clearContinueAutomaticRoute();
@ -820,7 +815,6 @@ events.prototype._changeFloor_getInfo = function (
if (main.mode != 'play' || core.isReplaying()) time = 0; if (main.mode != 'play' || core.isReplaying()) time = 0;
if (time == null) time = core.values.floorChangeTime; if (time == null) time = core.values.floorChangeTime;
time /= 20;
return { return {
floorId: floorId, floorId: floorId,
@ -869,15 +863,17 @@ events.prototype._changeFloor_beforeChange = function (info, callback) {
this._changeFloor_playSound(); this._changeFloor_playSound();
// 需要 setTimeout 执行,不然会出错 // 需要 setTimeout 执行,不然会出错
window.setTimeout(function () { window.setTimeout(function () {
if (info.time == 0) core.events._changeFloor_changing(info, callback); if (info.time === 0 || main.replayChecking) {
else
core.showWithAnimate(
core.dom.floorMsgGroup,
info.time / 2,
function () {
core.events._changeFloor_changing(info, callback); core.events._changeFloor_changing(info, callback);
} else {
const Render = Mota.require('module', 'Render').MotaRenderer;
const main = Render.get('render-main');
const change = main.getElementById('floor-change');
change.setTitle(core.floors[info.floorId]?.title ?? '');
change.showChange(info.time / 2).then(() => {
core.events._changeFloor_changing(info, callback);
});
} }
);
}, 25); }, 25);
}; };
@ -900,15 +896,16 @@ events.prototype._changeFloor_changing = function (info, callback) {
core.drawHero(); core.drawHero();
core.setFlag('__lockViewport__', __lockViewport__); core.setFlag('__lockViewport__', __lockViewport__);
if (info.time == 0) this._changeFloor_afterChange(info, callback); if (info.time === 0 || main.replayChecking) {
else this._changeFloor_afterChange(info, callback);
core.hideWithAnimate( } else {
core.dom.floorMsgGroup, const Render = Mota.require('module', 'Render').MotaRenderer;
info.time / 4, const main = Render.get('render-main');
function () { const change = main.getElementById('floor-change');
change.hideChange(info.time / 2).then(() => {
core.events._changeFloor_afterChange(info, callback); core.events._changeFloor_afterChange(info, callback);
});
} }
);
}; };
events.prototype._changeFloor_afterChange = function (info, callback) { events.prototype._changeFloor_afterChange = function (info, callback) {
@ -3418,7 +3415,6 @@ events.prototype.load = function (fromUserAction) {
offset = saveIndex - 5 * page; offset = saveIndex - 5 * page;
// 游戏开始前读档 // 游戏开始前读档
if (!core.isPlaying()) { if (!core.isPlaying()) {
core.dom.startPanel.style.display = 'none';
core.clearStatus(); core.clearStatus();
core.clearMap('all'); core.clearMap('all');
core.status.event = { id: 'load', data: null }; core.status.event = { id: 'load', data: null };
@ -4206,20 +4202,7 @@ events.prototype._scaleImage_scale = function (ctx, scaleInfo, callback) {
////// 绘制或取消一张gif图片 ////// ////// 绘制或取消一张gif图片 //////
events.prototype.showGif = function (name, x, y) { events.prototype.showGif = function (name, x, y) {
name = core.getMappedName(name); // Deprecated.
var image = core.material.images.images[name];
if (image) {
var gif = new Image();
gif.src = image.src;
gif.style.position = 'absolute';
gif.style.left = x * core.domStyle.scale + 'px';
gif.style.top = y * core.domStyle.scale + 'px';
gif.style.width = image.width * core.domStyle.scale + 'px';
gif.style.height = image.height * core.domStyle.scale + 'px';
core.dom.gif2.appendChild(gif);
} else {
core.dom.gif2.innerHTML = '';
}
}; };
////// 淡入淡出音乐 ////// ////// 淡入淡出音乐 //////

View File

@ -13,14 +13,10 @@ function loader() {
loader.prototype._init = function () {}; loader.prototype._init = function () {};
////// 设置加载进度条进度 ////// ////// 设置加载进度条进度 //////
loader.prototype._setStartProgressVal = function (val) { loader.prototype._setStartProgressVal = function (val) {};
core.dom.startTopProgress.style.width = val + '%';
};
////// 设置加载进度条提示文字 ////// ////// 设置加载进度条提示文字 //////
loader.prototype._setStartLoadTipText = function (text) { loader.prototype._setStartLoadTipText = function (text) {};
core.dom.startTopLoadTips.innerText = text;
};
loader.prototype._load = function (callback) { loader.prototype._load = function (callback) {
if (main.useCompress) { if (main.useCompress) {

View File

@ -1960,16 +1960,7 @@ maps.prototype._getFloorImages = function (floorId) {
}; };
maps.prototype._drawFloorImages_gif = function (image, dx, dy) { maps.prototype._drawFloorImages_gif = function (image, dx, dy) {
core.dom.gif.innerHTML = ''; // Deprecated.
var gif = new Image();
gif.src = image.src;
gif.style.position = 'absolute';
gif.style.left = dx * core.domStyle.scale + 'px';
gif.style.top = dy * core.domStyle.scale + 'px';
gif.style.width = image.width * core.domStyle.scale + 'px';
gif.style.height = image.height * core.domStyle.scale + 'px';
core.dom.gif.appendChild(gif);
return;
}; };
maps.prototype._drawFloorImage = function ( maps.prototype._drawFloorImage = function (

View File

@ -50,7 +50,6 @@ ui.prototype.clearMap = function (name, x, y, width, height) {
core.canvas[m].canvas.height + 32 core.canvas[m].canvas.height + 32
); );
} }
core.dom.gif.innerHTML = '';
core.removeGlobalAnimate(); core.removeGlobalAnimate();
core.deleteCanvas(function (one) { core.deleteCanvas(function (one) {
return one.startsWith('_bigImage_'); return one.startsWith('_bigImage_');
@ -3759,85 +3758,7 @@ ui.prototype._drawSLPanel_drawRecords = function (n) {
}; };
ui.prototype._drawKeyBoard = function () { ui.prototype._drawKeyBoard = function () {
core.lockControl(); // Deprecated.
core.status.event.id = 'keyBoard';
core.clearUI();
core.playSound('打开界面');
var offset = core._WIDTH_ % 2 == 0 ? 16 : 0;
var width = 384,
height = 320;
var left = (core._PX_ - width) / 2 + offset,
right = left + width;
var top = (core._PY_ - height) / 2 + (core._HEIGHT_ % 2 == 0 ? 16 : 0),
bottom = top + height;
var isWindowSkin = this.drawBackground(left, top, right, bottom);
core.setTextAlign('ui', 'center');
core.setFillStyle('ui', core.arrayToRGBA(core.status.textAttribute.title));
core.fillText(
'ui',
'虚拟键盘',
core._PX_ / 2 + offset,
top + 35,
null,
this._buildFont(22, true)
);
core.setFont('ui', this._buildFont(17, false));
core.setFillStyle('ui', core.arrayToRGBA(core.status.textAttribute.text));
var now = core._PY_ / 2 - 89 + (core._HEIGHT_ % 2 == 0 ? 16 : 0);
var lines = [
['F1', 'F2', 'F3', 'F4', 'F5', 'F6', 'F7', 'F8', 'F9', '10', '11'],
['1', '2', '3', '4', '5', '6', '7', '8', '9', '0'],
['Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P'],
['A', 'S', 'D', 'F', 'G', 'H', 'J', 'K', 'L'],
['Z', 'X', 'C', 'V', 'B', 'N', 'M'],
['-', '=', '[', ']', '\\', ';', "'", ',', '.', '/', '`'],
['ES', 'TA', 'CA', 'SH', 'CT', 'AL', 'SP', 'BS', 'EN', 'DE']
];
lines.forEach(function (line) {
for (var i = 0; i < line.length; i++) {
core.fillText(
'ui',
line[i],
core._PX_ / 2 + 32 * (i - 5) + offset,
now
);
}
now += 32;
});
core.fillText(
'ui',
'返回游戏',
core._PX_ / 2 + 128 + offset,
now - 3,
'#FFFFFF',
this._buildFont(15, true)
);
if (isWindowSkin)
this._drawWindowSelector(
core.status.textAttribute.background,
core._PX_ / 2 + 92 + offset,
now - 22,
72,
27
);
else
core.strokeRoundRect(
'ui',
core._PX_ / 2 + 92 + offset,
now - 22,
72,
27,
6,
core.status.globalAttribute.selectColor,
2
);
}; };
////// 绘制“数据统计”界面 ////// ////// 绘制“数据统计”界面 //////
@ -4145,7 +4066,7 @@ ui.prototype.createCanvas = function (name, x, y, width, height, z) {
newCanvas.style.pointerEvents = 'none'; newCanvas.style.pointerEvents = 'none';
core.dymCanvas[name] = newCanvas.getContext('2d'); core.dymCanvas[name] = newCanvas.getContext('2d');
core.maps._setHDCanvasSize(core.dymCanvas[name], width, height); core.maps._setHDCanvasSize(core.dymCanvas[name], width, height);
core.dom.gameDraw.appendChild(newCanvas); // core.dom.gameDraw.appendChild(newCanvas);
return core.dymCanvas[name]; return core.dymCanvas[name];
}; };
@ -4223,7 +4144,7 @@ ui.prototype.deleteCanvas = function (name) {
} }
if (!core.dymCanvas[name]) return null; if (!core.dymCanvas[name]) return null;
core.dom.gameDraw.removeChild(core.dymCanvas[name].canvas); // core.dom.gameDraw.removeChild(core.dymCanvas[name].canvas);
delete core.dymCanvas[name]; delete core.dymCanvas[name];
}; };

View File

@ -22,55 +22,10 @@ function main() {
this.dom = { this.dom = {
body: document.body, body: document.body,
gameGroup: document.getElementById('gameGroup'), game: document.getElementById('game'),
mainTips: document.getElementById('mainTips'), gameDraw: document.getElementById('game-draw'),
musicBtn: document.getElementById('musicBtn'),
enlargeBtn: document.createElement('img'),
startPanel: document.getElementById('startPanel'),
startTop: document.getElementById('startTop'),
startTopProgressBar: document.getElementById('startTopProgressBar'),
startTopProgress: document.getElementById('startTopProgress'),
startTopLoadTips: document.getElementById('startTopLoadTips'),
floorMsgGroup: document.getElementById('floorMsgGroup'),
logoLabel: document.getElementById('logoLabel'),
versionLabel: document.getElementById('versionLabel'),
floorNameLabel: document.getElementById('floorNameLabel'),
statusBar: document.getElementById('statusBar'),
status: document.getElementsByClassName('status'),
tools: document.getElementsByClassName('tools'),
gameCanvas: document.getElementsByClassName('gameCanvas'), gameCanvas: document.getElementsByClassName('gameCanvas'),
gif: document.getElementById('gif'),
gif2: document.getElementById('gif2'),
gameDraw: document.getElementById('gameDraw'),
startButtons: document.getElementById('startButtons'),
playGame: document.getElementById('playGame'),
loadGame: document.getElementById('loadGame'),
replayGame: document.getElementById('replayGame'),
levelChooseButtons: document.getElementById('levelChooseButtons'),
data: document.getElementById('data'), data: document.getElementById('data'),
statusLabels: document.getElementsByClassName('statusLabel'),
statusTexts: document.getElementsByClassName('statusText'),
floorCol: document.getElementById('floorCol'),
nameCol: document.getElementById('nameCol'),
lvCol: document.getElementById('lvCol'),
hpmaxCol: document.getElementById('hpmaxCol'),
hpCol: document.getElementById('hpCol'),
manaCol: document.getElementById('manaCol'),
atkCol: document.getElementById('atkCol'),
defCol: document.getElementById('defCol'),
mdefCol: document.getElementById('mdefCol'),
moneyCol: document.getElementById('moneyCol'),
expCol: document.getElementById('expCol'),
upCol: document.getElementById('upCol'),
keyCol: document.getElementById('keyCol'),
pzfCol: document.getElementById('pzfCol'),
debuffCol: document.getElementById('debuffCol'),
skillCol: document.getElementById('skillCol'),
hard: document.getElementById('hard'),
statusCanvas: document.getElementById('statusCanvas'),
statusCanvasCtx: document
.getElementById('statusCanvas')
.getContext('2d'),
inputDiv: document.getElementById('inputDiv'), inputDiv: document.getElementById('inputDiv'),
inputMessage: document.getElementById('inputMessage'), inputMessage: document.getElementById('inputMessage'),
inputBox: document.getElementById('inputBox'), inputBox: document.getElementById('inputBox'),
@ -115,37 +70,7 @@ function main() {
]; ];
this.statusBar = { this.statusBar = {
image: { image: {},
floor: document.getElementById('img-floor'),
name: document.getElementById('img-name'),
lv: document.getElementById('img-lv'),
hpmax: document.getElementById('img-hpmax'),
hp: document.getElementById('img-hp'),
mana: document.getElementById('img-mana'),
atk: document.getElementById('img-atk'),
def: document.getElementById('img-def'),
mdef: document.getElementById('img-mdef'),
money: document.getElementById('img-money'),
exp: document.getElementById('img-exp'),
up: document.getElementById('img-up'),
skill: document.getElementById('img-skill'),
book: document.getElementById('img-book'),
fly: document.getElementById('img-fly'),
toolbox: document.getElementById('img-toolbox'),
keyboard: document.getElementById('img-keyboard'),
shop: document.getElementById('img-shop'),
save: document.getElementById('img-save'),
load: document.getElementById('img-load'),
settings: document.getElementById('img-settings'),
btn1: document.getElementById('img-btn1'),
btn2: document.getElementById('img-btn2'),
btn3: document.getElementById('img-btn3'),
btn4: document.getElementById('img-btn4'),
btn5: document.getElementById('img-btn5'),
btn6: document.getElementById('img-btn6'),
btn7: document.getElementById('img-btn7'),
btn8: document.getElementById('img-btn8')
},
icons: { icons: {
floor: 0, floor: 0,
name: null, name: null,
@ -183,31 +108,7 @@ function main() {
btn6: 32, btn6: 32,
btn7: 33, btn7: 33,
btn8: 34 btn8: 34
}, }
floor: document.getElementById('floor'),
name: document.getElementById('name'),
lv: document.getElementById('lv'),
hpmax: document.getElementById('hpmax'),
hp: document.getElementById('hp'),
mana: document.getElementById('mana'),
atk: document.getElementById('atk'),
def: document.getElementById('def'),
mdef: document.getElementById('mdef'),
money: document.getElementById('money'),
exp: document.getElementById('exp'),
up: document.getElementById('up'),
skill: document.getElementById('skill'),
yellowKey: document.getElementById('yellowKey'),
blueKey: document.getElementById('blueKey'),
redKey: document.getElementById('redKey'),
greenKey: document.getElementById('greenKey'),
poison: document.getElementById('poison'),
weak: document.getElementById('weak'),
curse: document.getElementById('curse'),
pickaxe: document.getElementById('pickaxe'),
bomb: document.getElementById('bomb'),
fly: document.getElementById('fly'),
hard: document.getElementById('hard')
}; };
this.floors = {}; this.floors = {};
this.canvas = {}; this.canvas = {};
@ -353,7 +254,6 @@ main.prototype.loadAsync = async function (mode, callback) {
main.setMainTipsText('正在加载楼层文件...'); main.setMainTipsText('正在加载楼层文件...');
if (main.useCompress) { if (main.useCompress) {
await main.loadScript(`project/floors.min.js?v=${main.version}`); await main.loadScript(`project/floors.min.js?v=${main.version}`);
main.dom.mainTips.style.display = 'none';
} else { } else {
await new Promise(res => { await new Promise(res => {
main.loadScript( main.loadScript(
@ -362,7 +262,6 @@ main.prototype.loadAsync = async function (mode, callback) {
}&id=${main.floorIds.join(',')}` }&id=${main.floorIds.join(',')}`
).then( ).then(
() => { () => {
main.dom.mainTips.style.display = 'none';
main.supportBunch = true; main.supportBunch = true;
res(); res();
}, },
@ -372,7 +271,6 @@ main.prototype.loadAsync = async function (mode, callback) {
main.loadScript(`project/floors/${v}.js`) main.loadScript(`project/floors/${v}.js`)
) )
); );
main.dom.mainTips.style.display = 'none';
res(); res();
} }
); );
@ -419,78 +317,27 @@ main.prototype.loadAsync = async function (mode, callback) {
let auto = Mota.require('var', 'mainSetting').getValue('autoScale', true); let auto = Mota.require('var', 'mainSetting').getValue('autoScale', true);
if (auto && !core.domStyle.isVertical) { if (auto && !core.domStyle.isVertical) {
try { const height = window.innerHeight;
Mota.Plugin.require('utils_g').maxGameScale(1); const width = window.innerWidth;
requestAnimationFrame(() => { const maxScale = Math.min(height / core._PY_, width / core._PX_);
var style = getComputedStyle(main.dom.gameGroup); const target = Number((Math.floor(maxScale * 4) / 4).toFixed(2));
var height = parseFloat(style.height); core.domStyle.scale = target - 0.25;
if (height > window.innerHeight * 0.95) {
core.control.setDisplayScale(-1);
if (!core.isPlaying() && core.flags.enableHDCanvas) {
core.domStyle.ratio = Math.max(
window.devicePixelRatio || 1,
core.domStyle.scale
);
core.resize();
} }
if (core.domStyle.isVertical) {
core.domStyle.scale = window.innerWidth / core._PX_;
} }
Mota.r(() => {
Mota.require('module', 'Render').MotaOffscreenCanvas2D.refreshAll();
}); });
} catch {}
}
}; };
////// 加载过程提示 ////// ////// 加载过程提示 //////
main.prototype.setMainTipsText = function (text) { main.prototype.setMainTipsText = function (text) {};
main.dom.mainTips.innerHTML = text;
};
main.prototype.createOnChoiceAnimation = function () { main.prototype.createOnChoiceAnimation = function () {};
var borderColor =
main.dom.startButtonGroup.style.caretColor || 'rgb(255, 215, 0)';
// get rgb value
var rgb =
/^rgba?\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*(,\s*\d+\s*)?\)$/.exec(
borderColor
);
if (rgb != null) {
var value = rgb[1] + ', ' + rgb[2] + ', ' + rgb[3];
var style = document.createElement('style');
style.type = 'text/css';
var keyFrames =
'onChoice { ' +
'0% { border-color: rgba(' +
value +
', 0.9); } ' +
'50% { border-color: rgba(' +
value +
', 0.3); } ' +
'100% { border-color: rgba(' +
value +
', 0.9); } ' +
'}';
style.innerHTML =
'@-webkit-keyframes ' + keyFrames + ' @keyframes ' + keyFrames;
document.body.appendChild(style);
}
};
////// 创建字体 ////// ////// 创建字体 //////
main.prototype.importFonts = function (fonts) { main.prototype.importFonts = function (fonts) {};
if (!(fonts instanceof Array) || fonts.length == 0) return;
var style = document.createElement('style');
style.type = 'text/css';
var html = '';
fonts.forEach(function (font) {
html +=
'@font-face { font-family: "' +
font +
'"; src: url("project/fonts/' +
font +
'.ttf") format("truetype"); }';
});
style.innerHTML = html;
document.body.appendChild(style);
};
main.prototype.listen = function () { main.prototype.listen = function () {
////// 窗口大小变化时 ////// ////// 窗口大小变化时 //////
@ -515,9 +362,6 @@ main.prototype.listen = function () {
} }
}; };
////// 在界面上放开某按键时 //////
main.dom.body.addEventListener('keyup', function (e) {});
////// 开始选择时 ////// ////// 开始选择时 //////
main.dom.body.onselectstart = function () { main.dom.body.onselectstart = function () {
return false; return false;
@ -527,7 +371,7 @@ main.prototype.listen = function () {
main.dom.data.onmousedown = function (e) { main.dom.data.onmousedown = function (e) {
try { try {
e.stopPropagation(); e.stopPropagation();
var loc = core.actions._getClickLoc(e.clientX, e.clientY); var loc = core.actions._getClickLoc(e.offsetX, e.offsetY);
if (loc == null) return; if (loc == null) return;
core.ondown(loc); core.ondown(loc);
} catch (ee) { } catch (ee) {
@ -538,7 +382,7 @@ main.prototype.listen = function () {
////// 鼠标移动时 ////// ////// 鼠标移动时 //////
main.dom.data.onmousemove = function (e) { main.dom.data.onmousemove = function (e) {
try { try {
var loc = core.actions._getClickLoc(e.clientX, e.clientY); var loc = core.actions._getClickLoc(e.offsetX, e.offsetY);
if (loc == null) return; if (loc == null) return;
core.onmove(loc); core.onmove(loc);
} catch (ee) { } catch (ee) {
@ -549,7 +393,7 @@ main.prototype.listen = function () {
////// 鼠标放开时 ////// ////// 鼠标放开时 //////
main.dom.data.onmouseup = function (e) { main.dom.data.onmouseup = function (e) {
try { try {
var loc = core.actions._getClickLoc(e.clientX, e.clientY); var loc = core.actions._getClickLoc(e.offsetX, e.offsetY);
if (loc == null) return; if (loc == null) return;
core.onup(loc); core.onup(loc);
} catch (ee) { } catch (ee) {
@ -573,7 +417,8 @@ main.prototype.listen = function () {
e.preventDefault(); e.preventDefault();
var loc = core.actions._getClickLoc( var loc = core.actions._getClickLoc(
e.targetTouches[0].clientX, e.targetTouches[0].clientX,
e.targetTouches[0].clientY e.targetTouches[0].clientY,
true
); );
if (loc == null) return; if (loc == null) return;
main.lastTouchLoc = loc; main.lastTouchLoc = loc;
@ -589,7 +434,8 @@ main.prototype.listen = function () {
e.preventDefault(); e.preventDefault();
var loc = core.actions._getClickLoc( var loc = core.actions._getClickLoc(
e.targetTouches[0].clientX, e.targetTouches[0].clientX,
e.targetTouches[0].clientY e.targetTouches[0].clientY,
true
); );
if (loc == null) return; if (loc == null) return;
main.lastTouchLoc = loc; main.lastTouchLoc = loc;
@ -612,218 +458,6 @@ main.prototype.listen = function () {
} }
}; };
////// 点击状态栏中的怪物手册时 //////
main.statusBar.image.book.onclick = function (e) {
e.stopPropagation();
if (core.isReplaying()) {
core.triggerReplay();
return;
}
if (core.isPlaying()) core.openBook(true);
};
////// 点击状态栏中的楼层传送器/装备栏时 //////
main.statusBar.image.fly.onclick = function (e) {
e.stopPropagation();
// 播放录像时
if (core.isReplaying()) {
core.stopReplay();
return;
}
if (core.isPlaying()) {
if (!core.flags.equipboxButton) {
core.useFly(true);
} else {
core.openEquipbox(true);
}
}
};
////// 点击状态栏中的工具箱时 //////
main.statusBar.image.toolbox.onclick = function (e) {
e.stopPropagation();
if (core.isReplaying()) {
core.rewindReplay();
return;
}
if (core.isPlaying()) {
core.openToolbox(core.status.event.id != 'equipbox');
}
};
////// 双击状态栏中的工具箱时 //////
main.statusBar.image.toolbox.ondblclick = function (e) {
e.stopPropagation();
if (core.isReplaying()) {
return;
}
if (core.isPlaying()) core.openEquipbox(true);
};
////// 点击状态栏中的虚拟键盘时 //////
main.statusBar.image.keyboard.onclick = function (e) {
e.stopPropagation();
if (core.isReplaying()) {
core.control._replay_book();
return;
}
if (core.isPlaying()) core.openKeyBoard(true);
};
////// 点击状态栏中的快捷商店时 //////
main.statusBar.image.shop.onclick = function (e) {
e.stopPropagation();
if (core.isReplaying()) {
core.control._replay_viewMap();
return;
}
if (core.isPlaying()) core.openQuickShop(true);
};
////// 点击金币时也可以开启快捷商店 //////
main.statusBar.image.money.onclick = function (e) {
e.stopPropagation();
if (core.isPlaying()) core.openQuickShop(true);
};
////// 点击楼梯图标也可以浏览地图 //////
main.statusBar.image.floor.onclick = function (e) {
e.stopPropagation();
if (
core &&
core.isPlaying() &&
!core.isMoving() &&
!core.status.lockControl
) {
core.ui._drawViewMaps();
}
};
////// 点击状态栏中的存档按钮时 //////
main.statusBar.image.save.onclick = function (e) {
e.stopPropagation();
if (core.isReplaying()) {
core.speedDownReplay();
return;
}
if (core.isPlaying()) core.save(true);
};
////// 点击状态栏中的读档按钮时 //////
main.statusBar.image.load.onclick = function (e) {
e.stopPropagation();
if (core.isReplaying()) {
core.speedUpReplay();
return;
}
if (core.isPlaying()) core.load(true);
};
////// 点击状态栏中的系统菜单时 //////
main.statusBar.image.settings.onclick = function (e) {
e.stopPropagation();
if (core.isReplaying()) {
core.control._replay_SL();
return;
}
if (core.isPlaying()) core.openSettings(true);
};
////// 点击工具栏时 //////
main.dom.hard.onclick = function () {
core.control.setToolbarButton(!core.domStyle.toolbarBtn);
};
////// 手机端的按钮1-7 //////
// 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.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.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.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)';
// }
// };
window.onblur = function () { window.onblur = function () {
if (core && core.control) { if (core && core.control) {
try { try {

View File

@ -102,7 +102,6 @@ var functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a = {
if (!noexit) { if (!noexit) {
core.clearMap('all'); // 清空全地图 core.clearMap('all'); // 清空全地图
core.deleteAllCanvas(); // 删除所有创建的画布 core.deleteAllCanvas(); // 删除所有创建的画布
core.dom.gif2.innerHTML = '';
} }
reason = core.replaceText(reason); reason = core.replaceText(reason);
core.drawText( core.drawText(
@ -391,37 +390,10 @@ var functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a = {
}); });
}, },
updateStatusBar: function () { updateStatusBar: function () {
// 更新状态栏
// 检查等级 // 检查等级
core.events.checkLvUp(); core.events.checkLvUp();
// 如果是自定义添加的状态栏,也需要在这里进行设置显示的数值
// 难度
if (core.statusBar.hard.innerText != core.status.hard) {
core.statusBar.hard.innerText = core.status.hard;
}
var hardColor = core.getFlag('__hardColor__', 'red');
if (core.statusBar.hard.getAttribute('_style') != hardColor) {
core.statusBar.hard.style.color = hardColor;
core.statusBar.hard.setAttribute('_style', hardColor);
}
// 更新全地图显伤 // 更新全地图显伤
core.updateDamage(); core.updateDamage();
if (main.replayChecking) return;
// 已学习的技能
// if (
// core.plugin.skillTree.getSkillLevel(11) > 0 &&
// (core.status.hero.special?.num ?? []).length > 0
// ) {
// mota.plugin.ui.showStudiedSkill.value = true;
// } else {
// mota.plugin.ui.showStudiedSkill.value = false;
// }
}, },
moveOneStep: function (callback) { moveOneStep: function (callback) {
// 勇士每走一步后执行的操作。callback为行走完毕后的回调 // 勇士每走一步后执行的操作。callback为行走完毕后的回调
@ -433,10 +405,6 @@ var functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a = {
// 增加步数 // 增加步数
core.status.hero.steps++; core.status.hero.steps++;
// 更新跟随者状态,并绘制
core.updateFollowers();
core.drawHero();
// 从v2.7开始,每一步行走不会再刷新状态栏。 // 从v2.7开始,每一步行走不会再刷新状态栏。
// 如果有特殊要求如每走一步都加buff之类可手动取消注释下面这一句 // 如果有特殊要求如每走一步都加buff之类可手动取消注释下面这一句
// core.updateStatusBar(true); // core.updateStatusBar(true);

View File

@ -17,344 +17,12 @@ body {
align-items: center; align-items: center;
} }
#gameGroup { #game-draw {
position: absolute;
box-sizing: border-box;
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
background-color: #000;
}
#mainTips {
color: #fff;
font-size: 0.8em;
position: fixed;
top: 10px;
left: 10px;
z-index: 370;
}
#musicBtn {
position: absolute;
bottom: 3px;
right: -20%;
cursor: pointer;
z-index: 400;
display: none;
}
#startPanel {
opacity: 0;
width: 150%;
height: 100%;
position: absolute;
top: 0;
left: -25%;
background-color: #000;
overflow: hidden;
z-index: 300;
}
#startTop {
width: 100%;
height: 100%;
position: absolute;
top: 0;
left: 0;
background-color: #000;
z-index: 350;
}
#startTopProgressBar {
width: 90%;
height: 5%;
margin: 0 5%;
position: absolute;
top: 5%;
background-color: #fff;
z-index: 15;
}
#startTopProgress {
width: 0%;
height: 100%;
background-color: #666;
}
#startTopLoadTips {
color: #fff;
font-size: 0.6em;
position: absolute;
top: 10%;
left: 5%;
z-index: 15;
}
#startTopHint {
color: #66ccff;
position: absolute;
bottom: 0;
left: 5%;
z-index: 15;
font-size: 1.1em;
}
#startBackground {
position: absolute;
top: 50%;
left: 50%;
height: 100%;
width: auto;
transform: translate(-50%, -50%);
z-index: 260;
object-fit: cover;
filter: sepia(30%) contrast(70%);
}
#startLogo {
position: absolute;
z-index: 290;
left: 0;
right: 0;
margin-left: auto;
margin-right: auto;
margin-top: 8%;
max-width: 100%;
color: transparent;
text-align: center;
font: 4em 'normal';
font-weight: 200;
background-image: linear-gradient(
to right,
rgb(0, 0, 0),
rgb(44, 44, 44),
rgb(136, 0, 214),
rgb(0, 2, 97),
rgb(0, 2, 97)
);
background-clip: text;
-webkit-background-clip: text;
text-shadow: 1px 1px 4px rgba(0, 0, 0, 0.5),
-1px -1px 3px rgba(255, 255, 255, 0.3), 5px 5px 5px rgba(0, 0, 0, 0.4);
filter: brightness(1.8);
user-select: none;
}
#startTitle {
position: absolute;
z-index: 280;
}
#startButtonGroup {
width: 25%;
position: absolute;
text-align: center;
font-size: 1.4em;
font-family: 'normal';
display: none;
z-index: 310;
bottom: 0;
margin-bottom: 7%;
left: 30%;
transform: translateX(-50%);
padding: 15px 25px;
text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.4),
0px 0px 1px rgba(255, 255, 255, 0.3);
}
#playGame {
position: relative; position: relative;
left: 10%;
color: transparent;
background-image: linear-gradient(
to bottom,
rgb(255, 255, 255),
rgb(0, 255, 255)
);
background-clip: text;
-webkit-background-clip: text;
} }
#loadGame { #game-draw > * {
position: relative;
left: 5%;
color: transparent;
background-image: linear-gradient(
to bottom,
rgb(255, 255, 255),
rgb(0, 255, 55)
);
background-clip: text;
-webkit-background-clip: text;
}
#replayGame {
position: relative;
color: transparent;
background-image: linear-gradient(
to bottom,
rgb(255, 255, 255),
rgb(255, 251, 0)
);
background-clip: text;
-webkit-background-clip: text;
}
#startButtons {
display: block;
}
#levelChooseButtons {
display: none;
}
span#hard {
background-image: linear-gradient(
to bottom,
rgb(255, 255, 255),
rgb(255, 0, 0)
);
}
#levelChooseButtons span {
color: transparent;
background-clip: text;
-webkit-background-clip: text;
}
.startButton {
width: 100%;
margin: 0;
font-weight: bold;
display: block;
cursor: pointer;
border-color: transparent;
border-width: 2px;
border-style: solid;
border-radius: 6px;
transition: box-shadow 0.3s linear, transform 0.2s ease-out;
box-shadow: 0px 0px 7px rgba(0, 0, 0, 0.4);
transform: scale(1);
}
.onChoiceAnimate {
animation: onChoice 2s ease-in-out 0s infinite normal none running;
}
#floorMsgGroup {
top: 3px;
right: 3px;
position: absolute; position: absolute;
text-align: center;
display: none;
color: transparent;
background-color: #000;
z-index: 230;
user-select: none;
}
#logoLabel {
margin-top: 8%;
font: bold 3em STXingkai;
margin-left: auto;
margin-right: auto;
}
#versionLabel {
margin-top: -3%;
font-size: 1.2em;
font-weight: bold;
}
#floorNameLabel {
margin-top: 30px;
font-size: 1.6em;
font-weight: bold;
}
#statusBar {
position: absolute;
box-sizing: border-box;
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
background: black;
z-index: 185;
display: none;
top: 0;
left: 0;
padding: 3px;
}
#statusBar .status {
user-select: none;
position: relative;
display: block;
float: left;
width: 100%;
}
.status img {
vertical-align: middle;
width: auto;
height: 100%;
max-height: 1.6em;
}
#statusBar span {
user-select: none;
font: bold italic 1.1em Verdana;
display: inline;
}
#statusBar p {
user-select: none;
display: inline-block;
vertical-align: middle;
width: 60%;
margin: 0;
color: white;
font: bold italic 1.1em Verdana;
white-space: nowrap;
}
#toolBar {
position: absolute;
z-index: 210;
box-sizing: border-box;
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
display: none;
padding: 3px;
border-top: 2px solid #ddd9;
margin-right: 3px;
}
#toolBar .tools {
position: relative;
display: block;
float: left;
}
p#hard {
user-select: none;
width: 6em;
vertical-align: middle;
display: inline-block;
color: red;
font: bold normal 1.1em 'Arial Black';
text-align: center;
margin: 0 6px 6px 0;
word-break: keep-all;
}
span#poison,
span#weak,
span#curse,
span#pickaxe,
span#bomb,
span#fly {
user-select: none;
font-style: normal;
font-size: 1em;
}
p#name {
font-style: normal;
} }
.gameCanvas { .gameCanvas {
@ -364,55 +32,6 @@ p#name {
-webkit-box-sizing: border-box; -webkit-box-sizing: border-box;
} }
#gif {
z-index: 20;
position: absolute;
overflow: hidden;
}
#gif2 {
z-index: 90;
position: absolute;
overflow: hidden;
}
#gameDraw {
position: absolute;
background: #000000;
overflow: hidden;
z-index: 185;
margin: 3px;
}
#bg {
z-index: 10;
}
#event {
z-index: 30;
}
#hero {
/* display: none; */
z-index: 40;
}
#event2 {
z-index: 50;
}
#fg {
z-index: 60;
}
#damage {
z-index: 65;
}
#animate {
z-index: 70;
}
#curtain { #curtain {
z-index: 125; z-index: 125;
} }
@ -425,14 +44,6 @@ p#name {
z-index: 170; z-index: 170;
} }
.no-anti-aliasing {
image-rendering: pixelated;
}
/* .draw-canvas {
filter: contrast(120%) brightness(80%);
} */
#inputDiv { #inputDiv {
display: none; display: none;
width: 100%; width: 100%;
@ -537,85 +148,3 @@ p#name {
transform: rotate(45deg) translate(-3px, -3px); transform: rotate(45deg) translate(-3px, -3px);
} }
} }
#startImageBackgroundDiv {
display: none;
width: 100%;
height: 100%;
position: fixed;
z-index: 10000;
}
#startImageDiv {
width: 100%;
height: 100%;
position: fixed;
background: black;
opacity: 1;
}
#startImageLogo {
opacity: 0;
max-width: 60%;
max-height: 60%;
position: fixed;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
}
.startImageAnimation {
-webkit-animation: startImage 4s ease-in-out 1s forwards 1;
animation: startImage 4s ease-in-out 1s forwards 1;
}
@-webkit-keyframes startImage {
0% {
opacity: 0;
}
60% {
opacity: 1;
}
100% {
opacity: 0;
}
}
@keyframes startImage {
0% {
opacity: 0;
}
60% {
opacity: 1;
}
100% {
opacity: 0;
}
}
.startImageDivAnimation {
-webkit-animation: startImageDivDisappear 2s ease-in-out 5s forwards 1;
animation: startImageDivDisappear 2s ease-in-out 5s forwards 1;
}
@-webkit-keyframes startImageDivDisappear {
0% {
opacity: 1;
}
100% {
opacity: 0;
}
}
@keyframes startImageDivDisappear {
0% {
opacity: 1;
}
100% {
opacity: 0;
}
}
.hide {
display: none;
}

View File

@ -1,7 +1,4 @@
import { parseCss } from '@/plugin/utils';
import { EventEmitter } from 'eventemitter3'; import { EventEmitter } from 'eventemitter3';
import { CSSObj } from '../interface';
import { isWebGL2Supported } from './webgl';
interface OffscreenCanvasEvent { interface OffscreenCanvasEvent {
/** 当被动触发resize时例如core.domStyle.scale变化、窗口大小变化时触发使用size函数并不会触发 */ /** 当被动触发resize时例如core.domStyle.scale变化、窗口大小变化时触发使用size函数并不会触发 */
@ -29,10 +26,15 @@ export class MotaOffscreenCanvas2D extends EventEmitter<OffscreenCanvasEvent> {
/** 更新标识符,如果发生变化则说明画布被动清空 */ /** 更新标识符,如果发生变化则说明画布被动清空 */
symbol: number = 0; symbol: number = 0;
constructor(alpha: boolean = true) { /**
*
* @param alpha
* @param canvas
*/
constructor(alpha: boolean = true, canvas?: HTMLCanvasElement) {
super(); super();
this.canvas = document.createElement('canvas'); this.canvas = canvas ?? document.createElement('canvas');
this.ctx = this.canvas.getContext('2d', { alpha })!; this.ctx = this.canvas.getContext('2d', { alpha })!;
this.width = this.canvas.width / devicePixelRatio; this.width = this.canvas.width / devicePixelRatio;
this.height = this.canvas.height / devicePixelRatio; this.height = this.canvas.height / devicePixelRatio;
@ -45,8 +47,9 @@ export class MotaOffscreenCanvas2D extends EventEmitter<OffscreenCanvasEvent> {
*/ */
size(width: number, height: number) { size(width: number, height: number) {
let ratio = this.highResolution ? devicePixelRatio : 1; let ratio = this.highResolution ? devicePixelRatio : 1;
if (this.autoScale && this.highResolution) { const scale = core.domStyle.scale;
ratio *= core.domStyle.scale; if (this.autoScale) {
ratio *= scale;
} }
this.scale = ratio; this.scale = ratio;
this.canvas.width = width * ratio; this.canvas.width = width * ratio;
@ -56,6 +59,10 @@ export class MotaOffscreenCanvas2D extends EventEmitter<OffscreenCanvasEvent> {
this.ctx.setTransform(1, 0, 0, 1, 0, 0); this.ctx.setTransform(1, 0, 0, 1, 0, 0);
this.ctx.scale(ratio, ratio); this.ctx.scale(ratio, ratio);
this.ctx.imageSmoothingEnabled = this.antiAliasing; this.ctx.imageSmoothingEnabled = this.antiAliasing;
if (this.canvas.isConnected) {
this.canvas.style.width = `${width * scale}px`;
this.canvas.style.height = `${height * scale}px`;
}
} }
/** /**
@ -100,7 +107,7 @@ export class MotaOffscreenCanvas2D extends EventEmitter<OffscreenCanvasEvent> {
} }
/** /**
* Canvas2D对象或Canvas2D对象 * Canvas2D对象
* @param canvas MotaOffscreenCanvas2D对象 * @param canvas MotaOffscreenCanvas2D对象
* @returns * @returns
*/ */
@ -118,220 +125,20 @@ export class MotaOffscreenCanvas2D extends EventEmitter<OffscreenCanvasEvent> {
); );
return newCanvas; return newCanvas;
} }
static refreshAll() {
this.list.forEach(v => {
if (v.autoScale) {
v.size(v.width, v.height);
v.symbol++;
v.emit('resize');
} }
});
export class MotaOffscreenCanvasGL2 extends EventEmitter<OffscreenCanvasEvent> {
static support: boolean = isWebGL2Supported();
static list: Set<MotaOffscreenCanvasGL2> = new Set();
canvas: HTMLCanvasElement;
gl: WebGL2RenderingContext;
width: number;
height: number;
/** 是否自动跟随样板的core.domStyle.scale进行缩放 */
autoScale: boolean = false;
/** 是否是高清画布 */
highResolution: boolean = true;
scale: number = 1;
/** 更新标识符,如果发生变化则说明画布被动清空 */
symbol: number = 0;
constructor() {
super();
this.canvas = document.createElement('canvas');
this.gl = this.canvas.getContext('webgl2')!;
this.width = this.canvas.width / devicePixelRatio;
this.height = this.canvas.height / devicePixelRatio;
}
/**
*
*/
size(width: number, height: number) {
let ratio = this.highResolution ? devicePixelRatio : 1;
if (this.autoScale && this.highResolution) {
ratio *= core.domStyle.scale;
}
this.scale = ratio;
this.canvas.width = width * ratio;
this.canvas.height = height * ratio;
this.width = width;
this.height = height;
}
/**
* core.domStyle.scale
*/
withGameScale(auto: boolean) {
this.autoScale = auto;
this.size(this.width, this.height);
}
/**
*
*/
setHD(hd: boolean) {
this.highResolution = hd;
this.size(this.width, this.height);
}
/**
*
*/
delete() {
MotaOffscreenCanvasGL2.list.delete(this);
}
}
export class MotaCanvas2D extends MotaOffscreenCanvas2D {
static map: Map<string, MotaCanvas2D> = new Map();
id: string = '';
x: number = 0;
y: number = 0;
private mounted: boolean = false;
private target!: HTMLElement;
/** 是否自动跟随样板的core.domStyle.scale进行缩放 */
autoScale: boolean = false;
/** 是否是高清画布 */
highResolution: boolean = true;
constructor(
id: string = '',
setTarget: boolean = true,
alpha: boolean = true
) {
super();
this.id = id;
if (setTarget) this.target = core.dom.gameDraw;
this.canvas = document.createElement('canvas');
this.canvas.id = id;
this.ctx = this.canvas.getContext('2d', { alpha })!;
this.width = this.canvas.width / devicePixelRatio;
this.height = this.canvas.height / devicePixelRatio;
this.canvas.style.position = 'absolute';
MotaCanvas2D.map.set(this.id, this);
}
/**
*
* @param target
*/
setTarget(target: HTMLElement) {
this.target = target;
if (this.mounted) {
this.unmount();
this.mount();
}
}
/**
*
*/
size(width: number, height: number) {
let ratio = this.highResolution ? devicePixelRatio : 1;
if (this.autoScale) {
const scale = core.domStyle.scale;
if (this.highResolution) ratio *= scale;
this.canvas.style.width = `${width * scale}px`;
this.canvas.style.height = `${height * scale}px`;
} else {
this.canvas.style.width = `${width}px`;
this.canvas.style.height = `${height}px`;
}
this.scale = ratio;
this.canvas.width = width * ratio;
this.canvas.height = height * ratio;
this.width = width;
this.height = height;
this.ctx.setTransform(1, 0, 0, 1, 0, 0);
this.ctx.scale(ratio, ratio);
}
/**
*
*/
pos(x: number, y: number) {
this.canvas.style.left = `${x}px`;
this.canvas.style.top = `${y}px`;
this.x = x;
this.y = y;
}
/**
* css
* @param css css
*/
css(css: string | CSSObj) {
const s = typeof css === 'string' ? parseCss(css) : css;
for (const [key, value] of Object.entries(s)) {
this.canvas.style[key as CanParseCss] = value;
}
}
/**
*
*/
delete() {
super.delete();
this.unmount();
MotaCanvas2D.map.delete(this.id);
}
/**
*
*/
mount() {
if (!this.mounted) {
this.mounted = true;
this.target.appendChild(this.canvas);
}
}
/**
*
*/
unmount() {
if (this.mounted) {
this.mounted = false;
this.canvas.remove();
}
}
/**
* Symbol.for
*/
static for(id: string, setTarget?: boolean) {
const canvas = this.map.get(id);
return canvas ?? new MotaCanvas2D(id, setTarget);
} }
} }
window.addEventListener('resize', () => { window.addEventListener('resize', () => {
requestAnimationFrame(() => { requestAnimationFrame(() => {
MotaOffscreenCanvas2D.list.forEach(v => { MotaOffscreenCanvas2D.refreshAll();
if (v.autoScale) {
v.size(v.width, v.height);
v.symbol++;
v.emit('resize');
}
});
MotaOffscreenCanvasGL2.list.forEach(v => {
if (v.autoScale) {
v.size(v.width, v.height);
v.symbol++;
v.emit('resize');
}
});
}); });
}); });

View File

@ -1,241 +0,0 @@
import { Ticker } from 'mutate-animate';
import { MotaCanvas2D } from '@/core/fx/canvas2d';
import { MotaSettingItem, mainSetting } from '@/core/main/setting';
// 苍蓝殿左上角区域的传送门机制的绘制部分,传送部分看 src/game/machanism/misc.ts
interface DrawingPortal {
color: string;
x: number;
y: number;
particles: PortalParticle[];
/** v表示竖向h表示横向 */
type: 'v' | 'h';
/** 上一次新增粒子的时间 */
lastParticle: number;
}
interface PortalParticle {
fx: number;
fy: number;
totalTime: number;
time: number;
tx: number;
ty: number;
r: number;
}
const MAX_PARTICLES = 10;
const PARTICLE_LAST = 2000;
const PARTICLE_INTERVAL = PARTICLE_LAST / MAX_PARTICLES;
const color: string[] = ['#0f0', '#ff0', '#0ff', '#fff', '#f0f'];
const drawing: DrawingPortal[] = [];
const ticker = new Ticker();
let canvas: MotaCanvas2D;
let ctx: CanvasRenderingContext2D;
let particleSetting: MotaSettingItem;
let lastTime = 0;
// Mota.require('var', 'loading').once('coreInit', () => {
// canvas = MotaCanvas2D.for('@portal');
// ctx = canvas.ctx;
// canvas.mount();
// canvas.css(`z-index: 51`);
// canvas.withGameScale(true);
// canvas.pos(0, 0);
// canvas.size(480, 480);
// canvas.on('resize', () => {
// canvas.css(`z-index: 51`);
// });
// particleSetting = mainSetting.getSetting('fx.portalParticle')!;
// ticker.add(tickPortal);
// });
// Mota.require('var', 'hook').on('changingFloor', id => {
// drawPortals(id);
// });
let needDraw = false;
function tickPortal(time: number) {
const last = lastTime;
lastTime = time;
const p = particleSetting.value;
if (!core.isPlaying() || drawing.length === 0) return;
if (!p && !needDraw) return;
needDraw = false;
ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
ctx.lineCap = 'round';
ctx.lineWidth = 3;
ctx.shadowOffsetX = 0;
ctx.shadowOffsetY = 0;
if (p) {
ctx.shadowBlur = 8;
} else {
ctx.shadowBlur = 0;
}
drawing.forEach(v => {
const { color, x, y, type, lastParticle, particles } = v;
ctx.strokeStyle = color;
ctx.fillStyle = color;
ctx.globalAlpha = 1;
ctx.shadowColor = color;
if (type === 'v') {
ctx.beginPath();
ctx.moveTo(x, y - 14);
ctx.lineTo(x, y + 30);
ctx.stroke();
} else {
ctx.beginPath();
ctx.moveTo(x + 2, y);
ctx.lineTo(x + 30, y);
ctx.stroke();
}
if (p) {
// 绘制粒子效果
let needDelete = false;
const dt = time - last;
particles.forEach(v => {
const { fx, fy, tx, ty, time: t, totalTime, r } = v;
const progress = t / totalTime;
const nx = (tx - fx) * progress + fx;
const ny = (ty - fy) * progress + fy;
v.time += dt;
if (progress > 1) {
needDelete = true;
return;
} else if (progress > 0.75) {
ctx.globalAlpha = (1 - progress) * 4;
} else if (progress < 0.25) {
ctx.globalAlpha = progress * 4;
} else {
ctx.globalAlpha = 1;
}
ctx.beginPath();
ctx.arc(nx, ny, r, 0, Math.PI * 2);
ctx.closePath();
ctx.fill();
});
if (needDelete) {
particles.shift();
}
if (
time - lastParticle >= PARTICLE_INTERVAL &&
particles.length < MAX_PARTICLES
) {
// 添加新粒子
const direction = Math.random();
const k = Math.random() / 2 - 0.3;
const verticle = Math.floor(Math.random() * 8 + 8);
const r = Math.random() * 2;
v.lastParticle = time;
if (direction > 0.5) {
// 左边 | 上边
if (type === 'h') {
const fx = Math.floor(Math.random() * 24 + x + 4);
particles.push({
fx: fx,
fy: y - 1,
tx: verticle * k + fx + 4,
ty: -verticle + y - 1,
r: r,
time: 0,
totalTime: PARTICLE_LAST
});
} else {
const fy = Math.floor(Math.random() * 44 + y - 14);
particles.push({
fy: fy,
fx: x - 1,
ty: verticle * k + fy + 4,
tx: -verticle + x - 1,
r: r,
time: 0,
totalTime: PARTICLE_LAST
});
}
} else {
// 右边 | 下边
if (type === 'h') {
const fx = Math.floor(Math.random() * 24 + x + 4);
particles.push({
fx: fx,
fy: y + 1,
tx: verticle * k + fx + 4,
ty: verticle + y - 1,
r: r,
time: 0,
totalTime: PARTICLE_LAST
});
} else {
const fy = Math.floor(Math.random() * 44 + y - 14);
particles.push({
fy: fy,
fx: x + 1,
ty: verticle * k + fy + 4,
tx: verticle + x + 1,
r: r,
time: 0,
totalTime: PARTICLE_LAST
});
}
}
}
}
});
}
/**
*
* @param floorId
*/
export function drawPortals(floorId: FloorIds) {
drawing.splice(0);
const p = Mota.require('module', 'Mechanism').BluePalace.portals[floorId];
if (!p) return;
p.forEach((v, i) => {
const c = color[i % color.length];
const { fx, fy, tx, ty, dir, toDir } = v;
let x1 = fx * 32;
let y1 = fy * 32;
let x2 = tx * 32;
let y2 = ty * 32;
if (dir === 'down') y1 += 32;
else if (dir === 'right') x1 += 32;
if (toDir === 'down') y2 += 32;
else if (toDir === 'right') x2 += 32;
drawing.push({
x: x1,
y: y1,
type: dir === 'left' || dir === 'right' ? 'v' : 'h',
color: c,
particles: [],
lastParticle: lastTime
});
drawing.push({
x: x2,
y: y2,
type: toDir === 'left' || toDir === 'right' ? 'v' : 'h',
color: c,
particles: [],
lastParticle: lastTime
});
});
needDraw = true;
}

View File

@ -990,7 +990,7 @@ export class Shadow {
} }
static mount() { static mount() {
core.dom.gameDraw.appendChild(this.canvas); // core.dom.gameDraw.appendChild(this.canvas);
} }
/** /**

View File

@ -60,8 +60,6 @@ import { ResourceController } from './loader/controller';
import { logger } from './common/logger'; import { logger } from './common/logger';
import { Danmaku } from './main/custom/danmaku'; import { Danmaku } from './main/custom/danmaku';
import * as Shadow from './fx/shadow'; import * as Shadow from './fx/shadow';
import { MotaCanvas2D } from './fx/canvas2d';
import * as portal from './fx/portal';
import { MotaRenderer } from './render/render'; import { MotaRenderer } from './render/render';
import { Container } from './render/container'; import { Container } from './render/container';
import { Sprite } from './render/sprite'; import { Sprite } from './render/sprite';
@ -77,6 +75,7 @@ import * as Animation from 'mutate-animate';
import './render/index'; import './render/index';
import * as RenderUtils from './render/utils'; import * as RenderUtils from './render/utils';
import '@/module'; import '@/module';
import { MotaOffscreenCanvas2D } from './fx/canvas2d';
// ----- 类注册 // ----- 类注册
Mota.register('class', 'AudioPlayer', AudioPlayer); Mota.register('class', 'AudioPlayer', AudioPlayer);
@ -95,7 +94,6 @@ Mota.register('class', 'UiController', UiController);
Mota.register('class', 'MComponent', MComponent); Mota.register('class', 'MComponent', MComponent);
Mota.register('class', 'ResourceController', ResourceController); Mota.register('class', 'ResourceController', ResourceController);
Mota.register('class', 'Danmaku', Danmaku); Mota.register('class', 'Danmaku', Danmaku);
Mota.register('class', 'MotaCanvas2D', MotaCanvas2D);
// ----- 函数注册 // ----- 函数注册
Mota.register('fn', 'm', m); Mota.register('fn', 'm', m);
Mota.register('fn', 'unwrapBinary', unwarpBinary); Mota.register('fn', 'unwrapBinary', unwarpBinary);
@ -151,9 +149,7 @@ Mota.register('module', 'UIComponents', {
}); });
Mota.register('module', 'MCGenerator', MCGenerator); Mota.register('module', 'MCGenerator', MCGenerator);
Mota.register('module', 'Shadow', Shadow); Mota.register('module', 'Shadow', Shadow);
Mota.register('module', 'Effect', { Mota.register('module', 'Effect', {});
Portal: portal
});
Mota.register('module', 'Render', { Mota.register('module', 'Render', {
texture, texture,
MotaRenderer, MotaRenderer,
@ -166,6 +162,7 @@ Mota.register('module', 'Render', {
Layer, Layer,
LayerGroupFloorBinder, LayerGroupFloorBinder,
Camera, Camera,
MotaOffscreenCanvas2D,
Utils: RenderUtils Utils: RenderUtils
}); });
Mota.register('module', 'Action', { Mota.register('module', 'Action', {

View File

@ -428,31 +428,6 @@ document.addEventListener('keyup', e => {
} }
} else { } else {
// polyfill样板 // polyfill样板
if (
main.dom.startPanel.style.display == 'block' &&
(main.dom.startButtons.style.display == 'block' ||
main.dom.levelChooseButtons.style.display == 'block')
) {
if (e.keyCode == 38 || e.keyCode == 33)
// up/pgup
main.selectButton((main.selectedButton || 0) - 1);
else if (e.keyCode == 40 || e.keyCode == 34)
// down/pgdn
main.selectButton((main.selectedButton || 0) + 1);
else if (e.keyCode == 67 || e.keyCode == 13 || e.keyCode == 32)
// C/Enter/Space
main.selectButton(main.selectedButton);
else if (
e.keyCode == 27 &&
main.dom.levelChooseButtons.style.display == 'block'
) {
// ESC
core.showStartAnimate(true);
e.preventDefault();
}
e.stopPropagation();
return;
}
if (main.dom.inputDiv.style.display == 'block') { if (main.dom.inputDiv.style.display == 'block') {
if (e.keyCode == 13) { if (e.keyCode == 13) {
setTimeout(function () { setTimeout(function () {

View File

@ -389,11 +389,13 @@ Mota.require('var', 'hook').on('reset', () => {
Mota.require('var', 'hook').once('reset', () => { Mota.require('var', 'hook').once('reset', () => {
const mainStorage = GameStorage.for(GameStorage.fromGame('main')); const mainStorage = GameStorage.for(GameStorage.fromGame('main'));
mainStorage.read(); mainStorage.read();
if (!mainStorage.getValue('played', false)) { if (mainStorage.getValue('played', false)) {
mainStorage.setValue('played', true); mainStorage.setValue('played', true);
const defaultsTool = let defaultsTool = CustomToolbar.list.find(v => v.id === '@defaults');
CustomToolbar.list.find(v => v.id === '@defaults') ?? const hasDefaults = !!defaultsTool;
new CustomToolbar('@defaults', true); if (!defaultsTool) {
defaultsTool = new CustomToolbar('@defaults', true);
}
defaultsTool.closeAll(); defaultsTool.closeAll();
defaultsTool.items = reactive([]); defaultsTool.items = reactive([]);
defaultsTool.add({ defaultsTool.add({
@ -417,38 +419,25 @@ Mota.require('var', 'hook').once('reset', () => {
'minimap' 'minimap'
] ]
}); });
// 计算位置 // 计算位置,显示在游戏画面下方
if (isMobile) { // if (!hasDefaults) {
// 手机端显示在最下方 // const gameGroup = core.dom.gameGroup;
defaultsTool.setPos(25, window.innerHeight - 100); // const bottom = gameGroup.offsetTop + gameGroup.offsetHeight - 3;
defaultsTool.setSize(window.innerWidth - 50, 100); // const left = gameGroup.offsetLeft + 3;
} else { // const width = gameGroup.offsetWidth - 6;
// 电脑显示在屏幕右方
const x = window.innerWidth / 2 + core.domStyle.scale * 240 + 75; // if (isMobile) {
defaultsTool.setPos(x, window.innerHeight / 2 + 100); // // 手机端显示在最下方
defaultsTool.setSize(window.innerWidth - x - 75, 200); // defaultsTool.setPos(16, window.innerHeight - 32);
} // defaultsTool.setSize(bottom, 35);
// } else {
// // 电脑显示在屏幕右方
// defaultsTool.setPos(left, bottom);
// defaultsTool.setSize(width, 70);
// }
// }
defaultsTool.show(); defaultsTool.show();
CustomToolbar.save(); CustomToolbar.save();
} }
}); });
window.addEventListener('resize', () => {
requestAnimationFrame(() => {
const defaultsTool = CustomToolbar.list.find(v => v.id === '@defaults');
if (!defaultsTool) return;
// 计算位置
if (isMobile) {
// 手机端显示在最下方
defaultsTool.setPos(25, window.innerHeight - 100);
defaultsTool.setSize(window.innerWidth - 50, 100);
} else {
// 电脑显示在屏幕右方
const x = window.innerWidth / 2 + core.domStyle.scale * 240 + 75;
defaultsTool.setPos(x, window.innerHeight / 2 + 100);
defaultsTool.setSize(window.innerWidth - x - 75, 200);
}
defaultsTool.refresh(true);
});
});

View File

@ -355,16 +355,6 @@ function handleScreenSetting<T extends number | boolean>(
} else if (key === 'heroDetail') { } else if (key === 'heroDetail') {
// 勇士显伤 // 勇士显伤
core.drawHero(); core.drawHero();
} else if (key === 'antiAlias') {
// 抗锯齿
for (const canvas of core.dom.gameCanvas) {
if (core.domStyle.hdCanvas.includes(canvas.id)) continue;
if (n) {
canvas.classList.remove('no-anti-aliasing');
} else {
canvas.classList.add('no-anti-aliasing');
}
}
} else if (key === 'fontSize') { } else if (key === 'fontSize') {
// 字体大小 // 字体大小
root.style.fontSize = `${n}px`; root.style.fontSize = `${n}px`;
@ -434,9 +424,8 @@ mainSetting
.register('itemDetail', '宝石血瓶显伤', true, COM.Boolean) .register('itemDetail', '宝石血瓶显伤', true, COM.Boolean)
.register('heroDetail', '勇士显伤', false, COM.Boolean) .register('heroDetail', '勇士显伤', false, COM.Boolean)
.register('transition', '界面动画', false, COM.Boolean) .register('transition', '界面动画', false, COM.Boolean)
.register('antiAlias', '抗锯齿', false, COM.Boolean)
.register('fontSize', '字体大小', 16, COM.Number, [2, 48, 1]) .register('fontSize', '字体大小', 16, COM.Number, [2, 48, 1])
.register('fontSizeStatus', '状态栏字体', 16, COM.Number, [2, 48, 1]) .register('fontSizeStatus', '状态栏字体', 16, COM.Number, [10, 300, 10])
.register('smoothView', '平滑镜头', true, COM.Boolean) .register('smoothView', '平滑镜头', true, COM.Boolean)
.register('criticalGem', '临界显示方式', false, COM.Boolean) .register('criticalGem', '临界显示方式', false, COM.Boolean)
.setDisplayFunc('criticalGem', value => (value ? '宝石数' : '攻击')) .setDisplayFunc('criticalGem', value => (value ? '宝石数' : '攻击'))
@ -501,7 +490,6 @@ loading.once('coreInit', () => {
'screen.itemDetail': !!storage.getValue('screen.itemDetail', true), 'screen.itemDetail': !!storage.getValue('screen.itemDetail', true),
'screen.heroDetail': !!storage.getValue('screen.heroDetail', false), 'screen.heroDetail': !!storage.getValue('screen.heroDetail', false),
'screen.transition': !!storage.getValue('screen.transition', false), 'screen.transition': !!storage.getValue('screen.transition', false),
'screen.antiAlias': !!storage.getValue('screen.antiAlias', false),
'screen.fontSize': storage.getValue('screen.fontSize', isMobile ? 9 : 16), 'screen.fontSize': storage.getValue('screen.fontSize', isMobile ? 9 : 16),
'screen.smoothView': !!storage.getValue('screen.smoothView', true), 'screen.smoothView': !!storage.getValue('screen.smoothView', true),
'screen.criticalGem': !!storage.getValue('screen.criticalGem', false), 'screen.criticalGem': !!storage.getValue('screen.criticalGem', false),

View File

@ -12,27 +12,33 @@ import { LayerGroupHalo } from '@/plugin/fx/halo';
import { FloorViewport } from './preset/viewport'; import { FloorViewport } from './preset/viewport';
import { Container } from './container'; import { Container } from './container';
import { PopText } from '@/plugin/fx/pop'; import { PopText } from '@/plugin/fx/pop';
import { FloorChange } from '@/plugin/fallback';
let main: MotaRenderer; let main: MotaRenderer;
Mota.require('var', 'loading').once('coreInit', () => { Mota.require('var', 'loading').once('coreInit', () => {
const render = new MotaRenderer(); const render = new MotaRenderer();
main = render; main = render;
render.mount();
render.hide(); render.hide();
const mapDraw = new Container(); const mapDraw = new Container();
const layer = new LayerGroup(); const layer = new LayerGroup();
const pop = new PopText('static'); const pop = new PopText('static');
const floorChange = new FloorChange('static');
mapDraw.id = 'map-draw'; mapDraw.id = 'map-draw';
layer.id = 'layer-main'; layer.id = 'layer-main';
pop.id = 'pop-main'; pop.id = 'pop-main';
floorChange.id = 'floor-change';
mapDraw.setHD(true); mapDraw.setHD(true);
mapDraw.setAntiAliasing(false); mapDraw.setAntiAliasing(false);
mapDraw.size(core._PX_, core._PY_); mapDraw.size(core._PX_, core._PY_);
floorChange.size(480, 480);
floorChange.setHD(true);
floorChange.setZIndex(10);
floorChange.setTips(tips);
pop.setZIndex(80); pop.setZIndex(80);
['bg', 'bg2', 'event', 'fg', 'fg2'].forEach(v => { ['bg', 'bg2', 'event', 'fg', 'fg2'].forEach(v => {
layer.addLayer(v as FloorLayer); layer.addLayer(v as FloorLayer);
}); });
@ -61,6 +67,7 @@ Mota.require('var', 'loading').once('coreInit', () => {
render.appendChild(mapDraw); render.appendChild(mapDraw);
mapDraw.appendChild(layer); mapDraw.appendChild(layer);
layer.appendChild(pop); layer.appendChild(pop);
mapDraw.appendChild(floorChange);
console.log(render); console.log(render);
}); });
@ -71,3 +78,37 @@ Mota.require('var', 'hook').on('reset', () => {
Mota.require('var', 'hook').on('restart', () => { Mota.require('var', 'hook').on('restart', () => {
main.hide(); main.hide();
}); });
const tips = [
'按下C可以查看鼠标位置怪物临界',
'按下E可以查看鼠标位置怪物属性',
'将鼠标移动到光环怪上以查看其产生的光环',
'字体太大?试试在背包的系统设置里面调整字体大小吧!',
'字体太小?试试在背包的系统设置里面调整字体大小吧!',
'按键不合心意?试试在背包的系统设置里面自定义快捷键',
'拖动状态栏左上角可以移动状态栏哦!',
'拖动状态栏右下角可以缩放状态栏哦!',
'按下M键鼠标位置的怪物的信息就会被你看光啦',
'咱就是说,要不要试一下工具栏的最后一个按钮?',
'要不要试试工具栏倒数第二个按钮呢?',
'想自定义工具栏?去背包的系统设置看看吧!',
'冷知识:临界界面可以拖动滚动条来查看减伤情况',
'可以用滚轮或者双指缩放小地图!',
'楼传的最左侧一栏可以选择区域!',
'冷知识:装备栏左栏最上面可以修改装备排序',
'冷冷冷知识:装备栏左栏最上面右侧可以更改顺序或倒序',
'第一章使用跳跃技能可是要扣血的!要注意!',
'按H查看本游戏的百科全书',
'给别人炫耀一下自己的成就点吧!虽然不能记榜(',
'抱团属性会在怪物右上角显示加成数量!',
'乾坤挪移属性绘制怪物左上角显示“乾”字!',
'电脑端可以试试按F11全屏游玩',
'手机端要不试试横屏玩?',
'不在楼梯边也可以使用楼传!',
'技能树的右下角可以切换章节!',
'开启自动切换技能就会自动帮你选择最优技能了!',
'魔塔不仅有撤回还有恢复按W或6就可以了',
'觉得卡顿?可以去试着设置里面关闭一些特性!',
'从第二章开始怪物负伤量不会超过其生命的1/4',
'生命回复不会超过防御的十分之一'
];

View File

@ -123,6 +123,8 @@ export interface ERenderItemEvent {
beforeRender: [transform: Transform]; beforeRender: [transform: Transform];
afterRender: [transform: Transform]; afterRender: [transform: Transform];
destroy: []; destroy: [];
/** 当这个元素被点击时触发 */
clickCapture: [x: number, y: number, type: number, ev: MouseEvent];
} }
interface TickerDelegation { interface TickerDelegation {

View File

@ -1,4 +1,5 @@
import { MotaCanvas2D } from '../fx/canvas2d'; import { logger } from '../common/logger';
import { MotaOffscreenCanvas2D } from '../fx/canvas2d';
import { Container } from './container'; import { Container } from './container';
import { RenderItem } from './item'; import { RenderItem } from './item';
import { Transform } from './transform'; import { Transform } from './transform';
@ -6,7 +7,7 @@ import { Transform } from './transform';
export class MotaRenderer extends Container { export class MotaRenderer extends Container {
static list: Map<string, MotaRenderer> = new Map(); static list: Map<string, MotaRenderer> = new Map();
target: MotaCanvas2D; target!: MotaOffscreenCanvas2D;
protected needUpdate: boolean = false; protected needUpdate: boolean = false;
readonly isRoot: boolean = true; readonly isRoot: boolean = true;
@ -14,11 +15,15 @@ export class MotaRenderer extends Container {
constructor(id: string = 'render-main') { constructor(id: string = 'render-main') {
super('static', false); super('static', false);
this.target = new MotaCanvas2D(id); const canvas = document.getElementById(id) as HTMLCanvasElement;
if (!canvas) {
logger.error(19);
return;
}
this.target = new MotaOffscreenCanvas2D(true, canvas);
this.size(core._PX_, core._PY_); this.size(core._PX_, core._PY_);
this.target.withGameScale(true); this.target.withGameScale(true);
this.target.size(core._PX_, core._PY_); this.target.size(core._PX_, core._PY_);
this.target.css(`z-index: 100`);
this.target.setAntiAliasing(false); this.target.setAntiAliasing(false);
this.setAnchor(0.5, 0.5); this.setAnchor(0.5, 0.5);
@ -72,13 +77,6 @@ export class MotaRenderer extends Container {
return null; return null;
} }
/**
*
*/
mount() {
this.target.mount();
}
destroy() { destroy() {
MotaRenderer.list.delete(this.id); MotaRenderer.list.delete(this.id);
} }

View File

@ -18,6 +18,7 @@
"16": "Cannot find log message for $1 code $2.", "16": "Cannot find log message for $1 code $2.",
"17": "Cannot use shader program for shader element that does not belong to it.", "17": "Cannot use shader program for shader element that does not belong to it.",
"18": "Cannot delete shader program for shader element that does not belong to it.", "18": "Cannot delete shader program for shader element that does not belong to it.",
"19": "Cannot create MotaRenderer instance for nonexistent canvas.",
"1101": "Shadow extension needs 'floor-hero' extension as dependency.", "1101": "Shadow extension needs 'floor-hero' extension as dependency.",
"1201": "Floor-damage extension needs 'floor-binder' extension as dependency.", "1201": "Floor-damage extension needs 'floor-binder' extension as dependency.",
"1301": "Portal extension need 'floor-binder' extension as dependency.", "1301": "Portal extension need 'floor-binder' extension as dependency.",

View File

@ -10,9 +10,6 @@
"是否展示当一个ui界面如怪物手册等的打开与关闭时的动画。当此项开启时", "是否展示当一个ui界面如怪物手册等的打开与关闭时的动画。当此项开启时",
"所有界面被打开或关闭时都会展示动画,否则会直接展示出来" "所有界面被打开或关闭时都会展示动画,否则会直接展示出来"
], ],
"antiAlias": [
"是否开启抗锯齿。开启后,画面会变得不那么锐利,观感更加舒适;关闭后,可以更好地展现出像素感,同时部分像素错误也不会出现。"
],
"fontSize": [ "fontSize": [
"在各种 ui 界面中显示的文字大小,范围为 2 - 48。注意字体过大可能会引起 ui 布局发生错误" "在各种 ui 界面中显示的文字大小,范围为 2 - 48。注意字体过大可能会引起 ui 布局发生错误"
], ],

View File

@ -24,8 +24,6 @@ import type * as damage from './enemy/damage';
import type { Logger } from '@/core/common/logger'; import type { Logger } from '@/core/common/logger';
import type { Danmaku } from '@/core/main/custom/danmaku'; import type { Danmaku } from '@/core/main/custom/danmaku';
import type * as misc from './mechanism/misc'; import type * as misc from './mechanism/misc';
import type { MotaCanvas2D } from '@/core/fx/canvas2d';
import type * as portal from '@/core/fx/portal';
import type { texture } from '@/core/render/cache'; import type { texture } from '@/core/render/cache';
import type { MotaRenderer } from '@/core/render/render'; import type { MotaRenderer } from '@/core/render/render';
import type { Container } from '@/core/render/container'; import type { Container } from '@/core/render/container';
@ -42,6 +40,7 @@ import type { Camera } from '@/core/render/camera';
import type * as Animation from 'mutate-animate'; import type * as Animation from 'mutate-animate';
import type * as RenderUtils from '@/core/render/utils'; import type * as RenderUtils from '@/core/render/utils';
import type { WeatherController } from '@/module/weather/weather'; import type { WeatherController } from '@/module/weather/weather';
import type { MotaOffscreenCanvas2D } from '@/core/fx/canvas2d';
interface ClassInterface { interface ClassInterface {
// 渲染进程与游戏进程通用 // 渲染进程与游戏进程通用
@ -62,7 +61,6 @@ interface ClassInterface {
SoundEffect: typeof SoundEffect; SoundEffect: typeof SoundEffect;
SoundController: typeof SoundController; SoundController: typeof SoundController;
BgmController: typeof BgmController; BgmController: typeof BgmController;
MotaCanvas2D: typeof MotaCanvas2D;
Danmaku: typeof Danmaku; Danmaku: typeof Danmaku;
// todo: 放到插件 ShaderEffect: typeof ShaderEffect; // todo: 放到插件 ShaderEffect: typeof ShaderEffect;
// 定义于游戏进程,渲染进程依然可用 // 定义于游戏进程,渲染进程依然可用
@ -110,9 +108,7 @@ interface ModuleInterface {
MiscData: typeof misc.MiscData; MiscData: typeof misc.MiscData;
HeroSkill: typeof misc.HeroSkill; HeroSkill: typeof misc.HeroSkill;
}; };
Effect: { Effect: {};
Portal: typeof portal;
};
Render: { Render: {
texture: typeof texture; texture: typeof texture;
MotaRenderer: typeof MotaRenderer; MotaRenderer: typeof MotaRenderer;
@ -125,6 +121,7 @@ interface ModuleInterface {
Layer: typeof Layer; Layer: typeof Layer;
LayerGroupFloorBinder: typeof LayerGroupFloorBinder; LayerGroupFloorBinder: typeof LayerGroupFloorBinder;
Camera: typeof Camera; Camera: typeof Camera;
MotaOffscreenCanvas2D: typeof MotaOffscreenCanvas2D;
Utils: typeof RenderUtils; Utils: typeof RenderUtils;
}; };
State: { State: {

View File

18
src/module/weather/sun.ts Normal file
View File

@ -0,0 +1,18 @@
import { Shader, ShaderProgram } from '@/core/render/shader';
import { IWeather, WeatherController } from './weather';
export class SunWeather implements IWeather {
static id: string = 'sun';
activate(): void {}
frame(): void {}
deactivate(): void {}
}
WeatherController.register(SunWeather);
class SunShader extends Shader {
protected override postDraw(gl: WebGL2RenderingContext): void {}
}

108
src/plugin/fallback.ts Normal file
View File

@ -0,0 +1,108 @@
import { MotaOffscreenCanvas2D } from '@/core/fx/canvas2d';
import { RenderItem, RenderItemPosition } from '@/core/render/item';
import { Transform } from '@/core/render/transform';
// 渲染端的向后兼容用,会充当两个版本间过渡的作用
export class FloorChange extends RenderItem {
private tips: string[] = [];
/** 当前小贴士 */
private usingTip: string = '';
/** 透明度 */
private alpha: number = 0;
private title: string = '';
constructor(type: RenderItemPosition) {
super(type, false);
}
/**
*
*/
setTips(tip: string[]) {
this.tips = tip;
}
/**
*
*/
setTitle(title: string) {
this.title = title;
}
/**
*
* @param time
*/
showChange(time: number) {
const length = this.tips.length;
const tip = this.tips[Math.floor(Math.random() * length)] ?? '';
this.usingTip = tip;
return new Promise<void>(res => {
const start = Date.now();
const id = this.delegateTicker(
() => {
const dt = Date.now() - start;
const progress = dt / time;
if (progress > 1) {
this.alpha = 1;
this.removeTicker(id);
} else {
this.alpha = progress;
}
this.update();
},
10000,
res
);
});
}
/**
*
* @param time
*/
async hideChange(time: number) {
return new Promise<void>(res => {
const start = Date.now();
const id = this.delegateTicker(
() => {
const dt = Date.now() - start;
const progress = dt / time;
if (progress > 1) {
this.removeTicker(id);
this.alpha = 0;
} else {
this.alpha = 1 - progress;
}
this.update();
},
10000,
res
);
});
}
protected render(
canvas: MotaOffscreenCanvas2D,
transform: Transform
): void {
if (this.alpha === 0) return;
const ctx = canvas.ctx;
ctx.globalAlpha = this.alpha;
ctx.fillStyle = '#000';
ctx.fillRect(0, 0, canvas.width, canvas.height);
ctx.textAlign = 'center';
ctx.fillStyle = '#fff';
ctx.font = '32px "normal"';
ctx.fillText(this.title, canvas.width / 2, canvas.height * 0.4);
ctx.font = '16px "normal"';
if (this.usingTip.length > 0) {
ctx.fillText(
'小贴士:' + this.usingTip,
canvas.width / 2,
canvas.height * 0.75
);
}
}
}

View File

@ -17,9 +17,14 @@ function createCanvas(name, zIndex) {
} }
export function init() { export function init() {
// 大地图适配
core.initStatus.bg2maps = {};
core.initStatus.fg2maps = {};
if (main.mode == 'editor') {
var bg2Canvas = createCanvas('bg2', 20); var bg2Canvas = createCanvas('bg2', 20);
var fg2Canvas = createCanvas('fg2', 63); var fg2Canvas = createCanvas('fg2', 63);
// 大地图适配
core.bigmap.canvas = [ core.bigmap.canvas = [
'bg2', 'bg2',
'fg2', 'fg2',
@ -29,10 +34,6 @@ export function init() {
'fg', 'fg',
'damage' 'damage'
]; ];
core.initStatus.bg2maps = {};
core.initStatus.fg2maps = {};
if (main.mode == 'editor') {
/*插入编辑器的图层 不做此步新增图层无法在编辑器显示*/ /*插入编辑器的图层 不做此步新增图层无法在编辑器显示*/
// 编辑器图层覆盖优先级 eui > efg > fg(前景层) > event2(48*32图块的事件层) > event(事件层) > bg(背景层) // 编辑器图层覆盖优先级 eui > efg > fg(前景层) > event2(48*32图块的事件层) > event(事件层) > bg(背景层)
// 背景层2(bg2) 插入事件层(event)之前(即bg与event之间) // 背景层2(bg2) 插入事件层(event)之前(即bg与event之间)

View File

@ -35,30 +35,30 @@ export function init() {
// todo: 多个状态栏分离与控制 // todo: 多个状态栏分离与控制
control.prototype.showStatusBar = function () { control.prototype.showStatusBar = function () {
if (main.mode == 'editor') return; if (main.mode == 'editor') return;
const CustomToolbar = Mota.require('class', 'CustomToolbar');
const defaultsTool = CustomToolbar.get('@defaults');
core.removeFlag('hideStatusBar'); core.removeFlag('hideStatusBar');
if (!fixedUi.hasName('statusBar')) { if (!fixedUi.hasName('statusBar')) {
fixedUi.open('statusBar'); fixedUi.open('statusBar');
} }
defaultsTool?.show();
}; };
control.prototype.hideStatusBar = function (showToolbox) { control.prototype.hideStatusBar = function (showToolbox) {
if (main.mode == 'editor') return; if (main.mode == 'editor') return;
const CustomToolbar = Mota.require('class', 'CustomToolbar');
const defaultsTool = CustomToolbar.get('@defaults');
// 如果原本就是隐藏的,则先显示 // 如果原本就是隐藏的,则先显示
if (!core.domStyle.showStatusBar) this.showStatusBar(); if (!core.domStyle.showStatusBar) this.showStatusBar();
if (core.isReplaying()) showToolbox = true; if (core.isReplaying()) showToolbox = true;
fixedUi.closeByName('statusBar'); fixedUi.closeByName('statusBar');
if (!showToolbox) {
defaultsTool?.closeAll();
}
var toolItems = core.dom.tools;
core.setFlag('hideStatusBar', true); core.setFlag('hideStatusBar', true);
core.setFlag('showToolbox', showToolbox || null); core.setFlag('showToolbox', showToolbox || null);
if (
(!core.domStyle.isVertical && !core.flags.extendToolbar) ||
!showToolbox
) {
for (var i = 0; i < toolItems.length; ++i)
toolItems[i].style.display = 'none';
}
}; };
} }

View File

@ -2,7 +2,6 @@ import * as fly from './ui/fly';
import * as chase from './chase'; import * as chase from './chase';
import * as completion from './completion'; import * as completion from './completion';
import * as pop from './pop'; import * as pop from './pop';
import * as frag from './fx/frag';
import * as use from './use'; import * as use from './use';
import * as gameCanvas from './fx/gameCanvas'; import * as gameCanvas from './fx/gameCanvas';
import * as animateController from './animateController'; import * as animateController from './animateController';
@ -14,7 +13,6 @@ Mota.Plugin.register('fly_r', fly);
Mota.Plugin.register('chase_r', chase); Mota.Plugin.register('chase_r', chase);
Mota.Plugin.register('completion_r', completion, completion.init); Mota.Plugin.register('completion_r', completion, completion.init);
Mota.Plugin.register('pop_r', pop, pop.init); Mota.Plugin.register('pop_r', pop, pop.init);
Mota.Plugin.register('frag_r', frag, frag.init);
Mota.Plugin.register('use_r', use); Mota.Plugin.register('use_r', use);
Mota.Plugin.register('gameCanvas_r', gameCanvas); Mota.Plugin.register('gameCanvas_r', gameCanvas);
Mota.Plugin.register( Mota.Plugin.register(

7
src/types/core.d.ts vendored
View File

@ -939,21 +939,25 @@ interface Core extends Pick<Main, CoreDataFromMain> {
readonly material: Material; readonly material: Material;
/** /**
* @deprecated
* *
*/ */
readonly timeout: Timeout; readonly timeout: Timeout;
/** /**
* @deprecated
* *
*/ */
readonly interval: Interval; readonly interval: Interval;
/** /**
* @deprecated
* *
*/ */
readonly animateFrame: AnimateFrame; readonly animateFrame: AnimateFrame;
/** /**
* @deprecated
* *
*/ */
readonly musicStatus: Readonly<MusicStatus>; readonly musicStatus: Readonly<MusicStatus>;
@ -964,11 +968,13 @@ interface Core extends Pick<Main, CoreDataFromMain> {
readonly platform: Readonly<CorePlatform>; readonly platform: Readonly<CorePlatform>;
/** /**
* @deprecated
* dom样式 * dom样式
*/ */
readonly domStyle: Readonly<DomStyle>; readonly domStyle: Readonly<DomStyle>;
/** /**
* @deprecated
* *
*/ */
readonly bigmap: CoreBigmap; readonly bigmap: CoreBigmap;
@ -989,6 +995,7 @@ interface Core extends Pick<Main, CoreDataFromMain> {
readonly initStatus: DeepReadonly<InitGameStatus>; readonly initStatus: DeepReadonly<InitGameStatus>;
/** /**
* @deprecated
* *
*/ */
readonly dymCanvas: Record<string, CanvasRenderingContext2D>; readonly dymCanvas: Record<string, CanvasRenderingContext2D>;

View File

@ -155,7 +155,6 @@ async function clickStartButton(id: string) {
core.startGame(id === 'easy' ? 'easy' : 'hard'); core.startGame(id === 'easy' ? 'easy' : 'hard');
} }
if (id === 'load-game') { if (id === 'load-game') {
core.dom.gameGroup.style.display = 'block';
start.style.top = '200vh'; start.style.top = '200vh';
core.load(); core.load();
} }