尝试搬运样板到2.10.3
This commit is contained in:
parent
0a8d854596
commit
dbf932519e
@ -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 {
|
.etableInputDiv textarea:hover {
|
||||||
margin: -5px;
|
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;
|
margin: -5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: Fira;
|
||||||
|
src: url(./FiraCode.ttf);
|
||||||
|
}
|
||||||
|
|
||||||
|
.main .CodeMirror {
|
||||||
|
font-family: Fira, Menlo, Consolas, 'Courier New', Courier, monospace;
|
||||||
|
}
|
||||||
|
@ -236,7 +236,15 @@ 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 () {
|
||||||
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);
|
codeEditor.setOption("autocomplete", editor_multi.lintAutocomplete);
|
||||||
document.getElementById("lintCheckbox").checked = editor_multi.lintAutocomplete;
|
document.getElementById("lintCheckbox").checked = editor_multi.lintAutocomplete;
|
||||||
}
|
}
|
||||||
@ -253,7 +261,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(js_beautify(codeEditor.getValue(), {
|
_setValue(beautifier.js(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
|
||||||
@ -486,6 +494,22 @@ 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();
|
@ -555,14 +555,20 @@ 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": "在横屏状态下是否隐藏左侧状态栏,从而获得仿RM的沉浸式体验"
|
"_data": "开启后道具栏会被挪动至游戏画面的下方"
|
||||||
|
},
|
||||||
|
"hideLeftStatusBar": {
|
||||||
|
"_leaf": true,
|
||||||
|
"_type": "checkbox",
|
||||||
|
"_docs": "隐藏左侧状态栏",
|
||||||
|
"_data": "是否隐藏左侧状态栏,开启后强制开启画面下方道具栏"
|
||||||
},
|
},
|
||||||
"flyNearStair": {
|
"flyNearStair": {
|
||||||
"_leaf": true,
|
"_leaf": true,
|
||||||
|
@ -242,6 +242,7 @@
|
|||||||
<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>
|
||||||
@ -251,6 +252,11 @@
|
|||||||
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 -->
|
||||||
|
@ -238,6 +238,7 @@
|
|||||||
<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>
|
||||||
@ -247,6 +248,11 @@
|
|||||||
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 -->
|
||||||
|
13
index.html
13
index.html
@ -1,10 +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' 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>
|
<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">
|
||||||
@ -19,6 +21,10 @@
|
|||||||
<div id='startImageBackgroundDiv'>
|
<div id='startImageBackgroundDiv'>
|
||||||
<div id='startImageDiv'></div>
|
<div id='startImageDiv'></div>
|
||||||
<img id='startImageLogo' />
|
<img id='startImageLogo' />
|
||||||
|
</div>
|
||||||
|
<!-- 状态栏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>
|
||||||
</div>
|
</div>
|
||||||
<script>
|
<script>
|
||||||
(function () {
|
(function () {
|
||||||
@ -61,7 +67,7 @@
|
|||||||
<div id='startButtonGroup'>
|
<div id='startButtonGroup'>
|
||||||
<div id='startButtons'>
|
<div id='startButtons'>
|
||||||
<span class='startButton' id='playGame'>开始游戏</span>
|
<span class='startButton' id='playGame'>开始游戏</span>
|
||||||
<span class='startButton' id='loadGame'>继续游戏</span>
|
<span class='startButton' id='loadGame'>载入游戏</span>
|
||||||
<span class='startButton' id='replayGame'>录像回放</span>
|
<span class='startButton' id='replayGame'>录像回放</span>
|
||||||
</div>
|
</div>
|
||||||
<div id='levelChooseButtons'></div>
|
<div id='levelChooseButtons'></div>
|
||||||
@ -143,7 +149,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 状态栏canvas化 -->
|
<!-- 状态栏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>
|
<canvas id="caidan1" style="position: absolute; left: 0; top: 0;"></canvas>
|
||||||
</div>
|
</div>
|
||||||
<div id="toolBar" class="clearfix">
|
<div id="toolBar" class="clearfix">
|
||||||
@ -200,4 +206,5 @@
|
|||||||
<script>main.init('play');main.listen();</script>
|
<script>main.init('play');main.listen();</script>
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
</html>
|
</html>
|
@ -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 = this.LAST / per_page;
|
var u = (core._HEIGHT_ - 1) / 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;
|
||||||
|
@ -18,6 +18,7 @@ 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);
|
||||||
@ -3046,22 +3047,27 @@ 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();
|
||||||
requestAnimationFrame(this.updateStatusBar_update)
|
if (!core.control.updateNextFrame) {
|
||||||
|
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()) {
|
||||||
@ -3265,9 +3271,10 @@ 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;
|
||||||
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)) {
|
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.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);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3317,7 +3325,8 @@ 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);
|
||||||
@ -3339,7 +3348,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.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);
|
totalHeight = obj.outerHeight + (obj.extendToolbar ? obj.TOOLBAR_HEIGHT * core.domStyle.scale + obj.BORDER : 0);
|
||||||
}
|
}
|
||||||
gameGroup.style.width = totalWidth + "px";
|
gameGroup.style.width = totalWidth + "px";
|
||||||
@ -3409,9 +3418,7 @@ 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;
|
||||||
var ratio = canvas.hasAttribute('isHD') ? core.domStyle.ratio : 1;
|
core.resizeCanvas(ctx, parseFloat(canvas.getAttribute("_width")), parseFloat(canvas.getAttribute("_height")))
|
||||||
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";
|
||||||
}
|
}
|
||||||
@ -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.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.extendToolbar) {
|
if (obj.hideLeftStatusBar) {
|
||||||
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.extendToolbar ? 'none' : 'block';
|
statusBar.style.display = obj.hideLeftStatusBar ? '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;
|
||||||
@ -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.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.extendToolbar ? "block" : "none";
|
core.dom.statusCanvas.style.display = core.flags.statusCanvas && !obj.hideLeftStatusBar ? "block" : "none";
|
||||||
}
|
}
|
||||||
|
|
||||||
control.prototype._resize_status = function (obj) {
|
control.prototype._resize_status = function (obj) {
|
||||||
@ -3464,7 +3471,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.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
|
// status
|
||||||
for (var i = 0; i < core.dom.status.length; ++i) {
|
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;
|
toolBar.style.background = obj.globalAttribute.toolsBackground;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (obj.extendToolbar) {
|
if (obj.extendToolbar || obj.hideLeftStatusBar) {
|
||||||
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";
|
||||||
|
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);
|
ctx.setTransform(1, 0, 0, 1, 0, 0);
|
||||||
var ratio = core.domStyle.ratio;
|
var ratio = core.domStyle.scale;
|
||||||
if (ctx === core.bigmap.tempCanvas) ratio = core.domStyle.scale;
|
ratio *= devicePixelRatio;
|
||||||
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);
|
||||||
@ -1728,18 +1727,20 @@ 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 * scale;
|
tempCanvas.canvas.width = width * 32;
|
||||||
tempCanvas.canvas.height = height * 32 * scale;
|
tempCanvas.canvas.height = height * 32;
|
||||||
} else core.resizeCanvas(tempCanvas, width * 32 * scale, height * 32 * scale, false, true);
|
tempCanvas.canvas.removeAttribute('isHD');
|
||||||
tempCanvas.scale(scale, scale);
|
} else {
|
||||||
|
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_;
|
||||||
} 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;
|
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);
|
||||||
@ -1751,7 +1752,8 @@ 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;
|
||||||
} 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;
|
options.ctx = tempCanvas;
|
||||||
|
|
||||||
@ -1813,6 +1815,7 @@ 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;
|
||||||
// 绘制全景图
|
// 绘制全景图
|
||||||
@ -1833,20 +1836,28 @@ maps.prototype._drawThumbnail_drawToTarget = function (floorId, options) {
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// 只绘制可见窗口
|
// 只绘制可见窗口
|
||||||
var pw = core._PX_, ph = core._PY_, hw = core._HALF_WIDTH_, hh = core._HALF_HEIGHT_, W = core._WIDTH_, H = core._HEIGHT_;
|
var pw = core._PX_,
|
||||||
var ratio = core.domStyle.isVertical ? core.domStyle.ratio : core.domStyle.scale;
|
ph = core._PY_,
|
||||||
if (main.mode == 'editor') { pw = ph = core.__PIXELS__; hw = hh = core.__HALF_SIZE__; W = H = core.__SIZE__; }
|
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) {
|
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 {
|
} 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);
|
||||||
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) {
|
if (x != null && y != null && width != null && height != null) {
|
||||||
ctx.clearRect(x, y, width, height);
|
ctx.clearRect(x, y, width, height);
|
||||||
} else {
|
} 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.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) {
|
if (config.isHD && ctx) {
|
||||||
core.maps._setHDCanvasSize(tempCtx, ctx.canvas.width, ctx.canvas.height);
|
core.maps._setHDCanvasSize(
|
||||||
|
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;
|
||||||
@ -1148,10 +1158,20 @@ 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) {
|
||||||
var ratio = config.isHD ? core.domStyle.ratio : 1;
|
// It works, why?
|
||||||
core.drawImage(ctx, tempCtx.canvas, block.left * ratio, block.top * ratio, block.width * ratio, block.height * ratio,
|
const scale = config.isHD ? devicePixelRatio * core.domStyle.scale : 1;
|
||||||
config.left + block.left + block.marginLeft, config.top + block.top + block.marginTop,
|
core.drawImage(
|
||||||
block.width, block.height);
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
@ -2512,23 +2532,24 @@ 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, 120, this._buildFont(19, true));
|
var lines = core.splitLines('ui', title, lastWidth, 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_ - 60, start_y, '#FFFFFF');
|
core.fillText('ui', lines[i], core._PX_ - lastWidth * 0.5, 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_ - 60, middle - 64, null, this._buildFont(17, false));
|
core.fillText('ui', '▲', core._PX_ - lastWidth * 0.5, middle - 64, null, this._buildFont(17, false));
|
||||||
core.fillText('ui', '▲', core._PX_ - 60, middle - 96);
|
core.fillText('ui', '▲', core._PX_ - lastWidth * 0.5, middle - 96);
|
||||||
core.fillText('ui', '▲', core._PX_ - 60, middle - 96 - 7);
|
core.fillText('ui', '▲', core._PX_ - lastWidth * 0.5, middle - 96 - 7);
|
||||||
}
|
}
|
||||||
if (core.actions._getNextFlyFloor(-1) != page) {
|
if (core.actions._getNextFlyFloor(-1) != page) {
|
||||||
core.fillText('ui', '▼', core._PX_ - 60, middle + 64, null, this._buildFont(17, false));
|
core.fillText('ui', '▼', core._PX_ - lastWidth * 0.5, middle + 64, null, this._buildFont(17, false));
|
||||||
core.fillText('ui', '▼', core._PX_ - 60, middle + 96);
|
core.fillText('ui', '▼', core._PX_ - lastWidth * 0.5, middle + 96);
|
||||||
core.fillText('ui', '▼', core._PX_ - 60, middle + 96 + 7);
|
core.fillText('ui', '▼', core._PX_ - lastWidth * 0.5, 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);
|
||||||
@ -3381,6 +3402,8 @@ 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';
|
||||||
@ -3439,16 +3462,21 @@ ui.prototype.rotateCanvas = function (name, angle, centerX, centerY) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
////// canvas重置 //////
|
////// canvas重置 //////
|
||||||
ui.prototype.resizeCanvas = function (name, width, height, styleOnly, isTempCanvas) {
|
ui.prototype.resizeCanvas = function (name, width, height, styleOnly) {
|
||||||
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) 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';
|
ctx.canvas.style.width = width * core.domStyle.scale + 'px';
|
||||||
|
canvas.setAttribute('_width', width);
|
||||||
}
|
}
|
||||||
if (height != null) {
|
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';
|
ctx.canvas.style.height = height * core.domStyle.scale + 'px';
|
||||||
|
canvas.setAttribute('_height', height);
|
||||||
}
|
}
|
||||||
return ctx;
|
return ctx;
|
||||||
}
|
}
|
||||||
|
@ -1595,6 +1595,7 @@ 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
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -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';
|
canvas.className = 'gameCanvas anti-aliasing';
|
||||||
// 编辑器模式下设置zIndex会导致加入的图层覆盖优先级过高
|
// 编辑器模式下设置zIndex会导致加入的图层覆盖优先级过高
|
||||||
if (main.mode != "editor") canvas.style.zIndex = zIndex || 0;
|
if (main.mode != "editor") canvas.style.zIndex = zIndex || 0;
|
||||||
// 将图层插入进游戏内容
|
// 将图层插入进游戏内容
|
||||||
|
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;
|
font-family: Fira Code;
|
||||||
src: url(../src/fonts/FiraCode-Regular.ttf);
|
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