Merge branch 'noAnimate' into hasAnimate
This commit is contained in:
commit
b547c096a5
@ -1,5 +0,0 @@
|
||||
[{000214A0-0000-0000-C000-000000000046}]
|
||||
Prop3=19,2
|
||||
[InternetShortcut]
|
||||
IDList=
|
||||
URL=https://www.bilibili.com/video/BV1SB4y1p7bg?spm_id_from=333.999.0.0
|
2
_server/CodeMirror/beautify.min.js
vendored
2
_server/CodeMirror/beautify.min.js
vendored
File diff suppressed because one or more lines are too long
2
_server/CodeMirror/jshint.min.js
vendored
2
_server/CodeMirror/jshint.min.js
vendored
File diff suppressed because one or more lines are too long
BIN
_server/css/FiraCode.ttf
Normal file
BIN
_server/css/FiraCode.ttf
Normal file
Binary file not shown.
@ -699,3 +699,12 @@ div.checkboxSet {
|
||||
.etableInputDiv textarea:hover {
|
||||
margin: -5px;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: code;
|
||||
src: url(./FiraCode.ttf);
|
||||
}
|
||||
|
||||
.main .CodeMirror {
|
||||
font-family: code, 微软雅黑, 黑体, 新宋体, Verdana;
|
||||
}
|
||||
|
@ -710,3 +710,11 @@ div.checkboxSet {
|
||||
margin: -5px;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: Fira;
|
||||
src: url(./FiraCode.ttf);
|
||||
}
|
||||
|
||||
.main .CodeMirror {
|
||||
font-family: Fira, Menlo, Consolas, 'Courier New', Courier, monospace;
|
||||
}
|
||||
|
@ -7,11 +7,11 @@ editor_multi = function () {
|
||||
var extraKeys = {
|
||||
"Ctrl-/": function (cm) { cm.toggleComment(); },
|
||||
"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,
|
||||
"Ctrl-F": CodeMirror.commands.findPersistent,
|
||||
"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-P": function () { editor_multi.openUrl('https://h5mota.com/plugins/'); }
|
||||
};
|
||||
@ -55,7 +55,7 @@ editor_multi = function () {
|
||||
}).join('');
|
||||
|
||||
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] = {
|
||||
"!type": "enemy",
|
||||
"!doc": core.material.enemys[name].name || "怪物"
|
||||
@ -236,7 +236,15 @@ editor_multi = function () {
|
||||
document.getElementById('left7').style = 'z-index:-1;opacity: 0;';
|
||||
}
|
||||
editor_multi.setLint = function () {
|
||||
codeEditor.setOption("lint", editor_multi.lintAutocomplete);
|
||||
if (editor_multi.lintAutocomplete) {
|
||||
codeEditor.setOption("lint", {
|
||||
options: {
|
||||
esversion: 2021
|
||||
}
|
||||
});
|
||||
} else {
|
||||
codeEditor.setOption("lint", false);
|
||||
}
|
||||
codeEditor.setOption("autocomplete", editor_multi.lintAutocomplete);
|
||||
document.getElementById("lintCheckbox").checked = editor_multi.lintAutocomplete;
|
||||
}
|
||||
@ -253,7 +261,7 @@ editor_multi = function () {
|
||||
var _format = function () {
|
||||
if (!editor_multi.lintAutocomplete) return;
|
||||
var offset = (codeEditor.getScrollInfo() || {}).top || 0;
|
||||
_setValue(js_beautify(codeEditor.getValue(), {
|
||||
_setValue(beautifier.js(codeEditor.getValue(), {
|
||||
brace_style: "collapse-preserve-inline",
|
||||
indent_with_tabs: true,
|
||||
jslint_happy: true
|
||||
@ -486,6 +494,22 @@ editor_multi = function () {
|
||||
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;
|
||||
}
|
||||
//editor_multi=editor_multi();
|
@ -555,14 +555,20 @@ var data_comment_c456ea59_6018_45ef_8bcc_211a24c627dc = {
|
||||
"autoScale": {
|
||||
"_leaf": true,
|
||||
"_type": "checkbox",
|
||||
"_docs": "自动缩放最大化",
|
||||
"_data": "是否自动缩放最大化,关闭后不再最大化"
|
||||
"_docs": "自动缩放",
|
||||
"_data": "是否自动缩放至合适值"
|
||||
},
|
||||
"extendToolbar": {
|
||||
"_leaf": true,
|
||||
"_type": "checkbox",
|
||||
"_docs": "横屏隐藏状态栏",
|
||||
"_data": "在横屏状态下是否隐藏左侧状态栏,从而获得仿RM的沉浸式体验"
|
||||
"_docs": "画面下方道具栏",
|
||||
"_data": "开启后道具栏会被挪动至游戏画面的下方"
|
||||
},
|
||||
"hideLeftStatusBar": {
|
||||
"_leaf": true,
|
||||
"_type": "checkbox",
|
||||
"_docs": "隐藏左侧状态栏",
|
||||
"_data": "是否隐藏左侧状态栏,开启后强制开启画面下方道具栏"
|
||||
},
|
||||
"flyNearStair": {
|
||||
"_leaf": true,
|
||||
|
@ -242,15 +242,21 @@
|
||||
<button onclick="confirmColor()">确定</button>
|
||||
</div>
|
||||
<div id="left7" style="z-index:-1;opacity: 0;"><!-- 多行文本编辑器 -->
|
||||
<button onclick="editor_multi.confirm()">确认</button>
|
||||
<button onclick="editor_multi.cancel()">取消</button>
|
||||
<button onclick="editor_multi.confirm(true)">应用</button>
|
||||
<button onclick="editor_multi.format()">格式化</button>
|
||||
<button id="editor_multi_preview" style="display: none;">预览</button>
|
||||
<input type="checkbox" onclick="editor_multi.toggerLint()" id="lintCheckbox"
|
||||
style="vertical-align: middle;margin-left:6px"/>
|
||||
<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>
|
||||
<div>
|
||||
<button onclick="editor_multi.confirm()">确认</button>
|
||||
<button onclick="editor_multi.cancel()">取消</button>
|
||||
<button onclick="editor_multi.confirm(true)">应用</button>
|
||||
<button onclick="editor_multi.format()">格式化</button>
|
||||
<button id="editor_multi_preview" style="display: none;">预览</button>
|
||||
<input type="checkbox" onclick="editor_multi.toggerLint()" id="lintCheckbox"
|
||||
style="vertical-align: middle;margin-left:6px"/>
|
||||
<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>
|
||||
<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>
|
||||
</div>
|
||||
<div id="left8" class='leftTab' style="z-index:-1;opacity: 0;"><!-- functions -->
|
||||
|
24
editor.html
24
editor.html
@ -238,15 +238,21 @@
|
||||
<button onclick="confirmColor()">确定</button>
|
||||
</div>
|
||||
<div id="left7" style="z-index:-1;opacity: 0;"><!-- 多行文本编辑器 -->
|
||||
<button onclick="editor_multi.confirm()">确认</button>
|
||||
<button onclick="editor_multi.cancel()">取消</button>
|
||||
<button onclick="editor_multi.confirm(true)">应用</button>
|
||||
<button onclick="editor_multi.format()">格式化</button>
|
||||
<button id="editor_multi_preview" style="display: none;">预览</button>
|
||||
<input type="checkbox" onclick="editor_multi.toggerLint()" id="lintCheckbox"
|
||||
style="vertical-align: middle;margin-left:6px"/>
|
||||
<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>
|
||||
<div>
|
||||
<button onclick="editor_multi.confirm()">确认</button>
|
||||
<button onclick="editor_multi.cancel()">取消</button>
|
||||
<button onclick="editor_multi.confirm(true)">应用</button>
|
||||
<button onclick="editor_multi.format()">格式化</button>
|
||||
<button id="editor_multi_preview" style="display: none;">预览</button>
|
||||
<input type="checkbox" onclick="editor_multi.toggerLint()" id="lintCheckbox"
|
||||
style="vertical-align: middle;margin-left:6px"/>
|
||||
<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>
|
||||
<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>
|
||||
</div>
|
||||
<div id="left8" class='leftTab' style="z-index:-1;opacity: 0;"><!-- functions -->
|
||||
|
251
index.html
251
index.html
@ -1,12 +1,14 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<meta http-equiv='content-type' content='text/html' charset='utf-8'>
|
||||
<meta http-equiv='X-UA-Compatible' content='IE=Edge, chrome=1'>
|
||||
<meta name='author' content='ckcz123'>
|
||||
<meta name='viewport' content='width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=yes'>
|
||||
<meta name='viewport'
|
||||
content='width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=yes'>
|
||||
<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="full-screen" content="yes">
|
||||
<meta name="browsermode" content="application">
|
||||
@ -20,130 +22,130 @@
|
||||
<div id='startImageDiv'></div>
|
||||
<img id='startImageLogo' />
|
||||
</div>
|
||||
<script>
|
||||
(function () {
|
||||
var startImageBackgroundDiv = document.getElementById('startImageBackgroundDiv');
|
||||
var startImageLogo = document.getElementById('startImageLogo');
|
||||
var startImageDiv = document.getElementById('startImageDiv');
|
||||
startImageLogo.onload = function () {
|
||||
startImageBackgroundDiv.style.display = 'block';
|
||||
var onAnimationEnd = function () {
|
||||
startImageBackgroundDiv.style.display = 'none';
|
||||
startImageLogo.classList.remove("startImageAnimation");
|
||||
startImageDiv.classList.remove("startImageDivAnimation");
|
||||
<script>
|
||||
(function () {
|
||||
var startImageBackgroundDiv = document.getElementById('startImageBackgroundDiv');
|
||||
var startImageLogo = document.getElementById('startImageLogo');
|
||||
var startImageDiv = document.getElementById('startImageDiv');
|
||||
startImageLogo.onload = function () {
|
||||
startImageBackgroundDiv.style.display = 'block';
|
||||
var onAnimationEnd = function () {
|
||||
startImageBackgroundDiv.style.display = 'none';
|
||||
startImageLogo.classList.remove("startImageAnimation");
|
||||
startImageDiv.classList.remove("startImageDivAnimation");
|
||||
}
|
||||
startImageDiv.addEventListener("webkitAnimationEnd", onAnimationEnd);
|
||||
startImageDiv.addEventListener("animationend", onAnimationEnd);
|
||||
startImageLogo.classList.add("startImageAnimation");
|
||||
startImageDiv.classList.add("startImageDivAnimation");
|
||||
// 注释下面这句话以禁止单击立刻跳过开场动画
|
||||
startImageBackgroundDiv.onclick = onAnimationEnd;
|
||||
}
|
||||
startImageDiv.addEventListener("webkitAnimationEnd", onAnimationEnd);
|
||||
startImageDiv.addEventListener("animationend", onAnimationEnd);
|
||||
startImageLogo.classList.add("startImageAnimation");
|
||||
startImageDiv.classList.add("startImageDivAnimation");
|
||||
// 注释下面这句话以禁止单击立刻跳过开场动画
|
||||
startImageBackgroundDiv.onclick = onAnimationEnd;
|
||||
}
|
||||
startImageLogo.onerror = function () {}
|
||||
startImageLogo.src = "logo.png";
|
||||
})();
|
||||
</script>
|
||||
<!-- injection -->
|
||||
<div id='gameGroup'>
|
||||
<canvas id="whole" style="position: absolute; left: 0; top: 0; z-index: 68;"></canvas>
|
||||
<p id='mainTips'>请稍候...</p>
|
||||
<img id='musicBtn'>
|
||||
<div id='startPanel'>
|
||||
<div id='startTop'>
|
||||
<div id='startTopProgressBar'>
|
||||
<div id='startTopProgress'></div>
|
||||
startImageLogo.onerror = function () { }
|
||||
startImageLogo.src = "logo.png";
|
||||
})();
|
||||
</script>
|
||||
<!-- injection -->
|
||||
<div id='gameGroup'>
|
||||
<canvas id="whole" style="position: absolute; left: 0; top: 0; z-index: 68;"></canvas>
|
||||
<p id='mainTips'>请稍候...</p>
|
||||
<img id='musicBtn'>
|
||||
<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>
|
||||
<p id='startTopLoadTips'>资源即将开始加载</p>
|
||||
<p id='startTopHint'>HTML5魔塔游戏平台,享受更多魔塔游戏:<br/>https://h5mota.com/</p>
|
||||
</div>
|
||||
<img id='startBackground'>
|
||||
<p id='startLogo'></p>
|
||||
<div id='startButtonGroup'>
|
||||
<div id='startButtons'>
|
||||
<span class='startButton' id='playGame'>开始游戏</span>
|
||||
<span class='startButton' id='loadGame'>继续游戏</span>
|
||||
<span class='startButton' id='replayGame'>录像回放</span>
|
||||
<img id='startBackground'>
|
||||
<p id='startLogo'></p>
|
||||
<div id='startButtonGroup'>
|
||||
<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 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 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; z-index: 50;"></canvas>
|
||||
<canvas id="statusCanvas" style="position: absolute; left: 0; top: 0;"></canvas>
|
||||
<canvas id="caidan1" style="position: absolute; left: 0; top: 0;"></canvas>
|
||||
</div>
|
||||
<div id="toolBar" class="clearfix">
|
||||
@ -168,11 +170,11 @@
|
||||
<div id="gameDraw">
|
||||
<div id="gif"></div>
|
||||
<div id="gif2"></div>
|
||||
<canvas class='gameCanvas' id='bg'></canvas>
|
||||
<canvas class='gameCanvas' id='event'></canvas>
|
||||
<canvas class='gameCanvas' id='hero'></canvas>
|
||||
<canvas class='gameCanvas' id='event2'></canvas>
|
||||
<canvas class='gameCanvas' id='fg'></canvas>
|
||||
<canvas class='gameCanvas anti-aliasing' id='bg'></canvas>
|
||||
<canvas class='gameCanvas anti-aliasing' id='event'></canvas>
|
||||
<canvas class='gameCanvas anti-aliasing' id='hero'></canvas>
|
||||
<canvas class='gameCanvas anti-aliasing' id='event2'></canvas>
|
||||
<canvas class='gameCanvas anti-aliasing' id='fg'></canvas>
|
||||
<canvas class='gameCanvas' id='caidan'></canvas>
|
||||
<canvas class='gameCanvas' id='damage'></canvas>
|
||||
<canvas class='gameCanvas' id='animate'></canvas>
|
||||
@ -200,4 +202,5 @@
|
||||
<script>main.init('play');main.listen();</script>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
@ -1225,7 +1225,7 @@ actions.prototype._clickBook = function (x, y) {
|
||||
var data = core.status.event.data;
|
||||
if (data != null && y < core._HEIGHT_-1) {
|
||||
var per_page = pageinfo.per_page, page = parseInt(data / per_page);
|
||||
var u = this.LAST / per_page;
|
||||
var u = (core._HEIGHT_ - 1) / per_page;
|
||||
for (var i = 0; i < per_page; ++i) {
|
||||
if (y >= u * i && y < u * (i + 1)) {
|
||||
var index = per_page * page + i;
|
||||
|
@ -18,6 +18,7 @@ control.prototype._init = function () {
|
||||
this.weathers = {};
|
||||
this.resizes = [];
|
||||
this.noAutoEvents = true;
|
||||
this.updateNextFrame = false;
|
||||
// --- 注册系统的animationFrame
|
||||
this.registerAnimationFrame("totalTime", false, this._animationFrame_totalTime);
|
||||
this.registerAnimationFrame("autoSave", true, this._animationFrame_autoSave);
|
||||
@ -3046,22 +3047,27 @@ control.prototype.clearStatusBar = function () {
|
||||
|
||||
////// 更新状态栏 //////
|
||||
control.prototype.updateStatusBar = function (doNotCheckAutoEvents, immediate) {
|
||||
if (!core.isPlaying()) return;
|
||||
if (immediate) {
|
||||
return this.updateStatusBar_update();
|
||||
}
|
||||
if (!doNotCheckAutoEvents) this.noAutoEvents = false;
|
||||
if (core.isReplaying()) return this.updateStatusBar_update();
|
||||
requestAnimationFrame(this.updateStatusBar_update)
|
||||
}
|
||||
if (!core.control.updateNextFrame) {
|
||||
core.control.updateNextFrame = true;
|
||||
requestAnimationFrame(this.updateStatusBar_update);
|
||||
}
|
||||
};
|
||||
|
||||
control.prototype.updateStatusBar_update = function () {
|
||||
core.control.updateNextFrame = false;
|
||||
if (!core.isPlaying() || core.hasFlag('__statistics__')) return;
|
||||
core.control.controldata.updateStatusBar();
|
||||
if (!core.control.noAutoEvents) core.checkAutoEvents();
|
||||
core.control._updateStatusBar_setToolboxIcon();
|
||||
core.clearRouteFolding();
|
||||
core.control.noAutoEvents = true;
|
||||
}
|
||||
};
|
||||
|
||||
control.prototype._updateStatusBar_setToolboxIcon = function () {
|
||||
if (core.isReplaying()) {
|
||||
@ -3265,9 +3271,10 @@ control.prototype.resize = function () {
|
||||
var clientWidth = main.dom.body.clientWidth, clientHeight = main.dom.body.clientHeight;
|
||||
var BORDER = 3;
|
||||
var extendToolbar = core.flags.extendToolbar;
|
||||
var BAR_WIDTH = extendToolbar ? 0 : Math.round(core._PY_ * 0.3);
|
||||
let hideLeftStatusBar = core.flags.hideLeftStatusBar;
|
||||
var BAR_WIDTH = hideLeftStatusBar ? 0 : Math.round(core._PY_ * 0.31);
|
||||
|
||||
var horizontalMaxRatio = (clientHeight - 2 * BORDER - (extendToolbar ? BORDER : 0)) / (core._PY_ + (extendToolbar ? 38 : 0));
|
||||
var horizontalMaxRatio = (clientHeight - 2 * BORDER - (hideLeftStatusBar ? BORDER : 0)) / (core._PY_ + (hideLeftStatusBar ? 38 : 0));
|
||||
|
||||
if (clientWidth - 3 * BORDER >= core._PX_ + BAR_WIDTH || (clientWidth > clientHeight && horizontalMaxRatio < 1)) {
|
||||
// 横屏
|
||||
@ -3289,6 +3296,7 @@ control.prototype.resize = function () {
|
||||
core.domStyle.scale = Math.min((clientWidth - 2 * BORDER) / core._PX_);
|
||||
core.domStyle.availableScale = [];
|
||||
extendToolbar = false;
|
||||
hideLeftStatusBar = false;
|
||||
BAR_WIDTH = Math.round(core._PX_ * 0.3);
|
||||
}
|
||||
|
||||
@ -3317,7 +3325,8 @@ control.prototype.resize = function () {
|
||||
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
|
||||
is15x15: false,
|
||||
hideLeftStatusBar
|
||||
};
|
||||
|
||||
this._doResize(obj);
|
||||
@ -3339,7 +3348,7 @@ control.prototype._resize_gameGroup = function (obj) {
|
||||
totalHeight = obj.outerHeight + obj.statusBarHeightInVertical + obj.toolbarHeightInVertical
|
||||
}
|
||||
else {
|
||||
totalWidth = obj.outerWidth + obj.BAR_WIDTH * core.domStyle.scale + (obj.extendToolbar ? 0 : obj.BORDER);
|
||||
totalWidth = obj.outerWidth + obj.BAR_WIDTH * core.domStyle.scale + (obj.hideLeftStatusBar ? 0 : obj.BORDER);
|
||||
totalHeight = obj.outerHeight + (obj.extendToolbar ? obj.TOOLBAR_HEIGHT * core.domStyle.scale + obj.BORDER : 0);
|
||||
}
|
||||
gameGroup.style.width = totalWidth + "px";
|
||||
@ -3409,9 +3418,7 @@ control.prototype._resize_canvas = function (obj) {
|
||||
} else {
|
||||
for (var name in core.dymCanvas) {
|
||||
var ctx = core.dymCanvas[name], canvas = ctx.canvas;
|
||||
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";
|
||||
core.resizeCanvas(ctx, parseFloat(canvas.getAttribute("_width")), parseFloat(canvas.getAttribute("_height")))
|
||||
canvas.style.left = parseFloat(canvas.getAttribute("_left")) * core.domStyle.scale + "px";
|
||||
canvas.style.top = parseFloat(canvas.getAttribute("_top")) * core.domStyle.scale + "px";
|
||||
}
|
||||
@ -3435,13 +3442,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.background = obj.globalAttribute.statusLeftBackground;
|
||||
// --- 计算文字大小
|
||||
if (obj.extendToolbar) {
|
||||
if (obj.hideLeftStatusBar) {
|
||||
statusBar.style.fontSize = 16 * core.domStyle.scale + "px";
|
||||
} else {
|
||||
statusBar.style.fontSize = 16 * Math.min(1, (core._HEIGHT_ - 4) / obj.count) * core.domStyle.scale + "px";
|
||||
}
|
||||
}
|
||||
statusBar.style.display = obj.extendToolbar ? 'none' : 'block';
|
||||
statusBar.style.display = obj.hideLeftStatusBar ? 'none' : 'block';
|
||||
statusBar.style.borderTop = statusBar.style.borderLeft = obj.border;
|
||||
statusBar.style.borderRight = core.domStyle.isVertical ? obj.border : '';
|
||||
statusBar.style.borderBottom = core.domStyle.isVertical ? '' : obj.border;
|
||||
@ -3456,7 +3463,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.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.extendToolbar ? "block" : "none";
|
||||
core.dom.statusCanvas.style.display = core.flags.statusCanvas && !obj.hideLeftStatusBar ? "block" : "none";
|
||||
}
|
||||
|
||||
control.prototype._resize_status = function (obj) {
|
||||
@ -3464,7 +3471,7 @@ control.prototype._resize_status = function (obj) {
|
||||
if (core.domStyle.isVertical) {
|
||||
statusHeight = 32 * core.domStyle.scale * 0.8;
|
||||
} else {
|
||||
statusHeight = (obj.extendToolbar ? core._HEIGHT_ : core._HEIGHT_ - 4) / obj.count * 32 * core.domStyle.scale * 0.8;
|
||||
statusHeight = (obj.hideLeftStatusBar ? core._HEIGHT_ : core._HEIGHT_ - 4) / obj.count * 32 * core.domStyle.scale * 0.8;
|
||||
}
|
||||
// status
|
||||
for (var i = 0; i < core.dom.status.length; ++i) {
|
||||
@ -3507,7 +3514,7 @@ control.prototype._resize_toolBar = function (obj) {
|
||||
toolBar.style.background = obj.globalAttribute.toolsBackground;
|
||||
}
|
||||
else {
|
||||
if (obj.extendToolbar) {
|
||||
if (obj.extendToolbar || obj.hideLeftStatusBar) {
|
||||
toolBar.style.left = "";
|
||||
toolBar.style.right = 0;
|
||||
toolBar.style.width = obj.outerWidth + "px";
|
||||
|
49
libs/maps.js
49
libs/maps.js
@ -34,11 +34,10 @@ maps.prototype._resetFloorImages = function () {
|
||||
}
|
||||
}
|
||||
|
||||
maps.prototype._setHDCanvasSize = function (ctx, width, height, isTempCanvas) {
|
||||
maps.prototype._setHDCanvasSize = function (ctx, width, height) {
|
||||
ctx.setTransform(1, 0, 0, 1, 0, 0);
|
||||
var ratio = core.domStyle.ratio;
|
||||
if (ctx === core.bigmap.tempCanvas) ratio = core.domStyle.scale;
|
||||
if (isTempCanvas) ratio = core.domStyle.ratio;
|
||||
var ratio = core.domStyle.scale;
|
||||
ratio *= devicePixelRatio;
|
||||
if (width != null) ctx.canvas.width = width * ratio;
|
||||
if (height != null) ctx.canvas.height = height * ratio;
|
||||
ctx.scale(ratio, ratio);
|
||||
@ -1728,18 +1727,20 @@ maps.prototype._drawThumbnail_drawTempCanvas = function (floorId, blocks, option
|
||||
// 如果是大地图模式?
|
||||
if (options.all) {
|
||||
// 计算比例
|
||||
var scale = Math.max(core._WIDTH_ / width, core._HEIGHT_ / height);
|
||||
if (options.noHD) {
|
||||
tempCanvas.canvas.width = width * 32 * scale;
|
||||
tempCanvas.canvas.height = height * 32 * scale;
|
||||
} else core.resizeCanvas(tempCanvas, width * 32 * scale, height * 32 * scale, false, true);
|
||||
tempCanvas.scale(scale, scale);
|
||||
tempCanvas.canvas.width = width * 32;
|
||||
tempCanvas.canvas.height = height * 32;
|
||||
tempCanvas.canvas.removeAttribute('isHD');
|
||||
} else {
|
||||
core.maps._setHDCanvasSize(tempCanvas, width * 32, height * 32);
|
||||
}
|
||||
} else if (width * height > core.bigmap.threshold) {
|
||||
options.v2 = true;
|
||||
if (options.noHD) {
|
||||
tempCanvas.canvas.width = core._PX_;
|
||||
tempCanvas.canvas.height = core._PY_;
|
||||
} else core.resizeCanvas(tempCanvas, core._PX_, core._PY_);
|
||||
tempCanvas.canvas.removeAttribute('isHD');
|
||||
} else core.maps._setHDCanvasSize(tempCanvas, width * 32, height * 32);
|
||||
var centerX = options.centerX, centerY = options.centerY;
|
||||
if (centerX == null) centerX = Math.floor(width / 2);
|
||||
if (centerY == null) centerY = Math.floor(height / 2);
|
||||
@ -1751,7 +1752,8 @@ maps.prototype._drawThumbnail_drawTempCanvas = function (floorId, blocks, option
|
||||
if (options.noHD) {
|
||||
tempCanvas.canvas.width = width * 32;
|
||||
tempCanvas.canvas.height = height * 32;
|
||||
} else core.resizeCanvas(tempCanvas, width * 32, height * 32, false, true);
|
||||
tempCanvas.canvas.removeAttribute('isHD');
|
||||
} else core.maps._setHDCanvasSize(tempCanvas, width * 32, height * 32);
|
||||
}
|
||||
options.ctx = tempCanvas;
|
||||
|
||||
@ -1813,6 +1815,7 @@ maps.prototype._drawThumbnail_drawToTarget = function (floorId, options) {
|
||||
if (centerY == null) centerY = Math.floor(height / 2);
|
||||
var tempCanvas = core.bigmap.tempCanvas;
|
||||
|
||||
const scale = core.domStyle.scale * devicePixelRatio;
|
||||
if (options.all) {
|
||||
var tempWidth = tempCanvas.canvas.width, tempHeight = tempCanvas.canvas.height;
|
||||
// 绘制全景图
|
||||
@ -1833,20 +1836,28 @@ maps.prototype._drawThumbnail_drawToTarget = function (floorId, options) {
|
||||
}
|
||||
else {
|
||||
// 只绘制可见窗口
|
||||
var pw = core._PX_, ph = core._PY_, hw = core._HALF_WIDTH_, hh = core._HALF_HEIGHT_, W = core._WIDTH_, H = core._HEIGHT_;
|
||||
var ratio = core.domStyle.isVertical ? core.domStyle.ratio : core.domStyle.scale;
|
||||
if (main.mode == 'editor') { pw = ph = core.__PIXELS__; hw = hh = core.__HALF_SIZE__; W = H = core.__SIZE__; }
|
||||
var pw = core._PX_,
|
||||
ph = core._PY_,
|
||||
hw = core._HALF_WIDTH_,
|
||||
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) {
|
||||
core.drawImage(ctx, tempCanvas.canvas, 0, 0, pw * ratio, ph * ratio, x, y, w, h);
|
||||
if (options.noHD) core.drawImage(ctx, tempCanvas.canvas, 0, 0, pw, ph, x, y, w, h);
|
||||
else core.drawImage(ctx, tempCanvas.canvas, 0, 0, pw * scale, ph * scale, x, y, w, h);
|
||||
} else {
|
||||
var offsetX = core.clamp(centerX - hw, 0, width - W),
|
||||
offsetY = core.clamp(centerY - hh, 0, height - H),
|
||||
c = options.noHD ? 1 : core.domStyle.scale;
|
||||
offsetY = core.clamp(centerY - hh, 0, height - H);
|
||||
if (options.noHD) {
|
||||
core.drawImage(ctx, tempCanvas.canvas, offsetX * 32, offsetY * 32, pw, ph, x, y, w, h);
|
||||
return;
|
||||
} else {
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
66
libs/ui.js
66
libs/ui.js
@ -57,7 +57,13 @@ ui.prototype.clearMap = function (name, x, y, width, height) {
|
||||
if (x != null && y != null && width != null && height != null) {
|
||||
ctx.clearRect(x, y, width, height);
|
||||
} else {
|
||||
ctx.clearRect(-32, -32, ctx.canvas.width + 32, ctx.canvas.height + 32);
|
||||
if (ctx.canvas.getAttribute('isHD')) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1108,12 +1114,16 @@ ui.prototype.drawTextContent = function (ctx, content, config) {
|
||||
config.offsetY = 0;
|
||||
config.line = 0;
|
||||
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');
|
||||
if (config.isHD) {
|
||||
core.maps._setHDCanvasSize(tempCtx, ctx.canvas.width, ctx.canvas.height);
|
||||
if (config.isHD && ctx) {
|
||||
core.maps._setHDCanvasSize(
|
||||
tempCtx,
|
||||
ctx.canvas.width,
|
||||
ctx.canvas.height
|
||||
);
|
||||
} else {
|
||||
tempCtx.canvas.width = ctx == null ? 1 : ctx.canvas.width;
|
||||
tempCtx.canvas.height = ctx == null ? 1 : ctx.canvas.height;
|
||||
@ -1148,10 +1158,20 @@ ui.prototype._drawTextContent_draw = function (ctx, tempCtx, content, config) {
|
||||
if (config.index >= config.blocks.length) return false;
|
||||
var block = config.blocks[config.index++];
|
||||
if (block != null) {
|
||||
var ratio = config.isHD ? core.domStyle.ratio : 1;
|
||||
core.drawImage(ctx, tempCtx.canvas, block.left * ratio, block.top * ratio, block.width * ratio, block.height * ratio,
|
||||
config.left + block.left + block.marginLeft, config.top + block.top + block.marginTop,
|
||||
block.width, block.height);
|
||||
// It works, why?
|
||||
const scale = config.isHD ? devicePixelRatio * core.domStyle.scale : 1;
|
||||
core.drawImage(
|
||||
ctx,
|
||||
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;
|
||||
}
|
||||
@ -2512,23 +2532,24 @@ ui.prototype.drawFly = function (page) {
|
||||
core.setTextAlign('ui', 'center');
|
||||
|
||||
var middle = core._PY_ / 2 + 39;
|
||||
const lastWidth = 0.25 * core._PX_ - 16;
|
||||
|
||||
// 换行
|
||||
var lines = core.splitLines('ui', title, 120, this._buildFont(19, true));
|
||||
var lines = core.splitLines('ui', title, lastWidth, this._buildFont(19, true));
|
||||
var start_y = middle - (lines.length - 1) * 11;
|
||||
for (var i in lines) {
|
||||
core.fillText('ui', lines[i], core._PX_ - 60, start_y, '#FFFFFF');
|
||||
core.fillText('ui', lines[i], core._PX_ - lastWidth * 0.5, start_y, '#FFFFFF');
|
||||
start_y += 22;
|
||||
}
|
||||
if (core.actions._getNextFlyFloor(1) != page) {
|
||||
core.fillText('ui', '▲', core._PX_ - 60, middle - 64, null, this._buildFont(17, false));
|
||||
core.fillText('ui', '▲', core._PX_ - 60, middle - 96);
|
||||
core.fillText('ui', '▲', core._PX_ - 60, middle - 96 - 7);
|
||||
core.fillText('ui', '▲', core._PX_ - lastWidth * 0.5, middle - 64, null, this._buildFont(17, false));
|
||||
core.fillText('ui', '▲', core._PX_ - lastWidth * 0.5, middle - 96);
|
||||
core.fillText('ui', '▲', core._PX_ - lastWidth * 0.5, middle - 96 - 7);
|
||||
}
|
||||
if (core.actions._getNextFlyFloor(-1) != page) {
|
||||
core.fillText('ui', '▼', core._PX_ - 60, middle + 64, null, this._buildFont(17, false));
|
||||
core.fillText('ui', '▼', core._PX_ - 60, middle + 96);
|
||||
core.fillText('ui', '▼', core._PX_ - 60, middle + 96 + 7);
|
||||
core.fillText('ui', '▼', core._PX_ - lastWidth * 0.5, middle + 64, null, this._buildFont(17, false));
|
||||
core.fillText('ui', '▼', core._PX_ - lastWidth * 0.5, middle + 96);
|
||||
core.fillText('ui', '▼', core._PX_ - lastWidth * 0.5, middle + 96 + 7);
|
||||
}
|
||||
var size = 0.75;
|
||||
core.strokeRect('ui', 16, 64, size * core._PX_, size * core._PY_, '#FFFFFF', 2);
|
||||
@ -3381,6 +3402,8 @@ ui.prototype.createCanvas = function (name, x, y, width, height, z) {
|
||||
newCanvas.style.display = 'block';
|
||||
newCanvas.setAttribute("_left", x);
|
||||
newCanvas.setAttribute("_top", y);
|
||||
newCanvas.setAttribute("_width", width);
|
||||
newCanvas.setAttribute("_height", height);
|
||||
newCanvas.style.width = width * core.domStyle.scale + 'px';
|
||||
newCanvas.style.height = height * core.domStyle.scale + 'px';
|
||||
newCanvas.style.left = x * core.domStyle.scale + 'px';
|
||||
@ -3439,16 +3462,21 @@ ui.prototype.rotateCanvas = function (name, angle, centerX, centerY) {
|
||||
}
|
||||
|
||||
////// canvas重置 //////
|
||||
ui.prototype.resizeCanvas = function (name, width, height, styleOnly, isTempCanvas) {
|
||||
ui.prototype.resizeCanvas = function (name, width, height, styleOnly) {
|
||||
var ctx = core.getContextByName(name);
|
||||
const canvas = ctx.canvas;
|
||||
if (!ctx) return null;
|
||||
if (width != null) {
|
||||
if (!styleOnly) core.maps._setHDCanvasSize(ctx, width, null, isTempCanvas);
|
||||
if (!styleOnly && ctx.canvas.hasAttribute('isHD'))
|
||||
core.maps._setHDCanvasSize(ctx, width, null);
|
||||
ctx.canvas.style.width = width * core.domStyle.scale + 'px';
|
||||
canvas.setAttribute('_width', width);
|
||||
}
|
||||
if (height != null) {
|
||||
if (!styleOnly) core.maps._setHDCanvasSize(ctx, null, height, isTempCanvas);
|
||||
if (!styleOnly && ctx.canvas.hasAttribute('isHD'))
|
||||
core.maps._setHDCanvasSize(ctx, null, height);
|
||||
ctx.canvas.style.height = height * core.domStyle.scale + 'px';
|
||||
canvas.setAttribute('_height', height);
|
||||
}
|
||||
return ctx;
|
||||
}
|
||||
|
@ -718,7 +718,7 @@ var data_a1e2fb4a_e986_4524_b0da_9b7ba7c0874d =
|
||||
"firstData": {
|
||||
"title": "天塔",
|
||||
"name": "tianta",
|
||||
"version": "Ver 2.10.0",
|
||||
"version": "Ver 2.10.3",
|
||||
"floorId": "nandu",
|
||||
"hero": {
|
||||
"image": "hero.png",
|
||||
@ -1595,6 +1595,7 @@ var data_a1e2fb4a_e986_4524_b0da_9b7ba7c0874d =
|
||||
"enableMoveDirectly": true,
|
||||
"enableRouteFolding": true,
|
||||
"disableShopOnDamage": false,
|
||||
"blurFg": false
|
||||
"blurFg": false,
|
||||
"hideLeftStatusBar": false
|
||||
}
|
||||
}
|
@ -907,6 +907,11 @@ main.floors.MT0=
|
||||
"steps": [
|
||||
"right:1"
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "hide",
|
||||
"remove": true,
|
||||
"time": 0
|
||||
}
|
||||
]
|
||||
},
|
||||
|
@ -66,7 +66,7 @@ main.floors.MT16=
|
||||
"true": [
|
||||
{
|
||||
"type": "setBlock",
|
||||
"number": "339",
|
||||
"number": "372",
|
||||
"loc": [
|
||||
[
|
||||
11,
|
||||
@ -136,7 +136,7 @@ main.floors.MT16=
|
||||
"true": [
|
||||
{
|
||||
"type": "setBlock",
|
||||
"number": "339",
|
||||
"number": "372",
|
||||
"loc": [
|
||||
[
|
||||
11,
|
||||
@ -206,7 +206,7 @@ main.floors.MT16=
|
||||
"true": [
|
||||
{
|
||||
"type": "setBlock",
|
||||
"number": "339",
|
||||
"number": "372",
|
||||
"loc": [
|
||||
[
|
||||
11,
|
||||
@ -276,7 +276,7 @@ main.floors.MT16=
|
||||
"true": [
|
||||
{
|
||||
"type": "setBlock",
|
||||
"number": "339",
|
||||
"number": "372",
|
||||
"loc": [
|
||||
[
|
||||
11,
|
||||
@ -346,7 +346,7 @@ main.floors.MT16=
|
||||
"true": [
|
||||
{
|
||||
"type": "setBlock",
|
||||
"number": "339",
|
||||
"number": "372",
|
||||
"loc": [
|
||||
[
|
||||
11,
|
||||
@ -416,7 +416,7 @@ main.floors.MT16=
|
||||
"true": [
|
||||
{
|
||||
"type": "setBlock",
|
||||
"number": "339",
|
||||
"number": "372",
|
||||
"loc": [
|
||||
[
|
||||
11,
|
||||
@ -486,7 +486,7 @@ main.floors.MT16=
|
||||
"true": [
|
||||
{
|
||||
"type": "setBlock",
|
||||
"number": "339",
|
||||
"number": "372",
|
||||
"loc": [
|
||||
[
|
||||
11,
|
||||
@ -556,7 +556,7 @@ main.floors.MT16=
|
||||
"true": [
|
||||
{
|
||||
"type": "setBlock",
|
||||
"number": "339",
|
||||
"number": "372",
|
||||
"loc": [
|
||||
[
|
||||
11,
|
||||
@ -626,7 +626,7 @@ main.floors.MT16=
|
||||
"true": [
|
||||
{
|
||||
"type": "setBlock",
|
||||
"number": "339",
|
||||
"number": "372",
|
||||
"loc": [
|
||||
[
|
||||
11,
|
||||
@ -696,7 +696,7 @@ main.floors.MT16=
|
||||
"true": [
|
||||
{
|
||||
"type": "setBlock",
|
||||
"number": "339",
|
||||
"number": "372",
|
||||
"loc": [
|
||||
[
|
||||
11,
|
||||
@ -766,7 +766,7 @@ main.floors.MT16=
|
||||
"true": [
|
||||
{
|
||||
"type": "setBlock",
|
||||
"number": "339",
|
||||
"number": "372",
|
||||
"loc": [
|
||||
[
|
||||
11,
|
||||
@ -836,7 +836,7 @@ main.floors.MT16=
|
||||
"true": [
|
||||
{
|
||||
"type": "setBlock",
|
||||
"number": "339",
|
||||
"number": "372",
|
||||
"loc": [
|
||||
[
|
||||
11,
|
||||
@ -906,7 +906,7 @@ main.floors.MT16=
|
||||
"true": [
|
||||
{
|
||||
"type": "setBlock",
|
||||
"number": "339",
|
||||
"number": "372",
|
||||
"loc": [
|
||||
[
|
||||
11,
|
||||
@ -985,7 +985,7 @@ main.floors.MT16=
|
||||
"true": [
|
||||
{
|
||||
"type": "setBlock",
|
||||
"number": "339",
|
||||
"number": "372",
|
||||
"loc": [
|
||||
[
|
||||
11,
|
||||
@ -1450,7 +1450,7 @@ main.floors.MT16=
|
||||
"opacity": 1,
|
||||
"time": 0
|
||||
},
|
||||
"\t[杰克]这里似乎封印着类似于11层东南角的机遗迹一样的东西。",
|
||||
"\t[杰克]这里似乎封印着类似于11层东南角的机械遗迹一样的东西。",
|
||||
"\t[邵虎]..........好吧......我会注意的。",
|
||||
{
|
||||
"type": "hideImage",
|
||||
@ -1483,60 +1483,71 @@ main.floors.MT16=
|
||||
]
|
||||
}
|
||||
],
|
||||
"11,7": [
|
||||
{
|
||||
"type": "if",
|
||||
"condition": "(flag:xianjie2==1)",
|
||||
"true": [
|
||||
{
|
||||
"type": "setBlock",
|
||||
"number": "339",
|
||||
"loc": [
|
||||
[
|
||||
11,
|
||||
7
|
||||
]
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "hide",
|
||||
"remove": true
|
||||
}
|
||||
],
|
||||
"false": [
|
||||
{
|
||||
"type": "if",
|
||||
"condition": "(flag:xianjie==15)",
|
||||
"true": [
|
||||
{
|
||||
"type": "setBlock",
|
||||
"number": "89",
|
||||
"loc": [
|
||||
[
|
||||
12,
|
||||
1
|
||||
"11,7": {
|
||||
"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:xianjie2==1)",
|
||||
"true": [
|
||||
{
|
||||
"type": "hide",
|
||||
"remove": true
|
||||
}
|
||||
],
|
||||
"false": [
|
||||
{
|
||||
"type": "if",
|
||||
"condition": "(flag:xianjie==15)",
|
||||
"true": [
|
||||
{
|
||||
"type": "openDoor",
|
||||
"loc": [
|
||||
11,
|
||||
7
|
||||
]
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "setValue",
|
||||
"name": "flag:xianjie",
|
||||
"operator": "+=",
|
||||
"value": "1",
|
||||
"norefresh": true
|
||||
},
|
||||
{
|
||||
"type": "setValue",
|
||||
"name": "flag:xianjie2",
|
||||
"operator": "+=",
|
||||
"value": "1"
|
||||
}
|
||||
],
|
||||
"false": []
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
},
|
||||
{
|
||||
"type": "setBlock",
|
||||
"number": "89",
|
||||
"loc": [
|
||||
[
|
||||
12,
|
||||
1
|
||||
]
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "setValue",
|
||||
"name": "flag:xianjie",
|
||||
"operator": "+=",
|
||||
"value": "1",
|
||||
"norefresh": true
|
||||
},
|
||||
{
|
||||
"type": "setValue",
|
||||
"name": "flag:xianjie2",
|
||||
"operator": "+=",
|
||||
"value": "1"
|
||||
}
|
||||
],
|
||||
"false": []
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"6,1": [
|
||||
{
|
||||
"type": "function",
|
||||
@ -1593,7 +1604,7 @@ main.floors.MT16=
|
||||
"true": [
|
||||
{
|
||||
"type": "setBlock",
|
||||
"number": "339",
|
||||
"number": "372",
|
||||
"loc": [
|
||||
[
|
||||
11,
|
||||
@ -1606,7 +1617,133 @@ 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": {
|
||||
"8,4": {
|
||||
@ -1620,7 +1757,25 @@ main.floors.MT16=
|
||||
"time": 200
|
||||
}
|
||||
},
|
||||
"afterBattle": {},
|
||||
"afterBattle": {
|
||||
"6,4": [
|
||||
{
|
||||
"type": "setValue",
|
||||
"name": "flag:112",
|
||||
"value": "true"
|
||||
},
|
||||
{
|
||||
"type": "setBlock",
|
||||
"number": "372",
|
||||
"loc": [
|
||||
[
|
||||
8,
|
||||
8
|
||||
]
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"afterGetItem": {},
|
||||
"afterOpenDoor": {},
|
||||
"cannotMove": {},
|
||||
@ -1630,11 +1785,11 @@ main.floors.MT16=
|
||||
[ 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, 0,475, 2, 2, 2, 2, 2, 81, 2, 2, 27,352, 0],
|
||||
[ 0,348, 0,206, 81,372,213, 0, 87,372, 2,475, 31,352, 0],
|
||||
[ 0,348, 0,206, 81,361,213, 0, 87,361, 2,475, 31,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, 0, 0, 2,206, 0, 0, 0, 32, 2, 2, 2,352, 0],
|
||||
[ 0,348, 31,475, 2,372, 88,123,372,372, 81,206, 0,352, 0],
|
||||
[ 0,348, 31,475, 2,361, 88,123,361,361, 81,206, 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, 0,218, 0,475, 2,475,475, 0, 28, 0, 0,352, 0],
|
||||
|
@ -11,10 +11,20 @@ main.floors.XIANJIE=
|
||||
"firstArrive": [],
|
||||
"events": {
|
||||
"7,1": [
|
||||
{
|
||||
"type": "setValue",
|
||||
"name": "flag:isRMshop",
|
||||
"value": "true"
|
||||
},
|
||||
{
|
||||
"type": "openShop",
|
||||
"id": "expShop1",
|
||||
"open": true
|
||||
},
|
||||
{
|
||||
"type": "setValue",
|
||||
"name": "flag:isRMshop",
|
||||
"value": "false"
|
||||
}
|
||||
]
|
||||
},
|
||||
|
@ -326,12 +326,12 @@ var functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a =
|
||||
core.status.hero.exp += exp;
|
||||
core.status.hero.statistics.exp += exp;
|
||||
|
||||
var hint = "打败 " + core.getEnemyValue(enemy, "name", x, y);
|
||||
if (core.flags.statusBarItems.indexOf('enableMoney') >= 0)
|
||||
hint += ',' + core.getStatusLabel('money') + '+' + money; // hint += ",金币+" + money;
|
||||
if (core.flags.statusBarItems.indexOf('enableExp') >= 0)
|
||||
hint += ',' + core.getStatusLabel('exp') + '+' + exp; // hint += ",经验+" + exp;
|
||||
if (!core.getFlag("isNoTip")) core.drawTip(hint, enemy.id);
|
||||
var hint = "打败 " + core.getEnemyValue(enemy, "name", x, y);
|
||||
if (core.flags.statusBarItems.indexOf('enableMoney') >= 0)
|
||||
hint += ',' + core.getStatusLabel('money') + '+' + money; // hint += ",金币+" + money;
|
||||
if (core.flags.statusBarItems.indexOf('enableExp') >= 0)
|
||||
hint += ',' + core.getStatusLabel('exp') + '+' + exp; // hint += ",经验+" + exp;
|
||||
if (!core.getFlag("isNoTip")) core.drawTip(hint, enemy.id);
|
||||
|
||||
// 中毒
|
||||
if (core.enemys.hasSpecial(special, 12)) {
|
||||
@ -388,6 +388,8 @@ var functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a =
|
||||
core.push(todo, [{ "type": "insert", "name": "加点事件", "args": [point] }]);
|
||||
}
|
||||
|
||||
//等待动画执行完毕
|
||||
core.push(todo, [{ "type": "waitAsync" }]);
|
||||
// 战后事件
|
||||
if (core.status.floorId != null) {
|
||||
core.push(todo, core.floors[core.status.floorId].afterBattle[x + "," + y]);
|
||||
|
@ -246,14 +246,14 @@ var maps_90f36752_8815_4be8_b32b_d7fad1d0542e =
|
||||
"358": {"cls":"animates","id":"A358"},
|
||||
"359": {"cls":"animates","id":"A359"},
|
||||
"360": {"cls":"animates","id":"A360"},
|
||||
"361": {"cls":"animates","id":"A361"},
|
||||
"361": {"cls":"animates","id":"A361","animate":1,"trigger":"openDoor","doorInfo":{"time":160,"openSound":"door.mp3","closeSound":"door.mp3","keys":{}}},
|
||||
"362": {"cls":"animates","id":"A362"},
|
||||
"363": {"cls":"animates","id":"A363"},
|
||||
"364": {"cls":"animates","id":"A364"},
|
||||
"365": {"cls":"animates","id":"A365"},
|
||||
"366": {"cls":"animates","id":"A366"},
|
||||
"367": {"cls":"animates","id":"A367","event":null,"canPass":true},
|
||||
"368": {"cls":"animates","id":"A368"},
|
||||
"368": {"cls":"animates","id":"A368","trigger":"openDoor","animate":1,"doorInfo":{"time":160,"openSound":"door.mp3","closeSound":"door.mp3","keys":{}}},
|
||||
"369": {"cls":"animates","id":"A369"},
|
||||
"370": {"cls":"animates","id":"A370"},
|
||||
"371": {"cls":"npcs","id":"N371"},
|
||||
|
@ -42,7 +42,7 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 =
|
||||
if (clientWidth - 3 * BORDER >= core._PX_ + BAR_WIDTH || (clientWidth > clientHeight && horizontalMaxRatio < 1)) {
|
||||
core.domStyle.isVertical = false;
|
||||
core.clearMap('Vertical');
|
||||
} else {
|
||||
} else if (core.status.played) {
|
||||
// 竖屏
|
||||
core.domStyle.isVertical = true;
|
||||
core.createCanvas('Vertical', 0, 0, 480, 480, 200);
|
||||
@ -1856,7 +1856,7 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 =
|
||||
if (!name) return;
|
||||
var canvas = document.createElement('canvas');
|
||||
canvas.id = name;
|
||||
canvas.className = 'gameCanvas';
|
||||
canvas.className = 'gameCanvas anti-aliasing';
|
||||
// 编辑器模式下设置zIndex会导致加入的图层覆盖优先级过高
|
||||
if (main.mode != "editor") canvas.style.zIndex = zIndex || 0;
|
||||
// 将图层插入进游戏内容
|
||||
@ -3902,19 +3902,21 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 =
|
||||
// 准备渐变
|
||||
this.maskPrepare = function () {
|
||||
// 执行后画面将凝固
|
||||
core.ui.createCanvas2("mask", 0, 0, core.__PIXELS__, core.__PIXELS__, 155);
|
||||
for (var m in core.canvas) {
|
||||
core.dymCanvas.mask.drawImage(core.canvas[m].canvas, 0, 0);
|
||||
};
|
||||
var mask = core.ui.createCanvas2("mask", 0, 0, core.__PIXELS__ + 161, core.__PIXELS__, 200);
|
||||
core.drawThumbnail(core.status.floorId, null, { ctx: mask, x: 161, y: 0, size: 1, damage: false, all: true });
|
||||
core.drawImage('mask', 'caidan.png', 0, 0);
|
||||
// for (var m in core.canvas) {
|
||||
// core.dymCanvas.mask.drawImage(core.canvas[m].canvas, 0, 0);
|
||||
// };
|
||||
}
|
||||
|
||||
// 执行渐变
|
||||
this.maskFliter = function (time, sample) { // sample为渐变图名称,渐变图需要在全塔属性注册
|
||||
var tempCanvas = core.bigmap.tempCanvas;
|
||||
var tempWidth = core.__PIXELS__,
|
||||
tempHeight = core.__PIXELS__;
|
||||
tempCanvas.canvas.width = tempWidth;
|
||||
tempCanvas.canvas.height = tempHeight;
|
||||
var tempCanvas = core.ui.createCanvas2("mask2", 0, 0, core.__PIXELS__ + 161, core.__PIXELS__, 200);
|
||||
var tempWidth = tempCanvas.canvas.width,
|
||||
tempHeight = tempCanvas.canvas.height;
|
||||
//tempCanvas.canvas.width = tempWidth;
|
||||
//tempCanvas.canvas.height = tempHeight;
|
||||
tempCanvas.clearRect(0, 0, tempWidth, tempHeight);
|
||||
tempCanvas.drawImage(core.material.images.images[sample], 0, 0, tempWidth, tempHeight);
|
||||
// 读取渐变图开始处理
|
||||
|
651
server.js
Normal file
651
server.js
Normal file
@ -0,0 +1,651 @@
|
||||
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();
|
||||
});
|
@ -528,3 +528,8 @@ p#name {
|
||||
font-family: Fira Code;
|
||||
src: url(../src/fonts/FiraCode-Regular.ttf);
|
||||
}
|
||||
|
||||
/* 注释下面这三行以开启抗锯齿 */
|
||||
.anti-aliasing {
|
||||
image-rendering: pixelated;
|
||||
}
|
@ -1,9 +0,0 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"allowJs": true,
|
||||
"noEmit": true,
|
||||
},
|
||||
"include": [
|
||||
"main.js", "project/**/*.js", "libs/**/*.js", "runtime.d.ts"
|
||||
]
|
||||
}
|
Loading…
Reference in New Issue
Block a user