Compare commits

..

No commits in common. "b547c096a50772e8db57cbc54eaf10c1c41c5f18" and "69b67e8aaca168edfa5ebe58215aed02d4a17b47" have entirely different histories.

27 changed files with 593 additions and 1683 deletions

5
B站视频教程.url Normal file
View File

@ -0,0 +1,5 @@
[{000214A0-0000-0000-C000-000000000046}]
Prop3=19,2
[InternetShortcut]
IDList=
URL=https://www.bilibili.com/video/BV1SB4y1p7bg?spm_id_from=333.999.0.0

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

Binary file not shown.

View File

@ -699,12 +699,3 @@ div.checkboxSet {
.etableInputDiv textarea:hover { .etableInputDiv textarea:hover {
margin: -5px; margin: -5px;
} }
@font-face {
font-family: code;
src: url(./FiraCode.ttf);
}
.main .CodeMirror {
font-family: code, 微软雅黑, 黑体, 新宋体, Verdana;
}

View File

@ -710,11 +710,3 @@ div.checkboxSet {
margin: -5px; margin: -5px;
} }
@font-face {
font-family: Fira;
src: url(./FiraCode.ttf);
}
.main .CodeMirror {
font-family: Fira, Menlo, Consolas, 'Courier New', Courier, monospace;
}

View File

@ -7,11 +7,11 @@ editor_multi = function () {
var extraKeys = { var extraKeys = {
"Ctrl-/": function (cm) { cm.toggleComment(); }, "Ctrl-/": function (cm) { cm.toggleComment(); },
"Ctrl-B": function (cm) { ternServer.jumpToDef(cm); }, "Ctrl-B": function (cm) { ternServer.jumpToDef(cm); },
"Ctrl-Q": function (cm) { ternServer.rename(cm); }, "Ctrl-Q": function(cm) { ternServer.rename(cm); },
"Cmd-F": CodeMirror.commands.findPersistent, "Cmd-F": CodeMirror.commands.findPersistent,
"Ctrl-F": CodeMirror.commands.findPersistent, "Ctrl-F": CodeMirror.commands.findPersistent,
"Ctrl-R": CodeMirror.commands.replaceAll, "Ctrl-R": CodeMirror.commands.replaceAll,
"Ctrl-D": function (cm) { cm.foldCode(cm.getCursor()); }, "Ctrl-D": function(cm){ cm.foldCode(cm.getCursor()); },
"Ctrl-O": function () { editor_multi.openUrl('/_docs/#/api'); }, "Ctrl-O": function () { editor_multi.openUrl('/_docs/#/api'); },
"Ctrl-P": function () { editor_multi.openUrl('https://h5mota.com/plugins/'); } "Ctrl-P": function () { editor_multi.openUrl('https://h5mota.com/plugins/'); }
}; };
@ -48,14 +48,14 @@ editor_multi = function () {
'Ctrl-P': '打开在线插件列表Ctrl+P' 'Ctrl-P': '打开在线插件列表Ctrl+P'
}; };
document.getElementById('codemirrorCommands').innerHTML = document.getElementById('codemirrorCommands').innerHTML =
"<option value='' selected>执行操作...</option>" + "<option value='' selected>执行操作...</option>" +
Object.keys(commandsName).map(function (name) { Object.keys(commandsName).map(function (name) {
return "<option value='" + name + "'>" + commandsName[name] + "</option>" return "<option value='" + name + "'>" + commandsName[name] + "</option>"
}).join(''); }).join('');
var coredef = terndefs_f6783a0a_522d_417e_8407_94c67b692e50[2]; var coredef = terndefs_f6783a0a_522d_417e_8407_94c67b692e50[2];
Object.keys(core.material.enemys).forEach(function (name) { Object.keys(core.material.enemys).forEach(function (name){
coredef.core.material.enemys[name] = { coredef.core.material.enemys[name] = {
"!type": "enemy", "!type": "enemy",
"!doc": core.material.enemys[name].name || "怪物" "!doc": core.material.enemys[name].name || "怪物"
@ -236,15 +236,7 @@ editor_multi = function () {
document.getElementById('left7').style = 'z-index:-1;opacity: 0;'; document.getElementById('left7').style = 'z-index:-1;opacity: 0;';
} }
editor_multi.setLint = function () { editor_multi.setLint = function () {
if (editor_multi.lintAutocomplete) { codeEditor.setOption("lint", editor_multi.lintAutocomplete);
codeEditor.setOption("lint", {
options: {
esversion: 2021
}
});
} else {
codeEditor.setOption("lint", false);
}
codeEditor.setOption("autocomplete", editor_multi.lintAutocomplete); codeEditor.setOption("autocomplete", editor_multi.lintAutocomplete);
document.getElementById("lintCheckbox").checked = editor_multi.lintAutocomplete; document.getElementById("lintCheckbox").checked = editor_multi.lintAutocomplete;
} }
@ -261,7 +253,7 @@ editor_multi = function () {
var _format = function () { var _format = function () {
if (!editor_multi.lintAutocomplete) return; if (!editor_multi.lintAutocomplete) return;
var offset = (codeEditor.getScrollInfo() || {}).top || 0; var offset = (codeEditor.getScrollInfo() || {}).top || 0;
_setValue(beautifier.js(codeEditor.getValue(), { _setValue(js_beautify(codeEditor.getValue(), {
brace_style: "collapse-preserve-inline", brace_style: "collapse-preserve-inline",
indent_with_tabs: true, indent_with_tabs: true,
jslint_happy: true jslint_happy: true
@ -494,22 +486,6 @@ editor_multi = function () {
editor_multi.importFile(dict[mod]) editor_multi.importFile(dict[mod])
} }
// 字体大小
{
const CONFIG_KEY = "editor_multi.fontSize";
let fontsize = editor.config.get(CONFIG_KEY, 14);
const input = document.getElementById("editor_multi_fontsize");
const check = document.getElementById("editor_multi_fontweight")
input.value = fontsize;
editor_multi.setFontSize = function () {
const value = Number(input.value);
editor.config.set(CONFIG_KEY, value);
const ele = codeEditor.getWrapperElement()
ele.style.fontSize = `${value}px`;
ele.style.fontWeight = `${check.checked ? 'bold' : 'normal'}`
}
}
return editor_multi; return editor_multi;
} }
//editor_multi=editor_multi(); //editor_multi=editor_multi();

View File

@ -555,20 +555,14 @@ var data_comment_c456ea59_6018_45ef_8bcc_211a24c627dc = {
"autoScale": { "autoScale": {
"_leaf": true, "_leaf": true,
"_type": "checkbox", "_type": "checkbox",
"_docs": "自动缩放", "_docs": "自动缩放最大化",
"_data": "是否自动缩放至合适值" "_data": "是否自动缩放最大化,关闭后不再最大化"
}, },
"extendToolbar": { "extendToolbar": {
"_leaf": true, "_leaf": true,
"_type": "checkbox", "_type": "checkbox",
"_docs": "画面下方道具栏", "_docs": "横屏隐藏状态栏",
"_data": "开启后道具栏会被挪动至游戏画面的下方" "_data": "在横屏状态下是否隐藏左侧状态栏从而获得仿RM的沉浸式体验"
},
"hideLeftStatusBar": {
"_leaf": true,
"_type": "checkbox",
"_docs": "隐藏左侧状态栏",
"_data": "是否隐藏左侧状态栏,开启后强制开启画面下方道具栏"
}, },
"flyNearStair": { "flyNearStair": {
"_leaf": true, "_leaf": true,

View File

@ -242,21 +242,15 @@
<button onclick="confirmColor()">确定</button> <button onclick="confirmColor()">确定</button>
</div> </div>
<div id="left7" style="z-index:-1;opacity: 0;"><!-- 多行文本编辑器 --> <div id="left7" style="z-index:-1;opacity: 0;"><!-- 多行文本编辑器 -->
<div> <button onclick="editor_multi.confirm()">确认</button>
<button onclick="editor_multi.confirm()">确认</button> <button onclick="editor_multi.cancel()">取消</button>
<button onclick="editor_multi.cancel()">取消</button> <button onclick="editor_multi.confirm(true)">应用</button>
<button onclick="editor_multi.confirm(true)">应用</button> <button onclick="editor_multi.format()">格式化</button>
<button onclick="editor_multi.format()">格式化</button> <button id="editor_multi_preview" style="display: none;">预览</button>
<button id="editor_multi_preview" style="display: none;">预览</button> <input type="checkbox" onclick="editor_multi.toggerLint()" id="lintCheckbox"
<input type="checkbox" onclick="editor_multi.toggerLint()" id="lintCheckbox" style="vertical-align: middle;margin-left:6px"/>
style="vertical-align: middle;margin-left:6px"/> <span style="vertical-align: middle; margin-left: -3px">语法检查</span>
<span style="vertical-align: middle; margin-left: -3px">语法检查</span> <select id="codemirrorCommands" onchange="editor_multi.doCommand(this)" style="vertical-align: middle; margin-left: 6px;"></select>
<select id="codemirrorCommands" onchange="editor_multi.doCommand(this)" style="vertical-align: middle; margin-left: 6px;"></select>
<span>字体大小</span>
<input style="width: 40px" type="number" onchange="editor_multi.setFontSize()" id="editor_multi_fontsize" />
<span>字体加粗</span>
<input style="width: 40px" type="checkbox" onchange="editor_multi.setFontSize()" id="editor_multi_fontweight" />
</div>
<textarea id="multiLineCode" name="multiLineCode"></textarea> <textarea id="multiLineCode" name="multiLineCode"></textarea>
</div> </div>
<div id="left8" class='leftTab' style="z-index:-1;opacity: 0;"><!-- functions --> <div id="left8" class='leftTab' style="z-index:-1;opacity: 0;"><!-- functions -->

View File

@ -238,21 +238,15 @@
<button onclick="confirmColor()">确定</button> <button onclick="confirmColor()">确定</button>
</div> </div>
<div id="left7" style="z-index:-1;opacity: 0;"><!-- 多行文本编辑器 --> <div id="left7" style="z-index:-1;opacity: 0;"><!-- 多行文本编辑器 -->
<div> <button onclick="editor_multi.confirm()">确认</button>
<button onclick="editor_multi.confirm()">确认</button> <button onclick="editor_multi.cancel()">取消</button>
<button onclick="editor_multi.cancel()">取消</button> <button onclick="editor_multi.confirm(true)">应用</button>
<button onclick="editor_multi.confirm(true)">应用</button> <button onclick="editor_multi.format()">格式化</button>
<button onclick="editor_multi.format()">格式化</button> <button id="editor_multi_preview" style="display: none;">预览</button>
<button id="editor_multi_preview" style="display: none;">预览</button> <input type="checkbox" onclick="editor_multi.toggerLint()" id="lintCheckbox"
<input type="checkbox" onclick="editor_multi.toggerLint()" id="lintCheckbox" style="vertical-align: middle;margin-left:6px"/>
style="vertical-align: middle;margin-left:6px"/> <span style="vertical-align: middle; margin-left: -3px">语法检查</span>
<span style="vertical-align: middle; margin-left: -3px">语法检查</span> <select id="codemirrorCommands" onchange="editor_multi.doCommand(this)" style="vertical-align: middle; margin-left: 6px;"></select>
<select id="codemirrorCommands" onchange="editor_multi.doCommand(this)" style="vertical-align: middle; margin-left: 6px;"></select>
<span>字体大小</span>
<input style="width: 40px" type="number" onchange="editor_multi.setFontSize()" id="editor_multi_fontsize" />
<span>字体加粗</span>
<input style="width: 40px" type="checkbox" onchange="editor_multi.setFontSize()" id="editor_multi_fontweight" />
</div>
<textarea id="multiLineCode" name="multiLineCode"></textarea> <textarea id="multiLineCode" name="multiLineCode"></textarea>
</div> </div>
<div id="left8" class='leftTab' style="z-index:-1;opacity: 0;"><!-- functions --> <div id="left8" class='leftTab' style="z-index:-1;opacity: 0;"><!-- functions -->

View File

@ -1,14 +1,12 @@
<!DOCTYPE html> <!DOCTYPE html>
<html> <html>
<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='ckcz123'>
<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>
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" /> <meta name="apple-mobile-web-app-status-bar-style" content="black-translucent"/>
<meta name="screen-orientation" content="portrait"> <meta name="screen-orientation" content="portrait">
<meta name="full-screen" content="yes"> <meta name="full-screen" content="yes">
<meta name="browsermode" content="application"> <meta name="browsermode" content="application">
@ -22,130 +20,130 @@
<div id='startImageDiv'></div> <div id='startImageDiv'></div>
<img id='startImageLogo' /> <img id='startImageLogo' />
</div> </div>
<script> <script>
(function () { (function () {
var startImageBackgroundDiv = document.getElementById('startImageBackgroundDiv'); var startImageBackgroundDiv = document.getElementById('startImageBackgroundDiv');
var startImageLogo = document.getElementById('startImageLogo'); var startImageLogo = document.getElementById('startImageLogo');
var startImageDiv = document.getElementById('startImageDiv'); var startImageDiv = document.getElementById('startImageDiv');
startImageLogo.onload = function () { startImageLogo.onload = function () {
startImageBackgroundDiv.style.display = 'block'; startImageBackgroundDiv.style.display = 'block';
var onAnimationEnd = function () { var onAnimationEnd = function () {
startImageBackgroundDiv.style.display = 'none'; startImageBackgroundDiv.style.display = 'none';
startImageLogo.classList.remove("startImageAnimation"); startImageLogo.classList.remove("startImageAnimation");
startImageDiv.classList.remove("startImageDivAnimation"); startImageDiv.classList.remove("startImageDivAnimation");
}
startImageDiv.addEventListener("webkitAnimationEnd", onAnimationEnd);
startImageDiv.addEventListener("animationend", onAnimationEnd);
startImageLogo.classList.add("startImageAnimation");
startImageDiv.classList.add("startImageDivAnimation");
// 注释下面这句话以禁止单击立刻跳过开场动画
startImageBackgroundDiv.onclick = onAnimationEnd;
} }
startImageLogo.onerror = function () { } startImageDiv.addEventListener("webkitAnimationEnd", onAnimationEnd);
startImageLogo.src = "logo.png"; startImageDiv.addEventListener("animationend", onAnimationEnd);
})(); startImageLogo.classList.add("startImageAnimation");
</script> startImageDiv.classList.add("startImageDivAnimation");
<!-- injection --> // 注释下面这句话以禁止单击立刻跳过开场动画
<div id='gameGroup'> startImageBackgroundDiv.onclick = onAnimationEnd;
<canvas id="whole" style="position: absolute; left: 0; top: 0; z-index: 68;"></canvas> }
<p id='mainTips'>请稍候...</p> startImageLogo.onerror = function () {}
<img id='musicBtn'> startImageLogo.src = "logo.png";
<div id='startPanel'> })();
<div id='startTop'> </script>
<div id='startTopProgressBar'> <!-- injection -->
<div id='startTopProgress'></div> <div id='gameGroup'>
</div> <canvas id="whole" style="position: absolute; left: 0; top: 0; z-index: 68;"></canvas>
<p id='startTopLoadTips'>资源即将开始加载</p> <p id='mainTips'>请稍候...</p>
<p id='startTopHint'>HTML5魔塔游戏平台享受更多魔塔游戏<br />https://h5mota.com/</p> <img id='musicBtn'>
</div> <div id='startPanel'>
<img id='startBackground'> <div id='startTop'>
<p id='startLogo'></p> <div id='startTopProgressBar'>
<div id='startButtonGroup'> <div id='startTopProgress'></div>
<div id='startButtons'>
<span class='startButton' id='playGame'>开始游戏</span>
<span class='startButton' id='loadGame'>继续游戏</span>
<span class='startButton' id='replayGame'>录像回放</span>
</div>
<div id='levelChooseButtons'></div>
</div> </div>
<p id='startTopLoadTips'>资源即将开始加载</p>
<p id='startTopHint'>HTML5魔塔游戏平台享受更多魔塔游戏<br/>https://h5mota.com/</p>
</div> </div>
<div id='floorMsgGroup'> <img id='startBackground'>
<p id='logoLabel'></p> <p id='startLogo'></p>
<p id='versionLabel'></p> <div id='startButtonGroup'>
<p id='floorNameLabel'></p> <div id='startButtons'>
<span class='startButton' id='playGame'>开始游戏</span>
<span class='startButton' id='loadGame'>继续游戏</span>
<span class='startButton' id='replayGame'>录像回放</span>
</div>
<div id='levelChooseButtons'></div>
</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> </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化 -->
<canvas id="statusCanvas" style="position: absolute; left: 0; top: 0;"></canvas> <canvas id="statusCanvas" style="position: absolute; left: 0; top: 0; z-index: 50;"></canvas>
<canvas id="caidan1" style="position: absolute; left: 0; top: 0;"></canvas> <canvas id="caidan1" style="position: absolute; left: 0; top: 0;"></canvas>
</div> </div>
<div id="toolBar" class="clearfix"> <div id="toolBar" class="clearfix">
@ -170,11 +168,11 @@
<div id="gameDraw"> <div id="gameDraw">
<div id="gif"></div> <div id="gif"></div>
<div id="gif2"></div> <div id="gif2"></div>
<canvas class='gameCanvas anti-aliasing' id='bg'></canvas> <canvas class='gameCanvas' id='bg'></canvas>
<canvas class='gameCanvas anti-aliasing' id='event'></canvas> <canvas class='gameCanvas' id='event'></canvas>
<canvas class='gameCanvas anti-aliasing' id='hero'></canvas> <canvas class='gameCanvas' id='hero'></canvas>
<canvas class='gameCanvas anti-aliasing' id='event2'></canvas> <canvas class='gameCanvas' id='event2'></canvas>
<canvas class='gameCanvas anti-aliasing' id='fg'></canvas> <canvas class='gameCanvas' id='fg'></canvas>
<canvas class='gameCanvas' id='caidan'></canvas> <canvas class='gameCanvas' id='caidan'></canvas>
<canvas class='gameCanvas' id='damage'></canvas> <canvas class='gameCanvas' id='damage'></canvas>
<canvas class='gameCanvas' id='animate'></canvas> <canvas class='gameCanvas' id='animate'></canvas>
@ -202,5 +200,4 @@
<script>main.init('play');main.listen();</script> <script>main.init('play');main.listen();</script>
</body> </body>
</html> </html>

View File

@ -1225,7 +1225,7 @@ actions.prototype._clickBook = function (x, y) {
var data = core.status.event.data; var data = core.status.event.data;
if (data != null && y < core._HEIGHT_-1) { if (data != null && y < core._HEIGHT_-1) {
var per_page = pageinfo.per_page, page = parseInt(data / per_page); var per_page = pageinfo.per_page, page = parseInt(data / per_page);
var u = (core._HEIGHT_ - 1) / per_page; var u = this.LAST / per_page;
for (var i = 0; i < per_page; ++i) { for (var i = 0; i < per_page; ++i) {
if (y >= u * i && y < u * (i + 1)) { if (y >= u * i && y < u * (i + 1)) {
var index = per_page * page + i; var index = per_page * page + i;

View File

@ -18,7 +18,6 @@ control.prototype._init = function () {
this.weathers = {}; this.weathers = {};
this.resizes = []; this.resizes = [];
this.noAutoEvents = true; this.noAutoEvents = true;
this.updateNextFrame = false;
// --- 注册系统的animationFrame // --- 注册系统的animationFrame
this.registerAnimationFrame("totalTime", false, this._animationFrame_totalTime); this.registerAnimationFrame("totalTime", false, this._animationFrame_totalTime);
this.registerAnimationFrame("autoSave", true, this._animationFrame_autoSave); this.registerAnimationFrame("autoSave", true, this._animationFrame_autoSave);
@ -3047,27 +3046,22 @@ control.prototype.clearStatusBar = function () {
////// 更新状态栏 ////// ////// 更新状态栏 //////
control.prototype.updateStatusBar = function (doNotCheckAutoEvents, immediate) { control.prototype.updateStatusBar = function (doNotCheckAutoEvents, immediate) {
if (!core.isPlaying()) return;
if (immediate) { if (immediate) {
return this.updateStatusBar_update(); return this.updateStatusBar_update();
} }
if (!doNotCheckAutoEvents) this.noAutoEvents = false; if (!doNotCheckAutoEvents) this.noAutoEvents = false;
if (core.isReplaying()) return this.updateStatusBar_update(); if (core.isReplaying()) return this.updateStatusBar_update();
if (!core.control.updateNextFrame) { requestAnimationFrame(this.updateStatusBar_update)
core.control.updateNextFrame = true; }
requestAnimationFrame(this.updateStatusBar_update);
}
};
control.prototype.updateStatusBar_update = function () { control.prototype.updateStatusBar_update = function () {
core.control.updateNextFrame = false;
if (!core.isPlaying() || core.hasFlag('__statistics__')) return; if (!core.isPlaying() || core.hasFlag('__statistics__')) return;
core.control.controldata.updateStatusBar(); core.control.controldata.updateStatusBar();
if (!core.control.noAutoEvents) core.checkAutoEvents(); if (!core.control.noAutoEvents) core.checkAutoEvents();
core.control._updateStatusBar_setToolboxIcon(); core.control._updateStatusBar_setToolboxIcon();
core.clearRouteFolding(); core.clearRouteFolding();
core.control.noAutoEvents = true; core.control.noAutoEvents = true;
}; }
control.prototype._updateStatusBar_setToolboxIcon = function () { control.prototype._updateStatusBar_setToolboxIcon = function () {
if (core.isReplaying()) { if (core.isReplaying()) {
@ -3271,10 +3265,9 @@ control.prototype.resize = function () {
var clientWidth = main.dom.body.clientWidth, clientHeight = main.dom.body.clientHeight; var clientWidth = main.dom.body.clientWidth, clientHeight = main.dom.body.clientHeight;
var BORDER = 3; var BORDER = 3;
var extendToolbar = core.flags.extendToolbar; var extendToolbar = core.flags.extendToolbar;
let hideLeftStatusBar = core.flags.hideLeftStatusBar; var BAR_WIDTH = extendToolbar ? 0 : Math.round(core._PY_ * 0.3);
var BAR_WIDTH = hideLeftStatusBar ? 0 : Math.round(core._PY_ * 0.31);
var horizontalMaxRatio = (clientHeight - 2 * BORDER - (hideLeftStatusBar ? BORDER : 0)) / (core._PY_ + (hideLeftStatusBar ? 38 : 0)); var horizontalMaxRatio = (clientHeight - 2 * BORDER - (extendToolbar ? BORDER : 0)) / (core._PY_ + (extendToolbar ? 38 : 0));
if (clientWidth - 3 * BORDER >= core._PX_ + BAR_WIDTH || (clientWidth > clientHeight && horizontalMaxRatio < 1)) { if (clientWidth - 3 * BORDER >= core._PX_ + BAR_WIDTH || (clientWidth > clientHeight && horizontalMaxRatio < 1)) {
// 横屏 // 横屏
@ -3296,7 +3289,6 @@ control.prototype.resize = function () {
core.domStyle.scale = Math.min((clientWidth - 2 * BORDER) / core._PX_); core.domStyle.scale = Math.min((clientWidth - 2 * BORDER) / core._PX_);
core.domStyle.availableScale = []; core.domStyle.availableScale = [];
extendToolbar = false; extendToolbar = false;
hideLeftStatusBar = false;
BAR_WIDTH = Math.round(core._PX_ * 0.3); BAR_WIDTH = Math.round(core._PX_ * 0.3);
} }
@ -3325,8 +3317,7 @@ control.prototype.resize = function () {
statusBarHeightInVertical: core.domStyle.isVertical ? (32 * col + 6) * core.domStyle.scale + 2 * BORDER : 0, statusBarHeightInVertical: core.domStyle.isVertical ? (32 * col + 6) * core.domStyle.scale + 2 * BORDER : 0,
toolbarHeightInVertical: core.domStyle.isVertical ? 38 * core.domStyle.scale + 2 * BORDER : 0, toolbarHeightInVertical: core.domStyle.isVertical ? 38 * core.domStyle.scale + 2 * BORDER : 0,
extendToolbar: extendToolbar, extendToolbar: extendToolbar,
is15x15: false, is15x15: false
hideLeftStatusBar
}; };
this._doResize(obj); this._doResize(obj);
@ -3348,7 +3339,7 @@ control.prototype._resize_gameGroup = function (obj) {
totalHeight = obj.outerHeight + obj.statusBarHeightInVertical + obj.toolbarHeightInVertical totalHeight = obj.outerHeight + obj.statusBarHeightInVertical + obj.toolbarHeightInVertical
} }
else { else {
totalWidth = obj.outerWidth + obj.BAR_WIDTH * core.domStyle.scale + (obj.hideLeftStatusBar ? 0 : obj.BORDER); totalWidth = obj.outerWidth + obj.BAR_WIDTH * core.domStyle.scale + (obj.extendToolbar ? 0 : obj.BORDER);
totalHeight = obj.outerHeight + (obj.extendToolbar ? obj.TOOLBAR_HEIGHT * core.domStyle.scale + obj.BORDER : 0); totalHeight = obj.outerHeight + (obj.extendToolbar ? obj.TOOLBAR_HEIGHT * core.domStyle.scale + obj.BORDER : 0);
} }
gameGroup.style.width = totalWidth + "px"; gameGroup.style.width = totalWidth + "px";
@ -3418,7 +3409,9 @@ control.prototype._resize_canvas = function (obj) {
} else { } else {
for (var name in core.dymCanvas) { for (var name in core.dymCanvas) {
var ctx = core.dymCanvas[name], canvas = ctx.canvas; var ctx = core.dymCanvas[name], canvas = ctx.canvas;
core.resizeCanvas(ctx, parseFloat(canvas.getAttribute("_width")), parseFloat(canvas.getAttribute("_height"))) var ratio = canvas.hasAttribute('isHD') ? core.domStyle.ratio : 1;
canvas.style.width = canvas.width / ratio * core.domStyle.scale + "px";
canvas.style.height = canvas.height / ratio * core.domStyle.scale + "px";
canvas.style.left = parseFloat(canvas.getAttribute("_left")) * core.domStyle.scale + "px"; canvas.style.left = parseFloat(canvas.getAttribute("_left")) * core.domStyle.scale + "px";
canvas.style.top = parseFloat(canvas.getAttribute("_top")) * core.domStyle.scale + "px"; canvas.style.top = parseFloat(canvas.getAttribute("_top")) * core.domStyle.scale + "px";
} }
@ -3442,13 +3435,13 @@ control.prototype._resize_statusBar = function (obj) {
statusBar.style.height = obj.outerHeight + (obj.extendToolbar ? obj.TOOLBAR_HEIGHT * core.domStyle.scale + obj.BORDER : 0) + "px"; statusBar.style.height = obj.outerHeight + (obj.extendToolbar ? obj.TOOLBAR_HEIGHT * core.domStyle.scale + obj.BORDER : 0) + "px";
statusBar.style.background = obj.globalAttribute.statusLeftBackground; statusBar.style.background = obj.globalAttribute.statusLeftBackground;
// --- 计算文字大小 // --- 计算文字大小
if (obj.hideLeftStatusBar) { if (obj.extendToolbar) {
statusBar.style.fontSize = 16 * core.domStyle.scale + "px"; statusBar.style.fontSize = 16 * core.domStyle.scale + "px";
} else { } else {
statusBar.style.fontSize = 16 * Math.min(1, (core._HEIGHT_ - 4) / obj.count) * core.domStyle.scale + "px"; statusBar.style.fontSize = 16 * Math.min(1, (core._HEIGHT_ - 4) / obj.count) * core.domStyle.scale + "px";
} }
} }
statusBar.style.display = obj.hideLeftStatusBar ? 'none' : 'block'; statusBar.style.display = obj.extendToolbar ? 'none' : 'block';
statusBar.style.borderTop = statusBar.style.borderLeft = obj.border; statusBar.style.borderTop = statusBar.style.borderLeft = obj.border;
statusBar.style.borderRight = core.domStyle.isVertical ? obj.border : ''; statusBar.style.borderRight = core.domStyle.isVertical ? obj.border : '';
statusBar.style.borderBottom = core.domStyle.isVertical ? '' : obj.border; statusBar.style.borderBottom = core.domStyle.isVertical ? '' : obj.border;
@ -3463,7 +3456,7 @@ control.prototype._resize_statusBar = function (obj) {
core.dom.statusCanvas.style.height = obj.outerHeight - 2 * obj.BORDER + (obj.extendToolbar ? obj.TOOLBAR_HEIGHT * core.domStyle.scale + obj.BORDER : 0) + "px"; core.dom.statusCanvas.style.height = obj.outerHeight - 2 * obj.BORDER + (obj.extendToolbar ? obj.TOOLBAR_HEIGHT * core.domStyle.scale + obj.BORDER : 0) + "px";
core.maps._setHDCanvasSize(core.dom.statusCanvasCtx, obj.BAR_WIDTH, core._PY_ + (obj.extendToolbar ? obj.TOOLBAR_HEIGHT + obj.BORDER : 0)); core.maps._setHDCanvasSize(core.dom.statusCanvasCtx, obj.BAR_WIDTH, core._PY_ + (obj.extendToolbar ? obj.TOOLBAR_HEIGHT + obj.BORDER : 0));
} }
core.dom.statusCanvas.style.display = core.flags.statusCanvas && !obj.hideLeftStatusBar ? "block" : "none"; core.dom.statusCanvas.style.display = core.flags.statusCanvas && !obj.extendToolbar ? "block" : "none";
} }
control.prototype._resize_status = function (obj) { control.prototype._resize_status = function (obj) {
@ -3471,7 +3464,7 @@ control.prototype._resize_status = function (obj) {
if (core.domStyle.isVertical) { if (core.domStyle.isVertical) {
statusHeight = 32 * core.domStyle.scale * 0.8; statusHeight = 32 * core.domStyle.scale * 0.8;
} else { } else {
statusHeight = (obj.hideLeftStatusBar ? core._HEIGHT_ : core._HEIGHT_ - 4) / obj.count * 32 * core.domStyle.scale * 0.8; statusHeight = (obj.extendToolbar ? core._HEIGHT_ : core._HEIGHT_ - 4) / obj.count * 32 * core.domStyle.scale * 0.8;
} }
// status // status
for (var i = 0; i < core.dom.status.length; ++i) { for (var i = 0; i < core.dom.status.length; ++i) {
@ -3514,7 +3507,7 @@ control.prototype._resize_toolBar = function (obj) {
toolBar.style.background = obj.globalAttribute.toolsBackground; toolBar.style.background = obj.globalAttribute.toolsBackground;
} }
else { else {
if (obj.extendToolbar || obj.hideLeftStatusBar) { if (obj.extendToolbar) {
toolBar.style.left = ""; toolBar.style.left = "";
toolBar.style.right = 0; toolBar.style.right = 0;
toolBar.style.width = obj.outerWidth + "px"; toolBar.style.width = obj.outerWidth + "px";

View File

@ -34,10 +34,11 @@ maps.prototype._resetFloorImages = function () {
} }
} }
maps.prototype._setHDCanvasSize = function (ctx, width, height) { maps.prototype._setHDCanvasSize = function (ctx, width, height, isTempCanvas) {
ctx.setTransform(1, 0, 0, 1, 0, 0); ctx.setTransform(1, 0, 0, 1, 0, 0);
var ratio = core.domStyle.scale; var ratio = core.domStyle.ratio;
ratio *= devicePixelRatio; if (ctx === core.bigmap.tempCanvas) ratio = core.domStyle.scale;
if (isTempCanvas) ratio = core.domStyle.ratio;
if (width != null) ctx.canvas.width = width * ratio; if (width != null) ctx.canvas.width = width * ratio;
if (height != null) ctx.canvas.height = height * ratio; if (height != null) ctx.canvas.height = height * ratio;
ctx.scale(ratio, ratio); ctx.scale(ratio, ratio);
@ -1727,20 +1728,18 @@ maps.prototype._drawThumbnail_drawTempCanvas = function (floorId, blocks, option
// 如果是大地图模式? // 如果是大地图模式?
if (options.all) { if (options.all) {
// 计算比例 // 计算比例
var scale = Math.max(core._WIDTH_ / width, core._HEIGHT_ / height);
if (options.noHD) { if (options.noHD) {
tempCanvas.canvas.width = width * 32; tempCanvas.canvas.width = width * 32 * scale;
tempCanvas.canvas.height = height * 32; tempCanvas.canvas.height = height * 32 * scale;
tempCanvas.canvas.removeAttribute('isHD'); } else core.resizeCanvas(tempCanvas, width * 32 * scale, height * 32 * scale, false, true);
} else { tempCanvas.scale(scale, scale);
core.maps._setHDCanvasSize(tempCanvas, width * 32, height * 32);
}
} else if (width * height > core.bigmap.threshold) { } else if (width * height > core.bigmap.threshold) {
options.v2 = true; options.v2 = true;
if (options.noHD) { if (options.noHD) {
tempCanvas.canvas.width = core._PX_; tempCanvas.canvas.width = core._PX_;
tempCanvas.canvas.height = core._PY_; tempCanvas.canvas.height = core._PY_;
tempCanvas.canvas.removeAttribute('isHD'); } else core.resizeCanvas(tempCanvas, core._PX_, core._PY_);
} else core.maps._setHDCanvasSize(tempCanvas, width * 32, height * 32);
var centerX = options.centerX, centerY = options.centerY; var centerX = options.centerX, centerY = options.centerY;
if (centerX == null) centerX = Math.floor(width / 2); if (centerX == null) centerX = Math.floor(width / 2);
if (centerY == null) centerY = Math.floor(height / 2); if (centerY == null) centerY = Math.floor(height / 2);
@ -1752,8 +1751,7 @@ maps.prototype._drawThumbnail_drawTempCanvas = function (floorId, blocks, option
if (options.noHD) { if (options.noHD) {
tempCanvas.canvas.width = width * 32; tempCanvas.canvas.width = width * 32;
tempCanvas.canvas.height = height * 32; tempCanvas.canvas.height = height * 32;
tempCanvas.canvas.removeAttribute('isHD'); } else core.resizeCanvas(tempCanvas, width * 32, height * 32, false, true);
} else core.maps._setHDCanvasSize(tempCanvas, width * 32, height * 32);
} }
options.ctx = tempCanvas; options.ctx = tempCanvas;
@ -1815,7 +1813,6 @@ maps.prototype._drawThumbnail_drawToTarget = function (floorId, options) {
if (centerY == null) centerY = Math.floor(height / 2); if (centerY == null) centerY = Math.floor(height / 2);
var tempCanvas = core.bigmap.tempCanvas; var tempCanvas = core.bigmap.tempCanvas;
const scale = core.domStyle.scale * devicePixelRatio;
if (options.all) { if (options.all) {
var tempWidth = tempCanvas.canvas.width, tempHeight = tempCanvas.canvas.height; var tempWidth = tempCanvas.canvas.width, tempHeight = tempCanvas.canvas.height;
// 绘制全景图 // 绘制全景图
@ -1836,28 +1833,20 @@ maps.prototype._drawThumbnail_drawToTarget = function (floorId, options) {
} }
else { else {
// 只绘制可见窗口 // 只绘制可见窗口
var pw = core._PX_, var pw = core._PX_, ph = core._PY_, hw = core._HALF_WIDTH_, hh = core._HALF_HEIGHT_, W = core._WIDTH_, H = core._HEIGHT_;
ph = core._PY_, var ratio = core.domStyle.isVertical ? core.domStyle.ratio : core.domStyle.scale;
hw = core._HALF_WIDTH_, if (main.mode == 'editor') { pw = ph = core.__PIXELS__; hw = hh = core.__HALF_SIZE__; W = H = core.__SIZE__; }
hh = core._HALF_HEIGHT_,
W = core._WIDTH_,
H = core._HEIGHT_;
if (main.mode == 'editor') {
pw = ph = core.__PIXELS__;
hw = hh = core.__HALF_SIZE__;
W = H = core.__SIZE__;
}
if (options.v2) { if (options.v2) {
if (options.noHD) core.drawImage(ctx, tempCanvas.canvas, 0, 0, pw, ph, x, y, w, h); core.drawImage(ctx, tempCanvas.canvas, 0, 0, pw * ratio, ph * ratio, x, y, w, h);
else core.drawImage(ctx, tempCanvas.canvas, 0, 0, pw * scale, ph * scale, x, y, w, h);
} else { } else {
var offsetX = core.clamp(centerX - hw, 0, width - W), var offsetX = core.clamp(centerX - hw, 0, width - W),
offsetY = core.clamp(centerY - hh, 0, height - H); offsetY = core.clamp(centerY - hh, 0, height - H),
c = options.noHD ? 1 : core.domStyle.scale;
if (options.noHD) { if (options.noHD) {
core.drawImage(ctx, tempCanvas.canvas, offsetX * 32, offsetY * 32, pw, ph, x, y, w, h); core.drawImage(ctx, tempCanvas.canvas, offsetX * 32, offsetY * 32, pw, ph, x, y, w, h);
} else { return;
core.drawImage(ctx, tempCanvas.canvas, offsetX * 32 * scale, offsetY * 32 * scale, pw * scale, ph * scale, x, y, w, h);
} }
core.drawImage(ctx, tempCanvas.canvas, offsetX * 32 * ratio, offsetY * 32 * ratio, pw * ratio, ph * ratio, x, y, w, h);
} }
} }
} }

View File

@ -57,13 +57,7 @@ ui.prototype.clearMap = function (name, x, y, width, height) {
if (x != null && y != null && width != null && height != null) { if (x != null && y != null && width != null && height != null) {
ctx.clearRect(x, y, width, height); ctx.clearRect(x, y, width, height);
} else { } else {
if (ctx.canvas.getAttribute('isHD')) { ctx.clearRect(-32, -32, ctx.canvas.width + 32, ctx.canvas.height + 32);
const width = ctx.canvas.width / core.domStyle.scale / devicePixelRatio;
const height = ctx.canvas.height / core.domStyle.scale / devicePixelRatio;
ctx.clearRect(0, 0, width, height);
} else {
ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
}
} }
} }
} }
@ -1114,16 +1108,12 @@ ui.prototype.drawTextContent = function (ctx, content, config) {
config.offsetY = 0; config.offsetY = 0;
config.line = 0; config.line = 0;
config.blocks = []; config.blocks = [];
config.isHD = ctx == null || ctx.canvas.hasAttribute('isHD'); config.isHD = ctx != null && ctx.canvas.hasAttribute('isHD');
// 创建一个新的临时画布 // 创建一个新的临时画布
var tempCtx = document.createElement('canvas').getContext('2d'); var tempCtx = document.createElement('canvas').getContext('2d');
if (config.isHD && ctx) { if (config.isHD) {
core.maps._setHDCanvasSize( core.maps._setHDCanvasSize(tempCtx, ctx.canvas.width, ctx.canvas.height);
tempCtx,
ctx.canvas.width,
ctx.canvas.height
);
} else { } else {
tempCtx.canvas.width = ctx == null ? 1 : ctx.canvas.width; tempCtx.canvas.width = ctx == null ? 1 : ctx.canvas.width;
tempCtx.canvas.height = ctx == null ? 1 : ctx.canvas.height; tempCtx.canvas.height = ctx == null ? 1 : ctx.canvas.height;
@ -1158,20 +1148,10 @@ ui.prototype._drawTextContent_draw = function (ctx, tempCtx, content, config) {
if (config.index >= config.blocks.length) return false; if (config.index >= config.blocks.length) return false;
var block = config.blocks[config.index++]; var block = config.blocks[config.index++];
if (block != null) { if (block != null) {
// It works, why? var ratio = config.isHD ? core.domStyle.ratio : 1;
const scale = config.isHD ? devicePixelRatio * core.domStyle.scale : 1; core.drawImage(ctx, tempCtx.canvas, block.left * ratio, block.top * ratio, block.width * ratio, block.height * ratio,
core.drawImage( config.left + block.left + block.marginLeft, config.top + block.top + block.marginTop,
ctx, block.width, block.height);
tempCtx.canvas,
block.left * scale,
block.top * scale,
block.width * scale,
block.height * scale,
config.left + block.left + block.marginLeft,
config.top + block.top + block.marginTop,
block.width,
block.height
);
} }
return true; return true;
} }
@ -2532,24 +2512,23 @@ ui.prototype.drawFly = function (page) {
core.setTextAlign('ui', 'center'); core.setTextAlign('ui', 'center');
var middle = core._PY_ / 2 + 39; var middle = core._PY_ / 2 + 39;
const lastWidth = 0.25 * core._PX_ - 16;
// 换行 // 换行
var lines = core.splitLines('ui', title, lastWidth, this._buildFont(19, true)); var lines = core.splitLines('ui', title, 120, this._buildFont(19, true));
var start_y = middle - (lines.length - 1) * 11; var start_y = middle - (lines.length - 1) * 11;
for (var i in lines) { for (var i in lines) {
core.fillText('ui', lines[i], core._PX_ - lastWidth * 0.5, start_y, '#FFFFFF'); core.fillText('ui', lines[i], core._PX_ - 60, start_y, '#FFFFFF');
start_y += 22; start_y += 22;
} }
if (core.actions._getNextFlyFloor(1) != page) { if (core.actions._getNextFlyFloor(1) != page) {
core.fillText('ui', '▲', core._PX_ - lastWidth * 0.5, middle - 64, null, this._buildFont(17, false)); core.fillText('ui', '▲', core._PX_ - 60, middle - 64, null, this._buildFont(17, false));
core.fillText('ui', '▲', core._PX_ - lastWidth * 0.5, middle - 96); core.fillText('ui', '▲', core._PX_ - 60, middle - 96);
core.fillText('ui', '▲', core._PX_ - lastWidth * 0.5, middle - 96 - 7); core.fillText('ui', '▲', core._PX_ - 60, middle - 96 - 7);
} }
if (core.actions._getNextFlyFloor(-1) != page) { if (core.actions._getNextFlyFloor(-1) != page) {
core.fillText('ui', '▼', core._PX_ - lastWidth * 0.5, middle + 64, null, this._buildFont(17, false)); core.fillText('ui', '▼', core._PX_ - 60, middle + 64, null, this._buildFont(17, false));
core.fillText('ui', '▼', core._PX_ - lastWidth * 0.5, middle + 96); core.fillText('ui', '▼', core._PX_ - 60, middle + 96);
core.fillText('ui', '▼', core._PX_ - lastWidth * 0.5, middle + 96 + 7); core.fillText('ui', '▼', core._PX_ - 60, middle + 96 + 7);
} }
var size = 0.75; var size = 0.75;
core.strokeRect('ui', 16, 64, size * core._PX_, size * core._PY_, '#FFFFFF', 2); core.strokeRect('ui', 16, 64, size * core._PX_, size * core._PY_, '#FFFFFF', 2);
@ -3402,8 +3381,6 @@ ui.prototype.createCanvas = function (name, x, y, width, height, z) {
newCanvas.style.display = 'block'; newCanvas.style.display = 'block';
newCanvas.setAttribute("_left", x); newCanvas.setAttribute("_left", x);
newCanvas.setAttribute("_top", y); newCanvas.setAttribute("_top", y);
newCanvas.setAttribute("_width", width);
newCanvas.setAttribute("_height", height);
newCanvas.style.width = width * core.domStyle.scale + 'px'; newCanvas.style.width = width * core.domStyle.scale + 'px';
newCanvas.style.height = height * core.domStyle.scale + 'px'; newCanvas.style.height = height * core.domStyle.scale + 'px';
newCanvas.style.left = x * core.domStyle.scale + 'px'; newCanvas.style.left = x * core.domStyle.scale + 'px';
@ -3462,21 +3439,16 @@ ui.prototype.rotateCanvas = function (name, angle, centerX, centerY) {
} }
////// canvas重置 ////// ////// canvas重置 //////
ui.prototype.resizeCanvas = function (name, width, height, styleOnly) { ui.prototype.resizeCanvas = function (name, width, height, styleOnly, isTempCanvas) {
var ctx = core.getContextByName(name); var ctx = core.getContextByName(name);
const canvas = ctx.canvas;
if (!ctx) return null; if (!ctx) return null;
if (width != null) { if (width != null) {
if (!styleOnly && ctx.canvas.hasAttribute('isHD')) if (!styleOnly) core.maps._setHDCanvasSize(ctx, width, null, isTempCanvas);
core.maps._setHDCanvasSize(ctx, width, null);
ctx.canvas.style.width = width * core.domStyle.scale + 'px'; ctx.canvas.style.width = width * core.domStyle.scale + 'px';
canvas.setAttribute('_width', width);
} }
if (height != null) { if (height != null) {
if (!styleOnly && ctx.canvas.hasAttribute('isHD')) if (!styleOnly) core.maps._setHDCanvasSize(ctx, null, height, isTempCanvas);
core.maps._setHDCanvasSize(ctx, null, height);
ctx.canvas.style.height = height * core.domStyle.scale + 'px'; ctx.canvas.style.height = height * core.domStyle.scale + 'px';
canvas.setAttribute('_height', height);
} }
return ctx; return ctx;
} }

715
main.js

File diff suppressed because it is too large Load Diff

View File

@ -718,7 +718,7 @@ var data_a1e2fb4a_e986_4524_b0da_9b7ba7c0874d =
"firstData": { "firstData": {
"title": "天塔", "title": "天塔",
"name": "tianta", "name": "tianta",
"version": "Ver 2.10.3", "version": "Ver 2.10.0",
"floorId": "nandu", "floorId": "nandu",
"hero": { "hero": {
"image": "hero.png", "image": "hero.png",
@ -1595,7 +1595,6 @@ var data_a1e2fb4a_e986_4524_b0da_9b7ba7c0874d =
"enableMoveDirectly": true, "enableMoveDirectly": true,
"enableRouteFolding": true, "enableRouteFolding": true,
"disableShopOnDamage": false, "disableShopOnDamage": false,
"blurFg": false, "blurFg": false
"hideLeftStatusBar": false
} }
} }

View File

@ -907,11 +907,6 @@ main.floors.MT0=
"steps": [ "steps": [
"right:1" "right:1"
] ]
},
{
"type": "hide",
"remove": true,
"time": 0
} }
] ]
}, },

View File

@ -66,7 +66,7 @@ main.floors.MT16=
"true": [ "true": [
{ {
"type": "setBlock", "type": "setBlock",
"number": "372", "number": "339",
"loc": [ "loc": [
[ [
11, 11,
@ -136,7 +136,7 @@ main.floors.MT16=
"true": [ "true": [
{ {
"type": "setBlock", "type": "setBlock",
"number": "372", "number": "339",
"loc": [ "loc": [
[ [
11, 11,
@ -206,7 +206,7 @@ main.floors.MT16=
"true": [ "true": [
{ {
"type": "setBlock", "type": "setBlock",
"number": "372", "number": "339",
"loc": [ "loc": [
[ [
11, 11,
@ -276,7 +276,7 @@ main.floors.MT16=
"true": [ "true": [
{ {
"type": "setBlock", "type": "setBlock",
"number": "372", "number": "339",
"loc": [ "loc": [
[ [
11, 11,
@ -346,7 +346,7 @@ main.floors.MT16=
"true": [ "true": [
{ {
"type": "setBlock", "type": "setBlock",
"number": "372", "number": "339",
"loc": [ "loc": [
[ [
11, 11,
@ -416,7 +416,7 @@ main.floors.MT16=
"true": [ "true": [
{ {
"type": "setBlock", "type": "setBlock",
"number": "372", "number": "339",
"loc": [ "loc": [
[ [
11, 11,
@ -486,7 +486,7 @@ main.floors.MT16=
"true": [ "true": [
{ {
"type": "setBlock", "type": "setBlock",
"number": "372", "number": "339",
"loc": [ "loc": [
[ [
11, 11,
@ -556,7 +556,7 @@ main.floors.MT16=
"true": [ "true": [
{ {
"type": "setBlock", "type": "setBlock",
"number": "372", "number": "339",
"loc": [ "loc": [
[ [
11, 11,
@ -626,7 +626,7 @@ main.floors.MT16=
"true": [ "true": [
{ {
"type": "setBlock", "type": "setBlock",
"number": "372", "number": "339",
"loc": [ "loc": [
[ [
11, 11,
@ -696,7 +696,7 @@ main.floors.MT16=
"true": [ "true": [
{ {
"type": "setBlock", "type": "setBlock",
"number": "372", "number": "339",
"loc": [ "loc": [
[ [
11, 11,
@ -766,7 +766,7 @@ main.floors.MT16=
"true": [ "true": [
{ {
"type": "setBlock", "type": "setBlock",
"number": "372", "number": "339",
"loc": [ "loc": [
[ [
11, 11,
@ -836,7 +836,7 @@ main.floors.MT16=
"true": [ "true": [
{ {
"type": "setBlock", "type": "setBlock",
"number": "372", "number": "339",
"loc": [ "loc": [
[ [
11, 11,
@ -906,7 +906,7 @@ main.floors.MT16=
"true": [ "true": [
{ {
"type": "setBlock", "type": "setBlock",
"number": "372", "number": "339",
"loc": [ "loc": [
[ [
11, 11,
@ -985,7 +985,7 @@ main.floors.MT16=
"true": [ "true": [
{ {
"type": "setBlock", "type": "setBlock",
"number": "372", "number": "339",
"loc": [ "loc": [
[ [
11, 11,
@ -1450,7 +1450,7 @@ main.floors.MT16=
"opacity": 1, "opacity": 1,
"time": 0 "time": 0
}, },
"\t[杰克]这里似乎封印着类似于11层东南角的机遗迹一样的东西。", "\t[杰克]这里似乎封印着类似于11层东南角的机遗迹一样的东西。",
"\t[邵虎]..........好吧......我会注意的。", "\t[邵虎]..........好吧......我会注意的。",
{ {
"type": "hideImage", "type": "hideImage",
@ -1483,71 +1483,60 @@ main.floors.MT16=
] ]
} }
], ],
"11,7": { "11,7": [
"trigger": "action", {
"enable": true, "type": "if",
"noPass": null, "condition": "(flag:xianjie2==1)",
"displayDamage": true, "true": [
"opacity": 1, {
"filter": { "type": "setBlock",
"blur": 0, "number": "339",
"hue": 0, "loc": [
"grayscale": 0, [
"invert": false, 11,
"shadow": 0 7
}, ]
"data": [ ]
{ },
"type": "if", {
"condition": "(flag:xianjie2==1)", "type": "hide",
"true": [ "remove": true
{ }
"type": "hide", ],
"remove": true "false": [
} {
], "type": "if",
"false": [ "condition": "(flag:xianjie==15)",
{ "true": [
"type": "if", {
"condition": "(flag:xianjie==15)", "type": "setBlock",
"true": [ "number": "89",
{ "loc": [
"type": "openDoor", [
"loc": [ 12,
11, 1
7
] ]
}, ]
{ },
"type": "setBlock", {
"number": "89", "type": "setValue",
"loc": [ "name": "flag:xianjie",
[ "operator": "+=",
12, "value": "1",
1 "norefresh": true
] },
] {
}, "type": "setValue",
{ "name": "flag:xianjie2",
"type": "setValue", "operator": "+=",
"name": "flag:xianjie", "value": "1"
"operator": "+=", }
"value": "1", ],
"norefresh": true "false": []
}, }
{ ]
"type": "setValue", }
"name": "flag:xianjie2", ],
"operator": "+=",
"value": "1"
}
],
"false": []
}
]
}
]
},
"6,1": [ "6,1": [
{ {
"type": "function", "type": "function",
@ -1604,7 +1593,7 @@ main.floors.MT16=
"true": [ "true": [
{ {
"type": "setBlock", "type": "setBlock",
"number": "372", "number": "339",
"loc": [ "loc": [
[ [
11, 11,
@ -1617,133 +1606,7 @@ main.floors.MT16=
} }
] ]
} }
], ]
"8,8": {
"trigger": "action",
"enable": true,
"noPass": null,
"displayDamage": true,
"opacity": 1,
"filter": {
"blur": 0,
"hue": 0,
"grayscale": 0,
"invert": false,
"shadow": 0
},
"data": [
{
"type": "if",
"condition": "flag:112",
"true": [
{
"type": "vibrate",
"direction": "horizontal",
"time": 1000,
"speed": 10,
"power": 10,
"async": true
},
{
"type": "openDoor",
"loc": [
8,
8
]
},
{
"type": "openDoor",
"loc": [
5,
4
]
},
{
"type": "openDoor",
"loc": [
9,
4
]
},
{
"type": "openDoor",
"loc": [
5,
8
]
},
{
"type": "openDoor",
"loc": [
9,
8
]
}
],
"false": []
}
]
},
"5,4": {
"trigger": "action",
"enable": true,
"noPass": null,
"displayDamage": true,
"opacity": 1,
"filter": {
"blur": 0,
"hue": 0,
"grayscale": 0,
"invert": false,
"shadow": 0
},
"data": []
},
"5,8": {
"trigger": "action",
"enable": true,
"noPass": null,
"displayDamage": true,
"opacity": 1,
"filter": {
"blur": 0,
"hue": 0,
"grayscale": 0,
"invert": false,
"shadow": 0
},
"data": []
},
"9,4": {
"trigger": "action",
"enable": true,
"noPass": null,
"displayDamage": true,
"opacity": 1,
"filter": {
"blur": 0,
"hue": 0,
"grayscale": 0,
"invert": false,
"shadow": 0
},
"data": []
},
"9,8": {
"trigger": "action",
"enable": true,
"noPass": null,
"displayDamage": true,
"opacity": 1,
"filter": {
"blur": 0,
"hue": 0,
"grayscale": 0,
"invert": false,
"shadow": 0
},
"data": []
}
}, },
"changeFloor": { "changeFloor": {
"8,4": { "8,4": {
@ -1757,25 +1620,7 @@ main.floors.MT16=
"time": 200 "time": 200
} }
}, },
"afterBattle": { "afterBattle": {},
"6,4": [
{
"type": "setValue",
"name": "flag:112",
"value": "true"
},
{
"type": "setBlock",
"number": "372",
"loc": [
[
8,
8
]
]
}
]
},
"afterGetItem": {}, "afterGetItem": {},
"afterOpenDoor": {}, "afterOpenDoor": {},
"cannotMove": {}, "cannotMove": {},
@ -1785,11 +1630,11 @@ main.floors.MT16=
[ 0,348,475, 0, 28, 0,475, 0, 2,475,475,218, 0,352, 0], [ 0,348,475, 0, 28, 0,475, 0, 2,475,475,218, 0,352, 0],
[ 0,348,218, 0, 2, 0, 0, 21, 2,206, 0, 0, 32,352, 0], [ 0,348,218, 0, 2, 0, 0, 21, 2,206, 0, 0, 32,352, 0],
[ 0,348, 0,475, 2, 2, 2, 2, 2, 81, 2, 2, 27,352, 0], [ 0,348, 0,475, 2, 2, 2, 2, 2, 81, 2, 2, 27,352, 0],
[ 0,348, 0,206, 81,361,213, 0, 87,361, 2,475, 31,352, 0], [ 0,348, 0,206, 81,372,213, 0, 87,372, 2,475, 31,352, 0],
[ 0,348, 2, 2, 2, 32, 0, 0, 0,206, 2, 0, 0,352, 0], [ 0,348, 2, 2, 2, 32, 0, 0, 0,206, 2, 0, 0,352, 0],
[ 0,348,475, 21, 2, 2, 2, 32, 2, 2, 2, 21,475,352, 0], [ 0,348,475, 21, 2, 2, 2, 32, 2, 2, 2, 21,475,352, 0],
[ 0,348, 0, 0, 2,206, 0, 0, 0, 32, 2, 2, 2,352, 0], [ 0,348, 0, 0, 2,206, 0, 0, 0, 32, 2, 2, 2,352, 0],
[ 0,348, 31,475, 2,361, 88,123,361,361, 81,206, 0,352, 0], [ 0,348, 31,475, 2,372, 88,123,372,372, 81,206, 0,352, 0],
[ 0,348, 27, 2, 2, 81, 2, 2, 2, 2, 2,475, 0,352, 0], [ 0,348, 27, 2, 2, 81, 2, 2, 2, 2, 2,475, 0,352, 0],
[ 0,348, 32,475, 0,206, 2, 21, 0, 0, 2,475,218,352, 0], [ 0,348, 32,475, 0,206, 2, 21, 0, 0, 2,475,218,352, 0],
[ 0,348, 0,218, 0,475, 2,475,475, 0, 28, 0, 0,352, 0], [ 0,348, 0,218, 0,475, 2,475,475, 0, 28, 0, 0,352, 0],

View File

@ -11,20 +11,10 @@ main.floors.XIANJIE=
"firstArrive": [], "firstArrive": [],
"events": { "events": {
"7,1": [ "7,1": [
{
"type": "setValue",
"name": "flag:isRMshop",
"value": "true"
},
{ {
"type": "openShop", "type": "openShop",
"id": "expShop1", "id": "expShop1",
"open": true "open": true
},
{
"type": "setValue",
"name": "flag:isRMshop",
"value": "false"
} }
] ]
}, },

View File

@ -326,12 +326,12 @@ var functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a =
core.status.hero.exp += exp; core.status.hero.exp += exp;
core.status.hero.statistics.exp += exp; core.status.hero.statistics.exp += exp;
var hint = "打败 " + core.getEnemyValue(enemy, "name", x, y); var hint = "打败 " + core.getEnemyValue(enemy, "name", x, y);
if (core.flags.statusBarItems.indexOf('enableMoney') >= 0) if (core.flags.statusBarItems.indexOf('enableMoney') >= 0)
hint += ',' + core.getStatusLabel('money') + '+' + money; // hint += ",金币+" + money; hint += ',' + core.getStatusLabel('money') + '+' + money; // hint += ",金币+" + money;
if (core.flags.statusBarItems.indexOf('enableExp') >= 0) if (core.flags.statusBarItems.indexOf('enableExp') >= 0)
hint += ',' + core.getStatusLabel('exp') + '+' + exp; // hint += ",经验+" + exp; hint += ',' + core.getStatusLabel('exp') + '+' + exp; // hint += ",经验+" + exp;
if (!core.getFlag("isNoTip")) core.drawTip(hint, enemy.id); if (!core.getFlag("isNoTip")) core.drawTip(hint, enemy.id);
// 中毒 // 中毒
if (core.enemys.hasSpecial(special, 12)) { if (core.enemys.hasSpecial(special, 12)) {
@ -388,8 +388,6 @@ var functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a =
core.push(todo, [{ "type": "insert", "name": "加点事件", "args": [point] }]); core.push(todo, [{ "type": "insert", "name": "加点事件", "args": [point] }]);
} }
//等待动画执行完毕
core.push(todo, [{ "type": "waitAsync" }]);
// 战后事件 // 战后事件
if (core.status.floorId != null) { if (core.status.floorId != null) {
core.push(todo, core.floors[core.status.floorId].afterBattle[x + "," + y]); core.push(todo, core.floors[core.status.floorId].afterBattle[x + "," + y]);

View File

@ -246,14 +246,14 @@ var maps_90f36752_8815_4be8_b32b_d7fad1d0542e =
"358": {"cls":"animates","id":"A358"}, "358": {"cls":"animates","id":"A358"},
"359": {"cls":"animates","id":"A359"}, "359": {"cls":"animates","id":"A359"},
"360": {"cls":"animates","id":"A360"}, "360": {"cls":"animates","id":"A360"},
"361": {"cls":"animates","id":"A361","animate":1,"trigger":"openDoor","doorInfo":{"time":160,"openSound":"door.mp3","closeSound":"door.mp3","keys":{}}}, "361": {"cls":"animates","id":"A361"},
"362": {"cls":"animates","id":"A362"}, "362": {"cls":"animates","id":"A362"},
"363": {"cls":"animates","id":"A363"}, "363": {"cls":"animates","id":"A363"},
"364": {"cls":"animates","id":"A364"}, "364": {"cls":"animates","id":"A364"},
"365": {"cls":"animates","id":"A365"}, "365": {"cls":"animates","id":"A365"},
"366": {"cls":"animates","id":"A366"}, "366": {"cls":"animates","id":"A366"},
"367": {"cls":"animates","id":"A367","event":null,"canPass":true}, "367": {"cls":"animates","id":"A367","event":null,"canPass":true},
"368": {"cls":"animates","id":"A368","trigger":"openDoor","animate":1,"doorInfo":{"time":160,"openSound":"door.mp3","closeSound":"door.mp3","keys":{}}}, "368": {"cls":"animates","id":"A368"},
"369": {"cls":"animates","id":"A369"}, "369": {"cls":"animates","id":"A369"},
"370": {"cls":"animates","id":"A370"}, "370": {"cls":"animates","id":"A370"},
"371": {"cls":"npcs","id":"N371"}, "371": {"cls":"npcs","id":"N371"},

View File

@ -42,7 +42,7 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 =
if (clientWidth - 3 * BORDER >= core._PX_ + BAR_WIDTH || (clientWidth > clientHeight && horizontalMaxRatio < 1)) { if (clientWidth - 3 * BORDER >= core._PX_ + BAR_WIDTH || (clientWidth > clientHeight && horizontalMaxRatio < 1)) {
core.domStyle.isVertical = false; core.domStyle.isVertical = false;
core.clearMap('Vertical'); core.clearMap('Vertical');
} else if (core.status.played) { } else {
// 竖屏 // 竖屏
core.domStyle.isVertical = true; core.domStyle.isVertical = true;
core.createCanvas('Vertical', 0, 0, 480, 480, 200); core.createCanvas('Vertical', 0, 0, 480, 480, 200);
@ -1856,7 +1856,7 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 =
if (!name) return; if (!name) return;
var canvas = document.createElement('canvas'); var canvas = document.createElement('canvas');
canvas.id = name; canvas.id = name;
canvas.className = 'gameCanvas anti-aliasing'; canvas.className = 'gameCanvas';
// 编辑器模式下设置zIndex会导致加入的图层覆盖优先级过高 // 编辑器模式下设置zIndex会导致加入的图层覆盖优先级过高
if (main.mode != "editor") canvas.style.zIndex = zIndex || 0; if (main.mode != "editor") canvas.style.zIndex = zIndex || 0;
// 将图层插入进游戏内容 // 将图层插入进游戏内容
@ -3902,21 +3902,19 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 =
// 准备渐变 // 准备渐变
this.maskPrepare = function () { this.maskPrepare = function () {
// 执行后画面将凝固 // 执行后画面将凝固
var mask = core.ui.createCanvas2("mask", 0, 0, core.__PIXELS__ + 161, core.__PIXELS__, 200); core.ui.createCanvas2("mask", 0, 0, core.__PIXELS__, core.__PIXELS__, 155);
core.drawThumbnail(core.status.floorId, null, { ctx: mask, x: 161, y: 0, size: 1, damage: false, all: true }); for (var m in core.canvas) {
core.drawImage('mask', 'caidan.png', 0, 0); core.dymCanvas.mask.drawImage(core.canvas[m].canvas, 0, 0);
// for (var m in core.canvas) { };
// core.dymCanvas.mask.drawImage(core.canvas[m].canvas, 0, 0);
// };
} }
// 执行渐变 // 执行渐变
this.maskFliter = function (time, sample) { // sample为渐变图名称渐变图需要在全塔属性注册 this.maskFliter = function (time, sample) { // sample为渐变图名称渐变图需要在全塔属性注册
var tempCanvas = core.ui.createCanvas2("mask2", 0, 0, core.__PIXELS__ + 161, core.__PIXELS__, 200); var tempCanvas = core.bigmap.tempCanvas;
var tempWidth = tempCanvas.canvas.width, var tempWidth = core.__PIXELS__,
tempHeight = tempCanvas.canvas.height; tempHeight = core.__PIXELS__;
//tempCanvas.canvas.width = tempWidth; tempCanvas.canvas.width = tempWidth;
//tempCanvas.canvas.height = tempHeight; tempCanvas.canvas.height = tempHeight;
tempCanvas.clearRect(0, 0, tempWidth, tempHeight); tempCanvas.clearRect(0, 0, tempWidth, tempHeight);
tempCanvas.drawImage(core.material.images.images[sample], 0, 0, tempWidth, tempHeight); tempCanvas.drawImage(core.material.images.images[sample], 0, 0, tempWidth, tempHeight);
// 读取渐变图开始处理 // 读取渐变图开始处理

651
server.js
View File

@ -1,651 +0,0 @@
const http = require('http');
const fs = require('fs/promises');
const fss = require('fs');
const path = require('path');
const name = (() => {
const data = fss.readFileSync('./project/data.js', 'utf-8');
const json = JSON.parse(
data
.split(/(\n|\r\n)/)
.slice(1)
.join('\n')
);
return json.firstData.name;
})();
/** 核心服务器 */
const server = http.createServer();
/** 是否需要重新加载浏览器 */
let needReload = true;
/** 热重载信息 */
let hotReloadData = '';
/** 是否已经启动了热重载模块 */
let watched = false;
/** 是否已经启动了录像调试模块 */
let replayed = false;
/** 监听端口 */
let port = 3000;
const next = () => {
server.listen(port, '127.0.0.1');
server.on('error', () => {
console.log(`${port}端口已被占用`);
port++;
next();
});
};
next();
let repStart;
const listenedFloors = [];
// ----- GET file
/**
* 请求文件
* @param {http.IncomingMessage} req
* @param {http.ServerResponse<http.IncomingMessage> & {req: http.IncomingMessage;}} res
* @param {string} path
*/
async function getFile(req, res, path) {
try {
const data = await fs.readFile(path);
if (path.endsWith('.js'))
res.writeHead(200, { 'Content-type': 'text/javascript' });
if (path.endsWith('.css'))
res.writeHead(200, { 'Content-type': 'text/css' });
if (path.endsWith('.html'))
res.writeHead(200, { 'Content-type': 'text/html' });
return res.end(data), true;
} catch {
return false;
}
}
/**
* 高层塔优化及动画加载
* @param {http.IncomingMessage} req
* @param {http.ServerResponse<http.IncomingMessage> & {req: http.IncomingMessage;}} res
* @param {string[]} ids
* @param {string} suffix 后缀名
* @param {string} dir 文件夹路径
* @param {string} join 分隔符
*/
async function getAll(req, res, ids, suffix, dir, join) {
let data = {};
const tasks = ids.map(v => {
return new Promise(res => {
const d = path.resolve(__dirname, `${dir}${v}${suffix}`);
try {
fs.readFile(d).then(vv => {
data[v] = vv;
res(`${v} pack success.`);
});
} catch {
throw new ReferenceError(`The file ${d} does not exists.`);
}
});
});
await Promise.all(tasks);
const result = ids.map(v => data[v]);
return res.end(result.join(join)), true;
}
// ----- 样板的fs功能
/**
* 获取POST的数据
* @param {http.IncomingMessage} req
*/
async function getPostData(req) {
let data = '';
await new Promise(res => {
req.on('data', chunk => {
data += chunk.toString();
});
req.on('end', res);
});
return data;
}
/**
* @param {http.IncomingMessage} req
* @param {http.ServerResponse<http.IncomingMessage> & {req: http.IncomingMessage;}} res
*/
async function readDir(req, res) {
const data = await getPostData(req);
const dir = path.resolve(__dirname, data.toString().slice(5));
try {
const info = await fs.readdir(dir);
res.end(JSON.stringify(info));
} catch (e) {
console.error(e);
res.end(`error: Read dir ${dir} fail. Does the dir exists?`);
}
}
/**
* @param {http.IncomingMessage} req
* @param {http.ServerResponse<http.IncomingMessage> & {req: http.IncomingMessage;}} res
*/
async function mkdir(req, res) {
const data = await getPostData(req);
const dir = path.resolve(__dirname, data.toString().slice(5));
try {
await fs.mkdir(dir);
} catch (e) {}
res.end();
}
/**
* @param {http.IncomingMessage} req
* @param {http.ServerResponse<http.IncomingMessage> & {req: http.IncomingMessage;}} res
*/
async function readFile(req, res) {
const data = (await getPostData(req)).toString();
const dir = path.resolve(__dirname, data.split('&name=')[1]);
try {
const type = /^type=(utf8|base64)/.exec(data)[0];
const info = await fs.readFile(dir, { encoding: type.slice(5) });
res.end(info);
} catch (e) {
res.end();
}
}
/**
* @param {http.IncomingMessage} req
* @param {http.ServerResponse<http.IncomingMessage> & {req: http.IncomingMessage;}} res
*/
async function writeFile(req, res) {
const data = (await getPostData(req)).toString();
const name = data.split('&name=')[1].split('&value=')[0];
const dir = path.resolve(__dirname, name);
try {
const type = /^type=(utf8|base64)/.exec(data)[0].slice(5);
const value = /&value=[^]+/.exec(data)[0].slice(7);
await fs.writeFile(dir, value, { encoding: type });
testWatchFloor(name);
} catch (e) {
console.error(e);
res.end(
`error: Write file ${dir} fail. Does the parent folder exists?`
);
}
res.end();
}
/**
* @param {http.IncomingMessage} req
* @param {http.ServerResponse<http.IncomingMessage> & {req: http.IncomingMessage;}} res
*/
async function rm(req, res) {
const data = (await getPostData(req)).toString();
const dir = path.resolve(__dirname, data.slice(5));
try {
await fs.rm(dir);
} catch (e) {
console.error(e);
res.end(`error: Remove file ${dir} fail. Does this file exists?`);
}
res.end();
}
/**
* @param {http.IncomingMessage} req
* @param {http.ServerResponse<http.IncomingMessage> & {req: http.IncomingMessage;}} res
*/
async function moveFile(req, res) {
const data = (await getPostData(req)).toString();
const info = data.split('&dest=');
const src = path.resolve(__dirname, info[0].slice(4));
const dest = info[1];
try {
const data = await fs.readFile(src);
await fs.writeFile(path.resolve(__dirname, dest), data);
await fs.rm(src);
} catch (e) {
console.error(e);
res.end(`error: Move file ${dir} fail.`);
}
res.end();
}
/**
* @param {http.IncomingMessage} req
* @param {http.ServerResponse<http.IncomingMessage> & {req: http.IncomingMessage;}} res
*/
async function writeMultiFiles(req, res) {
const data = (await getPostData(req)).toString();
const names = /name=[^]+&value=/.exec(data)[0].slice(5, -7).split(';');
const value = /&value=[^]+/.exec(data)[0].slice(7).split(';');
const tasks = names.map((v, i) => {
try {
return new Promise(res => {
fs.writeFile(
path.resolve(__dirname, v),
value[i],
'base64' // 多文件是base64写入的
).then(v => {
testWatchFloor(v);
res(`write ${v} success.`);
});
});
} catch {
console.error(e);
res.end(`error: Write multi files fail.`);
}
});
await Promise.all(tasks);
res.end();
}
// ----- extract path & utils
/**
* 解析路径
* @param {...string} dirs
* @returns {Promise<string[]>}
*/
async function extract(...dirs) {
const res = [];
const tasks = dirs.map(v => {
return new Promise(resolve => {
if (v.endsWith('/')) {
// 匹配路径
const dir = path.resolve(__dirname, v.slice(0, -1));
fs.readdir(dir).then(files => {
const all = files
.filter(v => v !== 'thirdparty') // 排除第三方库
.map(vv => v + vv);
res.push(...all);
resolve('success');
});
} else if (/\/\*.\w+$/.test(v)) {
// 匹配文件夹中的后缀名
const suffix = /\.\w+$/.exec(v)[0];
const d = v.split(`/*${suffix}`)[0];
const dir = path.resolve(__dirname, d);
fs.readdir(dir).then(files => {
const all = files
.filter(v => v.endsWith(suffix))
.map(v => `${d === '' ? '' : d + '/'}${v}`);
res.push(...all);
resolve('success');
});
} else {
res.push(v);
resolve('success');
}
});
});
await Promise.all(tasks);
return res;
}
// ----- hot reload
/**
* 监听文件变化
*/
async function watch() {
// 需要重新加载的文件
const refresh = await extract('main.js', 'index.html', 'libs/');
const option = {
interval: 1000
};
refresh.forEach(v => {
const dir = path.resolve(__dirname, v);
fss.watchFile(dir, option, () => {
needReload = true;
console.log(`change: ${v}`);
});
});
// css 热重载
const css = await extract('/*.css');
css.forEach(v => {
const dir = path.resolve(__dirname, v);
fss.watchFile(dir, option, () => {
hotReloadData += `@@css:${v}`;
console.log(`css hot reload: ${v}`);
});
});
// 楼层 热重载
// 注意这里要逐个监听,并通过创建文件来监听文件改变
const floors = await extract('project/floors/*.js');
floors.forEach(v => {
watchOneFloor(v.slice(15));
});
// 脚本编辑 及 插件 热重载
const scripts = await extract('project/functions.js', 'project/plugins.js');
scripts.forEach(v => {
const dir = path.resolve(__dirname, v);
const type = v.split('/').at(-1).slice(0, -3);
fss.watchFile(dir, option, () => {
hotReloadData += `@@script:${type}`;
console.log(`script hot reload: ${type}.js`);
});
});
// 数据热重载
const datas = (await extract('project/*.js')).filter(
v => !v.endsWith('functions.js') && !v.endsWith('plugins.js')
);
datas.forEach(v => {
const dir = path.resolve(__dirname, v);
const type = v.split('/').at(-1).slice(0, -3);
fss.watchFile(dir, option, () => {
hotReloadData += `@@data:${type}`;
console.log(`data hot reload: ${type}`);
});
});
}
/**
* 检测是否是楼层文件并进行监听
* @param {string} url 要测试的路径
*/
function testWatchFloor(url) {
if (/project(\/|\\)floors(\/|\\).*\.js/.test(url)) {
const f = url.slice(15);
if (!listenedFloors.includes(f.slice(0, -3))) {
watchOneFloor(f);
}
}
}
/**
* 监听一个楼层文件
* @param {string} file 要监听的文件
*/
function watchOneFloor(file) {
if (!/.*\.js/.test(file)) return;
const f = file.slice(0, -3);
listenedFloors.push(file.slice(0, -3));
fss.watchFile(`project/floors/${file}`, { interval: 1000 }, () => {
const floorId = f;
if (hotReloadData.includes(`@@floor:${floorId}`)) return;
hotReloadData += `@@floor:${floorId}`;
console.log(`floor hot reload: ${floorId}`);
});
}
/**
* 修改部分文件后重新加载及热重载
* @param {http.IncomingMessage} req
* @param {http.ServerResponse<http.IncomingMessage> & {req: http.IncomingMessage;}} res
*/
function reload(req, res, hot = false) {
req.on('data', chunk => {
if (chunk.toString() === 'test' && !watched) {
watch();
watched = true;
console.log(`服务器热重载模块已开始服务`);
}
});
req.on('end', () => {
if (!hot) {
res.end(`${needReload}`);
needReload = false;
} else {
res.end(hotReloadData);
hotReloadData = '';
}
});
}
// ----- replay debugger
/**
* 录像调试
* @param {http.IncomingMessage} req
* @param {http.ServerResponse<http.IncomingMessage> & {req: http.IncomingMessage;}} res
*/
function replay(req, res) {
req.on('data', async chunk => {
if (chunk.toString() === 'test' && !replayed) {
replayed = true;
try {
await fs.mkdir(path.resolve(__dirname, '_replay'));
await fs.mkdir(path.resolve(__dirname, '_replay/status'));
await fs.mkdir(path.resolve(__dirname, '_replay/save'));
} catch {}
try {
await fs.readFile(
path.resolve(__dirname, '_replay/.info'),
'utf-8'
);
} catch {
await fs.writeFile(
path.resolve(__dirname, '_replay/.info'),
`{
"cnt": 0
}`,
'utf-8'
);
}
const data = fss.readFileSync(
path.resolve(__dirname, '_replay/.info'),
'utf-8'
);
repStart = Number(JSON.parse(data).cnt);
console.log(`服务器录像调试模块已开始服务`);
}
});
req.on('end', () => {
res.end();
});
}
/**
* 获取未占用的状态栏位
* @param {http.IncomingMessage} req
* @param {http.ServerResponse<http.IncomingMessage> & {req: http.IncomingMessage;}} res
*/
async function replayCnt() {
const data = `{
"cnt": ${++repStart}
}`;
fss.writeFileSync(path.resolve(__dirname, '_replay/.info'), data, 'utf-8');
return repStart;
}
/**
* 写入
* @param {http.IncomingMessage} req
* @param {http.ServerResponse<http.IncomingMessage> & {req: http.IncomingMessage;}} res
*/
async function replayWrite(req, res) {
const data = await getPostData(req);
const n = await replayCnt();
if (isNaN(n)) res.end('@error');
await Promise.all([
fs.writeFile(
path.resolve(__dirname, '_replay/.info'),
`{
"cnt": ${n + 1}
}`,
'utf-8'
),
fs.writeFile(
path.resolve(__dirname, `_replay/status/${n}.rep`),
data,
'utf-8'
)
]);
res.end(n.toString());
}
/**
* 比对录像与本地数据
* @param {http.IncomingMessage} req
* @param {http.ServerResponse<http.IncomingMessage> & {req: http.IncomingMessage;}} res
*/
async function replayCheck(req, res) {
const ans = await getPostData(req);
const [n, data] = ans.split('@-|-@');
const local = (
await fs.readFile(
path.resolve(__dirname, `_replay/status/${n}.rep`),
'utf-8'
)
)
.split('@---@')
.map(v => JSON.parse(v));
const rep = data.split('@---@').map(v => JSON.parse(v));
if (local.length !== rep.length) return res.end('false');
const check = (a, b) => {
if (a === b) return true;
if (typeof a !== typeof b) return false;
if (typeof a === 'object' && a !== null) {
for (const j in a) {
if (j === 'statistics' || j === 'timeout') continue; // 忽略统计信息
const aa = a[j];
const bb = b[j];
if (!check(aa, bb)) {
return false;
}
}
return true;
}
if (
typeof a === 'boolean' ||
typeof a === 'number' ||
typeof a === 'string' ||
typeof a === 'symbol' ||
typeof a === 'undefined' ||
typeof a === 'bigint' ||
a === null
) {
return a === b;
}
return true;
};
for (let i = 0; i < local.length; i++) {
const a = local[i];
const b = rep[i];
if (!check(a, b)) return res.end('false');
}
res.end('true');
}
/**
* 获取本地属性
* @param {http.IncomingMessage} req
* @param {http.ServerResponse<http.IncomingMessage> & {req: http.IncomingMessage;}} res
*/
async function replayGet(req, res, dir) {
const ans = Number(await getPostData(req));
const data = await fs.readFile(
path.resolve(__dirname, `_replay/${dir}/${ans}.rep`)
);
res.end(data);
}
/**
* 录像回放存档
* @param {http.IncomingMessage} req
* @param {http.ServerResponse<http.IncomingMessage> & {req: http.IncomingMessage;}} res
*/
async function replaySave(req, res) {
const data = await getPostData(req);
const [cnt, save] = data.split('@-|-@');
if (isNaN(Number(cnt))) {
console.log('Invalid input of save cnt');
res.end('@error: 不合法的录像存档信息');
}
await fs.writeFile(
path.resolve(__dirname, `_replay/save/${cnt}.rep`),
save,
'utf-8'
);
res.end('success');
}
// ----- server
server.on('listening', () => {
console.log(`服务已启动编辑器地址http://127.0.0.1:${port}/editor.html`);
console.log(`游戏地址http://127.0.0.1:${port}`);
});
// 处理请求
server.on('request', async (req, res) => {
/** @type {string} */
const p = req.url.replace(`/games/${name}`, '').replace('/all/', '/');
if (req.method === 'GET') {
const dir = path
.resolve(__dirname, p === '/' ? 'index.html' : p.slice(1))
.split('?v=')[0];
if (await getFile(req, res, dir)) return;
if (p.startsWith('/__all_floors__.js')) {
const all = p.split('&id=')[1].split(',');
res.writeHead(200, { 'Content-type': 'text/javascript' });
return await getAll(req, res, all, '.js', 'project/floors/', '\n');
}
if (p.startsWith('/__all_animates__')) {
const all = p.split('&id=')[1].split(',');
return await getAll(
req,
res,
all,
'.animate',
'project/animates/',
'@@@~~~###~~~@@@'
);
}
}
if (req.method === 'POST') {
if (p === '/listFile') return await readDir(req, res);
if (p === '/makeDir') return await mkdir(req, res);
if (p === '/readFile') return await readFile(req, res);
if (p === '/writeFile') return await writeFile(req, res);
if (p === '/deleteFile') return await rm(req, res);
if (p === '/moveFile') return await moveFile(req, res);
if (p === '/writeMultiFiles') return await writeMultiFiles(req, res);
if (p === '/reload') return reload(req, res);
if (p === '/hotReload') return reload(req, res, true);
if (p === '/replay') return replay(req, res);
if (p === '/replayWrite') return await replayWrite(req, res);
if (p === '/replayCheck') return await replayCheck(req, res);
if (p === '/replayGet') return await replayGet(req, res, 'status');
if (p === '/replaySave') return await replaySave(req, res);
if (p === '/replayGetSave') return await replayGet(req, res, 'save');
}
res.statusCode = 404;
res.end();
});

View File

@ -527,9 +527,4 @@ p#name {
@font-face { @font-face {
font-family: Fira Code; font-family: Fira Code;
src: url(../src/fonts/FiraCode-Regular.ttf); src: url(../src/fonts/FiraCode-Regular.ttf);
}
/* 注释下面这三行以开启抗锯齿 */
.anti-aliasing {
image-rendering: pixelated;
} }

9
tsconfig.json Normal file
View File

@ -0,0 +1,9 @@
{
"compilerOptions": {
"allowJs": true,
"noEmit": true,
},
"include": [
"main.js", "project/**/*.js", "libs/**/*.js", "runtime.d.ts"
]
}

Binary file not shown.