V2.0 to Master
V2.0 to Master
1
.gitignore
vendored
@ -1,4 +1,5 @@
|
||||
.vscode
|
||||
*ce5eec52_2fa1_447b_8dad_764e267a7fab*
|
||||
|
||||
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm
|
||||
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
|
||||
|
||||
8
.idea/markdown-exported-files.xml
Normal file
@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="MarkdownExportedFiles">
|
||||
<htmlFiles />
|
||||
<imageFiles />
|
||||
<otherFiles />
|
||||
</component>
|
||||
</project>
|
||||
57
README.md
@ -16,29 +16,44 @@ HTML5 canvas制作的魔塔样板,支持全平台游戏!
|
||||
``` bash
|
||||
├── /_server/ # 为可视化地图编辑器提供一些支持的目录
|
||||
├── /docs/ # 文档目录
|
||||
├── /animates/ # 动画目录
|
||||
├── /images/ # 所有图片素材目录
|
||||
│ ├─ /常用素材/ # 可以被直接替换的素材
|
||||
│ └─ *.png # 对应的某个具体的图片素材
|
||||
├── /libs/ # JS源代码目录
|
||||
│ ├─ /floors/ # 剧本文件,记录了每个地图的数据和事件
|
||||
├── /libs/ # 系统库目录
|
||||
│ ├─ /thirdparty/ # 游戏所用到的第三方库文件
|
||||
│ ├─ core.js # 系统核心文件
|
||||
│ ├─ data.js # 记录了勇士的初始化信息、各个全局变量和全局Flag值
|
||||
│ ├─ enemys.js # 记录了怪物的信息,包括怪物的数据和特殊属性、伤害计算公式、临界值计算等。
|
||||
│ ├─ actions.js # 处理用户交互的文件
|
||||
│ ├─ core.js # 系统核心文件(游戏入口,接口&转发)
|
||||
│ ├─ control.js # 游戏逻辑控制
|
||||
│ ├─ data.js # 记录了一些初始化信息
|
||||
│ ├─ enemys.js # 记录了怪物的信息,包括特殊属性、伤害计算公式、临界值计算等。
|
||||
│ ├─ events.js # 处理事件的文件,所有自定义事件都会在此文件中进行处理
|
||||
│ ├─ icons.js # 记录了图标信息,将元件的ID和images目录下的素材图标对应起来
|
||||
│ ├─ items.js # 记录了道具的信息,包括道具说明、道具效果等。
|
||||
│ ├─ maps.js # 记录了地图信息,负责将数字与元件的ID一一对应起来。
|
||||
│ └─ ui.js # UI绘制信息,主要负责绘制各个UI窗口。
|
||||
├── /sounds/ # 音效目录
|
||||
│ ├─ icons.js # 记录了图标信息
|
||||
│ ├─ items.js # 道具的使用
|
||||
│ ├─ loader.js # 动态加载JS代码、图片、音效等
|
||||
│ ├─ maps.js # 记录了地图信息,和地图绘制等操作
|
||||
│ ├─ ui.js # UI绘制信息,主要负责绘制各个UI窗口。
|
||||
│ └─ utils.js # 工具类
|
||||
├── /project/ # 项目目录,用户需要在这里做自己的塔
|
||||
│ ├─ /animates/ # 动画目录
|
||||
│ ├─ /floors/ # 剧本文件,记录了每个地图的数据和事件
|
||||
│ ├─ /images/ # 所有图片素材目录
|
||||
│ │ ├─ /常用素材/ # 可以被直接替换的素材
|
||||
│ │ └─ *.png # 对应的某个具体的图片素材
|
||||
│ ├─ /sounds/ # 音效目录
|
||||
│ ├─ comments.js # 对怪物、道具、楼层等的注释
|
||||
│ ├─ data.comment.js # 对全局变量的注释
|
||||
│ ├─ data.js # 全局变量信息
|
||||
│ ├─ enemys.js # 怪物属性数据
|
||||
│ ├─ functions.comment.js # 脚本编辑的注释
|
||||
│ ├─ functions.js # 可能会被修改的脚本代码
|
||||
│ ├─ icons.js # 素材和ID的对应关系定义
|
||||
│ ├─ items.js # 道具的定义,获得道具的效果
|
||||
│ ├─ maps.commment.js # 地图信息的注释
|
||||
│ └─ maps.js # 地图和数字的对应关系
|
||||
├── /常用工具/ # 一些常用工具,可以辅助造塔
|
||||
│ ├─ RM动画导出器.exe # 能从RMXP中导出动画,以供H5使用。 http://github.com/ckcz123/animate_export/
|
||||
│ ├─ JS代码压缩工具.exe # 能对Javascript代码进行压缩和整合,从而减少IO请求量。 http://github.com/ckcz123/JSCompressor/
|
||||
│ ├─ 便捷PS工具.exe # 能只用复制和粘贴来快速对素材进行PS操作。 http://github.com/ckcz123/ps/
|
||||
│ ├─ 地图生成器.exe # 能从一张截图识别出来具体的数字数组,方便复刻已有的塔。 http://github.com/ckcz123/map_generator/
|
||||
│ └─ 伤害和临界值计算器.exe # 一个能帮助计算怪物的伤害和临界值的小工具。 http://github.com/ckcz123/magic-tower-calculator/
|
||||
├── drawMapGUI.html # 可视化地图编辑工具,能简单地在界面上绘制地图
|
||||
├── editor.html # 可视化地图编辑工具
|
||||
├── index.html # 主程序,游戏的入口
|
||||
├── main.js # JS程序的入口,将动态对所需JS进行加载
|
||||
├── style.css # 游戏所需要用到的样式表
|
||||
@ -47,6 +62,18 @@ HTML5 canvas制作的魔塔样板,支持全平台游戏!
|
||||
|
||||
## 更新说明
|
||||
|
||||
### 2018.3.14 V2.0
|
||||
|
||||
* [x] 全GUI造塔,现在用户无需打开任何文件直接编辑JS代码了。
|
||||
* [x] 整体改变目录架构,将数据和逻辑进行分离
|
||||
* [x] 支持48x32的怪物和NPC素材
|
||||
* [x] 加点改成系统开关进行处理,怪物手册会列出加点值
|
||||
* [x] 支持带有血量上限的塔
|
||||
* [x] 增加前景图片绘制
|
||||
* [x] 便捷PS工具对于非标准的图片可以自动进行调整
|
||||
* [x] 录像存储机制进行修改,对于道具记录全ID
|
||||
* [x] 其他细节的优化
|
||||
|
||||
### 2018.2.9 V1.4.1
|
||||
|
||||
* [x] 改变图块(setBlock事件)。
|
||||
|
||||
21
_server/CodeMirror/LICENSE
Normal file
@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (C) 2017 by Marijn Haverbeke <marijnh@gmail.com> and others
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
1
_server/CodeMirror/codeMirror.bundle.min.js
vendored
Normal file
346
_server/CodeMirror/codemirror.css
Normal file
@ -0,0 +1,346 @@
|
||||
/* BASICS */
|
||||
|
||||
.CodeMirror {
|
||||
/* Set height, width, borders, and global font properties here */
|
||||
font-family: monospace;
|
||||
height: 300px;
|
||||
color: black;
|
||||
direction: ltr;
|
||||
}
|
||||
|
||||
/* PADDING */
|
||||
|
||||
.CodeMirror-lines {
|
||||
padding: 4px 0; /* Vertical padding around content */
|
||||
}
|
||||
.CodeMirror pre {
|
||||
padding: 0 4px; /* Horizontal padding of content */
|
||||
}
|
||||
|
||||
.CodeMirror-scrollbar-filler, .CodeMirror-gutter-filler {
|
||||
background-color: white; /* The little square between H and V scrollbars */
|
||||
}
|
||||
|
||||
/* GUTTER */
|
||||
|
||||
.CodeMirror-gutters {
|
||||
border-right: 1px solid #ddd;
|
||||
background-color: #f7f7f7;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.CodeMirror-linenumbers {}
|
||||
.CodeMirror-linenumber {
|
||||
padding: 0 3px 0 5px;
|
||||
min-width: 20px;
|
||||
text-align: right;
|
||||
color: #999;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.CodeMirror-guttermarker { color: black; }
|
||||
.CodeMirror-guttermarker-subtle { color: #999; }
|
||||
|
||||
/* CURSOR */
|
||||
|
||||
.CodeMirror-cursor {
|
||||
border-left: 1px solid black;
|
||||
border-right: none;
|
||||
width: 0;
|
||||
}
|
||||
/* Shown when moving in bi-directional text */
|
||||
.CodeMirror div.CodeMirror-secondarycursor {
|
||||
border-left: 1px solid silver;
|
||||
}
|
||||
.cm-fat-cursor .CodeMirror-cursor {
|
||||
width: auto;
|
||||
border: 0 !important;
|
||||
background: #7e7;
|
||||
}
|
||||
.cm-fat-cursor div.CodeMirror-cursors {
|
||||
z-index: 1;
|
||||
}
|
||||
.cm-fat-cursor-mark {
|
||||
background-color: rgba(20, 255, 20, 0.5);
|
||||
-webkit-animation: blink 1.06s steps(1) infinite;
|
||||
-moz-animation: blink 1.06s steps(1) infinite;
|
||||
animation: blink 1.06s steps(1) infinite;
|
||||
}
|
||||
.cm-animate-fat-cursor {
|
||||
width: auto;
|
||||
border: 0;
|
||||
-webkit-animation: blink 1.06s steps(1) infinite;
|
||||
-moz-animation: blink 1.06s steps(1) infinite;
|
||||
animation: blink 1.06s steps(1) infinite;
|
||||
background-color: #7e7;
|
||||
}
|
||||
@-moz-keyframes blink {
|
||||
0% {}
|
||||
50% { background-color: transparent; }
|
||||
100% {}
|
||||
}
|
||||
@-webkit-keyframes blink {
|
||||
0% {}
|
||||
50% { background-color: transparent; }
|
||||
100% {}
|
||||
}
|
||||
@keyframes blink {
|
||||
0% {}
|
||||
50% { background-color: transparent; }
|
||||
100% {}
|
||||
}
|
||||
|
||||
/* Can style cursor different in overwrite (non-insert) mode */
|
||||
.CodeMirror-overwrite .CodeMirror-cursor {}
|
||||
|
||||
.cm-tab { display: inline-block; text-decoration: inherit; }
|
||||
|
||||
.CodeMirror-rulers {
|
||||
position: absolute;
|
||||
left: 0; right: 0; top: -50px; bottom: -20px;
|
||||
overflow: hidden;
|
||||
}
|
||||
.CodeMirror-ruler {
|
||||
border-left: 1px solid #ccc;
|
||||
top: 0; bottom: 0;
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
/* DEFAULT THEME */
|
||||
|
||||
.cm-s-default .cm-header {color: blue;}
|
||||
.cm-s-default .cm-quote {color: #090;}
|
||||
.cm-negative {color: #d44;}
|
||||
.cm-positive {color: #292;}
|
||||
.cm-header, .cm-strong {font-weight: bold;}
|
||||
.cm-em {font-style: italic;}
|
||||
.cm-link {text-decoration: underline;}
|
||||
.cm-strikethrough {text-decoration: line-through;}
|
||||
|
||||
.cm-s-default .cm-keyword {color: #708;}
|
||||
.cm-s-default .cm-atom {color: #219;}
|
||||
.cm-s-default .cm-number {color: #164;}
|
||||
.cm-s-default .cm-def {color: #00f;}
|
||||
.cm-s-default .cm-variable,
|
||||
.cm-s-default .cm-punctuation,
|
||||
.cm-s-default .cm-property,
|
||||
.cm-s-default .cm-operator {}
|
||||
.cm-s-default .cm-variable-2 {color: #05a;}
|
||||
.cm-s-default .cm-variable-3, .cm-s-default .cm-type {color: #085;}
|
||||
.cm-s-default .cm-comment {color: #a50;}
|
||||
.cm-s-default .cm-string {color: #a11;}
|
||||
.cm-s-default .cm-string-2 {color: #f50;}
|
||||
.cm-s-default .cm-meta {color: #555;}
|
||||
.cm-s-default .cm-qualifier {color: #555;}
|
||||
.cm-s-default .cm-builtin {color: #30a;}
|
||||
.cm-s-default .cm-bracket {color: #997;}
|
||||
.cm-s-default .cm-tag {color: #170;}
|
||||
.cm-s-default .cm-attribute {color: #00c;}
|
||||
.cm-s-default .cm-hr {color: #999;}
|
||||
.cm-s-default .cm-link {color: #00c;}
|
||||
|
||||
.cm-s-default .cm-error {color: #f00;}
|
||||
.cm-invalidchar {color: #f00;}
|
||||
|
||||
.CodeMirror-composing { border-bottom: 2px solid; }
|
||||
|
||||
/* Default styles for common addons */
|
||||
|
||||
div.CodeMirror span.CodeMirror-matchingbracket {color: #0b0;}
|
||||
div.CodeMirror span.CodeMirror-nonmatchingbracket {color: #a22;}
|
||||
.CodeMirror-matchingtag { background: rgba(255, 150, 0, .3); }
|
||||
.CodeMirror-activeline-background {background: #e8f2ff;}
|
||||
|
||||
/* STOP */
|
||||
|
||||
/* The rest of this file contains styles related to the mechanics of
|
||||
the editor. You probably shouldn't touch them. */
|
||||
|
||||
.CodeMirror {
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
background: white;
|
||||
}
|
||||
|
||||
.CodeMirror-scroll {
|
||||
overflow: scroll !important; /* Things will break if this is overridden */
|
||||
/* 30px is the magic margin used to hide the element's real scrollbars */
|
||||
/* See overflow: hidden in .CodeMirror */
|
||||
margin-bottom: -30px; margin-right: -30px;
|
||||
padding-bottom: 30px;
|
||||
height: 100%;
|
||||
outline: none; /* Prevent dragging from highlighting the element */
|
||||
position: relative;
|
||||
}
|
||||
.CodeMirror-sizer {
|
||||
position: relative;
|
||||
border-right: 30px solid transparent;
|
||||
}
|
||||
|
||||
/* The fake, visible scrollbars. Used to force redraw during scrolling
|
||||
before actual scrolling happens, thus preventing shaking and
|
||||
flickering artifacts. */
|
||||
.CodeMirror-vscrollbar, .CodeMirror-hscrollbar, .CodeMirror-scrollbar-filler, .CodeMirror-gutter-filler {
|
||||
position: absolute;
|
||||
z-index: 6;
|
||||
display: none;
|
||||
}
|
||||
.CodeMirror-vscrollbar {
|
||||
right: 0; top: 0;
|
||||
overflow-x: hidden;
|
||||
overflow-y: scroll;
|
||||
}
|
||||
.CodeMirror-hscrollbar {
|
||||
bottom: 0; left: 0;
|
||||
overflow-y: hidden;
|
||||
overflow-x: scroll;
|
||||
}
|
||||
.CodeMirror-scrollbar-filler {
|
||||
right: 0; bottom: 0;
|
||||
}
|
||||
.CodeMirror-gutter-filler {
|
||||
left: 0; bottom: 0;
|
||||
}
|
||||
|
||||
.CodeMirror-gutters {
|
||||
position: absolute; left: 0; top: 0;
|
||||
min-height: 100%;
|
||||
z-index: 3;
|
||||
}
|
||||
.CodeMirror-gutter {
|
||||
white-space: normal;
|
||||
height: 100%;
|
||||
display: inline-block;
|
||||
vertical-align: top;
|
||||
margin-bottom: -30px;
|
||||
}
|
||||
.CodeMirror-gutter-wrapper {
|
||||
position: absolute;
|
||||
z-index: 4;
|
||||
background: none !important;
|
||||
border: none !important;
|
||||
}
|
||||
.CodeMirror-gutter-background {
|
||||
position: absolute;
|
||||
top: 0; bottom: 0;
|
||||
z-index: 4;
|
||||
}
|
||||
.CodeMirror-gutter-elt {
|
||||
position: absolute;
|
||||
cursor: default;
|
||||
z-index: 4;
|
||||
}
|
||||
.CodeMirror-gutter-wrapper ::selection { background-color: transparent }
|
||||
.CodeMirror-gutter-wrapper ::-moz-selection { background-color: transparent }
|
||||
|
||||
.CodeMirror-lines {
|
||||
cursor: text;
|
||||
min-height: 1px; /* prevents collapsing before first draw */
|
||||
}
|
||||
.CodeMirror pre {
|
||||
/* Reset some styles that the rest of the page might have set */
|
||||
-moz-border-radius: 0; -webkit-border-radius: 0; border-radius: 0;
|
||||
border-width: 0;
|
||||
background: transparent;
|
||||
font-family: inherit;
|
||||
font-size: inherit;
|
||||
margin: 0;
|
||||
white-space: pre;
|
||||
word-wrap: normal;
|
||||
line-height: inherit;
|
||||
color: inherit;
|
||||
z-index: 2;
|
||||
position: relative;
|
||||
overflow: visible;
|
||||
-webkit-tap-highlight-color: transparent;
|
||||
-webkit-font-variant-ligatures: contextual;
|
||||
font-variant-ligatures: contextual;
|
||||
}
|
||||
.CodeMirror-wrap pre {
|
||||
word-wrap: break-word;
|
||||
white-space: pre-wrap;
|
||||
word-break: normal;
|
||||
}
|
||||
|
||||
.CodeMirror-linebackground {
|
||||
position: absolute;
|
||||
left: 0; right: 0; top: 0; bottom: 0;
|
||||
z-index: 0;
|
||||
}
|
||||
|
||||
.CodeMirror-linewidget {
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
padding: 0.1px; /* Force widget margins to stay inside of the container */
|
||||
}
|
||||
|
||||
.CodeMirror-widget {}
|
||||
|
||||
.CodeMirror-rtl pre { direction: rtl; }
|
||||
|
||||
.CodeMirror-code {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
/* Force content-box sizing for the elements where we expect it */
|
||||
.CodeMirror-scroll,
|
||||
.CodeMirror-sizer,
|
||||
.CodeMirror-gutter,
|
||||
.CodeMirror-gutters,
|
||||
.CodeMirror-linenumber {
|
||||
-moz-box-sizing: content-box;
|
||||
box-sizing: content-box;
|
||||
}
|
||||
|
||||
.CodeMirror-measure {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 0;
|
||||
overflow: hidden;
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
.CodeMirror-cursor {
|
||||
position: absolute;
|
||||
pointer-events: none;
|
||||
}
|
||||
.CodeMirror-measure pre { position: static; }
|
||||
|
||||
div.CodeMirror-cursors {
|
||||
visibility: hidden;
|
||||
position: relative;
|
||||
z-index: 3;
|
||||
}
|
||||
div.CodeMirror-dragcursors {
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
.CodeMirror-focused div.CodeMirror-cursors {
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
.CodeMirror-selected { background: #d9d9d9; }
|
||||
.CodeMirror-focused .CodeMirror-selected { background: #d7d4f0; }
|
||||
.CodeMirror-crosshair { cursor: crosshair; }
|
||||
.CodeMirror-line::selection, .CodeMirror-line > span::selection, .CodeMirror-line > span > span::selection { background: #d7d4f0; }
|
||||
.CodeMirror-line::-moz-selection, .CodeMirror-line > span::-moz-selection, .CodeMirror-line > span > span::-moz-selection { background: #d7d4f0; }
|
||||
|
||||
.cm-searching {
|
||||
background-color: #ffa;
|
||||
background-color: rgba(255, 255, 0, .4);
|
||||
}
|
||||
|
||||
/* Used to force a border model for a node */
|
||||
.cm-force-border { padding-right: .1px; }
|
||||
|
||||
@media print {
|
||||
/* Hide the cursor when printing */
|
||||
.CodeMirror div.CodeMirror-cursors {
|
||||
visibility: hidden;
|
||||
}
|
||||
}
|
||||
|
||||
/* See issue #2901 */
|
||||
.cm-tab-wrap-hack:after { content: ''; }
|
||||
|
||||
/* Help users use markselection to safely style text background */
|
||||
span.CodeMirror-selectedtext { background: none; }
|
||||
184
_server/README.md
Normal file
@ -0,0 +1,184 @@
|
||||
# editor
|
||||
|
||||
本目录下所有文件,以及`../editor.html`和`../启动服务.exe`([源码](http://github.com/ckcz123/mota-js-server/))是地图编辑器的所有组件.
|
||||
|
||||
`editor.js`,`editor_file.js`和`editor_mode.js`耦合较强,`editor_blockly.js`和`editor_multi.js`和`fs.js`基本可以独立使用.
|
||||
|
||||
## 各组件功能
|
||||
|
||||
### 总体上
|
||||
|
||||
以`display:none`的形式引入了`index.html`的`dom`,修改了原来的`.gameCanvas #ui #data`等的名字以避免冲突
|
||||
|
||||
通过`main.init('editor')`加载数据
|
||||
|
||||
`editor`模式关闭了部分动画
|
||||
|
||||
`core.drawMap`中`editor`模式下不再画图,而是生成画图的函数提供给`editor`
|
||||
|
||||
`editor`模式下`GlobalAnimate`可以独立的选择是否播放
|
||||
|
||||
`core.playBgm`和`core.playSound`中非`play`模式不再播放声音
|
||||
|
||||
`core.show`和`core.hide`中非`play`模式不再进行动画而是立刻完成并执行回调
|
||||
|
||||
`editor`模式不执行`core.resize`
|
||||
|
||||
### editor.js
|
||||
|
||||
``` js
|
||||
editor.mapInit();//清空地图
|
||||
editor.changeFloor('MT2')//切换地图
|
||||
editor.guid()//产生一个可以作为id的长随机字符串
|
||||
```
|
||||
|
||||
`editor.updateMap`中画未定义快的报错
|
||||
|
||||
### editor_file.js
|
||||
|
||||
提供了以下函数进行楼层`map`数组相关的操作
|
||||
```javascript
|
||||
editor.file.getFloorFileList
|
||||
editor.file.loadFloorFile
|
||||
editor.file.saveFloorFile
|
||||
editor.file.saveFloorFileAs
|
||||
```
|
||||
|
||||
编辑模式有关的查询
|
||||
```javascript
|
||||
editor.file.editItem('redJewel',[],function(a){console.log(a)});
|
||||
editor.file.editEnemy('redBat',[],function(a){console.log(a)});
|
||||
editor.file.editLoc(2,0,[],function(a){console.log(a)});
|
||||
editor.file.editFloor([],function(a){console.log(a)});
|
||||
editor.file.editTower([],function(a){console.log(a)});
|
||||
editor.file.editFunctions([],function(a){console.log(a)});
|
||||
```
|
||||
|
||||
编辑模式有关的编辑
|
||||
```javascript
|
||||
editor.info={images: "terrains", y: 9};
|
||||
editor.file.changeIdAndIdnum('yellowWall2',16,editor.info,function(a){console.log(a)});
|
||||
editor.file.editItem('book',[["change","['items']['name']","怪物手册的新名字"]],function(a){console.log(a)});
|
||||
editor.file.editEnemy('redBat',[['change',"['atk']",20]],function(a){console.log(a)});
|
||||
editor.file.editLoc(2,6,[["change","['afterBattle']",null]],function(a){console.log(a)});
|
||||
editor.file.editFloor([["change","['title']",'样板 33 层']],function(a){console.log(a)});
|
||||
editor.file.editTower([["change","['values']['lavaDamage']",200]],function(a){console.log(a)});
|
||||
editor.file.editFunctions(["change","['events']['afterChangeLight']","function(x,y){console.log(x,y)}"],function(a){console.log(a)});
|
||||
```
|
||||
|
||||
### editor_mode.js
|
||||
生成表格并绑定事件的函数
|
||||
```javascript
|
||||
editor.mode.loc();
|
||||
editor.mode.emenyitem();
|
||||
editor.mode.floor();
|
||||
editor.mode.tower();
|
||||
editor.mode.functions();
|
||||
```
|
||||
|
||||
切换模式
|
||||
```javascript
|
||||
editor.mode.onmode('');//清空
|
||||
editor.mode.onmode('save');//保存
|
||||
editor.mode.onmode('nextChange');//下次onmode时前端进行切换
|
||||
|
||||
editor.mode.onmode('loc');
|
||||
editor.mode.onmode('emenyitem');
|
||||
editor.mode.onmode('floor');
|
||||
editor.mode.onmode('tower');
|
||||
editor.mode.onmode('functions');
|
||||
editor.mode.onmode('map');
|
||||
editor.mode.onmode('appendpic');
|
||||
```
|
||||
在`onmode('save')`时,改动才会保存到文件,涉及到图片的改动需要刷新页面使得`editor`能看到
|
||||
|
||||
表格的`onchange`的实现中,获得当前模式的方式.不注意的话,修改`index.html`中页面的结构,会被坑
|
||||
```javascript
|
||||
var node = thisTr.parentNode;
|
||||
while (!editor_mode._ids.hasOwnProperty(node.getAttribute('id'))) {
|
||||
node = node.parentNode;
|
||||
}
|
||||
editor_mode.onmode(editor_mode._ids[node.getAttribute('id')]);
|
||||
```
|
||||
|
||||
`editor.mode.listen`中提供了追加素材的支持.
|
||||
|
||||
处理注释的特殊指令
|
||||
```
|
||||
$range(evalstr:thiseval)$end
|
||||
限制取值范围,要求修改后的eval(evalstr)为true
|
||||
$leaf(evalstr:thiseval)$end
|
||||
强制指定为叶节点,如果eval(evalstr)为true
|
||||
|
||||
//以下几个中选一个 [
|
||||
$select(evalstr)$end
|
||||
渲染成<select>,选项为数组eval(evalstr)['values']
|
||||
$input(evalstr)$end
|
||||
渲染成<input>
|
||||
$textarea(evalstr)$end
|
||||
渲染成<textarea>
|
||||
默认选项为$textarea()$end
|
||||
// ]
|
||||
```
|
||||
|
||||
### editor_blockly.js
|
||||
|
||||
把选定`id_`的事件用blockly编辑
|
||||
``` js
|
||||
editor_blockly.import(id_);
|
||||
```
|
||||
|
||||
把文本区域的代码转换成图块
|
||||
``` js
|
||||
editor_blockly.parse();
|
||||
```
|
||||
|
||||
### editor_multi.js
|
||||
|
||||
用[CodeMirror](https://github.com/codemirror/CodeMirror) 实现有高亮的多行文本编辑
|
||||
|
||||
编辑选定`id_`的文本域
|
||||
``` js
|
||||
editor_multi.import(id_)
|
||||
```
|
||||
|
||||
编辑blockly方块的特定域
|
||||
``` js
|
||||
editor_multi.multiLineEdit(value,b,f,callback)
|
||||
```
|
||||
|
||||
### fs.js
|
||||
|
||||
模仿node的fs模块提供如下api,与`启动服务.exe`配合为js提供文件读写功能
|
||||
``` js
|
||||
fs.readFile('file.in','utf-8',callback)
|
||||
//读文本文件
|
||||
//callback:function(err, data)
|
||||
//data:字符串
|
||||
fs.readFile('file.in','base64',callback)
|
||||
//读二进制文件
|
||||
//callback:function(err, data)
|
||||
//data:base64字符串
|
||||
|
||||
fs.writeFile('file.out', data ,'utf-8', callback)
|
||||
//写文本文件
|
||||
//callback:function(err)
|
||||
//data:字符串
|
||||
fs.writeFile('file.out', data ,'base64', callback)
|
||||
//写二进制文件
|
||||
//callback:function(err)
|
||||
//data:base64字符串
|
||||
|
||||
fs.readdir(path, callback)
|
||||
//callback:function(err, data)
|
||||
//path:支持"/"做分隔符
|
||||
//data:[filename1,filename2,..] filename是字符串,只包含文件不包含目录
|
||||
|
||||
//所有参数不允许缺省
|
||||
```
|
||||
|
||||
## z-index
|
||||
|
||||
目前主体部分使用了 0-15,75,100
|
||||
|
||||
blockly使用 200 ,多行文本编辑器使用 300
|
||||
1
_server/blockly/Converter.bundle.min.js
vendored
Normal file
177
_server/blockly/LICENSE
Normal file
@ -0,0 +1,177 @@
|
||||
|
||||
Apache License
|
||||
Version 2.0, January 2011
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
1456
_server/blockly/MotaAction.g4
Normal file
21
_server/blockly/NOTICE.md
Normal file
@ -0,0 +1,21 @@
|
||||
# NOTICE
|
||||
files
|
||||
`blockly_compressed.js`
|
||||
`blocks_compressed.js`
|
||||
`javascript_compressed.js`
|
||||
`zh-hans.js`
|
||||
`media/*`
|
||||
copyed from
|
||||
https://github.com/google/blockly.git
|
||||
|
||||
|
||||
### diff in blockly code
|
||||
blocks_compressed.js
|
||||
line 44 ~ 48
|
||||
```javascript
|
||||
// change by zhaouv @ logic_compare output : "Boolean" -> null
|
||||
colour:"%{BKY_LOGIC_HUE}",tooltip:"%{BKYCONTROLS_IF_TOOLTIP_2}",helpUrl:"%{BKY_CONTROLS_IF_HELPURL}",extensions:["controls_if_tooltip"]},{type:"logic_compare",message0:"%1 %2 %3",args0:[{type:"input_value",name:"A"},{type:"field_dropdown",name:"OP",options:[["=","EQ"],["\u2260","NEQ"],["<","LT"],["\u2264","LTE"],[">","GT"],["\u2265","GTE"]]},{type:"input_value",name:"B"}],inputsInline:!0,output:null,colour:"%{BKY_LOGIC_HUE}",helpUrl:"%{BKY_LOGIC_COMPARE_HELPURL}",extensions:["logic_compare",
|
||||
// change by zhaouv @ logic_operation output,check : "Boolean" -> null
|
||||
// change by zhaouv @ logic_negate output,check : "Boolean" -> null
|
||||
"logic_op_tooltip"]},{type:"logic_operation",message0:"%1 %2 %3",args0:[{type:"input_value",name:"A",check:null},{type:"field_dropdown",name:"OP",options:[["%{BKY_LOGIC_OPERATION_AND}","AND"],["%{BKY_LOGIC_OPERATION_OR}","OR"]]},{type:"input_value",name:"B",check:null}],inputsInline:!0,output:null,colour:"%{BKY_LOGIC_HUE}",helpUrl:"%{BKY_LOGIC_OPERATION_HELPURL}",extensions:["logic_op_tooltip"]},{type:"logic_negate",message0:"%{BKY_LOGIC_NEGATE_TITLE}",args0:[{type:"input_value",name:"BOOL",
|
||||
```
|
||||
1604
_server/blockly/blockly_compressed.js
Normal file
159
_server/blockly/blocks_compressed.js
Normal file
@ -0,0 +1,159 @@
|
||||
// Do not edit this file; automatically generated by build.py.
|
||||
'use strict';
|
||||
|
||||
|
||||
Blockly.Blocks.colour={};Blockly.Constants={};Blockly.Constants.Colour={};Blockly.Constants.Colour.HUE=20;Blockly.Blocks.colour.HUE=Blockly.Constants.Colour.HUE;
|
||||
Blockly.defineBlocksWithJsonArray([{type:"colour_picker",message0:"%1",args0:[{type:"field_colour",name:"COLOUR",colour:"#ff0000"}],output:"Colour",colour:"%{BKY_COLOUR_HUE}",helpUrl:"%{BKY_COLOUR_PICKER_HELPURL}",tooltip:"%{BKY_COLOUR_PICKER_TOOLTIP}",extensions:["parent_tooltip_when_inline"]},{type:"colour_random",message0:"%{BKY_COLOUR_RANDOM_TITLE}",output:"Colour",colour:"%{BKY_COLOUR_HUE}",helpUrl:"%{BKY_COLOUR_RANDOM_HELPURL}",tooltip:"%{BKY_COLOUR_RANDOM_TOOLTIP}"},{type:"colour_rgb",message0:"%{BKY_COLOUR_RGB_TITLE} %{BKY_COLOUR_RGB_RED} %1 %{BKY_COLOUR_RGB_GREEN} %2 %{BKY_COLOUR_RGB_BLUE} %3",
|
||||
args0:[{type:"input_value",name:"RED",check:"Number",align:"RIGHT"},{type:"input_value",name:"GREEN",check:"Number",align:"RIGHT"},{type:"input_value",name:"BLUE",check:"Number",align:"RIGHT"}],output:"Colour",colour:"%{BKY_COLOUR_HUE}",helpUrl:"%{BKY_COLOUR_RGB_HELPURL}",tooltip:"%{BKY_COLOUR_RGB_TOOLTIP}"},{type:"colour_blend",message0:"%{BKY_COLOUR_BLEND_TITLE} %{BKY_COLOUR_BLEND_COLOUR1} %1 %{BKY_COLOUR_BLEND_COLOUR2} %2 %{BKY_COLOUR_BLEND_RATIO} %3",args0:[{type:"input_value",name:"COLOUR1",
|
||||
check:"Colour",align:"RIGHT"},{type:"input_value",name:"COLOUR2",check:"Colour",align:"RIGHT"},{type:"input_value",name:"RATIO",check:"Number",align:"RIGHT"}],output:"Colour",colour:"%{BKY_COLOUR_HUE}",helpUrl:"%{BKY_COLOUR_BLEND_HELPURL}",tooltip:"%{BKY_COLOUR_BLEND_TOOLTIP}"}]);Blockly.Blocks.lists={};Blockly.Constants.Lists={};Blockly.Constants.Lists.HUE=260;Blockly.Blocks.lists.HUE=Blockly.Constants.Lists.HUE;
|
||||
Blockly.defineBlocksWithJsonArray([{type:"lists_create_empty",message0:"%{BKY_LISTS_CREATE_EMPTY_TITLE}",output:"Array",colour:"%{BKY_LISTS_HUE}",tooltip:"%{BKY_LISTS_CREATE_EMPTY_TOOLTIP}",helpUrl:"%{BKY_LISTS_CREATE_EMPTY_HELPURL}"},{type:"lists_repeat",message0:"%{BKY_LISTS_REPEAT_TITLE}",args0:[{type:"input_value",name:"ITEM"},{type:"input_value",name:"NUM",check:"Number"}],output:"Array",colour:"%{BKY_LISTS_HUE}",tooltip:"%{BKY_LISTS_REPEAT_TOOLTIP}",helpUrl:"%{BKY_LISTS_REPEAT_HELPURL}"},{type:"lists_reverse",
|
||||
message0:"%{BKY_LISTS_REVERSE_MESSAGE0}",args0:[{type:"input_value",name:"LIST",check:"Array"}],output:"Array",inputsInline:!0,colour:"%{BKY_LISTS_HUE}",tooltip:"%{BKY_LISTS_REVERSE_TOOLTIP}",helpUrl:"%{BKY_LISTS_REVERSE_HELPURL}"},{type:"lists_isEmpty",message0:"%{BKY_LISTS_ISEMPTY_TITLE}",args0:[{type:"input_value",name:"VALUE",check:["String","Array"]}],output:"Boolean",colour:"%{BKY_LISTS_HUE}",tooltip:"%{BKY_LISTS_ISEMPTY_TOOLTIP}",helpUrl:"%{BKY_LISTS_ISEMPTY_HELPURL}"},{type:"lists_length",
|
||||
message0:"%{BKY_LISTS_LENGTH_TITLE}",args0:[{type:"input_value",name:"VALUE",check:["String","Array"]}],output:"Number",colour:"%{BKY_LISTS_HUE}",tooltip:"%{BKY_LISTS_LENGTH_TOOLTIP}",helpUrl:"%{BKY_LISTS_LENGTH_HELPURL}"}]);
|
||||
Blockly.Blocks.lists_create_with={init:function(){this.setHelpUrl(Blockly.Msg.LISTS_CREATE_WITH_HELPURL);this.setColour(Blockly.Blocks.lists.HUE);this.itemCount_=3;this.updateShape_();this.setOutput(!0,"Array");this.setMutator(new Blockly.Mutator(["lists_create_with_item"]));this.setTooltip(Blockly.Msg.LISTS_CREATE_WITH_TOOLTIP)},mutationToDom:function(){var a=document.createElement("mutation");a.setAttribute("items",this.itemCount_);return a},domToMutation:function(a){this.itemCount_=parseInt(a.getAttribute("items"),
|
||||
10);this.updateShape_()},decompose:function(a){var b=a.newBlock("lists_create_with_container");b.initSvg();for(var c=b.getInput("STACK").connection,d=0;d<this.itemCount_;d++){var e=a.newBlock("lists_create_with_item");e.initSvg();c.connect(e.previousConnection);c=e.nextConnection}return b},compose:function(a){var b=a.getInputTargetBlock("STACK");for(a=[];b;)a.push(b.valueConnection_),b=b.nextConnection&&b.nextConnection.targetBlock();for(b=0;b<this.itemCount_;b++){var c=this.getInput("ADD"+b).connection.targetConnection;
|
||||
c&&-1==a.indexOf(c)&&c.disconnect()}this.itemCount_=a.length;this.updateShape_();for(b=0;b<this.itemCount_;b++)Blockly.Mutator.reconnect(a[b],this,"ADD"+b)},saveConnections:function(a){a=a.getInputTargetBlock("STACK");for(var b=0;a;){var c=this.getInput("ADD"+b);a.valueConnection_=c&&c.connection.targetConnection;b++;a=a.nextConnection&&a.nextConnection.targetBlock()}},updateShape_:function(){this.itemCount_&&this.getInput("EMPTY")?this.removeInput("EMPTY"):this.itemCount_||this.getInput("EMPTY")||
|
||||
this.appendDummyInput("EMPTY").appendField(Blockly.Msg.LISTS_CREATE_EMPTY_TITLE);for(var a=0;a<this.itemCount_;a++)if(!this.getInput("ADD"+a)){var b=this.appendValueInput("ADD"+a);0==a&&b.appendField(Blockly.Msg.LISTS_CREATE_WITH_INPUT_WITH)}for(;this.getInput("ADD"+a);)this.removeInput("ADD"+a),a++}};
|
||||
Blockly.Blocks.lists_create_with_container={init:function(){this.setColour(Blockly.Blocks.lists.HUE);this.appendDummyInput().appendField(Blockly.Msg.LISTS_CREATE_WITH_CONTAINER_TITLE_ADD);this.appendStatementInput("STACK");this.setTooltip(Blockly.Msg.LISTS_CREATE_WITH_CONTAINER_TOOLTIP);this.contextMenu=!1}};
|
||||
Blockly.Blocks.lists_create_with_item={init:function(){this.setColour(Blockly.Blocks.lists.HUE);this.appendDummyInput().appendField(Blockly.Msg.LISTS_CREATE_WITH_ITEM_TITLE);this.setPreviousStatement(!0);this.setNextStatement(!0);this.setTooltip(Blockly.Msg.LISTS_CREATE_WITH_ITEM_TOOLTIP);this.contextMenu=!1}};
|
||||
Blockly.Blocks.lists_indexOf={init:function(){var a=[[Blockly.Msg.LISTS_INDEX_OF_FIRST,"FIRST"],[Blockly.Msg.LISTS_INDEX_OF_LAST,"LAST"]];this.setHelpUrl(Blockly.Msg.LISTS_INDEX_OF_HELPURL);this.setColour(Blockly.Blocks.lists.HUE);this.setOutput(!0,"Number");this.appendValueInput("VALUE").setCheck("Array").appendField(Blockly.Msg.LISTS_INDEX_OF_INPUT_IN_LIST);this.appendValueInput("FIND").appendField(new Blockly.FieldDropdown(a),"END");this.setInputsInline(!0);var b=this;this.setTooltip(function(){return Blockly.Msg.LISTS_INDEX_OF_TOOLTIP.replace("%1",
|
||||
b.workspace.options.oneBasedIndex?"0":"-1")})}};
|
||||
Blockly.Blocks.lists_getIndex={init:function(){var a=[[Blockly.Msg.LISTS_GET_INDEX_GET,"GET"],[Blockly.Msg.LISTS_GET_INDEX_GET_REMOVE,"GET_REMOVE"],[Blockly.Msg.LISTS_GET_INDEX_REMOVE,"REMOVE"]];this.WHERE_OPTIONS=[[Blockly.Msg.LISTS_GET_INDEX_FROM_START,"FROM_START"],[Blockly.Msg.LISTS_GET_INDEX_FROM_END,"FROM_END"],[Blockly.Msg.LISTS_GET_INDEX_FIRST,"FIRST"],[Blockly.Msg.LISTS_GET_INDEX_LAST,"LAST"],[Blockly.Msg.LISTS_GET_INDEX_RANDOM,"RANDOM"]];this.setHelpUrl(Blockly.Msg.LISTS_GET_INDEX_HELPURL);this.setColour(Blockly.Blocks.lists.HUE);
|
||||
a=new Blockly.FieldDropdown(a,function(a){this.sourceBlock_.updateStatement_("REMOVE"==a)});this.appendValueInput("VALUE").setCheck("Array").appendField(Blockly.Msg.LISTS_GET_INDEX_INPUT_IN_LIST);this.appendDummyInput().appendField(a,"MODE").appendField("","SPACE");this.appendDummyInput("AT");Blockly.Msg.LISTS_GET_INDEX_TAIL&&this.appendDummyInput("TAIL").appendField(Blockly.Msg.LISTS_GET_INDEX_TAIL);this.setInputsInline(!0);this.setOutput(!0);this.updateAt_(!0);var b=this;this.setTooltip(function(){var a=
|
||||
b.getFieldValue("MODE"),d=b.getFieldValue("WHERE"),e="";switch(a+" "+d){case "GET FROM_START":case "GET FROM_END":e=Blockly.Msg.LISTS_GET_INDEX_TOOLTIP_GET_FROM;break;case "GET FIRST":e=Blockly.Msg.LISTS_GET_INDEX_TOOLTIP_GET_FIRST;break;case "GET LAST":e=Blockly.Msg.LISTS_GET_INDEX_TOOLTIP_GET_LAST;break;case "GET RANDOM":e=Blockly.Msg.LISTS_GET_INDEX_TOOLTIP_GET_RANDOM;break;case "GET_REMOVE FROM_START":case "GET_REMOVE FROM_END":e=Blockly.Msg.LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FROM;break;case "GET_REMOVE FIRST":e=
|
||||
Blockly.Msg.LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FIRST;break;case "GET_REMOVE LAST":e=Blockly.Msg.LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_LAST;break;case "GET_REMOVE RANDOM":e=Blockly.Msg.LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_RANDOM;break;case "REMOVE FROM_START":case "REMOVE FROM_END":e=Blockly.Msg.LISTS_GET_INDEX_TOOLTIP_REMOVE_FROM;break;case "REMOVE FIRST":e=Blockly.Msg.LISTS_GET_INDEX_TOOLTIP_REMOVE_FIRST;break;case "REMOVE LAST":e=Blockly.Msg.LISTS_GET_INDEX_TOOLTIP_REMOVE_LAST;break;case "REMOVE RANDOM":e=
|
||||
Blockly.Msg.LISTS_GET_INDEX_TOOLTIP_REMOVE_RANDOM}if("FROM_START"==d||"FROM_END"==d)e+=" "+("FROM_START"==d?Blockly.Msg.LISTS_INDEX_FROM_START_TOOLTIP:Blockly.Msg.LISTS_INDEX_FROM_END_TOOLTIP).replace("%1",b.workspace.options.oneBasedIndex?"#1":"#0");return e})},mutationToDom:function(){var a=document.createElement("mutation");a.setAttribute("statement",!this.outputConnection);var b=this.getInput("AT").type==Blockly.INPUT_VALUE;a.setAttribute("at",b);return a},domToMutation:function(a){var b="true"==
|
||||
a.getAttribute("statement");this.updateStatement_(b);a="false"!=a.getAttribute("at");this.updateAt_(a)},updateStatement_:function(a){a!=!this.outputConnection&&(this.unplug(!0,!0),a?(this.setOutput(!1),this.setPreviousStatement(!0),this.setNextStatement(!0)):(this.setPreviousStatement(!1),this.setNextStatement(!1),this.setOutput(!0)))},updateAt_:function(a){this.removeInput("AT");this.removeInput("ORDINAL",!0);a?(this.appendValueInput("AT").setCheck("Number"),Blockly.Msg.ORDINAL_NUMBER_SUFFIX&&this.appendDummyInput("ORDINAL").appendField(Blockly.Msg.ORDINAL_NUMBER_SUFFIX)):
|
||||
this.appendDummyInput("AT");var b=new Blockly.FieldDropdown(this.WHERE_OPTIONS,function(b){var c="FROM_START"==b||"FROM_END"==b;if(c!=a){var e=this.sourceBlock_;e.updateAt_(c);e.setFieldValue(b,"WHERE");return null}});this.getInput("AT").appendField(b,"WHERE");Blockly.Msg.LISTS_GET_INDEX_TAIL&&this.moveInputBefore("TAIL",null)}};
|
||||
Blockly.Blocks.lists_setIndex={init:function(){var a=[[Blockly.Msg.LISTS_SET_INDEX_SET,"SET"],[Blockly.Msg.LISTS_SET_INDEX_INSERT,"INSERT"]];this.WHERE_OPTIONS=[[Blockly.Msg.LISTS_GET_INDEX_FROM_START,"FROM_START"],[Blockly.Msg.LISTS_GET_INDEX_FROM_END,"FROM_END"],[Blockly.Msg.LISTS_GET_INDEX_FIRST,"FIRST"],[Blockly.Msg.LISTS_GET_INDEX_LAST,"LAST"],[Blockly.Msg.LISTS_GET_INDEX_RANDOM,"RANDOM"]];this.setHelpUrl(Blockly.Msg.LISTS_SET_INDEX_HELPURL);this.setColour(Blockly.Blocks.lists.HUE);this.appendValueInput("LIST").setCheck("Array").appendField(Blockly.Msg.LISTS_SET_INDEX_INPUT_IN_LIST);
|
||||
this.appendDummyInput().appendField(new Blockly.FieldDropdown(a),"MODE").appendField("","SPACE");this.appendDummyInput("AT");this.appendValueInput("TO").appendField(Blockly.Msg.LISTS_SET_INDEX_INPUT_TO);this.setInputsInline(!0);this.setPreviousStatement(!0);this.setNextStatement(!0);this.setTooltip(Blockly.Msg.LISTS_SET_INDEX_TOOLTIP);this.updateAt_(!0);var b=this;this.setTooltip(function(){var a=b.getFieldValue("MODE"),d=b.getFieldValue("WHERE"),e="";switch(a+" "+d){case "SET FROM_START":case "SET FROM_END":e=
|
||||
Blockly.Msg.LISTS_SET_INDEX_TOOLTIP_SET_FROM;break;case "SET FIRST":e=Blockly.Msg.LISTS_SET_INDEX_TOOLTIP_SET_FIRST;break;case "SET LAST":e=Blockly.Msg.LISTS_SET_INDEX_TOOLTIP_SET_LAST;break;case "SET RANDOM":e=Blockly.Msg.LISTS_SET_INDEX_TOOLTIP_SET_RANDOM;break;case "INSERT FROM_START":case "INSERT FROM_END":e=Blockly.Msg.LISTS_SET_INDEX_TOOLTIP_INSERT_FROM;break;case "INSERT FIRST":e=Blockly.Msg.LISTS_SET_INDEX_TOOLTIP_INSERT_FIRST;break;case "INSERT LAST":e=Blockly.Msg.LISTS_SET_INDEX_TOOLTIP_INSERT_LAST;
|
||||
break;case "INSERT RANDOM":e=Blockly.Msg.LISTS_SET_INDEX_TOOLTIP_INSERT_RANDOM}if("FROM_START"==d||"FROM_END"==d)e+=" "+Blockly.Msg.LISTS_INDEX_FROM_START_TOOLTIP.replace("%1",b.workspace.options.oneBasedIndex?"#1":"#0");return e})},mutationToDom:function(){var a=document.createElement("mutation"),b=this.getInput("AT").type==Blockly.INPUT_VALUE;a.setAttribute("at",b);return a},domToMutation:function(a){a="false"!=a.getAttribute("at");this.updateAt_(a)},updateAt_:function(a){this.removeInput("AT");
|
||||
this.removeInput("ORDINAL",!0);a?(this.appendValueInput("AT").setCheck("Number"),Blockly.Msg.ORDINAL_NUMBER_SUFFIX&&this.appendDummyInput("ORDINAL").appendField(Blockly.Msg.ORDINAL_NUMBER_SUFFIX)):this.appendDummyInput("AT");var b=new Blockly.FieldDropdown(this.WHERE_OPTIONS,function(b){var c="FROM_START"==b||"FROM_END"==b;if(c!=a){var e=this.sourceBlock_;e.updateAt_(c);e.setFieldValue(b,"WHERE");return null}});this.moveInputBefore("AT","TO");this.getInput("ORDINAL")&&this.moveInputBefore("ORDINAL",
|
||||
"TO");this.getInput("AT").appendField(b,"WHERE")}};
|
||||
Blockly.Blocks.lists_getSublist={init:function(){this.WHERE_OPTIONS_1=[[Blockly.Msg.LISTS_GET_SUBLIST_START_FROM_START,"FROM_START"],[Blockly.Msg.LISTS_GET_SUBLIST_START_FROM_END,"FROM_END"],[Blockly.Msg.LISTS_GET_SUBLIST_START_FIRST,"FIRST"]];this.WHERE_OPTIONS_2=[[Blockly.Msg.LISTS_GET_SUBLIST_END_FROM_START,"FROM_START"],[Blockly.Msg.LISTS_GET_SUBLIST_END_FROM_END,"FROM_END"],[Blockly.Msg.LISTS_GET_SUBLIST_END_LAST,"LAST"]];this.setHelpUrl(Blockly.Msg.LISTS_GET_SUBLIST_HELPURL);this.setColour(Blockly.Blocks.lists.HUE);
|
||||
this.appendValueInput("LIST").setCheck("Array").appendField(Blockly.Msg.LISTS_GET_SUBLIST_INPUT_IN_LIST);this.appendDummyInput("AT1");this.appendDummyInput("AT2");Blockly.Msg.LISTS_GET_SUBLIST_TAIL&&this.appendDummyInput("TAIL").appendField(Blockly.Msg.LISTS_GET_SUBLIST_TAIL);this.setInputsInline(!0);this.setOutput(!0,"Array");this.updateAt_(1,!0);this.updateAt_(2,!0);this.setTooltip(Blockly.Msg.LISTS_GET_SUBLIST_TOOLTIP)},mutationToDom:function(){var a=document.createElement("mutation"),b=this.getInput("AT1").type==
|
||||
Blockly.INPUT_VALUE;a.setAttribute("at1",b);b=this.getInput("AT2").type==Blockly.INPUT_VALUE;a.setAttribute("at2",b);return a},domToMutation:function(a){var b="true"==a.getAttribute("at1");a="true"==a.getAttribute("at2");this.updateAt_(1,b);this.updateAt_(2,a)},updateAt_:function(a,b){this.removeInput("AT"+a);this.removeInput("ORDINAL"+a,!0);b?(this.appendValueInput("AT"+a).setCheck("Number"),Blockly.Msg.ORDINAL_NUMBER_SUFFIX&&this.appendDummyInput("ORDINAL"+a).appendField(Blockly.Msg.ORDINAL_NUMBER_SUFFIX)):
|
||||
this.appendDummyInput("AT"+a);var c=new Blockly.FieldDropdown(this["WHERE_OPTIONS_"+a],function(c){var d="FROM_START"==c||"FROM_END"==c;if(d!=b){var f=this.sourceBlock_;f.updateAt_(a,d);f.setFieldValue(c,"WHERE"+a);return null}});this.getInput("AT"+a).appendField(c,"WHERE"+a);1==a&&(this.moveInputBefore("AT1","AT2"),this.getInput("ORDINAL1")&&this.moveInputBefore("ORDINAL1","AT2"));Blockly.Msg.LISTS_GET_SUBLIST_TAIL&&this.moveInputBefore("TAIL",null)}};
|
||||
Blockly.Blocks.lists_sort={init:function(){this.jsonInit({message0:Blockly.Msg.LISTS_SORT_TITLE,args0:[{type:"field_dropdown",name:"TYPE",options:[[Blockly.Msg.LISTS_SORT_TYPE_NUMERIC,"NUMERIC"],[Blockly.Msg.LISTS_SORT_TYPE_TEXT,"TEXT"],[Blockly.Msg.LISTS_SORT_TYPE_IGNORECASE,"IGNORE_CASE"]]},{type:"field_dropdown",name:"DIRECTION",options:[[Blockly.Msg.LISTS_SORT_ORDER_ASCENDING,"1"],[Blockly.Msg.LISTS_SORT_ORDER_DESCENDING,"-1"]]},{type:"input_value",name:"LIST",check:"Array"}],output:"Array",colour:Blockly.Blocks.lists.HUE,
|
||||
tooltip:Blockly.Msg.LISTS_SORT_TOOLTIP,helpUrl:Blockly.Msg.LISTS_SORT_HELPURL})}};
|
||||
Blockly.Blocks.lists_split={init:function(){var a=this,b=new Blockly.FieldDropdown([[Blockly.Msg.LISTS_SPLIT_LIST_FROM_TEXT,"SPLIT"],[Blockly.Msg.LISTS_SPLIT_TEXT_FROM_LIST,"JOIN"]],function(b){a.updateType_(b)});this.setHelpUrl(Blockly.Msg.LISTS_SPLIT_HELPURL);this.setColour(Blockly.Blocks.lists.HUE);this.appendValueInput("INPUT").setCheck("String").appendField(b,"MODE");this.appendValueInput("DELIM").setCheck("String").appendField(Blockly.Msg.LISTS_SPLIT_WITH_DELIMITER);this.setInputsInline(!0);
|
||||
this.setOutput(!0,"Array");this.setTooltip(function(){var b=a.getFieldValue("MODE");if("SPLIT"==b)return Blockly.Msg.LISTS_SPLIT_TOOLTIP_SPLIT;if("JOIN"==b)return Blockly.Msg.LISTS_SPLIT_TOOLTIP_JOIN;throw"Unknown mode: "+b;})},updateType_:function(a){"SPLIT"==a?(this.outputConnection.setCheck("Array"),this.getInput("INPUT").setCheck("String")):(this.outputConnection.setCheck("String"),this.getInput("INPUT").setCheck("Array"))},mutationToDom:function(){var a=document.createElement("mutation");a.setAttribute("mode",
|
||||
this.getFieldValue("MODE"));return a},domToMutation:function(a){this.updateType_(a.getAttribute("mode"))}};Blockly.Blocks.logic={};Blockly.Constants.Logic={};Blockly.Constants.Logic.HUE=210;Blockly.Blocks.logic.HUE=Blockly.Constants.Logic.HUE;
|
||||
Blockly.defineBlocksWithJsonArray([{type:"logic_boolean",message0:"%1",args0:[{type:"field_dropdown",name:"BOOL",options:[["%{BKY_LOGIC_BOOLEAN_TRUE}","TRUE"],["%{BKY_LOGIC_BOOLEAN_FALSE}","FALSE"]]}],output:"Boolean",colour:"%{BKY_LOGIC_HUE}",tooltip:"%{BKY_LOGIC_BOOLEAN_TOOLTIP}",helpUrl:"%{BKY_LOGIC_BOOLEAN_HELPURL}"},{type:"controls_if",message0:"%{BKY_CONTROLS_IF_MSG_IF} %1",args0:[{type:"input_value",name:"IF0",check:"Boolean"}],message1:"%{BKY_CONTROLS_IF_MSG_THEN} %1",args1:[{type:"input_statement",
|
||||
name:"DO0"}],previousStatement:null,nextStatement:null,colour:"%{BKY_LOGIC_HUE}",helpUrl:"%{BKY_CONTROLS_IF_HELPURL}",mutator:"controls_if_mutator",extensions:["controls_if_tooltip"]},{type:"controls_ifelse",message0:"%{BKY_CONTROLS_IF_MSG_IF} %1",args0:[{type:"input_value",name:"IF0",check:"Boolean"}],message1:"%{BKY_CONTROLS_IF_MSG_THEN} %1",args1:[{type:"input_statement",name:"DO0"}],message2:"%{BKY_CONTROLS_IF_MSG_ELSE} %1",args2:[{type:"input_statement",name:"ELSE"}],previousStatement:null,nextStatement:null,
|
||||
// change by zhaouv @ logic_compare output : "Boolean" -> null
|
||||
colour:"%{BKY_LOGIC_HUE}",tooltip:"%{BKYCONTROLS_IF_TOOLTIP_2}",helpUrl:"%{BKY_CONTROLS_IF_HELPURL}",extensions:["controls_if_tooltip"]},{type:"logic_compare",message0:"%1 %2 %3",args0:[{type:"input_value",name:"A"},{type:"field_dropdown",name:"OP",options:[["=","EQ"],["\u2260","NEQ"],["<","LT"],["\u2264","LTE"],[">","GT"],["\u2265","GTE"]]},{type:"input_value",name:"B"}],inputsInline:!0,output:null,colour:"%{BKY_LOGIC_HUE}",helpUrl:"%{BKY_LOGIC_COMPARE_HELPURL}",extensions:["logic_compare",
|
||||
// change by zhaouv @ logic_operation output,check : "Boolean" -> null
|
||||
// change by zhaouv @ logic_negate output,check : "Boolean" -> null
|
||||
"logic_op_tooltip"]},{type:"logic_operation",message0:"%1 %2 %3",args0:[{type:"input_value",name:"A",check:null},{type:"field_dropdown",name:"OP",options:[["%{BKY_LOGIC_OPERATION_AND}","AND"],["%{BKY_LOGIC_OPERATION_OR}","OR"]]},{type:"input_value",name:"B",check:null}],inputsInline:!0,output:null,colour:"%{BKY_LOGIC_HUE}",helpUrl:"%{BKY_LOGIC_OPERATION_HELPURL}",extensions:["logic_op_tooltip"]},{type:"logic_negate",message0:"%{BKY_LOGIC_NEGATE_TITLE}",args0:[{type:"input_value",name:"BOOL",
|
||||
check:null}],output:null,colour:"%{BKY_LOGIC_HUE}",tooltip:"%{BKY_LOGIC_NEGATE_TOOLTIP}",helpUrl:"%{BKY_LOGIC_NEGATE_HELPURL}"},{type:"logic_null",message0:"%{BKY_LOGIC_NULL}",output:null,colour:"%{BKY_LOGIC_HUE}",tooltip:"%{BKY_LOGIC_NULL_TOOLTIP}",helpUrl:"%{BKY_LOGIC_NULL_HELPURL}"},{type:"logic_ternary",message0:"%{BKY_LOGIC_TERNARY_CONDITION} %1",args0:[{type:"input_value",name:"IF",check:"Boolean"}],message1:"%{BKY_LOGIC_TERNARY_IF_TRUE} %1",args1:[{type:"input_value",name:"THEN"}],
|
||||
message2:"%{BKY_LOGIC_TERNARY_IF_FALSE} %1",args2:[{type:"input_value",name:"ELSE"}],output:null,colour:"%{BKY_LOGIC_HUE}",tooltip:"%{BKY_LOGIC_TERNARY_TOOLTIP}",helpUrl:"%{BKY_LOGIC_TERNARY_HELPURL}",extensions:["logic_ternary"]}]);
|
||||
Blockly.defineBlocksWithJsonArray([{type:"controls_if_if",message0:"%{BKY_CONTROLS_IF_IF_TITLE_IF}",nextStatement:null,enableContextMenu:!1,colour:"%{BKY_LOGIC_HUE}",tooltip:"%{BKY_CONTROLS_IF_IF_TOOLTIP}"},{type:"controls_if_elseif",message0:"%{BKY_CONTROLS_IF_ELSEIF_TITLE_ELSEIF}",previousStatement:null,nextStatement:null,enableContextMenu:!1,colour:"%{BKY_LOGIC_HUE}",tooltip:"%{BKY_CONTROLS_IF_ELSEIF_TOOLTIP}"},{type:"controls_if_else",message0:"%{BKY_CONTROLS_IF_ELSE_TITLE_ELSE}",previousStatement:null,
|
||||
enableContextMenu:!1,colour:"%{BKY_LOGIC_HUE}",tooltip:"%{BKY_CONTROLS_IF_ELSE_TOOLTIP}"}]);Blockly.Constants.Logic.TOOLTIPS_BY_OP={EQ:"%{BKY_LOGIC_COMPARE_TOOLTIP_EQ}",NEQ:"%{BKY_LOGIC_COMPARE_TOOLTIP_NEQ}",LT:"%{BKY_LOGIC_COMPARE_TOOLTIP_LT}",LTE:"%{BKY_LOGIC_COMPARE_TOOLTIP_LTE}",GT:"%{BKY_LOGIC_COMPARE_TOOLTIP_GT}",GTE:"%{BKY_LOGIC_COMPARE_TOOLTIP_GTE}",AND:"%{BKY_LOGIC_OPERATION_TOOLTIP_AND}",OR:"%{BKY_LOGIC_OPERATION_TOOLTIP_OR}"};
|
||||
Blockly.Extensions.register("logic_op_tooltip",Blockly.Extensions.buildTooltipForDropdown("OP",Blockly.Constants.Logic.TOOLTIPS_BY_OP));
|
||||
Blockly.Constants.Logic.CONTROLS_IF_MUTATOR_MIXIN={elseifCount_:0,elseCount_:0,mutationToDom:function(){if(!this.elseifCount_&&!this.elseCount_)return null;var a=document.createElement("mutation");this.elseifCount_&&a.setAttribute("elseif",this.elseifCount_);this.elseCount_&&a.setAttribute("else",1);return a},domToMutation:function(a){this.elseifCount_=parseInt(a.getAttribute("elseif"),10)||0;this.elseCount_=parseInt(a.getAttribute("else"),10)||0;this.updateShape_()},decompose:function(a){var b=a.newBlock("controls_if_if");
|
||||
b.initSvg();for(var c=b.nextConnection,d=1;d<=this.elseifCount_;d++){var e=a.newBlock("controls_if_elseif");e.initSvg();c.connect(e.previousConnection);c=e.nextConnection}this.elseCount_&&(a=a.newBlock("controls_if_else"),a.initSvg(),c.connect(a.previousConnection));return b},compose:function(a){var b=a.nextConnection.targetBlock();this.elseCount_=this.elseifCount_=0;a=[null];for(var c=[null],d=null;b;){switch(b.type){case "controls_if_elseif":this.elseifCount_++;a.push(b.valueConnection_);c.push(b.statementConnection_);
|
||||
break;case "controls_if_else":this.elseCount_++;d=b.statementConnection_;break;default:throw"Unknown block type.";}b=b.nextConnection&&b.nextConnection.targetBlock()}this.updateShape_();for(b=1;b<=this.elseifCount_;b++)Blockly.Mutator.reconnect(a[b],this,"IF"+b),Blockly.Mutator.reconnect(c[b],this,"DO"+b);Blockly.Mutator.reconnect(d,this,"ELSE")},saveConnections:function(a){a=a.nextConnection.targetBlock();for(var b=1;a;){switch(a.type){case "controls_if_elseif":var c=this.getInput("IF"+b),d=this.getInput("DO"+
|
||||
b);a.valueConnection_=c&&c.connection.targetConnection;a.statementConnection_=d&&d.connection.targetConnection;b++;break;case "controls_if_else":d=this.getInput("ELSE");a.statementConnection_=d&&d.connection.targetConnection;break;default:throw"Unknown block type.";}a=a.nextConnection&&a.nextConnection.targetBlock()}},updateShape_:function(){this.getInput("ELSE")&&this.removeInput("ELSE");for(var a=1;this.getInput("IF"+a);)this.removeInput("IF"+a),this.removeInput("DO"+a),a++;for(a=1;a<=this.elseifCount_;a++)this.appendValueInput("IF"+
|
||||
a).setCheck("Boolean").appendField(Blockly.Msg.CONTROLS_IF_MSG_ELSEIF),this.appendStatementInput("DO"+a).appendField(Blockly.Msg.CONTROLS_IF_MSG_THEN);this.elseCount_&&this.appendStatementInput("ELSE").appendField(Blockly.Msg.CONTROLS_IF_MSG_ELSE)}};Blockly.Extensions.registerMutator("controls_if_mutator",Blockly.Constants.Logic.CONTROLS_IF_MUTATOR_MIXIN,null,["controls_if_elseif","controls_if_else"]);
|
||||
Blockly.Constants.Logic.CONTROLS_IF_TOOLTIP_EXTENSION=function(){this.setTooltip(function(){if(this.elseifCount_||this.elseCount_){if(!this.elseifCount_&&this.elseCount_)return Blockly.Msg.CONTROLS_IF_TOOLTIP_2;if(this.elseifCount_&&!this.elseCount_)return Blockly.Msg.CONTROLS_IF_TOOLTIP_3;if(this.elseifCount_&&this.elseCount_)return Blockly.Msg.CONTROLS_IF_TOOLTIP_4}else return Blockly.Msg.CONTROLS_IF_TOOLTIP_1;return""}.bind(this))};Blockly.Extensions.register("controls_if_tooltip",Blockly.Constants.Logic.CONTROLS_IF_TOOLTIP_EXTENSION);
|
||||
Blockly.Constants.Logic.fixLogicCompareRtlOpLabels=function(){var a={LT:"\u200f<\u200f",LTE:"\u200f\u2264\u200f",GT:"\u200f>\u200f",GTE:"\u200f\u2265\u200f"},b=this.getField("OP");if(b){b=b.getOptions();for(var c=0;c<b.length;++c){var d=b[c],e=a[d[1]];goog.isString(d[0])&&e&&(d[0]=e)}}};
|
||||
Blockly.Constants.Logic.LOGIC_COMPARE_ONCHANGE_MIXIN={prevBlocks_:[null,null],onchange:function(a){var b=this.getInputTargetBlock("A"),c=this.getInputTargetBlock("B");if(b&&c&&!b.outputConnection.checkType_(c.outputConnection)){Blockly.Events.setGroup(a.group);for(a=0;a<this.prevBlocks_.length;a++){var d=this.prevBlocks_[a];if(d===b||d===c)d.unplug(),d.bumpNeighbours_()}Blockly.Events.setGroup(!1)}this.prevBlocks_[0]=b;this.prevBlocks_[1]=c}};
|
||||
Blockly.Constants.Logic.LOGIC_COMPARE_EXTENSION=function(){this.RTL&&Blockly.Constants.Logic.fixLogicCompareRtlOpLabels.apply(this);this.mixin(Blockly.Constants.Logic.LOGIC_COMPARE_ONCHANGE_MIXIN)};Blockly.Extensions.register("logic_compare",Blockly.Constants.Logic.LOGIC_COMPARE_EXTENSION);
|
||||
Blockly.Constants.Logic.LOGIC_TERNARY_ONCHANGE_MIXIN={prevParentConnection_:null,onchange:function(a){var b=this.getInputTargetBlock("THEN"),c=this.getInputTargetBlock("ELSE"),d=this.outputConnection.targetConnection;if((b||c)&&d)for(var e=0;2>e;e++){var f=1==e?b:c;f&&!f.outputConnection.checkType_(d)&&(Blockly.Events.setGroup(a.group),d===this.prevParentConnection_?(this.unplug(),d.getSourceBlock().bumpNeighbours_()):(f.unplug(),f.bumpNeighbours_()),Blockly.Events.setGroup(!1))}this.prevParentConnection_=
|
||||
d}};Blockly.Extensions.registerMixin("logic_ternary",Blockly.Constants.Logic.LOGIC_TERNARY_ONCHANGE_MIXIN);Blockly.Blocks.loops={};Blockly.Constants.Loops={};Blockly.Constants.Loops.HUE=120;Blockly.Blocks.loops.HUE=Blockly.Constants.Loops.HUE;
|
||||
Blockly.defineBlocksWithJsonArray([{type:"controls_repeat_ext",message0:"%{BKY_CONTROLS_REPEAT_TITLE}",args0:[{type:"input_value",name:"TIMES",check:"Number"}],message1:"%{BKY_CONTROLS_REPEAT_INPUT_DO} %1",args1:[{type:"input_statement",name:"DO"}],previousStatement:null,nextStatement:null,colour:"%{BKY_LOOPS_HUE}",tooltip:"%{BKY_CONTROLS_REPEAT_TOOLTIP}",helpUrl:"%{BKY_CONTROLS_REPEAT_HELPURL}"},{type:"controls_repeat",message0:"%{BKY_CONTROLS_REPEAT_TITLE}",args0:[{type:"field_number",name:"TIMES",
|
||||
value:10,min:0,precision:1}],message1:"%{BKY_CONTROLS_REPEAT_INPUT_DO} %1",args1:[{type:"input_statement",name:"DO"}],previousStatement:null,nextStatement:null,colour:"%{BKY_LOOPS_HUE}",tooltip:"%{BKY_CONTROLS_REPEAT_TOOLTIP}",helpUrl:"%{BKY_CONTROLS_REPEAT_HELPURL}"},{type:"controls_whileUntil",message0:"%1 %2",args0:[{type:"field_dropdown",name:"MODE",options:[["%{BKY_CONTROLS_WHILEUNTIL_OPERATOR_WHILE}","WHILE"],["%{BKY_CONTROLS_WHILEUNTIL_OPERATOR_UNTIL}","UNTIL"]]},{type:"input_value",name:"BOOL",
|
||||
check:"Boolean"}],message1:"%{BKY_CONTROLS_REPEAT_INPUT_DO} %1",args1:[{type:"input_statement",name:"DO"}],previousStatement:null,nextStatement:null,colour:"%{BKY_LOOPS_HUE}",helpUrl:"%{BKY_CONTROLS_WHILEUNTIL_HELPURL}",extensions:["controls_whileUntil_tooltip"]},{type:"controls_for",message0:"%{BKY_CONTROLS_FOR_TITLE}",args0:[{type:"field_variable",name:"VAR",variable:null},{type:"input_value",name:"FROM",check:"Number",align:"RIGHT"},{type:"input_value",name:"TO",check:"Number",align:"RIGHT"},{type:"input_value",
|
||||
name:"BY",check:"Number",align:"RIGHT"}],message1:"%{BKY_CONTROLS_REPEAT_INPUT_DO} %1",args1:[{type:"input_statement",name:"DO"}],inputsInline:!0,previousStatement:null,nextStatement:null,colour:"%{BKY_LOOPS_HUE}",helpUrl:"%{BKY_CONTROLS_FOR_HELPURL}",extensions:["contextMenu_newGetVariableBlock","controls_for_tooltip"]},{type:"controls_forEach",message0:"%{BKY_CONTROLS_FOREACH_TITLE}",args0:[{type:"field_variable",name:"VAR",variable:null},{type:"input_value",name:"LIST",check:"Array"}],message1:"%{BKY_CONTROLS_REPEAT_INPUT_DO} %1",
|
||||
args1:[{type:"input_statement",name:"DO"}],previousStatement:null,nextStatement:null,colour:"%{BKY_LOOPS_HUE}",helpUrl:"%{BKY_CONTROLS_FOREACH_HELPURL}",extensions:["contextMenu_newGetVariableBlock","controls_forEach_tooltip"]},{type:"controls_flow_statements",message0:"%1",args0:[{type:"field_dropdown",name:"FLOW",options:[["%{BKY_CONTROLS_FLOW_STATEMENTS_OPERATOR_BREAK}","BREAK"],["%{BKY_CONTROLS_FLOW_STATEMENTS_OPERATOR_CONTINUE}","CONTINUE"]]}],previousStatement:null,colour:"%{BKY_LOOPS_HUE}",
|
||||
helpUrl:"%{BKY_CONTROLS_FLOW_STATEMENTS_HELPURL}",extensions:["controls_flow_tooltip","controls_flow_in_loop_check"]}]);Blockly.Constants.Loops.WHILE_UNTIL_TOOLTIPS={WHILE:"%{BKY_CONTROLS_WHILEUNTIL_TOOLTIP_WHILE}",UNTIL:"%{BKY_CONTROLS_WHILEUNTIL_TOOLTIP_UNTIL}"};Blockly.Extensions.register("controls_whileUntil_tooltip",Blockly.Extensions.buildTooltipForDropdown("MODE",Blockly.Constants.Loops.WHILE_UNTIL_TOOLTIPS));
|
||||
Blockly.Constants.Loops.BREAK_CONTINUE_TOOLTIPS={BREAK:"%{BKY_CONTROLS_FLOW_STATEMENTS_TOOLTIP_BREAK}",CONTINUE:"%{BKY_CONTROLS_FLOW_STATEMENTS_TOOLTIP_CONTINUE}"};Blockly.Extensions.register("controls_flow_tooltip",Blockly.Extensions.buildTooltipForDropdown("FLOW",Blockly.Constants.Loops.BREAK_CONTINUE_TOOLTIPS));
|
||||
Blockly.Constants.Loops.CUSTOM_CONTEXT_MENU_CREATE_VARIABLES_GET_MIXIN={customContextMenu:function(a){var b=this.getFieldValue("VAR");if(!this.isCollapsed()&&null!=b){var c={enabled:!0};c.text=Blockly.Msg.VARIABLES_SET_CREATE_GET.replace("%1",b);b=goog.dom.createDom("field",null,b);b.setAttribute("name","VAR");b=goog.dom.createDom("block",null,b);b.setAttribute("type","variables_get");c.callback=Blockly.ContextMenu.callbackFactory(this,b);a.push(c)}}};
|
||||
Blockly.Extensions.registerMixin("contextMenu_newGetVariableBlock",Blockly.Constants.Loops.CUSTOM_CONTEXT_MENU_CREATE_VARIABLES_GET_MIXIN);Blockly.Extensions.register("controls_for_tooltip",Blockly.Extensions.buildTooltipWithFieldValue("%{BKY_CONTROLS_FOR_TOOLTIP}","VAR"));Blockly.Extensions.register("controls_forEach_tooltip",Blockly.Extensions.buildTooltipWithFieldValue("%{BKY_CONTROLS_FOREACH_TOOLTIP}","VAR"));
|
||||
Blockly.Constants.Loops.CONTROL_FLOW_IN_LOOP_CHECK_MIXIN={LOOP_TYPES:["controls_repeat","controls_repeat_ext","controls_forEach","controls_for","controls_whileUntil"],onchange:function(){if(this.workspace.isDragging&&!this.workspace.isDragging()){var a=!1,b=this;do{if(-1!=this.LOOP_TYPES.indexOf(b.type)){a=!0;break}b=b.getSurroundParent()}while(b);a?(this.setWarningText(null),this.isInFlyout||this.setDisabled(!1)):(this.setWarningText(Blockly.Msg.CONTROLS_FLOW_STATEMENTS_WARNING),this.isInFlyout||
|
||||
this.getInheritedDisabled()||this.setDisabled(!0))}}};Blockly.Extensions.registerMixin("controls_flow_in_loop_check",Blockly.Constants.Loops.CONTROL_FLOW_IN_LOOP_CHECK_MIXIN);Blockly.Blocks.math={};Blockly.Constants.Math={};Blockly.Constants.Math.HUE=230;Blockly.Blocks.math.HUE=Blockly.Constants.Math.HUE;
|
||||
Blockly.defineBlocksWithJsonArray([{type:"math_number",message0:"%1",args0:[{type:"field_number",name:"NUM",value:0}],output:"Number",colour:"%{BKY_MATH_HUE}",helpUrl:"%{BKY_MATH_NUMBER_HELPURL}",tooltip:"%{BKY_MATH_NUMBER_TOOLTIP}",extensions:["parent_tooltip_when_inline"]},{type:"math_arithmetic",message0:"%1 %2 %3",args0:[{type:"input_value",name:"A",check:"Number"},{type:"field_dropdown",name:"OP",options:[["%{BKY_MATH_ADDITION_SYMBOL}","ADD"],["%{BKY_MATH_SUBTRACTION_SYMBOL}","MINUS"],["%{BKY_MATH_MULTIPLICATION_SYMBOL}",
|
||||
"MULTIPLY"],["%{BKY_MATH_DIVISION_SYMBOL}","DIVIDE"],["%{BKY_MATH_POWER_SYMBOL}","POWER"]]},{type:"input_value",name:"B",check:"Number"}],inputsInline:!0,output:"Number",colour:"%{BKY_MATH_HUE}",helpUrl:"%{BKY_MATH_ARITHMETIC_HELPURL}",extensions:["math_op_tooltip"]},{type:"math_single",message0:"%1 %2",args0:[{type:"field_dropdown",name:"OP",options:[["%{BKY_MATH_SINGLE_OP_ROOT}","ROOT"],["%{BKY_MATH_SINGLE_OP_ABSOLUTE}","ABS"],["-","NEG"],["ln","LN"],["log10","LOG10"],["e^","EXP"],["10^","POW10"]]},
|
||||
{type:"input_value",name:"NUM",check:"Number"}],output:"Number",colour:"%{BKY_MATH_HUE}",helpUrl:"%{BKY_MATH_SINGLE_HELPURL}",extensions:["math_op_tooltip"]},{type:"math_trig",message0:"%1 %2",args0:[{type:"field_dropdown",name:"OP",options:[["%{BKY_MATH_TRIG_SIN}","SIN"],["%{BKY_MATH_TRIG_COS}","COS"],["%{BKY_MATH_TRIG_TAN}","TAN"],["%{BKY_MATH_TRIG_ASIN}","ASIN"],["%{BKY_MATH_TRIG_ACOS}","ACOS"],["%{BKY_MATH_TRIG_ATAN}","ATAN"]]},{type:"input_value",name:"NUM",check:"Number"}],output:"Number",colour:"%{BKY_MATH_HUE}",
|
||||
helpUrl:"%{BKY_MATH_TRIG_HELPURL}",extensions:["math_op_tooltip"]},{type:"math_constant",message0:"%1",args0:[{type:"field_dropdown",name:"CONSTANT",options:[["\u03c0","PI"],["e","E"],["\u03c6","GOLDEN_RATIO"],["sqrt(2)","SQRT2"],["sqrt(\u00bd)","SQRT1_2"],["\u221e","INFINITY"]]}],output:"Number",colour:"%{BKY_MATH_HUE}",tooltip:"%{BKY_MATH_CONSTANT_TOOLTIP}",helpUrl:"%{BKY_MATH_CONSTANT_HELPURL}"},{type:"math_number_property",message0:"%1 %2",args0:[{type:"input_value",name:"NUMBER_TO_CHECK",check:"Number"},
|
||||
{type:"field_dropdown",name:"PROPERTY",options:[["%{BKY_MATH_IS_EVEN}","EVEN"],["%{BKY_MATH_IS_ODD}","ODD"],["%{BKY_MATH_IS_PRIME}","PRIME"],["%{BKY_MATH_IS_WHOLE}","WHOLE"],["%{BKY_MATH_IS_POSITIVE}","POSITIVE"],["%{BKY_MATH_IS_NEGATIVE}","NEGATIVE"],["%{BKY_MATH_IS_DIVISIBLE_BY}","DIVISIBLE_BY"]]}],inputsInline:!0,output:"Boolean",colour:"%{BKY_MATH_HUE}",tooltip:"%{BKY_MATH_IS_TOOLTIP}",mutator:"math_is_divisibleby_mutator"},{type:"math_change",message0:"%{BKY_MATH_CHANGE_TITLE}",args0:[{type:"field_variable",
|
||||
name:"VAR",variable:"%{BKY_MATH_CHANGE_TITLE_ITEM}"},{type:"input_value",name:"DELTA",check:"Number"}],previousStatement:null,nextStatement:null,colour:"%{BKY_VARIABLES_HUE}",helpUrl:"%{BKY_MATH_CHANGE_HELPURL}",extensions:["math_change_tooltip"]},{type:"math_round",message0:"%1 %2",args0:[{type:"field_dropdown",name:"OP",options:[["%{BKY_MATH_ROUND_OPERATOR_ROUND}","ROUND"],["%{BKY_MATH_ROUND_OPERATOR_ROUNDUP}","ROUNDUP"],["%{BKY_MATH_ROUND_OPERATOR_ROUNDDOWN}","ROUNDDOWN"]]},{type:"input_value",
|
||||
name:"NUM",check:"Number"}],output:"Number",colour:"%{BKY_MATH_HUE}",helpUrl:"%{BKY_MATH_ROUND_HELPURL}",tooltip:"%{BKY_MATH_ROUND_TOOLTIP}"},{type:"math_on_list",message0:"%1 %2",args0:[{type:"field_dropdown",name:"OP",options:[["%{BKY_MATH_ONLIST_OPERATOR_SUM}","SUM"],["%{BKY_MATH_ONLIST_OPERATOR_MIN}","MIN"],["%{BKY_MATH_ONLIST_OPERATOR_MAX}","MAX"],["%{BKY_MATH_ONLIST_OPERATOR_AVERAGE}","AVERAGE"],["%{BKY_MATH_ONLIST_OPERATOR_MEDIAN}","MEDIAN"],["%{BKY_MATH_ONLIST_OPERATOR_MODE}","MODE"],["%{BKY_MATH_ONLIST_OPERATOR_STD_DEV}",
|
||||
"STD_DEV"],["%{BKY_MATH_ONLIST_OPERATOR_RANDOM}","RANDOM"]]},{type:"input_value",name:"LIST",check:"Array"}],output:"Number",colour:"%{BKY_MATH_HUE}",helpUrl:"%{BKY_MATH_ONLIST_HELPURL}",mutator:"math_modes_of_list_mutator",extensions:["math_op_tooltip"]},{type:"math_modulo",message0:"%{BKY_MATH_MODULO_TITLE}",args0:[{type:"input_value",name:"DIVIDEND",check:"Number"},{type:"input_value",name:"DIVISOR",check:"Number"}],inputsInline:!0,output:"Number",colour:"%{BKY_MATH_HUE}",tooltip:"%{BKY_MATH_MODULO_TOOLTIP}",
|
||||
helpUrl:"%{BKY_MATH_MODULO_HELPURL}"},{type:"math_constrain",message0:"%{BKY_MATH_CONSTRAIN_TITLE}",args0:[{type:"input_value",name:"VALUE",check:"Number"},{type:"input_value",name:"LOW",check:"Number"},{type:"input_value",name:"HIGH",check:"Number"}],inputsInline:!0,output:"Number",colour:"%{BKY_MATH_HUE}",tooltip:"%{BKY_MATH_CONSTRAIN_TOOLTIP}",helpUrl:"%{BKY_MATH_CONSTRAIN_HELPURL}"},{type:"math_random_int",message0:"%{BKY_MATH_RANDOM_INT_TITLE}",args0:[{type:"input_value",name:"FROM",check:"Number"},
|
||||
{type:"input_value",name:"TO",check:"Number"}],inputsInline:!0,output:"Number",colour:"%{BKY_MATH_HUE}",tooltip:"%{BKY_MATH_RANDOM_INT_TOOLTIP}",helpUrl:"%{BKY_MATH_RANDOM_INT_HELPURL}"},{type:"math_random_float",message0:"%{BKY_MATH_RANDOM_FLOAT_TITLE_RANDOM}",output:"Number",colour:"%{BKY_MATH_HUE}",tooltip:"%{BKY_MATH_RANDOM_FLOAT_TOOLTIP}",helpUrl:"%{BKY_MATH_RANDOM_FLOAT_HELPURL}"}]);
|
||||
Blockly.Constants.Math.TOOLTIPS_BY_OP={ADD:"%{BKY_MATH_ARITHMETIC_TOOLTIP_ADD}",MINUS:"%{BKY_MATH_ARITHMETIC_TOOLTIP_MINUS}",MULTIPLY:"%{BKY_MATH_ARITHMETIC_TOOLTIP_MULTIPLY}",DIVIDE:"%{BKY_MATH_ARITHMETIC_TOOLTIP_DIVIDE}",POWER:"%{BKY_MATH_ARITHMETIC_TOOLTIP_POWER}",ROOT:"%{BKY_MATH_SINGLE_TOOLTIP_ROOT}",ABS:"%{BKY_MATH_SINGLE_TOOLTIP_ABS}",NEG:"%{BKY_MATH_SINGLE_TOOLTIP_NEG}",LN:"%{BKY_MATH_SINGLE_TOOLTIP_LN}",LOG10:"%{BKY_MATH_SINGLE_TOOLTIP_LOG10}",EXP:"%{BKY_MATH_SINGLE_TOOLTIP_EXP}",POW10:"%{BKY_MATH_SINGLE_TOOLTIP_POW10}",
|
||||
SIN:"%{BKY_MATH_TRIG_TOOLTIP_SIN}",COS:"%{BKY_MATH_TRIG_TOOLTIP_COS}",TAN:"%{BKY_MATH_TRIG_TOOLTIP_TAN}",ASIN:"%{BKY_MATH_TRIG_TOOLTIP_ASIN}",ACOS:"%{BKY_MATH_TRIG_TOOLTIP_ACOS}",ATAN:"%{BKY_MATH_TRIG_TOOLTIP_ATAN}",SUM:"%{BKY_MATH_ONLIST_TOOLTIP_SUM}",MIN:"%{BKY_MATH_ONLIST_TOOLTIP_MIN}",MAX:"%{BKY_MATH_ONLIST_TOOLTIP_MAX}",AVERAGE:"%{BKY_MATH_ONLIST_TOOLTIP_AVERAGE}",MEDIAN:"%{BKY_MATH_ONLIST_TOOLTIP_MEDIAN}",MODE:"%{BKY_MATH_ONLIST_TOOLTIP_MODE}",STD_DEV:"%{BKY_MATH_ONLIST_TOOLTIP_STD_DEV}",RANDOM:"%{BKY_MATH_ONLIST_TOOLTIP_RANDOM}"};
|
||||
Blockly.Extensions.register("math_op_tooltip",Blockly.Extensions.buildTooltipForDropdown("OP",Blockly.Constants.Math.TOOLTIPS_BY_OP));
|
||||
Blockly.Constants.Math.IS_DIVISIBLEBY_MUTATOR_MIXIN={mutationToDom:function(){var a=document.createElement("mutation"),b="DIVISIBLE_BY"==this.getFieldValue("PROPERTY");a.setAttribute("divisor_input",b);return a},domToMutation:function(a){a="true"==a.getAttribute("divisor_input");this.updateShape_(a)},updateShape_:function(a){var b=this.getInput("DIVISOR");a?b||this.appendValueInput("DIVISOR").setCheck("Number"):b&&this.removeInput("DIVISOR")}};
|
||||
Blockly.Constants.Math.IS_DIVISIBLE_MUTATOR_EXTENSION=function(){this.getField("PROPERTY").setValidator(function(a){this.sourceBlock_.updateShape_("DIVISIBLE_BY"==a)})};Blockly.Extensions.registerMutator("math_is_divisibleby_mutator",Blockly.Constants.Math.IS_DIVISIBLEBY_MUTATOR_MIXIN,Blockly.Constants.Math.IS_DIVISIBLE_MUTATOR_EXTENSION);Blockly.Constants.Math.CHANGE_TOOLTIP_EXTENSION=function(){this.setTooltip(function(){return Blockly.Msg.MATH_CHANGE_TOOLTIP.replace("%1",this.getFieldValue("VAR"))}.bind(this))};
|
||||
Blockly.Extensions.register("math_change_tooltip",Blockly.Extensions.buildTooltipWithFieldValue("%{BKY_MATH_CHANGE_TOOLTIP}","VAR"));Blockly.Constants.Math.LIST_MODES_MUTATOR_MIXIN={updateType_:function(a){"MODE"==a?this.outputConnection.setCheck("Array"):this.outputConnection.setCheck("Number")},mutationToDom:function(){var a=document.createElement("mutation");a.setAttribute("op",this.getFieldValue("OP"));return a},domToMutation:function(a){this.updateType_(a.getAttribute("op"))}};
|
||||
Blockly.Constants.Math.LIST_MODES_MUTATOR_EXTENSION=function(){this.getField("OP").setValidator(function(a){this.updateType_(a)}.bind(this))};Blockly.Extensions.registerMutator("math_modes_of_list_mutator",Blockly.Constants.Math.LIST_MODES_MUTATOR_MIXIN,Blockly.Constants.Math.LIST_MODES_MUTATOR_EXTENSION);Blockly.Blocks.procedures={};Blockly.Blocks.procedures.HUE=290;
|
||||
Blockly.Blocks.procedures_defnoreturn={init:function(){var a=new Blockly.FieldTextInput("",Blockly.Procedures.rename);a.setSpellcheck(!1);this.appendDummyInput().appendField(Blockly.Msg.PROCEDURES_DEFNORETURN_TITLE).appendField(a,"NAME").appendField("","PARAMS");this.setMutator(new Blockly.Mutator(["procedures_mutatorarg"]));(this.workspace.options.comments||this.workspace.options.parentWorkspace&&this.workspace.options.parentWorkspace.options.comments)&&Blockly.Msg.PROCEDURES_DEFNORETURN_COMMENT&&
|
||||
this.setCommentText(Blockly.Msg.PROCEDURES_DEFNORETURN_COMMENT);this.setColour(Blockly.Blocks.procedures.HUE);this.setTooltip(Blockly.Msg.PROCEDURES_DEFNORETURN_TOOLTIP);this.setHelpUrl(Blockly.Msg.PROCEDURES_DEFNORETURN_HELPURL);this.arguments_=[];this.setStatements_(!0);this.statementConnection_=null},setStatements_:function(a){this.hasStatements_!==a&&(a?(this.appendStatementInput("STACK").appendField(Blockly.Msg.PROCEDURES_DEFNORETURN_DO),this.getInput("RETURN")&&this.moveInputBefore("STACK",
|
||||
"RETURN")):this.removeInput("STACK",!0),this.hasStatements_=a)},updateParams_:function(){for(var a=!1,b={},c=0;c<this.arguments_.length;c++){if(b["arg_"+this.arguments_[c].toLowerCase()]){a=!0;break}b["arg_"+this.arguments_[c].toLowerCase()]=!0}a?this.setWarningText(Blockly.Msg.PROCEDURES_DEF_DUPLICATE_WARNING):this.setWarningText(null);a="";this.arguments_.length&&(a=Blockly.Msg.PROCEDURES_BEFORE_PARAMS+" "+this.arguments_.join(", "));Blockly.Events.disable();try{this.setFieldValue(a,"PARAMS")}finally{Blockly.Events.enable()}},
|
||||
mutationToDom:function(a){var b=document.createElement("mutation");a&&b.setAttribute("name",this.getFieldValue("NAME"));for(var c=0;c<this.arguments_.length;c++){var d=document.createElement("arg");d.setAttribute("name",this.arguments_[c]);a&&this.paramIds_&&d.setAttribute("paramId",this.paramIds_[c]);b.appendChild(d)}this.hasStatements_||b.setAttribute("statements","false");return b},domToMutation:function(a){this.arguments_=[];for(var b=0,c;c=a.childNodes[b];b++)"arg"==c.nodeName.toLowerCase()&&
|
||||
this.arguments_.push(c.getAttribute("name"));this.updateParams_();Blockly.Procedures.mutateCallers(this);this.setStatements_("false"!==a.getAttribute("statements"))},decompose:function(a){var b=a.newBlock("procedures_mutatorcontainer");b.initSvg();this.getInput("RETURN")?b.setFieldValue(this.hasStatements_?"TRUE":"FALSE","STATEMENTS"):b.getInput("STATEMENT_INPUT").setVisible(!1);for(var c=b.getInput("STACK").connection,d=0;d<this.arguments_.length;d++){var e=a.newBlock("procedures_mutatorarg");e.initSvg();
|
||||
e.setFieldValue(this.arguments_[d],"NAME");e.oldLocation=d;c.connect(e.previousConnection);c=e.nextConnection}Blockly.Procedures.mutateCallers(this);return b},compose:function(a){this.arguments_=[];this.paramIds_=[];for(var b=a.getInputTargetBlock("STACK");b;)this.arguments_.push(b.getFieldValue("NAME")),this.paramIds_.push(b.id),b=b.nextConnection&&b.nextConnection.targetBlock();this.updateParams_();Blockly.Procedures.mutateCallers(this);a=a.getFieldValue("STATEMENTS");if(null!==a&&(a="TRUE"==a,
|
||||
this.hasStatements_!=a))if(a)this.setStatements_(!0),Blockly.Mutator.reconnect(this.statementConnection_,this,"STACK"),this.statementConnection_=null;else{a=this.getInput("STACK").connection;if(this.statementConnection_=a.targetConnection)a=a.targetBlock(),a.unplug(),a.bumpNeighbours_();this.setStatements_(!1)}},getProcedureDef:function(){return[this.getFieldValue("NAME"),this.arguments_,!1]},getVars:function(){return this.arguments_},renameVar:function(a,b){for(var c=!1,d=0;d<this.arguments_.length;d++)Blockly.Names.equals(a,
|
||||
this.arguments_[d])&&(this.arguments_[d]=b,c=!0);if(c&&(this.updateParams_(),this.mutator.isVisible())){c=this.mutator.workspace_.getAllBlocks();d=0;for(var e;e=c[d];d++)"procedures_mutatorarg"==e.type&&Blockly.Names.equals(a,e.getFieldValue("NAME"))&&e.setFieldValue(b,"NAME")}},customContextMenu:function(a){var b={enabled:!0},c=this.getFieldValue("NAME");b.text=Blockly.Msg.PROCEDURES_CREATE_DO.replace("%1",c);var d=goog.dom.createDom("mutation");d.setAttribute("name",c);for(var e=0;e<this.arguments_.length;e++)c=
|
||||
goog.dom.createDom("arg"),c.setAttribute("name",this.arguments_[e]),d.appendChild(c);d=goog.dom.createDom("block",null,d);d.setAttribute("type",this.callType_);b.callback=Blockly.ContextMenu.callbackFactory(this,d);a.push(b);if(!this.isCollapsed())for(e=0;e<this.arguments_.length;e++)b={enabled:!0},c=this.arguments_[e],b.text=Blockly.Msg.VARIABLES_SET_CREATE_GET.replace("%1",c),d=goog.dom.createDom("field",null,c),d.setAttribute("name","VAR"),d=goog.dom.createDom("block",null,d),d.setAttribute("type",
|
||||
"variables_get"),b.callback=Blockly.ContextMenu.callbackFactory(this,d),a.push(b)},callType_:"procedures_callnoreturn"};
|
||||
Blockly.Blocks.procedures_defreturn={init:function(){var a=new Blockly.FieldTextInput("",Blockly.Procedures.rename);a.setSpellcheck(!1);this.appendDummyInput().appendField(Blockly.Msg.PROCEDURES_DEFRETURN_TITLE).appendField(a,"NAME").appendField("","PARAMS");this.appendValueInput("RETURN").setAlign(Blockly.ALIGN_RIGHT).appendField(Blockly.Msg.PROCEDURES_DEFRETURN_RETURN);this.setMutator(new Blockly.Mutator(["procedures_mutatorarg"]));(this.workspace.options.comments||this.workspace.options.parentWorkspace&&
|
||||
this.workspace.options.parentWorkspace.options.comments)&&Blockly.Msg.PROCEDURES_DEFRETURN_COMMENT&&this.setCommentText(Blockly.Msg.PROCEDURES_DEFRETURN_COMMENT);this.setColour(Blockly.Blocks.procedures.HUE);this.setTooltip(Blockly.Msg.PROCEDURES_DEFRETURN_TOOLTIP);this.setHelpUrl(Blockly.Msg.PROCEDURES_DEFRETURN_HELPURL);this.arguments_=[];this.setStatements_(!0);this.statementConnection_=null},setStatements_:Blockly.Blocks.procedures_defnoreturn.setStatements_,updateParams_:Blockly.Blocks.procedures_defnoreturn.updateParams_,
|
||||
mutationToDom:Blockly.Blocks.procedures_defnoreturn.mutationToDom,domToMutation:Blockly.Blocks.procedures_defnoreturn.domToMutation,decompose:Blockly.Blocks.procedures_defnoreturn.decompose,compose:Blockly.Blocks.procedures_defnoreturn.compose,getProcedureDef:function(){return[this.getFieldValue("NAME"),this.arguments_,!0]},getVars:Blockly.Blocks.procedures_defnoreturn.getVars,renameVar:Blockly.Blocks.procedures_defnoreturn.renameVar,customContextMenu:Blockly.Blocks.procedures_defnoreturn.customContextMenu,
|
||||
callType_:"procedures_callreturn"};Blockly.Blocks.procedures_mutatorcontainer={init:function(){this.appendDummyInput().appendField(Blockly.Msg.PROCEDURES_MUTATORCONTAINER_TITLE);this.appendStatementInput("STACK");this.appendDummyInput("STATEMENT_INPUT").appendField(Blockly.Msg.PROCEDURES_ALLOW_STATEMENTS).appendField(new Blockly.FieldCheckbox("TRUE"),"STATEMENTS");this.setColour(Blockly.Blocks.procedures.HUE);this.setTooltip(Blockly.Msg.PROCEDURES_MUTATORCONTAINER_TOOLTIP);this.contextMenu=!1}};
|
||||
Blockly.Blocks.procedures_mutatorarg={init:function(){var a=new Blockly.FieldTextInput("x",this.validator_);this.appendDummyInput().appendField(Blockly.Msg.PROCEDURES_MUTATORARG_TITLE).appendField(a,"NAME");this.setPreviousStatement(!0);this.setNextStatement(!0);this.setColour(Blockly.Blocks.procedures.HUE);this.setTooltip(Blockly.Msg.PROCEDURES_MUTATORARG_TOOLTIP);this.contextMenu=!1;a.onFinishEditing_=this.createNewVar_;a.onFinishEditing_("x")},validator_:function(a){return(a=a.replace(/[\s\xa0]+/g,
|
||||
" ").replace(/^ | $/g,""))||null},createNewVar_:function(a){var b=this.sourceBlock_;if(b&&b.workspace&&b.workspace.options&&b.workspace.options.parentWorkspace){b=b.workspace.options.parentWorkspace;var c=b.getVariable(a);c&&c.name!==a?b.renameVariableById(c.getId(),a):b.createVariable(a)}}};
|
||||
Blockly.Blocks.procedures_callnoreturn={init:function(){this.appendDummyInput("TOPROW").appendField(this.id,"NAME");this.setPreviousStatement(!0);this.setNextStatement(!0);this.setColour(Blockly.Blocks.procedures.HUE);this.setHelpUrl(Blockly.Msg.PROCEDURES_CALLNORETURN_HELPURL);this.arguments_=[];this.quarkConnections_={};this.quarkIds_=null},getProcedureCall:function(){return this.getFieldValue("NAME")},renameProcedure:function(a,b){Blockly.Names.equals(a,this.getProcedureCall())&&(this.setFieldValue(b,
|
||||
"NAME"),this.setTooltip((this.outputConnection?Blockly.Msg.PROCEDURES_CALLRETURN_TOOLTIP:Blockly.Msg.PROCEDURES_CALLNORETURN_TOOLTIP).replace("%1",b)))},setProcedureParameters_:function(a,b){var c=Blockly.Procedures.getDefinition(this.getProcedureCall(),this.workspace),d=c&&c.mutator&&c.mutator.isVisible();d||(this.quarkConnections_={},this.quarkIds_=null);if(b)if(goog.array.equals(this.arguments_,a))this.quarkIds_=b;else{if(b.length!=a.length)throw"Error: paramNames and paramIds must be the same length.";
|
||||
this.setCollapsed(!1);this.quarkIds_||(this.quarkConnections_={},a.join("\n")==this.arguments_.join("\n")?this.quarkIds_=b:this.quarkIds_=[]);c=this.rendered;this.rendered=!1;for(var e=0;e<this.arguments_.length;e++){var f=this.getInput("ARG"+e);f&&(f=f.connection.targetConnection,this.quarkConnections_[this.quarkIds_[e]]=f,d&&f&&-1==b.indexOf(this.quarkIds_[e])&&(f.disconnect(),f.getSourceBlock().bumpNeighbours_()))}this.arguments_=[].concat(a);this.updateShape_();if(this.quarkIds_=b)for(e=0;e<this.arguments_.length;e++)d=
|
||||
this.quarkIds_[e],d in this.quarkConnections_&&(f=this.quarkConnections_[d],Blockly.Mutator.reconnect(f,this,"ARG"+e)||delete this.quarkConnections_[d]);(this.rendered=c)&&this.render()}},updateShape_:function(){for(var a=0;a<this.arguments_.length;a++){var b=this.getField("ARGNAME"+a);if(b){Blockly.Events.disable();try{b.setValue(this.arguments_[a])}finally{Blockly.Events.enable()}}else b=new Blockly.FieldLabel(this.arguments_[a]),this.appendValueInput("ARG"+a).setAlign(Blockly.ALIGN_RIGHT).appendField(b,
|
||||
"ARGNAME"+a).init()}for(;this.getInput("ARG"+a);)this.removeInput("ARG"+a),a++;if(a=this.getInput("TOPROW"))this.arguments_.length?this.getField("WITH")||(a.appendField(Blockly.Msg.PROCEDURES_CALL_BEFORE_PARAMS,"WITH"),a.init()):this.getField("WITH")&&a.removeField("WITH")},mutationToDom:function(){var a=document.createElement("mutation");a.setAttribute("name",this.getProcedureCall());for(var b=0;b<this.arguments_.length;b++){var c=document.createElement("arg");c.setAttribute("name",this.arguments_[b]);
|
||||
a.appendChild(c)}return a},domToMutation:function(a){var b=a.getAttribute("name");this.renameProcedure(this.getProcedureCall(),b);b=[];for(var c=[],d=0,e;e=a.childNodes[d];d++)"arg"==e.nodeName.toLowerCase()&&(b.push(e.getAttribute("name")),c.push(e.getAttribute("paramId")));this.setProcedureParameters_(b,c)},renameVar:function(a,b){for(var c=0;c<this.arguments_.length;c++)Blockly.Names.equals(a,this.arguments_[c])&&(this.arguments_[c]=b,this.getField("ARGNAME"+c).setValue(b))},onchange:function(a){if(this.workspace&&
|
||||
!this.workspace.isFlyout)if(a.type==Blockly.Events.BLOCK_CREATE&&-1!=a.ids.indexOf(this.id)){var b=this.getProcedureCall();b=Blockly.Procedures.getDefinition(b,this.workspace);!b||b.type==this.defType_&&JSON.stringify(b.arguments_)==JSON.stringify(this.arguments_)||(b=null);if(!b){Blockly.Events.setGroup(a.group);a=goog.dom.createDom("xml");b=goog.dom.createDom("block");b.setAttribute("type",this.defType_);var c=this.getRelativeToSurfaceXY(),d=c.y+2*Blockly.SNAP_RADIUS;b.setAttribute("x",c.x+Blockly.SNAP_RADIUS*
|
||||
(this.RTL?-1:1));b.setAttribute("y",d);c=this.mutationToDom();b.appendChild(c);c=goog.dom.createDom("field");c.setAttribute("name","NAME");c.appendChild(document.createTextNode(this.getProcedureCall()));b.appendChild(c);a.appendChild(b);Blockly.Xml.domToWorkspace(a,this.workspace);Blockly.Events.setGroup(!1)}}else a.type==Blockly.Events.BLOCK_DELETE&&(b=this.getProcedureCall(),b=Blockly.Procedures.getDefinition(b,this.workspace),b||(Blockly.Events.setGroup(a.group),this.dispose(!0,!1),Blockly.Events.setGroup(!1)))},
|
||||
customContextMenu:function(a){var b={enabled:!0};b.text=Blockly.Msg.PROCEDURES_HIGHLIGHT_DEF;var c=this.getProcedureCall(),d=this.workspace;b.callback=function(){var a=Blockly.Procedures.getDefinition(c,d);a&&a.select()};a.push(b)},defType_:"procedures_defnoreturn"};
|
||||
Blockly.Blocks.procedures_callreturn={init:function(){this.appendDummyInput("TOPROW").appendField("","NAME");this.setOutput(!0);this.setColour(Blockly.Blocks.procedures.HUE);this.setHelpUrl(Blockly.Msg.PROCEDURES_CALLRETURN_HELPURL);this.arguments_=[];this.quarkConnections_={};this.quarkIds_=null},getProcedureCall:Blockly.Blocks.procedures_callnoreturn.getProcedureCall,renameProcedure:Blockly.Blocks.procedures_callnoreturn.renameProcedure,setProcedureParameters_:Blockly.Blocks.procedures_callnoreturn.setProcedureParameters_,
|
||||
updateShape_:Blockly.Blocks.procedures_callnoreturn.updateShape_,mutationToDom:Blockly.Blocks.procedures_callnoreturn.mutationToDom,domToMutation:Blockly.Blocks.procedures_callnoreturn.domToMutation,renameVar:Blockly.Blocks.procedures_callnoreturn.renameVar,onchange:Blockly.Blocks.procedures_callnoreturn.onchange,customContextMenu:Blockly.Blocks.procedures_callnoreturn.customContextMenu,defType_:"procedures_defreturn"};
|
||||
Blockly.Blocks.procedures_ifreturn={init:function(){this.appendValueInput("CONDITION").setCheck("Boolean").appendField(Blockly.Msg.CONTROLS_IF_MSG_IF);this.appendValueInput("VALUE").appendField(Blockly.Msg.PROCEDURES_DEFRETURN_RETURN);this.setInputsInline(!0);this.setPreviousStatement(!0);this.setNextStatement(!0);this.setColour(Blockly.Blocks.procedures.HUE);this.setTooltip(Blockly.Msg.PROCEDURES_IFRETURN_TOOLTIP);this.setHelpUrl(Blockly.Msg.PROCEDURES_IFRETURN_HELPURL);this.hasReturnValue_=!0},
|
||||
mutationToDom:function(){var a=document.createElement("mutation");a.setAttribute("value",Number(this.hasReturnValue_));return a},domToMutation:function(a){this.hasReturnValue_=1==a.getAttribute("value");this.hasReturnValue_||(this.removeInput("VALUE"),this.appendDummyInput("VALUE").appendField(Blockly.Msg.PROCEDURES_DEFRETURN_RETURN))},onchange:function(){if(this.workspace.isDragging&&!this.workspace.isDragging()){var a=!1,b=this;do{if(-1!=this.FUNCTION_TYPES.indexOf(b.type)){a=!0;break}b=b.getSurroundParent()}while(b);
|
||||
a?("procedures_defnoreturn"==b.type&&this.hasReturnValue_?(this.removeInput("VALUE"),this.appendDummyInput("VALUE").appendField(Blockly.Msg.PROCEDURES_DEFRETURN_RETURN),this.hasReturnValue_=!1):"procedures_defreturn"!=b.type||this.hasReturnValue_||(this.removeInput("VALUE"),this.appendValueInput("VALUE").appendField(Blockly.Msg.PROCEDURES_DEFRETURN_RETURN),this.hasReturnValue_=!0),this.setWarningText(null),this.isInFlyout||this.setDisabled(!1)):(this.setWarningText(Blockly.Msg.PROCEDURES_IFRETURN_WARNING),
|
||||
this.isInFlyout||this.getInheritedDisabled()||this.setDisabled(!0))}},FUNCTION_TYPES:["procedures_defnoreturn","procedures_defreturn"]};Blockly.Blocks.texts={};Blockly.Constants.Text={};Blockly.Constants.Text.HUE=160;Blockly.Blocks.texts.HUE=Blockly.Constants.Text.HUE;
|
||||
Blockly.defineBlocksWithJsonArray([{type:"text",message0:"%1",args0:[{type:"field_input",name:"TEXT",text:""}],output:"String",colour:"%{BKY_TEXTS_HUE}",helpUrl:"%{BKY_TEXT_TEXT_HELPURL}",tooltip:"%{BKY_TEXT_TEXT_TOOLTIP}",extensions:["text_quotes","parent_tooltip_when_inline"]},{type:"text_join",message0:"",output:"String",colour:"%{BKY_TEXTS_HUE}",helpUrl:"%{BKY_TEXT_JOIN_HELPURL}",tooltip:"%{BKY_TEXT_JOIN_TOOLTIP}",mutator:"text_join_mutator"},{type:"text_create_join_container",message0:"%{BKY_TEXT_CREATE_JOIN_TITLE_JOIN} %1 %2",
|
||||
args0:[{type:"input_dummy"},{type:"input_statement",name:"STACK"}],colour:"%{BKY_TEXTS_HUE}",tooltip:"%{BKY_TEXT_CREATE_JOIN_TOOLTIP}",enableContextMenu:!1},{type:"text_create_join_item",message0:"%{BKY_TEXT_CREATE_JOIN_ITEM_TITLE_ITEM}",previousStatement:null,nextStatement:null,colour:"%{BKY_TEXTS_HUE}",tooltip:"{%BKY_TEXT_CREATE_JOIN_ITEM_TOOLTIP}",enableContextMenu:!1},{type:"text_append",message0:"%{BKY_TEXT_APPEND_TITLE}",args0:[{type:"field_variable",name:"VAR",variable:"%{BKY_TEXT_APPEND_VARIABLE}"},
|
||||
{type:"input_value",name:"TEXT"}],previousStatement:null,nextStatement:null,colour:"%{BKY_TEXTS_HUE}",extensions:["text_append_tooltip"]},{type:"text_length",message0:"%{BKY_TEXT_LENGTH_TITLE}",args0:[{type:"input_value",name:"VALUE",check:["String","Array"]}],output:"Number",colour:"%{BKY_TEXTS_HUE}",tooltip:"%{BKY_TEXT_LENGTH_TOOLTIP}",helpUrl:"%{BKY_TEXT_LENGTH_HELPURL}"},{type:"text_isEmpty",message0:"%{BKY_TEXT_ISEMPTY_TITLE}",args0:[{type:"input_value",name:"VALUE",check:["String","Array"]}],
|
||||
output:"Boolean",colour:"%{BKY_TEXTS_HUE}",tooltip:"%{BKY_TEXT_ISEMPTY_TOOLTIP}",helpUrl:"%{BKY_TEXT_ISEMPTY_HELPURL}"},{type:"text_indexOf",message0:"%{BKY_TEXT_INDEXOF_TITLE}",args0:[{type:"input_value",name:"VALUE",check:"String"},{type:"field_dropdown",name:"END",options:[["%{BKY_TEXT_INDEXOF_OPERATOR_FIRST}","FIRST"],["%{BKY_TEXT_INDEXOF_OPERATOR_LAST}","LAST"]]},{type:"input_value",name:"FIND",check:"String"}],output:"Number",colour:"%{BKY_TEXTS_HUE}",helpUrl:"%{BKY_TEXT_INDEXOF_HELPURL}",inputsInline:!0,
|
||||
extensions:["text_indexOf_tooltip"]},{type:"text_charAt",message0:"%{BKY_TEXT_CHARAT_TITLE}",args0:[{type:"input_value",name:"VALUE",check:"String"},{type:"field_dropdown",name:"WHERE",options:[["%{BKY_TEXT_CHARAT_FROM_START}","FROM_START"],["%{BKY_TEXT_CHARAT_FROM_END}","FROM_END"],["%{BKY_TEXT_CHARAT_FIRST}","FIRST"],["%{BKY_TEXT_CHARAT_LAST}","LAST"],["%{BKY_TEXT_CHARAT_RANDOM}","RANDOM"]]}],output:"String",colour:"%{BKY_TEXTS_HUE}",helpUrl:"%{BKY_TEXT_CHARAT_HELPURL}",inputsInline:!0,mutator:"text_charAt_mutator"}]);
|
||||
Blockly.Blocks.text_getSubstring={init:function(){this.WHERE_OPTIONS_1=[[Blockly.Msg.TEXT_GET_SUBSTRING_START_FROM_START,"FROM_START"],[Blockly.Msg.TEXT_GET_SUBSTRING_START_FROM_END,"FROM_END"],[Blockly.Msg.TEXT_GET_SUBSTRING_START_FIRST,"FIRST"]];this.WHERE_OPTIONS_2=[[Blockly.Msg.TEXT_GET_SUBSTRING_END_FROM_START,"FROM_START"],[Blockly.Msg.TEXT_GET_SUBSTRING_END_FROM_END,"FROM_END"],[Blockly.Msg.TEXT_GET_SUBSTRING_END_LAST,"LAST"]];this.setHelpUrl(Blockly.Msg.TEXT_GET_SUBSTRING_HELPURL);this.setColour(Blockly.Blocks.texts.HUE);
|
||||
this.appendValueInput("STRING").setCheck("String").appendField(Blockly.Msg.TEXT_GET_SUBSTRING_INPUT_IN_TEXT);this.appendDummyInput("AT1");this.appendDummyInput("AT2");Blockly.Msg.TEXT_GET_SUBSTRING_TAIL&&this.appendDummyInput("TAIL").appendField(Blockly.Msg.TEXT_GET_SUBSTRING_TAIL);this.setInputsInline(!0);this.setOutput(!0,"String");this.updateAt_(1,!0);this.updateAt_(2,!0);this.setTooltip(Blockly.Msg.TEXT_GET_SUBSTRING_TOOLTIP)},mutationToDom:function(){var a=document.createElement("mutation"),
|
||||
b=this.getInput("AT1").type==Blockly.INPUT_VALUE;a.setAttribute("at1",b);b=this.getInput("AT2").type==Blockly.INPUT_VALUE;a.setAttribute("at2",b);return a},domToMutation:function(a){var b="true"==a.getAttribute("at1");a="true"==a.getAttribute("at2");this.updateAt_(1,b);this.updateAt_(2,a)},updateAt_:function(a,b){this.removeInput("AT"+a);this.removeInput("ORDINAL"+a,!0);b?(this.appendValueInput("AT"+a).setCheck("Number"),Blockly.Msg.ORDINAL_NUMBER_SUFFIX&&this.appendDummyInput("ORDINAL"+a).appendField(Blockly.Msg.ORDINAL_NUMBER_SUFFIX)):
|
||||
this.appendDummyInput("AT"+a);2==a&&Blockly.Msg.TEXT_GET_SUBSTRING_TAIL&&(this.removeInput("TAIL",!0),this.appendDummyInput("TAIL").appendField(Blockly.Msg.TEXT_GET_SUBSTRING_TAIL));var c=new Blockly.FieldDropdown(this["WHERE_OPTIONS_"+a],function(c){var d="FROM_START"==c||"FROM_END"==c;if(d!=b){var f=this.sourceBlock_;f.updateAt_(a,d);f.setFieldValue(c,"WHERE"+a);return null}});this.getInput("AT"+a).appendField(c,"WHERE"+a);1==a&&this.moveInputBefore("AT1","AT2")}};
|
||||
Blockly.Blocks.text_changeCase={init:function(){var a=[[Blockly.Msg.TEXT_CHANGECASE_OPERATOR_UPPERCASE,"UPPERCASE"],[Blockly.Msg.TEXT_CHANGECASE_OPERATOR_LOWERCASE,"LOWERCASE"],[Blockly.Msg.TEXT_CHANGECASE_OPERATOR_TITLECASE,"TITLECASE"]];this.setHelpUrl(Blockly.Msg.TEXT_CHANGECASE_HELPURL);this.setColour(Blockly.Blocks.texts.HUE);this.appendValueInput("TEXT").setCheck("String").appendField(new Blockly.FieldDropdown(a),"CASE");this.setOutput(!0,"String");this.setTooltip(Blockly.Msg.TEXT_CHANGECASE_TOOLTIP)}};
|
||||
Blockly.Blocks.text_trim={init:function(){var a=[[Blockly.Msg.TEXT_TRIM_OPERATOR_BOTH,"BOTH"],[Blockly.Msg.TEXT_TRIM_OPERATOR_LEFT,"LEFT"],[Blockly.Msg.TEXT_TRIM_OPERATOR_RIGHT,"RIGHT"]];this.setHelpUrl(Blockly.Msg.TEXT_TRIM_HELPURL);this.setColour(Blockly.Blocks.texts.HUE);this.appendValueInput("TEXT").setCheck("String").appendField(new Blockly.FieldDropdown(a),"MODE");this.setOutput(!0,"String");this.setTooltip(Blockly.Msg.TEXT_TRIM_TOOLTIP)}};
|
||||
Blockly.Blocks.text_print={init:function(){this.jsonInit({message0:Blockly.Msg.TEXT_PRINT_TITLE,args0:[{type:"input_value",name:"TEXT"}],previousStatement:null,nextStatement:null,colour:Blockly.Blocks.texts.HUE,tooltip:Blockly.Msg.TEXT_PRINT_TOOLTIP,helpUrl:Blockly.Msg.TEXT_PRINT_HELPURL})}};
|
||||
Blockly.Blocks.text_prompt_ext={init:function(){var a=[[Blockly.Msg.TEXT_PROMPT_TYPE_TEXT,"TEXT"],[Blockly.Msg.TEXT_PROMPT_TYPE_NUMBER,"NUMBER"]];this.setHelpUrl(Blockly.Msg.TEXT_PROMPT_HELPURL);this.setColour(Blockly.Blocks.texts.HUE);var b=this;a=new Blockly.FieldDropdown(a,function(a){b.updateType_(a)});this.appendValueInput("TEXT").appendField(a,"TYPE");this.setOutput(!0,"String");this.setTooltip(function(){return"TEXT"==b.getFieldValue("TYPE")?Blockly.Msg.TEXT_PROMPT_TOOLTIP_TEXT:Blockly.Msg.TEXT_PROMPT_TOOLTIP_NUMBER})},
|
||||
updateType_:function(a){this.outputConnection.setCheck("NUMBER"==a?"Number":"String")},mutationToDom:function(){var a=document.createElement("mutation");a.setAttribute("type",this.getFieldValue("TYPE"));return a},domToMutation:function(a){this.updateType_(a.getAttribute("type"))}};
|
||||
Blockly.Blocks.text_prompt={init:function(){this.mixin(Blockly.Constants.Text.QUOTE_IMAGE_MIXIN);var a=[[Blockly.Msg.TEXT_PROMPT_TYPE_TEXT,"TEXT"],[Blockly.Msg.TEXT_PROMPT_TYPE_NUMBER,"NUMBER"]],b=this;this.setHelpUrl(Blockly.Msg.TEXT_PROMPT_HELPURL);this.setColour(Blockly.Blocks.texts.HUE);a=new Blockly.FieldDropdown(a,function(a){b.updateType_(a)});this.appendDummyInput().appendField(a,"TYPE").appendField(this.newQuote_(!0)).appendField(new Blockly.FieldTextInput(""),"TEXT").appendField(this.newQuote_(!1));
|
||||
this.setOutput(!0,"String");this.setTooltip(function(){return"TEXT"==b.getFieldValue("TYPE")?Blockly.Msg.TEXT_PROMPT_TOOLTIP_TEXT:Blockly.Msg.TEXT_PROMPT_TOOLTIP_NUMBER})},updateType_:Blockly.Blocks.text_prompt_ext.updateType_,mutationToDom:Blockly.Blocks.text_prompt_ext.mutationToDom,domToMutation:Blockly.Blocks.text_prompt_ext.domToMutation};
|
||||
Blockly.Blocks.text_count={init:function(){this.jsonInit({message0:Blockly.Msg.TEXT_COUNT_MESSAGE0,args0:[{type:"input_value",name:"SUB",check:"String"},{type:"input_value",name:"TEXT",check:"String"}],output:"Number",inputsInline:!0,colour:Blockly.Blocks.texts.HUE,tooltip:Blockly.Msg.TEXT_COUNT_TOOLTIP,helpUrl:Blockly.Msg.TEXT_COUNT_HELPURL})}};
|
||||
Blockly.Blocks.text_replace={init:function(){this.jsonInit({message0:Blockly.Msg.TEXT_REPLACE_MESSAGE0,args0:[{type:"input_value",name:"FROM",check:"String"},{type:"input_value",name:"TO",check:"String"},{type:"input_value",name:"TEXT",check:"String"}],output:"String",inputsInline:!0,colour:Blockly.Blocks.texts.HUE,tooltip:Blockly.Msg.TEXT_REPLACE_TOOLTIP,helpUrl:Blockly.Msg.TEXT_REPLACE_HELPURL})}};
|
||||
Blockly.Blocks.text_reverse={init:function(){this.jsonInit({message0:Blockly.Msg.TEXT_REVERSE_MESSAGE0,args0:[{type:"input_value",name:"TEXT",check:"String"}],output:"String",inputsInline:!0,colour:Blockly.Blocks.texts.HUE,tooltip:Blockly.Msg.TEXT_REVERSE_TOOLTIP,helpUrl:Blockly.Msg.TEXT_REVERSE_HELPURL})}};
|
||||
Blockly.Constants.Text.QUOTE_IMAGE_MIXIN={QUOTE_IMAGE_LEFT_DATAURI:"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAKCAQAAAAqJXdxAAAAn0lEQVQI1z3OMa5BURSF4f/cQhAKjUQhuQmFNwGJEUi0RKN5rU7FHKhpjEH3TEMtkdBSCY1EIv8r7nFX9e29V7EBAOvu7RPjwmWGH/VuF8CyN9/OAdvqIXYLvtRaNjx9mMTDyo+NjAN1HNcl9ZQ5oQMM3dgDUqDo1l8DzvwmtZN7mnD+PkmLa+4mhrxVA9fRowBWmVBhFy5gYEjKMfz9AylsaRRgGzvZAAAAAElFTkSuQmCC",QUOTE_IMAGE_RIGHT_DATAURI:"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAKCAQAAAAqJXdxAAAAqUlEQVQI1z3KvUpCcRiA8ef9E4JNHhI0aFEacm1o0BsI0Slx8wa8gLauoDnoBhq7DcfWhggONDmJJgqCPA7neJ7p934EOOKOnM8Q7PDElo/4x4lFb2DmuUjcUzS3URnGib9qaPNbuXvBO3sGPHJDRG6fGVdMSeWDP2q99FQdFrz26Gu5Tq7dFMzUvbXy8KXeAj57cOklgA+u1B5AoslLtGIHQMaCVnwDnADZIFIrXsoXrgAAAABJRU5ErkJggg==",
|
||||
QUOTE_IMAGE_WIDTH:12,QUOTE_IMAGE_HEIGHT:12,quoteField_:function(a){for(var b=0,c;c=this.inputList[b];b++)for(var d=0,e;e=c.fieldRow[d];d++)if(a==e.name){c.insertFieldAt(d,this.newQuote_(!0));c.insertFieldAt(d+2,this.newQuote_(!1));return}console.warn('field named "'+a+'" not found in '+this.toDevString())},newQuote_:function(a){a=this.RTL?!a:a;return new Blockly.FieldImage(a?this.QUOTE_IMAGE_LEFT_DATAURI:this.QUOTE_IMAGE_RIGHT_DATAURI,this.QUOTE_IMAGE_WIDTH,this.QUOTE_IMAGE_HEIGHT,a?"\u201c":"\u201d")}};
|
||||
Blockly.Constants.Text.TEXT_QUOTES_EXTENSION=function(){this.mixin(Blockly.Constants.Text.QUOTE_IMAGE_MIXIN);this.quoteField_("TEXT")};
|
||||
Blockly.Constants.Text.TEXT_JOIN_MUTATOR_MIXIN={mutationToDom:function(){var a=document.createElement("mutation");a.setAttribute("items",this.itemCount_);return a},domToMutation:function(a){this.itemCount_=parseInt(a.getAttribute("items"),10);this.updateShape_()},decompose:function(a){var b=a.newBlock("text_create_join_container");b.initSvg();for(var c=b.getInput("STACK").connection,d=0;d<this.itemCount_;d++){var e=a.newBlock("text_create_join_item");e.initSvg();c.connect(e.previousConnection);c=
|
||||
e.nextConnection}return b},compose:function(a){var b=a.getInputTargetBlock("STACK");for(a=[];b;)a.push(b.valueConnection_),b=b.nextConnection&&b.nextConnection.targetBlock();for(b=0;b<this.itemCount_;b++){var c=this.getInput("ADD"+b).connection.targetConnection;c&&-1==a.indexOf(c)&&c.disconnect()}this.itemCount_=a.length;this.updateShape_();for(b=0;b<this.itemCount_;b++)Blockly.Mutator.reconnect(a[b],this,"ADD"+b)},saveConnections:function(a){a=a.getInputTargetBlock("STACK");for(var b=0;a;){var c=
|
||||
this.getInput("ADD"+b);a.valueConnection_=c&&c.connection.targetConnection;b++;a=a.nextConnection&&a.nextConnection.targetBlock()}},updateShape_:function(){this.itemCount_&&this.getInput("EMPTY")?this.removeInput("EMPTY"):this.itemCount_||this.getInput("EMPTY")||this.appendDummyInput("EMPTY").appendField(this.newQuote_(!0)).appendField(this.newQuote_(!1));for(var a=0;a<this.itemCount_;a++)if(!this.getInput("ADD"+a)){var b=this.appendValueInput("ADD"+a);0==a&&b.appendField(Blockly.Msg.TEXT_JOIN_TITLE_CREATEWITH)}for(;this.getInput("ADD"+
|
||||
a);)this.removeInput("ADD"+a),a++}};Blockly.Constants.Text.TEXT_JOIN_EXTENSION=function(){this.mixin(Blockly.Constants.Text.QUOTE_IMAGE_MIXIN);this.itemCount_=2;this.updateShape_();this.setMutator(new Blockly.Mutator(["text_create_join_item"]))};Blockly.Constants.Text.TEXT_APPEND_TOOLTIP_EXTENSION=function(){var a=this;this.setTooltip(function(){return Blockly.Msg.TEXT_APPEND_TOOLTIP?Blockly.Msg.TEXT_APPEND_TOOLTIP.replace("%1",a.getFieldValue("VAR")):""})};
|
||||
Blockly.Constants.Text.TEXT_INDEXOF_TOOLTIP_EXTENSION=function(){var a=this;this.setTooltip(function(){return Blockly.Msg.TEXT_INDEXOF_TOOLTIP.replace("%1",a.workspace.options.oneBasedIndex?"0":"-1")})};
|
||||
Blockly.Constants.Text.TEXT_CHARAT_MUTATOR_MIXIN={mutationToDom:function(){var a=document.createElement("mutation");a.setAttribute("at",!!this.isAt_);return a},domToMutation:function(a){a="false"!=a.getAttribute("at");this.updateAt_(a)},updateAt_:function(a){this.removeInput("AT",!0);this.removeInput("ORDINAL",!0);a&&(this.appendValueInput("AT").setCheck("Number"),Blockly.Msg.ORDINAL_NUMBER_SUFFIX&&this.appendDummyInput("ORDINAL").appendField(Blockly.Msg.ORDINAL_NUMBER_SUFFIX));Blockly.Msg.TEXT_CHARAT_TAIL&&
|
||||
(this.removeInput("TAIL",!0),this.appendDummyInput("TAIL").appendField(Blockly.Msg.TEXT_CHARAT_TAIL));this.isAt_=a}};
|
||||
Blockly.Constants.Text.TEXT_CHARAT_EXTENSION=function(){this.getField("WHERE").setValidator(function(a){var b="FROM_START"==a||"FROM_END"==a;if(b!=this.isAt_){var d=this.sourceBlock_;d.updateAt_(b);d.setFieldValue(a,"WHERE");return null}});this.updateAt_(!0);var a=this;this.setTooltip(function(){var b=a.getFieldValue("WHERE"),c=Blockly.Msg.TEXT_CHARAT_TOOLTIP;("FROM_START"==b||"FROM_END"==b)&&(b="FROM_START"==b?Blockly.Msg.LISTS_INDEX_FROM_START_TOOLTIP:Blockly.Msg.LISTS_INDEX_FROM_END_TOOLTIP)&&
|
||||
(c+=" "+b.replace("%1",a.workspace.options.oneBasedIndex?"#1":"#0"));return c})};Blockly.Extensions.register("text_indexOf_tooltip",Blockly.Constants.Text.TEXT_INDEXOF_TOOLTIP_EXTENSION);Blockly.Extensions.register("text_quotes",Blockly.Constants.Text.TEXT_QUOTES_EXTENSION);Blockly.Extensions.register("text_append_tooltip",Blockly.Constants.Text.TEXT_APPEND_TOOLTIP_EXTENSION);Blockly.Extensions.registerMutator("text_join_mutator",Blockly.Constants.Text.TEXT_JOIN_MUTATOR_MIXIN,Blockly.Constants.Text.TEXT_JOIN_EXTENSION);
|
||||
Blockly.Extensions.registerMutator("text_charAt_mutator",Blockly.Constants.Text.TEXT_CHARAT_MUTATOR_MIXIN,Blockly.Constants.Text.TEXT_CHARAT_EXTENSION);Blockly.Blocks.variables={};Blockly.Constants.Variables={};Blockly.Constants.Variables.HUE=330;Blockly.Blocks.variables.HUE=Blockly.Constants.Variables.HUE;
|
||||
Blockly.defineBlocksWithJsonArray([{type:"variables_get",message0:"%1",args0:[{type:"field_variable",name:"VAR",variable:"%{BKY_VARIABLES_DEFAULT_NAME}"}],output:null,colour:"%{BKY_VARIABLES_HUE}",helpUrl:"%{BKY_VARIABLES_GET_HELPURL}",tooltip:"%{BKY_VARIABLES_GET_TOOLTIP}",extensions:["contextMenu_variableSetterGetter"]},{type:"variables_set",message0:"%{BKY_VARIABLES_SET}",args0:[{type:"field_variable",name:"VAR",variable:"%{BKY_VARIABLES_DEFAULT_NAME}"},{type:"input_value",name:"VALUE"}],previousStatement:null,
|
||||
nextStatement:null,colour:"%{BKY_VARIABLES_HUE}",tooltip:"%{BKY_VARIABLES_SET_TOOLTIP}",helpUrl:"%{BKY_VARIABLES_SET_HELPURL}",extensions:["contextMenu_variableSetterGetter"]}]);
|
||||
Blockly.Constants.Variables.CUSTOM_CONTEXT_MENU_VARIABLE_GETTER_SETTER_MIXIN={customContextMenu:function(a){if("variables_get"==this.type)var b="variables_set",c=Blockly.Msg.VARIABLES_GET_CREATE_SET;else b="variables_get",c=Blockly.Msg.VARIABLES_SET_CREATE_GET;var d={enabled:0<this.workspace.remainingCapacity()},e=this.getFieldValue("VAR");d.text=c.replace("%1",e);c=goog.dom.createDom("field",null,e);c.setAttribute("name","VAR");c=goog.dom.createDom("block",null,c);c.setAttribute("type",b);d.callback=
|
||||
Blockly.ContextMenu.callbackFactory(this,c);a.push(d)}};Blockly.Extensions.registerMixin("contextMenu_variableSetterGetter",Blockly.Constants.Variables.CUSTOM_CONTEXT_MENU_VARIABLE_GETTER_SETTER_MIXIN);
|
||||
93
_server/blockly/javascript_compressed.js
Normal file
BIN
_server/blockly/media/1x1.gif
Normal file
|
After Width: | Height: | Size: 43 B |
BIN
_server/blockly/media/click.mp3
Normal file
BIN
_server/blockly/media/click.ogg
Normal file
BIN
_server/blockly/media/click.wav
Normal file
BIN
_server/blockly/media/delete.mp3
Normal file
BIN
_server/blockly/media/delete.ogg
Normal file
BIN
_server/blockly/media/delete.wav
Normal file
BIN
_server/blockly/media/disconnect.mp3
Normal file
BIN
_server/blockly/media/disconnect.ogg
Normal file
BIN
_server/blockly/media/disconnect.wav
Normal file
BIN
_server/blockly/media/handclosed.cur
Normal file
|
After Width: | Height: | Size: 326 B |
BIN
_server/blockly/media/handdelete.cur
Normal file
|
After Width: | Height: | Size: 766 B |
BIN
_server/blockly/media/handopen.cur
Normal file
|
After Width: | Height: | Size: 198 B |
BIN
_server/blockly/media/quote0.png
Normal file
|
After Width: | Height: | Size: 796 B |
BIN
_server/blockly/media/quote1.png
Normal file
|
After Width: | Height: | Size: 738 B |
BIN
_server/blockly/media/sprites.png
Normal file
|
After Width: | Height: | Size: 4.0 KiB |
74
_server/blockly/media/sprites.svg
Normal file
@ -0,0 +1,74 @@
|
||||
<?xml version="1.0" encoding="utf-8" standalone="no"?>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="96px" height="124px">
|
||||
<style type="text/css">
|
||||
#background {
|
||||
fill: none;
|
||||
}
|
||||
.arrows {
|
||||
fill: #000;
|
||||
stroke: none;
|
||||
}
|
||||
.selected>.arrows {
|
||||
fill: #fff;
|
||||
}
|
||||
.checkmark {
|
||||
fill: #000;
|
||||
font-family: sans-serif;
|
||||
font-size: 10pt;
|
||||
text-anchor: middle;
|
||||
}
|
||||
.trash {
|
||||
fill: #888;
|
||||
}
|
||||
.zoom {
|
||||
fill: none;
|
||||
stroke: #888;
|
||||
stroke-width: 2;
|
||||
stroke-linecap: round;
|
||||
}
|
||||
.zoom>.center {
|
||||
fill: #888;
|
||||
stroke-width: 0;
|
||||
}
|
||||
</style>
|
||||
<rect id="background" width="96" height="124" x="0" y="0" />
|
||||
|
||||
<g>
|
||||
<path class="arrows" d="M 13,1.5 13,14.5 1.74,8 z" />
|
||||
<path class="arrows" d="M 17.5,3 30.5,3 24,14.26 z" />
|
||||
<path class="arrows" d="M 35,1.5 35,14.5 46.26,8 z" />
|
||||
</g>
|
||||
<g class="selected" transform="translate(0, 16)">
|
||||
<path class="arrows" d="M 13,1.5 13,14.5 1.74,8 z" />
|
||||
<path class="arrows" d="M 17.5,3 30.5,3 24,14.26 z" />
|
||||
<path class="arrows" d="M 35,1.5 35,14.5 46.26,8 z" />
|
||||
</g>
|
||||
|
||||
<text class="checkmark" x="55.5" y="28">✓</text>
|
||||
|
||||
<g class="trash">
|
||||
<path d="M 2,41 v 6 h 42 v -6 h -10.5 l -3,-3 h -15 l -3,3 z" />
|
||||
<rect width="36" height="20" x="5" y="50" />
|
||||
<rect width="36" height="42" x="5" y="50" rx="4" ry="4" />
|
||||
</g>
|
||||
|
||||
<g class="zoom">
|
||||
<circle r="11.5" cx="16" cy="108" />
|
||||
<circle r="4.3" cx="16" cy="108" class="center" />
|
||||
<path d="m 28,108 h3" />
|
||||
<path d="m 1,108 h3" />
|
||||
<path d="m 16,120 v3" />
|
||||
<path d="m 16,93 v3" />
|
||||
</g>
|
||||
|
||||
<g class="zoom">
|
||||
<circle r="15" cx="48" cy="108" />
|
||||
<path d="m 48,101.6 v12.8" />
|
||||
<path d="m 41.6,108 h12.8" />
|
||||
</g>
|
||||
|
||||
<g class="zoom">
|
||||
<circle r="15" cx="80" cy="108" />
|
||||
<path d="m 73.6,108 h12.8" />
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.7 KiB |
425
_server/blockly/zh-hans.js
Normal file
@ -0,0 +1,425 @@
|
||||
// This file was automatically generated. Do not modify.
|
||||
|
||||
'use strict';
|
||||
|
||||
goog.provide('Blockly.Msg.zh.hans');
|
||||
|
||||
goog.require('Blockly.Msg');
|
||||
|
||||
/** @export */ Blockly.Msg.ADD_COMMENT = "添加注释";
|
||||
/** @export */ Blockly.Msg.CANNOT_DELETE_VARIABLE_PROCEDURE = "不能删除变量“%1”,因为它是功能“%2”定义的一部分";
|
||||
/** @export */ Blockly.Msg.CHANGE_VALUE_TITLE = "更改值:";
|
||||
/** @export */ Blockly.Msg.CLEAN_UP = "整理块";
|
||||
/** @export */ Blockly.Msg.COLLAPSE_ALL = "折叠块";
|
||||
/** @export */ Blockly.Msg.COLLAPSE_BLOCK = "折叠块";
|
||||
/** @export */ Blockly.Msg.COLOUR_BLEND_COLOUR1 = "颜色1";
|
||||
/** @export */ Blockly.Msg.COLOUR_BLEND_COLOUR2 = "颜色2";
|
||||
/** @export */ Blockly.Msg.COLOUR_BLEND_HELPURL = "http://meyerweb.com/eric/tools/color-blend/"; // untranslated
|
||||
/** @export */ Blockly.Msg.COLOUR_BLEND_RATIO = "比例";
|
||||
/** @export */ Blockly.Msg.COLOUR_BLEND_TITLE = "混合";
|
||||
/** @export */ Blockly.Msg.COLOUR_BLEND_TOOLTIP = "用一个给定的比率(0.0-1.0)混合两种颜色。";
|
||||
/** @export */ Blockly.Msg.COLOUR_PICKER_HELPURL = "https://zh.wikipedia.org/wiki/颜色";
|
||||
/** @export */ Blockly.Msg.COLOUR_PICKER_TOOLTIP = "从调色板中选择一种颜色。";
|
||||
/** @export */ Blockly.Msg.COLOUR_RANDOM_HELPURL = "http://randomcolour.com"; // untranslated
|
||||
/** @export */ Blockly.Msg.COLOUR_RANDOM_TITLE = "随机颜色";
|
||||
/** @export */ Blockly.Msg.COLOUR_RANDOM_TOOLTIP = "随机选择一种颜色。";
|
||||
/** @export */ Blockly.Msg.COLOUR_RGB_BLUE = "蓝色";
|
||||
/** @export */ Blockly.Msg.COLOUR_RGB_GREEN = "绿色";
|
||||
/** @export */ Blockly.Msg.COLOUR_RGB_HELPURL = "http://www.december.com/html/spec/colorper.html"; // untranslated
|
||||
/** @export */ Blockly.Msg.COLOUR_RGB_RED = "红色";
|
||||
/** @export */ Blockly.Msg.COLOUR_RGB_TITLE = "颜色";
|
||||
/** @export */ Blockly.Msg.COLOUR_RGB_TOOLTIP = "通过指定红色、绿色和蓝色的量创建一种颜色。所有的值必须在0和100之间。";
|
||||
/** @export */ Blockly.Msg.CONTROLS_FLOW_STATEMENTS_HELPURL = "https://github.com/google/blockly/wiki/Loops#loop-termination-blocks"; // untranslated
|
||||
/** @export */ Blockly.Msg.CONTROLS_FLOW_STATEMENTS_OPERATOR_BREAK = "中断循环";
|
||||
/** @export */ Blockly.Msg.CONTROLS_FLOW_STATEMENTS_OPERATOR_CONTINUE = "继续下一次循环";
|
||||
/** @export */ Blockly.Msg.CONTROLS_FLOW_STATEMENTS_TOOLTIP_BREAK = "中断包含它的循环。";
|
||||
/** @export */ Blockly.Msg.CONTROLS_FLOW_STATEMENTS_TOOLTIP_CONTINUE = "跳过这个循环的剩余部分,并继续下一次迭代。";
|
||||
/** @export */ Blockly.Msg.CONTROLS_FLOW_STATEMENTS_WARNING = "警告:此块仅可用于在一个循环内。";
|
||||
/** @export */ Blockly.Msg.CONTROLS_FOREACH_HELPURL = "https://github.com/google/blockly/wiki/Loops#for-each"; // untranslated
|
||||
/** @export */ Blockly.Msg.CONTROLS_FOREACH_TITLE = "为每个项目 %1 在列表中 %2";
|
||||
/** @export */ Blockly.Msg.CONTROLS_FOREACH_TOOLTIP = "遍历每个列表中的项目,将变量“%1”设定到该项中,然后执行某些语句。";
|
||||
/** @export */ Blockly.Msg.CONTROLS_FOR_HELPURL = "https://github.com/google/blockly/wiki/Loops#count-with"; // untranslated
|
||||
/** @export */ Blockly.Msg.CONTROLS_FOR_TITLE = "使用 %1 从范围 %2 到 %3 每隔 %4";
|
||||
/** @export */ Blockly.Msg.CONTROLS_FOR_TOOLTIP = "从起始数到结尾数中取出变量“%1”的值,按指定的时间间隔,执行指定的块。";
|
||||
/** @export */ Blockly.Msg.CONTROLS_IF_ELSEIF_TOOLTIP = "在if语句块中增加一个条件。";
|
||||
/** @export */ Blockly.Msg.CONTROLS_IF_ELSE_TOOLTIP = "添加一个最终的,包括所有情况的节到if块中。";
|
||||
/** @export */ Blockly.Msg.CONTROLS_IF_HELPURL = "https://github.com/google/blockly/wiki/IfElse"; // untranslated
|
||||
/** @export */ Blockly.Msg.CONTROLS_IF_IF_TOOLTIP = "增加、删除或重新排列各节来重新配置“if”块。";
|
||||
/** @export */ Blockly.Msg.CONTROLS_IF_MSG_ELSE = "否则";
|
||||
/** @export */ Blockly.Msg.CONTROLS_IF_MSG_ELSEIF = "否则如果";
|
||||
/** @export */ Blockly.Msg.CONTROLS_IF_MSG_IF = "如果";
|
||||
/** @export */ Blockly.Msg.CONTROLS_IF_TOOLTIP_1 = "如果值为真,执行一些语句。";
|
||||
/** @export */ Blockly.Msg.CONTROLS_IF_TOOLTIP_2 = "如果值为真,则执行第一块语句。否则,则执行第二块语句。";
|
||||
/** @export */ Blockly.Msg.CONTROLS_IF_TOOLTIP_3 = "如果第一个值为真,则执行第一块的语句。否则,如果第二个值为真,则执行第二块的语句。";
|
||||
/** @export */ Blockly.Msg.CONTROLS_IF_TOOLTIP_4 = "如果第一个值为真,则执行第一块对语句。否则,如果第二个值为真,则执行语句的第二块。如果没有值为真,则执行最后一块的语句。";
|
||||
/** @export */ Blockly.Msg.CONTROLS_REPEAT_HELPURL = "https://zh.wikipedia.org/wiki/For循环";
|
||||
/** @export */ Blockly.Msg.CONTROLS_REPEAT_INPUT_DO = "执行";
|
||||
/** @export */ Blockly.Msg.CONTROLS_REPEAT_TITLE = "重复 %1 次";
|
||||
/** @export */ Blockly.Msg.CONTROLS_REPEAT_TOOLTIP = "多次执行一些语句。";
|
||||
/** @export */ Blockly.Msg.CONTROLS_WHILEUNTIL_HELPURL = "https://github.com/google/blockly/wiki/Loops#repeat"; // untranslated
|
||||
/** @export */ Blockly.Msg.CONTROLS_WHILEUNTIL_OPERATOR_UNTIL = "重复直到";
|
||||
/** @export */ Blockly.Msg.CONTROLS_WHILEUNTIL_OPERATOR_WHILE = "重复当";
|
||||
/** @export */ Blockly.Msg.CONTROLS_WHILEUNTIL_TOOLTIP_UNTIL = "只要值为假,执行一些语句。";
|
||||
/** @export */ Blockly.Msg.CONTROLS_WHILEUNTIL_TOOLTIP_WHILE = "只要值为真,执行一些语句。";
|
||||
/** @export */ Blockly.Msg.DELETE_ALL_BLOCKS = "删除所有%1块吗?";
|
||||
/** @export */ Blockly.Msg.DELETE_BLOCK = "删除块";
|
||||
/** @export */ Blockly.Msg.DELETE_VARIABLE = "删除“%1”变量";
|
||||
/** @export */ Blockly.Msg.DELETE_VARIABLE_CONFIRMATION = "删除“%2”变量的%1用途么?";
|
||||
/** @export */ Blockly.Msg.DELETE_X_BLOCKS = "删除 %1 块";
|
||||
/** @export */ Blockly.Msg.DISABLE_BLOCK = "禁用块";
|
||||
/** @export */ Blockly.Msg.DUPLICATE_BLOCK = "复制";
|
||||
/** @export */ Blockly.Msg.ENABLE_BLOCK = "启用块";
|
||||
/** @export */ Blockly.Msg.EXPAND_ALL = "展开块";
|
||||
/** @export */ Blockly.Msg.EXPAND_BLOCK = "展开块";
|
||||
/** @export */ Blockly.Msg.EXTERNAL_INPUTS = "外部输入";
|
||||
/** @export */ Blockly.Msg.HELP = "帮助";
|
||||
/** @export */ Blockly.Msg.INLINE_INPUTS = "单行输入";
|
||||
/** @export */ Blockly.Msg.IOS_CANCEL = "取消";
|
||||
/** @export */ Blockly.Msg.IOS_ERROR = "错误";
|
||||
/** @export */ Blockly.Msg.IOS_OK = "确定";
|
||||
/** @export */ Blockly.Msg.IOS_PROCEDURES_ADD_INPUT = "+添加输入";
|
||||
/** @export */ Blockly.Msg.IOS_PROCEDURES_ALLOW_STATEMENTS = "允许声明";
|
||||
/** @export */ Blockly.Msg.IOS_PROCEDURES_DUPLICATE_INPUTS_ERROR = "此功能有重复输入内容。";
|
||||
/** @export */ Blockly.Msg.IOS_PROCEDURES_INPUTS = "输入";
|
||||
/** @export */ Blockly.Msg.IOS_VARIABLES_ADD_BUTTON = "添加";
|
||||
/** @export */ Blockly.Msg.IOS_VARIABLES_ADD_VARIABLE = "+添加变量";
|
||||
/** @export */ Blockly.Msg.IOS_VARIABLES_DELETE_BUTTON = "删除";
|
||||
/** @export */ Blockly.Msg.IOS_VARIABLES_EMPTY_NAME_ERROR = "您不能使用空变量名称。";
|
||||
/** @export */ Blockly.Msg.IOS_VARIABLES_RENAME_BUTTON = "重命名";
|
||||
/** @export */ Blockly.Msg.IOS_VARIABLES_VARIABLE_NAME = "变量名称";
|
||||
/** @export */ Blockly.Msg.LISTS_CREATE_EMPTY_HELPURL = "https://github.com/google/blockly/wiki/Lists#create-empty-list";
|
||||
/** @export */ Blockly.Msg.LISTS_CREATE_EMPTY_TITLE = "创建空列表";
|
||||
/** @export */ Blockly.Msg.LISTS_CREATE_EMPTY_TOOLTIP = "返回一个列表,长度为 0,不包含任何数据记录";
|
||||
/** @export */ Blockly.Msg.LISTS_CREATE_WITH_CONTAINER_TITLE_ADD = "列表";
|
||||
/** @export */ Blockly.Msg.LISTS_CREATE_WITH_CONTAINER_TOOLTIP = "增加、删除或重新排列各部分以此重新配置这个列表块。";
|
||||
/** @export */ Blockly.Msg.LISTS_CREATE_WITH_HELPURL = "https://github.com/google/blockly/wiki/Lists#create-list-with";
|
||||
/** @export */ Blockly.Msg.LISTS_CREATE_WITH_INPUT_WITH = "建立列表使用";
|
||||
/** @export */ Blockly.Msg.LISTS_CREATE_WITH_ITEM_TOOLTIP = "将一个项添加到列表中。";
|
||||
/** @export */ Blockly.Msg.LISTS_CREATE_WITH_TOOLTIP = "建立一个具有任意数量项目的列表。";
|
||||
/** @export */ Blockly.Msg.LISTS_GET_INDEX_FIRST = "第一";
|
||||
/** @export */ Blockly.Msg.LISTS_GET_INDEX_FROM_END = "倒数第#";
|
||||
/** @export */ Blockly.Msg.LISTS_GET_INDEX_FROM_START = "#";
|
||||
/** @export */ Blockly.Msg.LISTS_GET_INDEX_GET = "取得";
|
||||
/** @export */ Blockly.Msg.LISTS_GET_INDEX_GET_REMOVE = "取出并移除";
|
||||
/** @export */ Blockly.Msg.LISTS_GET_INDEX_LAST = "最后";
|
||||
/** @export */ Blockly.Msg.LISTS_GET_INDEX_RANDOM = "随机";
|
||||
/** @export */ Blockly.Msg.LISTS_GET_INDEX_REMOVE = "移除";
|
||||
/** @export */ Blockly.Msg.LISTS_GET_INDEX_TAIL = "空白";
|
||||
/** @export */ Blockly.Msg.LISTS_GET_INDEX_TOOLTIP_GET_FIRST = "返回列表中的第一个项目。";
|
||||
/** @export */ Blockly.Msg.LISTS_GET_INDEX_TOOLTIP_GET_FROM = "返回在列表中的指定位置的项。";
|
||||
/** @export */ Blockly.Msg.LISTS_GET_INDEX_TOOLTIP_GET_LAST = "返回列表中的最后一项。";
|
||||
/** @export */ Blockly.Msg.LISTS_GET_INDEX_TOOLTIP_GET_RANDOM = "随机返回列表中的一个项目。";
|
||||
/** @export */ Blockly.Msg.LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FIRST = "移除并返回列表中的第一个项目。";
|
||||
/** @export */ Blockly.Msg.LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FROM = "移除并返回列表中的指定位置的项。";
|
||||
/** @export */ Blockly.Msg.LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_LAST = "移除并返回列表中的最后一个项目。";
|
||||
/** @export */ Blockly.Msg.LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_RANDOM = "移除并返回列表中的一个随机项目中。";
|
||||
/** @export */ Blockly.Msg.LISTS_GET_INDEX_TOOLTIP_REMOVE_FIRST = "移除列表中的第一项";
|
||||
/** @export */ Blockly.Msg.LISTS_GET_INDEX_TOOLTIP_REMOVE_FROM = "移除在列表中的指定位置的项。";
|
||||
/** @export */ Blockly.Msg.LISTS_GET_INDEX_TOOLTIP_REMOVE_LAST = "移除列表中的最后一项";
|
||||
/** @export */ Blockly.Msg.LISTS_GET_INDEX_TOOLTIP_REMOVE_RANDOM = "删除列表中的一个随机的项。";
|
||||
/** @export */ Blockly.Msg.LISTS_GET_SUBLIST_END_FROM_END = "到倒数第#";
|
||||
/** @export */ Blockly.Msg.LISTS_GET_SUBLIST_END_FROM_START = "到#";
|
||||
/** @export */ Blockly.Msg.LISTS_GET_SUBLIST_END_LAST = "到最后";
|
||||
/** @export */ Blockly.Msg.LISTS_GET_SUBLIST_HELPURL = "https://github.com/google/blockly/wiki/Lists#getting-a-sublist"; // untranslated
|
||||
/** @export */ Blockly.Msg.LISTS_GET_SUBLIST_START_FIRST = "从头获得子列表";
|
||||
/** @export */ Blockly.Msg.LISTS_GET_SUBLIST_START_FROM_END = "从倒数#取得子列表";
|
||||
/** @export */ Blockly.Msg.LISTS_GET_SUBLIST_START_FROM_START = "从#取得子列表";
|
||||
/** @export */ Blockly.Msg.LISTS_GET_SUBLIST_TAIL = "空白";
|
||||
/** @export */ Blockly.Msg.LISTS_GET_SUBLIST_TOOLTIP = "复制列表中指定的部分。";
|
||||
/** @export */ Blockly.Msg.LISTS_INDEX_FROM_END_TOOLTIP = "%1是最后一项。";
|
||||
/** @export */ Blockly.Msg.LISTS_INDEX_FROM_START_TOOLTIP = "%1是第一个项目。";
|
||||
/** @export */ Blockly.Msg.LISTS_INDEX_OF_FIRST = "找出第一个项出现";
|
||||
/** @export */ Blockly.Msg.LISTS_INDEX_OF_HELPURL = "https://github.com/google/blockly/wiki/Lists#getting-items-from-a-list"; // untranslated
|
||||
/** @export */ Blockly.Msg.LISTS_INDEX_OF_LAST = "找出最后一个项出现";
|
||||
/** @export */ Blockly.Msg.LISTS_INDEX_OF_TOOLTIP = "返回在列表中的第一/最后一个匹配项的索引值。如果找不到项目则返回%1。";
|
||||
/** @export */ Blockly.Msg.LISTS_INLIST = "在列表中";
|
||||
/** @export */ Blockly.Msg.LISTS_ISEMPTY_HELPURL = "https://github.com/google/blockly/wiki/Lists#is-empty"; // untranslated
|
||||
/** @export */ Blockly.Msg.LISTS_ISEMPTY_TITLE = "%1是空的";
|
||||
/** @export */ Blockly.Msg.LISTS_ISEMPTY_TOOLTIP = "如果改列表为空,则返回真。";
|
||||
/** @export */ Blockly.Msg.LISTS_LENGTH_HELPURL = "https://github.com/google/blockly/wiki/Lists#length-of"; // untranslated
|
||||
/** @export */ Blockly.Msg.LISTS_LENGTH_TITLE = "%1的长度";
|
||||
/** @export */ Blockly.Msg.LISTS_LENGTH_TOOLTIP = "返回列表的长度。";
|
||||
/** @export */ Blockly.Msg.LISTS_REPEAT_HELPURL = "https://github.com/google/blockly/wiki/Lists#create-list-with"; // untranslated
|
||||
/** @export */ Blockly.Msg.LISTS_REPEAT_TITLE = "建立列表使用项 %1 重复 %2 次";
|
||||
/** @export */ Blockly.Msg.LISTS_REPEAT_TOOLTIP = "建立包含指定重复次数的值的列表。";
|
||||
/** @export */ Blockly.Msg.LISTS_REVERSE_HELPURL = "https://github.com/google/blockly/wiki/Lists#reversing-a-list";
|
||||
/** @export */ Blockly.Msg.LISTS_REVERSE_MESSAGE0 = "倒转%1";
|
||||
/** @export */ Blockly.Msg.LISTS_REVERSE_TOOLTIP = "倒转一个列表的拷贝。";
|
||||
/** @export */ Blockly.Msg.LISTS_SET_INDEX_HELPURL = "https://github.com/google/blockly/wiki/Lists#in-list--set"; // untranslated
|
||||
/** @export */ Blockly.Msg.LISTS_SET_INDEX_INPUT_TO = "为";
|
||||
/** @export */ Blockly.Msg.LISTS_SET_INDEX_INSERT = "插入在";
|
||||
/** @export */ Blockly.Msg.LISTS_SET_INDEX_SET = "设置";
|
||||
/** @export */ Blockly.Msg.LISTS_SET_INDEX_TOOLTIP_INSERT_FIRST = "在列表的起始处添加该项。";
|
||||
/** @export */ Blockly.Msg.LISTS_SET_INDEX_TOOLTIP_INSERT_FROM = "插入在列表中指定位置的项。";
|
||||
/** @export */ Blockly.Msg.LISTS_SET_INDEX_TOOLTIP_INSERT_LAST = "将该项追加到列表的末尾。";
|
||||
/** @export */ Blockly.Msg.LISTS_SET_INDEX_TOOLTIP_INSERT_RANDOM = "在列表中随机插入项。";
|
||||
/** @export */ Blockly.Msg.LISTS_SET_INDEX_TOOLTIP_SET_FIRST = "设置列表中的第一个项目。";
|
||||
/** @export */ Blockly.Msg.LISTS_SET_INDEX_TOOLTIP_SET_FROM = "设置在列表中指定位置的项。";
|
||||
/** @export */ Blockly.Msg.LISTS_SET_INDEX_TOOLTIP_SET_LAST = "设置列表中的最后一项。";
|
||||
/** @export */ Blockly.Msg.LISTS_SET_INDEX_TOOLTIP_SET_RANDOM = "设置列表中一个随机的项目。";
|
||||
/** @export */ Blockly.Msg.LISTS_SORT_HELPURL = "https://github.com/google/blockly/wiki/Lists#sorting-a-list";
|
||||
/** @export */ Blockly.Msg.LISTS_SORT_ORDER_ASCENDING = "升序";
|
||||
/** @export */ Blockly.Msg.LISTS_SORT_ORDER_DESCENDING = "降序";
|
||||
/** @export */ Blockly.Msg.LISTS_SORT_TITLE = "排序%1 %2 %3";
|
||||
/** @export */ Blockly.Msg.LISTS_SORT_TOOLTIP = "排序一个列表的拷贝。";
|
||||
/** @export */ Blockly.Msg.LISTS_SORT_TYPE_IGNORECASE = "按字母排序,忽略大小写";
|
||||
/** @export */ Blockly.Msg.LISTS_SORT_TYPE_NUMERIC = "按数字排序";
|
||||
/** @export */ Blockly.Msg.LISTS_SORT_TYPE_TEXT = "按字母排序";
|
||||
/** @export */ Blockly.Msg.LISTS_SPLIT_HELPURL = "https://github.com/google/blockly/wiki/Lists#splitting-strings-and-joining-lists";
|
||||
/** @export */ Blockly.Msg.LISTS_SPLIT_LIST_FROM_TEXT = "从文本制作列表";
|
||||
/** @export */ Blockly.Msg.LISTS_SPLIT_TEXT_FROM_LIST = "从列表拆出文本";
|
||||
/** @export */ Blockly.Msg.LISTS_SPLIT_TOOLTIP_JOIN = "加入文本列表至一个文本,由分隔符分隔。";
|
||||
/** @export */ Blockly.Msg.LISTS_SPLIT_TOOLTIP_SPLIT = "拆分文本到文本列表,按每个分隔符拆分。";
|
||||
/** @export */ Blockly.Msg.LISTS_SPLIT_WITH_DELIMITER = "用分隔符";
|
||||
/** @export */ Blockly.Msg.LOGIC_BOOLEAN_FALSE = "假";
|
||||
/** @export */ Blockly.Msg.LOGIC_BOOLEAN_HELPURL = "https://github.com/google/blockly/wiki/Logic#values"; // untranslated
|
||||
/** @export */ Blockly.Msg.LOGIC_BOOLEAN_TOOLTIP = "返回真或假。";
|
||||
/** @export */ Blockly.Msg.LOGIC_BOOLEAN_TRUE = "真";
|
||||
/** @export */ Blockly.Msg.LOGIC_COMPARE_HELPURL = "https://zh.wikipedia.org/wiki/不等";
|
||||
/** @export */ Blockly.Msg.LOGIC_COMPARE_TOOLTIP_EQ = "如果两个输入结果相等,则返回真。";
|
||||
/** @export */ Blockly.Msg.LOGIC_COMPARE_TOOLTIP_GT = "如果第一个输入结果比第二个大,则返回真。";
|
||||
/** @export */ Blockly.Msg.LOGIC_COMPARE_TOOLTIP_GTE = "如果第一个输入结果大于或等于第二个输入结果,则返回真。";
|
||||
/** @export */ Blockly.Msg.LOGIC_COMPARE_TOOLTIP_LT = "如果第一个输入结果比第二个小,则返回真。";
|
||||
/** @export */ Blockly.Msg.LOGIC_COMPARE_TOOLTIP_LTE = "如果第一个输入结果小于或等于第二个输入结果,则返回真。";
|
||||
/** @export */ Blockly.Msg.LOGIC_COMPARE_TOOLTIP_NEQ = "如果两个输入结果不相等,则返回真。";
|
||||
/** @export */ Blockly.Msg.LOGIC_NEGATE_HELPURL = "https://github.com/google/blockly/wiki/Logic#not";
|
||||
/** @export */ Blockly.Msg.LOGIC_NEGATE_TITLE = "非%1";
|
||||
/** @export */ Blockly.Msg.LOGIC_NEGATE_TOOLTIP = "如果输入结果为假,则返回真;如果输入结果为真,则返回假。";
|
||||
/** @export */ Blockly.Msg.LOGIC_NULL = "空";
|
||||
/** @export */ Blockly.Msg.LOGIC_NULL_HELPURL = "https://en.wikipedia.org/wiki/Nullable_type"; // untranslated
|
||||
/** @export */ Blockly.Msg.LOGIC_NULL_TOOLTIP = "返回空值。";
|
||||
/** @export */ Blockly.Msg.LOGIC_OPERATION_AND = "和";
|
||||
/** @export */ Blockly.Msg.LOGIC_OPERATION_HELPURL = "https://github.com/google/blockly/wiki/Logic#logical-operations"; // untranslated
|
||||
/** @export */ Blockly.Msg.LOGIC_OPERATION_OR = "或";
|
||||
/** @export */ Blockly.Msg.LOGIC_OPERATION_TOOLTIP_AND = "如果两个输入结果都为真,则返回真。";
|
||||
/** @export */ Blockly.Msg.LOGIC_OPERATION_TOOLTIP_OR = "如果至少有一个输入结果为真,则返回真。";
|
||||
/** @export */ Blockly.Msg.LOGIC_TERNARY_CONDITION = "测试";
|
||||
/** @export */ Blockly.Msg.LOGIC_TERNARY_HELPURL = "https://zh.wikipedia.org/wiki/条件运算符";
|
||||
/** @export */ Blockly.Msg.LOGIC_TERNARY_IF_FALSE = "如果为假";
|
||||
/** @export */ Blockly.Msg.LOGIC_TERNARY_IF_TRUE = "如果为真";
|
||||
/** @export */ Blockly.Msg.LOGIC_TERNARY_TOOLTIP = "检查“test”中的条件。如果条件为真,则返回“if true”的值,否则,则返回“if false”的值。";
|
||||
/** @export */ Blockly.Msg.MATH_ADDITION_SYMBOL = "+"; // untranslated
|
||||
/** @export */ Blockly.Msg.MATH_ARITHMETIC_HELPURL = "https://zh.wikipedia.org/wiki/算术";
|
||||
/** @export */ Blockly.Msg.MATH_ARITHMETIC_TOOLTIP_ADD = "返回两个数字的和。";
|
||||
/** @export */ Blockly.Msg.MATH_ARITHMETIC_TOOLTIP_DIVIDE = "返回两个数字的商。";
|
||||
/** @export */ Blockly.Msg.MATH_ARITHMETIC_TOOLTIP_MINUS = "返回两个数字的区别。";
|
||||
/** @export */ Blockly.Msg.MATH_ARITHMETIC_TOOLTIP_MULTIPLY = "返回两个数字的乘积。";
|
||||
/** @export */ Blockly.Msg.MATH_ARITHMETIC_TOOLTIP_POWER = "返回第一个数的第二个数次幂。";
|
||||
/** @export */ Blockly.Msg.MATH_CHANGE_HELPURL = "https://zh.wikipedia.org/wiki/加法";
|
||||
/** @export */ Blockly.Msg.MATH_CHANGE_TITLE = "更改 %1 从 %2";
|
||||
/** @export */ Blockly.Msg.MATH_CHANGE_TOOLTIP = "将一个数添加到变量“%1”。";
|
||||
/** @export */ Blockly.Msg.MATH_CONSTANT_HELPURL = "https://zh.wikipedia.org/wiki/数学常数";
|
||||
/** @export */ Blockly.Msg.MATH_CONSTANT_TOOLTIP = "返回一个常见常量:π (3.141…)、e (2.718…)、φ (1.618…)、平方根 (1.414…)、开平方根 (0.707…)或∞ (infinity)。";
|
||||
/** @export */ Blockly.Msg.MATH_CONSTRAIN_HELPURL = "https://en.wikipedia.org/wiki/Clamping_(graphics)"; // untranslated
|
||||
/** @export */ Blockly.Msg.MATH_CONSTRAIN_TITLE = "限制数字 %1 介于 (低) %2 到 (高) %3";
|
||||
/** @export */ Blockly.Msg.MATH_CONSTRAIN_TOOLTIP = "限制数字介于两个指定的数字之间";
|
||||
/** @export */ Blockly.Msg.MATH_DIVISION_SYMBOL = "÷"; // untranslated
|
||||
/** @export */ Blockly.Msg.MATH_IS_DIVISIBLE_BY = "可被整除";
|
||||
/** @export */ Blockly.Msg.MATH_IS_EVEN = "是偶数";
|
||||
/** @export */ Blockly.Msg.MATH_IS_NEGATIVE = "为负";
|
||||
/** @export */ Blockly.Msg.MATH_IS_ODD = "是奇数";
|
||||
/** @export */ Blockly.Msg.MATH_IS_POSITIVE = "为正";
|
||||
/** @export */ Blockly.Msg.MATH_IS_PRIME = "是质数";
|
||||
/** @export */ Blockly.Msg.MATH_IS_TOOLTIP = "如果数字是偶数、奇数、非负整数、正数、负数或如果它可被某数字整除,则返回真或假。";
|
||||
/** @export */ Blockly.Msg.MATH_IS_WHOLE = "为整数";
|
||||
/** @export */ Blockly.Msg.MATH_MODULO_HELPURL = "https://zh.wikipedia.org/wiki/模除";
|
||||
/** @export */ Blockly.Msg.MATH_MODULO_TITLE = "取余数自 %1 ÷ %2";
|
||||
/** @export */ Blockly.Msg.MATH_MODULO_TOOLTIP = "返回这两个数字相除后的余数。";
|
||||
/** @export */ Blockly.Msg.MATH_MULTIPLICATION_SYMBOL = "×"; // untranslated
|
||||
/** @export */ Blockly.Msg.MATH_NUMBER_HELPURL = "https://zh.wikipedia.org/wiki/数";
|
||||
/** @export */ Blockly.Msg.MATH_NUMBER_TOOLTIP = "一个数字。";
|
||||
/** @export */ Blockly.Msg.MATH_ONLIST_HELPURL = ""; // untranslated
|
||||
/** @export */ Blockly.Msg.MATH_ONLIST_OPERATOR_AVERAGE = "列表中的平均数";
|
||||
/** @export */ Blockly.Msg.MATH_ONLIST_OPERATOR_MAX = "列表中的最大值";
|
||||
/** @export */ Blockly.Msg.MATH_ONLIST_OPERATOR_MEDIAN = "列表中位数";
|
||||
/** @export */ Blockly.Msg.MATH_ONLIST_OPERATOR_MIN = "列表中的最小值";
|
||||
/** @export */ Blockly.Msg.MATH_ONLIST_OPERATOR_MODE = "列表模式";
|
||||
/** @export */ Blockly.Msg.MATH_ONLIST_OPERATOR_RANDOM = "列表的随机项";
|
||||
/** @export */ Blockly.Msg.MATH_ONLIST_OPERATOR_STD_DEV = "列表中的标准差";
|
||||
/** @export */ Blockly.Msg.MATH_ONLIST_OPERATOR_SUM = "列表中的数的总和";
|
||||
/** @export */ Blockly.Msg.MATH_ONLIST_TOOLTIP_AVERAGE = "返回列表中的数值的平均值。";
|
||||
/** @export */ Blockly.Msg.MATH_ONLIST_TOOLTIP_MAX = "返回列表中最大数。";
|
||||
/** @export */ Blockly.Msg.MATH_ONLIST_TOOLTIP_MEDIAN = "返回列表中的中位数。";
|
||||
/** @export */ Blockly.Msg.MATH_ONLIST_TOOLTIP_MIN = "返回列表中最小数。";
|
||||
/** @export */ Blockly.Msg.MATH_ONLIST_TOOLTIP_MODE = "返回列表中的最常见的项的列表。";
|
||||
/** @export */ Blockly.Msg.MATH_ONLIST_TOOLTIP_RANDOM = "从列表中返回一个随机的元素。";
|
||||
/** @export */ Blockly.Msg.MATH_ONLIST_TOOLTIP_STD_DEV = "返回列表的标准偏差。";
|
||||
/** @export */ Blockly.Msg.MATH_ONLIST_TOOLTIP_SUM = "返回列表中的所有数字的和。";
|
||||
/** @export */ Blockly.Msg.MATH_POWER_SYMBOL = "^"; // untranslated
|
||||
/** @export */ Blockly.Msg.MATH_RANDOM_FLOAT_HELPURL = "https://zh.wikipedia.org/wiki/随机数生成器";
|
||||
/** @export */ Blockly.Msg.MATH_RANDOM_FLOAT_TITLE_RANDOM = "随机分数";
|
||||
/** @export */ Blockly.Msg.MATH_RANDOM_FLOAT_TOOLTIP = "返回介于(包含)0.0到1.0之间的随机数。";
|
||||
/** @export */ Blockly.Msg.MATH_RANDOM_INT_HELPURL = "https://zh.wikipedia.org/wiki/随机数生成器";
|
||||
/** @export */ Blockly.Msg.MATH_RANDOM_INT_TITLE = "从 %1 到 %2 之间的随机整数";
|
||||
/** @export */ Blockly.Msg.MATH_RANDOM_INT_TOOLTIP = "返回两个指定的范围(含)之间的随机整数。";
|
||||
/** @export */ Blockly.Msg.MATH_ROUND_HELPURL = "https://zh.wikipedia.org/wiki/数值修约";
|
||||
/** @export */ Blockly.Msg.MATH_ROUND_OPERATOR_ROUND = "向下舍入";
|
||||
/** @export */ Blockly.Msg.MATH_ROUND_OPERATOR_ROUNDDOWN = "向下舍入";
|
||||
/** @export */ Blockly.Msg.MATH_ROUND_OPERATOR_ROUNDUP = "向上舍入";
|
||||
/** @export */ Blockly.Msg.MATH_ROUND_TOOLTIP = "数字向上或向下舍入。";
|
||||
/** @export */ Blockly.Msg.MATH_SINGLE_HELPURL = "https://zh.wikipedia.org/wiki/平方根";
|
||||
/** @export */ Blockly.Msg.MATH_SINGLE_OP_ABSOLUTE = "绝对";
|
||||
/** @export */ Blockly.Msg.MATH_SINGLE_OP_ROOT = "平方根";
|
||||
/** @export */ Blockly.Msg.MATH_SINGLE_TOOLTIP_ABS = "返回一个数的绝对值。";
|
||||
/** @export */ Blockly.Msg.MATH_SINGLE_TOOLTIP_EXP = "返回一个数的e次幂。";
|
||||
/** @export */ Blockly.Msg.MATH_SINGLE_TOOLTIP_LN = "返回一个数的自然对数。";
|
||||
/** @export */ Blockly.Msg.MATH_SINGLE_TOOLTIP_LOG10 = "返回一个数的对数。";
|
||||
/** @export */ Blockly.Msg.MATH_SINGLE_TOOLTIP_NEG = "返回一个数的逻辑非。";
|
||||
/** @export */ Blockly.Msg.MATH_SINGLE_TOOLTIP_POW10 = "返回一个数的10次幂。";
|
||||
/** @export */ Blockly.Msg.MATH_SINGLE_TOOLTIP_ROOT = "返回一个数的平方根。";
|
||||
/** @export */ Blockly.Msg.MATH_SUBTRACTION_SYMBOL = "-"; // untranslated
|
||||
/** @export */ Blockly.Msg.MATH_TRIG_ACOS = "acos"; // untranslated
|
||||
/** @export */ Blockly.Msg.MATH_TRIG_ASIN = "asin"; // untranslated
|
||||
/** @export */ Blockly.Msg.MATH_TRIG_ATAN = "atan"; // untranslated
|
||||
/** @export */ Blockly.Msg.MATH_TRIG_COS = "cos"; // untranslated
|
||||
/** @export */ Blockly.Msg.MATH_TRIG_HELPURL = "https://zh.wikipedia.org/wiki/三角函数";
|
||||
/** @export */ Blockly.Msg.MATH_TRIG_SIN = "sin"; // untranslated
|
||||
/** @export */ Blockly.Msg.MATH_TRIG_TAN = "tan"; // untranslated
|
||||
/** @export */ Blockly.Msg.MATH_TRIG_TOOLTIP_ACOS = "返回一个数的反余弦值。";
|
||||
/** @export */ Blockly.Msg.MATH_TRIG_TOOLTIP_ASIN = "返回一个数的反正弦值。";
|
||||
/** @export */ Blockly.Msg.MATH_TRIG_TOOLTIP_ATAN = "返回指定角度的反正切值。";
|
||||
/** @export */ Blockly.Msg.MATH_TRIG_TOOLTIP_COS = "返回指定角度的余弦值(非弧度)。";
|
||||
/** @export */ Blockly.Msg.MATH_TRIG_TOOLTIP_SIN = "返回指定角度的正弦值(非弧度)。";
|
||||
/** @export */ Blockly.Msg.MATH_TRIG_TOOLTIP_TAN = "返回指定角度的正切值(非弧度)。";
|
||||
/** @export */ Blockly.Msg.NEW_VARIABLE = "创建变量...";
|
||||
/** @export */ Blockly.Msg.NEW_VARIABLE_TITLE = "新变量的名称:";
|
||||
/** @export */ Blockly.Msg.ORDINAL_NUMBER_SUFFIX = "空白";
|
||||
/** @export */ Blockly.Msg.PROCEDURES_ALLOW_STATEMENTS = "允许声明";
|
||||
/** @export */ Blockly.Msg.PROCEDURES_BEFORE_PARAMS = "与:";
|
||||
/** @export */ Blockly.Msg.PROCEDURES_CALLNORETURN_HELPURL = "https://zh.wikipedia.org/wiki/子程序";
|
||||
/** @export */ Blockly.Msg.PROCEDURES_CALLNORETURN_TOOLTIP = "运行用户定义的函数“%1”。";
|
||||
/** @export */ Blockly.Msg.PROCEDURES_CALLRETURN_HELPURL = "https://zh.wikipedia.org/wiki/子程序";
|
||||
/** @export */ Blockly.Msg.PROCEDURES_CALLRETURN_TOOLTIP = "运行用户定义的函数“%1”,并使用它的输出值。";
|
||||
/** @export */ Blockly.Msg.PROCEDURES_CALL_BEFORE_PARAMS = "与:";
|
||||
/** @export */ Blockly.Msg.PROCEDURES_CREATE_DO = "创建“%1”";
|
||||
/** @export */ Blockly.Msg.PROCEDURES_DEFNORETURN_COMMENT = "描述该功能...";
|
||||
/** @export */ Blockly.Msg.PROCEDURES_DEFNORETURN_DO = "空白";
|
||||
/** @export */ Blockly.Msg.PROCEDURES_DEFNORETURN_HELPURL = "https://zh.wikipedia.org/wiki/子程序";
|
||||
/** @export */ Blockly.Msg.PROCEDURES_DEFNORETURN_PROCEDURE = "做点什么";
|
||||
/** @export */ Blockly.Msg.PROCEDURES_DEFNORETURN_TITLE = "至";
|
||||
/** @export */ Blockly.Msg.PROCEDURES_DEFNORETURN_TOOLTIP = "创建一个不带输出值的函数。";
|
||||
/** @export */ Blockly.Msg.PROCEDURES_DEFRETURN_HELPURL = "https://zh.wikipedia.org/wiki/子程序";
|
||||
/** @export */ Blockly.Msg.PROCEDURES_DEFRETURN_RETURN = "返回";
|
||||
/** @export */ Blockly.Msg.PROCEDURES_DEFRETURN_TOOLTIP = "创建一个有输出值的函数。";
|
||||
/** @export */ Blockly.Msg.PROCEDURES_DEF_DUPLICATE_WARNING = "警告: 此函数具有重复参数。";
|
||||
/** @export */ Blockly.Msg.PROCEDURES_HIGHLIGHT_DEF = "突出显示函数定义";
|
||||
/** @export */ Blockly.Msg.PROCEDURES_IFRETURN_HELPURL = "http://c2.com/cgi/wiki?GuardClause";
|
||||
/** @export */ Blockly.Msg.PROCEDURES_IFRETURN_TOOLTIP = "如果值为真,则返回第二个值。";
|
||||
/** @export */ Blockly.Msg.PROCEDURES_IFRETURN_WARNING = "警告: 仅在定义函数内可使用此块。";
|
||||
/** @export */ Blockly.Msg.PROCEDURES_MUTATORARG_TITLE = "输入名称:";
|
||||
/** @export */ Blockly.Msg.PROCEDURES_MUTATORARG_TOOLTIP = "添加函数输入。";
|
||||
/** @export */ Blockly.Msg.PROCEDURES_MUTATORCONTAINER_TITLE = "输入";
|
||||
/** @export */ Blockly.Msg.PROCEDURES_MUTATORCONTAINER_TOOLTIP = "添加、删除或重新排此函数的输入。";
|
||||
/** @export */ Blockly.Msg.REDO = "重做";
|
||||
/** @export */ Blockly.Msg.REMOVE_COMMENT = "删除注释";
|
||||
/** @export */ Blockly.Msg.RENAME_VARIABLE = "重命名变量...";
|
||||
/** @export */ Blockly.Msg.RENAME_VARIABLE_TITLE = "将所有“%1”变量重命名为:";
|
||||
/** @export */ Blockly.Msg.TEXT_APPEND_HELPURL = "https://github.com/google/blockly/wiki/Text#text-modification"; // untranslated
|
||||
/** @export */ Blockly.Msg.TEXT_APPEND_TITLE = "至%1附加文本%2";
|
||||
/** @export */ Blockly.Msg.TEXT_APPEND_TOOLTIP = "将一些文本追加到变量“%1”。";
|
||||
/** @export */ Blockly.Msg.TEXT_CHANGECASE_HELPURL = "https://github.com/google/blockly/wiki/Text#adjusting-text-case"; // untranslated
|
||||
/** @export */ Blockly.Msg.TEXT_CHANGECASE_OPERATOR_LOWERCASE = "转为小写";
|
||||
/** @export */ Blockly.Msg.TEXT_CHANGECASE_OPERATOR_TITLECASE = "将首字母大写";
|
||||
/** @export */ Blockly.Msg.TEXT_CHANGECASE_OPERATOR_UPPERCASE = "转为大写";
|
||||
/** @export */ Blockly.Msg.TEXT_CHANGECASE_TOOLTIP = "在不同大小写下复制并返回这段文字。";
|
||||
/** @export */ Blockly.Msg.TEXT_CHARAT_FIRST = "获得第一个字符";
|
||||
/** @export */ Blockly.Msg.TEXT_CHARAT_FROM_END = "获得倒数第#个字符";
|
||||
/** @export */ Blockly.Msg.TEXT_CHARAT_FROM_START = "获得字符#";
|
||||
/** @export */ Blockly.Msg.TEXT_CHARAT_HELPURL = "https://github.com/google/blockly/wiki/Text#extracting-text"; // untranslated
|
||||
/** @export */ Blockly.Msg.TEXT_CHARAT_LAST = "获得最后一个字符";
|
||||
/** @export */ Blockly.Msg.TEXT_CHARAT_RANDOM = "获取随机的字母";
|
||||
/** @export */ Blockly.Msg.TEXT_CHARAT_TAIL = "空白";
|
||||
/** @export */ Blockly.Msg.TEXT_CHARAT_TITLE = "在文本%1 %2中";
|
||||
/** @export */ Blockly.Msg.TEXT_CHARAT_TOOLTIP = "返回位于指定位置的字母。";
|
||||
/** @export */ Blockly.Msg.TEXT_COUNT_HELPURL = "https://github.com/google/blockly/wiki/Text#counting-substrings";
|
||||
/** @export */ Blockly.Msg.TEXT_COUNT_MESSAGE0 = "将%1计算在%2之内";
|
||||
/** @export */ Blockly.Msg.TEXT_COUNT_TOOLTIP = "计算在一些其他文本中,部分文本重现了多少次。";
|
||||
/** @export */ Blockly.Msg.TEXT_CREATE_JOIN_ITEM_TOOLTIP = "将一个项添加到文本中。";
|
||||
/** @export */ Blockly.Msg.TEXT_CREATE_JOIN_TITLE_JOIN = "加入";
|
||||
/** @export */ Blockly.Msg.TEXT_CREATE_JOIN_TOOLTIP = "添加、移除或重新排列各节来重新配置这个文本块。";
|
||||
/** @export */ Blockly.Msg.TEXT_GET_SUBSTRING_END_FROM_END = "到倒数第#个字符";
|
||||
/** @export */ Blockly.Msg.TEXT_GET_SUBSTRING_END_FROM_START = "到字符#";
|
||||
/** @export */ Blockly.Msg.TEXT_GET_SUBSTRING_END_LAST = "到最后一个字符";
|
||||
/** @export */ Blockly.Msg.TEXT_GET_SUBSTRING_HELPURL = "https://github.com/google/blockly/wiki/Text#extracting-a-region-of-text"; // untranslated
|
||||
/** @export */ Blockly.Msg.TEXT_GET_SUBSTRING_INPUT_IN_TEXT = "自文本";
|
||||
/** @export */ Blockly.Msg.TEXT_GET_SUBSTRING_START_FIRST = "取得一段字串自第一个字符";
|
||||
/** @export */ Blockly.Msg.TEXT_GET_SUBSTRING_START_FROM_END = "取得一段字串自倒数第#个字符";
|
||||
/** @export */ Blockly.Msg.TEXT_GET_SUBSTRING_START_FROM_START = "取得一段字串自#";
|
||||
/** @export */ Blockly.Msg.TEXT_GET_SUBSTRING_TAIL = "空白";
|
||||
/** @export */ Blockly.Msg.TEXT_GET_SUBSTRING_TOOLTIP = "返回指定的部分文本。";
|
||||
/** @export */ Blockly.Msg.TEXT_INDEXOF_HELPURL = "https://github.com/google/blockly/wiki/Text#finding-text"; // untranslated
|
||||
/** @export */ Blockly.Msg.TEXT_INDEXOF_OPERATOR_FIRST = "寻找第一个出现的文本";
|
||||
/** @export */ Blockly.Msg.TEXT_INDEXOF_OPERATOR_LAST = "寻找最后一个出现的文本";
|
||||
/** @export */ Blockly.Msg.TEXT_INDEXOF_TITLE = "在文本%1 %2 %3中";
|
||||
/** @export */ Blockly.Msg.TEXT_INDEXOF_TOOLTIP = "返回在第二个字串中的第一/最后一个匹配项的索引值。如果未找到则返回%1。";
|
||||
/** @export */ Blockly.Msg.TEXT_ISEMPTY_HELPURL = "https://github.com/google/blockly/wiki/Text#checking-for-empty-text"; // untranslated
|
||||
/** @export */ Blockly.Msg.TEXT_ISEMPTY_TITLE = "%1是空的";
|
||||
/** @export */ Blockly.Msg.TEXT_ISEMPTY_TOOLTIP = "如果提供的文本为空,则返回真。";
|
||||
/** @export */ Blockly.Msg.TEXT_JOIN_HELPURL = "https://github.com/google/blockly/wiki/Text#text-creation"; // untranslated
|
||||
/** @export */ Blockly.Msg.TEXT_JOIN_TITLE_CREATEWITH = "建立字串使用";
|
||||
/** @export */ Blockly.Msg.TEXT_JOIN_TOOLTIP = "通过串起任意数量的项以建立一段文字。";
|
||||
/** @export */ Blockly.Msg.TEXT_LENGTH_HELPURL = "https://github.com/google/blockly/wiki/Text#text-modification"; // untranslated
|
||||
/** @export */ Blockly.Msg.TEXT_LENGTH_TITLE = "%1的长度";
|
||||
/** @export */ Blockly.Msg.TEXT_LENGTH_TOOLTIP = "返回提供文本的字母数(包括空格)。";
|
||||
/** @export */ Blockly.Msg.TEXT_PRINT_HELPURL = "https://github.com/google/blockly/wiki/Text#printing-text"; // untranslated
|
||||
/** @export */ Blockly.Msg.TEXT_PRINT_TITLE = "打印%1";
|
||||
/** @export */ Blockly.Msg.TEXT_PRINT_TOOLTIP = "打印指定的文字、数字或其他值。";
|
||||
/** @export */ Blockly.Msg.TEXT_PROMPT_HELPURL = "https://github.com/google/blockly/wiki/Text#getting-input-from-the-user"; // untranslated
|
||||
/** @export */ Blockly.Msg.TEXT_PROMPT_TOOLTIP_NUMBER = "提示用户输入数字。";
|
||||
/** @export */ Blockly.Msg.TEXT_PROMPT_TOOLTIP_TEXT = "提示用户输入一些文本。";
|
||||
/** @export */ Blockly.Msg.TEXT_PROMPT_TYPE_NUMBER = "输入数字并显示提示消息";
|
||||
/** @export */ Blockly.Msg.TEXT_PROMPT_TYPE_TEXT = "输入数字并显示提示消息";
|
||||
/** @export */ Blockly.Msg.TEXT_REPLACE_HELPURL = "https://github.com/google/blockly/wiki/Text#replacing-substrings";
|
||||
/** @export */ Blockly.Msg.TEXT_REPLACE_MESSAGE0 = "在%3中,将%1替换为%2";
|
||||
/** @export */ Blockly.Msg.TEXT_REPLACE_TOOLTIP = "在某些其他文本中,替换部分文本的所有事件。";
|
||||
/** @export */ Blockly.Msg.TEXT_REVERSE_HELPURL = "https://github.com/google/blockly/wiki/Text#reversing-text";
|
||||
/** @export */ Blockly.Msg.TEXT_REVERSE_MESSAGE0 = "倒转%1";
|
||||
/** @export */ Blockly.Msg.TEXT_REVERSE_TOOLTIP = "倒转文本中字符的排序。";
|
||||
/** @export */ Blockly.Msg.TEXT_TEXT_HELPURL = "https://zh.wikipedia.org/wiki/字符串";
|
||||
/** @export */ Blockly.Msg.TEXT_TEXT_TOOLTIP = "一个字母、单词或一行文本。";
|
||||
/** @export */ Blockly.Msg.TEXT_TRIM_HELPURL = "https://github.com/google/blockly/wiki/Text#trimming-removing-spaces"; // untranslated
|
||||
/** @export */ Blockly.Msg.TEXT_TRIM_OPERATOR_BOTH = "消除两侧空格";
|
||||
/** @export */ Blockly.Msg.TEXT_TRIM_OPERATOR_LEFT = "消除左侧空格";
|
||||
/** @export */ Blockly.Msg.TEXT_TRIM_OPERATOR_RIGHT = "消除右侧空格";
|
||||
/** @export */ Blockly.Msg.TEXT_TRIM_TOOLTIP = "复制这段文字的同时删除两端多余的空格。";
|
||||
/** @export */ Blockly.Msg.TODAY = "今天";
|
||||
/** @export */ Blockly.Msg.UNDO = "撤销";
|
||||
/** @export */ Blockly.Msg.VARIABLES_DEFAULT_NAME = "项目";
|
||||
/** @export */ Blockly.Msg.VARIABLES_GET_CREATE_SET = "创建“设定%1”";
|
||||
/** @export */ Blockly.Msg.VARIABLES_GET_HELPURL = "https://github.com/google/blockly/wiki/Variables#get"; // untranslated
|
||||
/** @export */ Blockly.Msg.VARIABLES_GET_TOOLTIP = "返回此变量的值。";
|
||||
/** @export */ Blockly.Msg.VARIABLES_SET = "赋值 %1 到 %2";
|
||||
/** @export */ Blockly.Msg.VARIABLES_SET_CREATE_GET = "创建“获得%1”";
|
||||
/** @export */ Blockly.Msg.VARIABLES_SET_HELPURL = "https://github.com/google/blockly/wiki/Variables#set"; // untranslated
|
||||
/** @export */ Blockly.Msg.VARIABLES_SET_TOOLTIP = "设置此变量,以使它和输入值相等。";
|
||||
/** @export */ Blockly.Msg.VARIABLE_ALREADY_EXISTS = "已存在名为“%1”的变量。";
|
||||
/** @export */ Blockly.Msg.VARIABLE_ALREADY_EXISTS_FOR_ANOTHER_TYPE = "名叫“%1”的变量已存在,但作为另一个变量类型“%2”存在。";
|
||||
/** @export */ Blockly.Msg.PROCEDURES_DEFRETURN_TITLE = Blockly.Msg.PROCEDURES_DEFNORETURN_TITLE;
|
||||
/** @export */ Blockly.Msg.CONTROLS_IF_IF_TITLE_IF = Blockly.Msg.CONTROLS_IF_MSG_IF;
|
||||
/** @export */ Blockly.Msg.CONTROLS_WHILEUNTIL_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
|
||||
/** @export */ Blockly.Msg.CONTROLS_IF_MSG_THEN = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
|
||||
/** @export */ Blockly.Msg.CONTROLS_IF_ELSE_TITLE_ELSE = Blockly.Msg.CONTROLS_IF_MSG_ELSE;
|
||||
/** @export */ Blockly.Msg.PROCEDURES_DEFRETURN_PROCEDURE = Blockly.Msg.PROCEDURES_DEFNORETURN_PROCEDURE;
|
||||
/** @export */ Blockly.Msg.LISTS_GET_SUBLIST_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
|
||||
/** @export */ Blockly.Msg.LISTS_GET_INDEX_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
|
||||
/** @export */ Blockly.Msg.MATH_CHANGE_TITLE_ITEM = Blockly.Msg.VARIABLES_DEFAULT_NAME;
|
||||
/** @export */ Blockly.Msg.PROCEDURES_DEFRETURN_DO = Blockly.Msg.PROCEDURES_DEFNORETURN_DO;
|
||||
/** @export */ Blockly.Msg.CONTROLS_IF_ELSEIF_TITLE_ELSEIF = Blockly.Msg.CONTROLS_IF_MSG_ELSEIF;
|
||||
/** @export */ Blockly.Msg.LISTS_GET_INDEX_HELPURL = Blockly.Msg.LISTS_INDEX_OF_HELPURL;
|
||||
/** @export */ Blockly.Msg.CONTROLS_FOREACH_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
|
||||
/** @export */ Blockly.Msg.LISTS_SET_INDEX_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
|
||||
/** @export */ Blockly.Msg.CONTROLS_FOR_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
|
||||
/** @export */ Blockly.Msg.LISTS_CREATE_WITH_ITEM_TITLE = Blockly.Msg.VARIABLES_DEFAULT_NAME;
|
||||
/** @export */ Blockly.Msg.TEXT_APPEND_VARIABLE = Blockly.Msg.VARIABLES_DEFAULT_NAME;
|
||||
/** @export */ Blockly.Msg.TEXT_CREATE_JOIN_ITEM_TITLE_ITEM = Blockly.Msg.VARIABLES_DEFAULT_NAME;
|
||||
/** @export */ Blockly.Msg.LISTS_INDEX_OF_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
|
||||
/** @export */ Blockly.Msg.PROCEDURES_DEFRETURN_COMMENT = Blockly.Msg.PROCEDURES_DEFNORETURN_COMMENT;
|
||||
|
||||
/** @export */ Blockly.Msg.MATH_HUE = "230";
|
||||
/** @export */ Blockly.Msg.LOOPS_HUE = "120";
|
||||
/** @export */ Blockly.Msg.LISTS_HUE = "260";
|
||||
/** @export */ Blockly.Msg.LOGIC_HUE = "210";
|
||||
/** @export */ Blockly.Msg.VARIABLES_HUE = "330";
|
||||
/** @export */ Blockly.Msg.TEXTS_HUE = "160";
|
||||
/** @export */ Blockly.Msg.PROCEDURES_HUE = "290";
|
||||
/** @export */ Blockly.Msg.COLOUR_HUE = "20";
|
||||
@ -184,10 +184,13 @@ body{
|
||||
top: 5px;
|
||||
overflow: auto;
|
||||
}
|
||||
.egameCanvas {
|
||||
position: absolute;
|
||||
}
|
||||
.gameCanvas {
|
||||
position: absolute;
|
||||
}
|
||||
#dataSelection{
|
||||
#dataSelection , .appendSelection{
|
||||
position: absolute;
|
||||
/* top:0;
|
||||
left:320px; */
|
||||
@ -207,12 +210,14 @@ body{
|
||||
color: #D50000;
|
||||
font-weight: 700;
|
||||
font-size: 14px;
|
||||
line-height: 1.2em;
|
||||
}
|
||||
.infoText{
|
||||
color: #2196F3;
|
||||
}
|
||||
.successText{
|
||||
color: #00897B
|
||||
color: #00897B;
|
||||
line-height: 1.2em;
|
||||
}
|
||||
|
||||
table, td {
|
||||
|
||||
166
_server/css/editor_mode.css
Normal file
@ -0,0 +1,166 @@
|
||||
.leftTab {
|
||||
border-radius: 2px;
|
||||
box-sizing: border-box;
|
||||
box-shadow: 0 2px 2px 0 rgba(0,0,0,.14), 0 3px 1px -2px rgba(0,0,0,.2), 0 1px 5px 0 rgba(0,0,0,.12);
|
||||
}
|
||||
|
||||
.leftTab {
|
||||
overflow: auto;
|
||||
position: absolute;
|
||||
height: 630px;
|
||||
}
|
||||
.leftTab > *{margin:2.5px 5px;}
|
||||
.leftTab > :first-child{margin-top:5px;}
|
||||
.leftTab > :last-child{margin-bottom:5px;}
|
||||
|
||||
.leftTab {
|
||||
left: 5px;
|
||||
top: 10px;
|
||||
width: 435px;
|
||||
}
|
||||
|
||||
#appendPicSelection span {
|
||||
position: absolute;
|
||||
font-size:11px;
|
||||
-webkit-text-stroke: 1px red;
|
||||
text-shadow: black 1px 0, black 0 1px, black -1px 0, black 0 -1px;
|
||||
}
|
||||
|
||||
#left6 {
|
||||
left: 5px;
|
||||
/* top: 1930px; */
|
||||
top: 5px;
|
||||
z-index: 200;
|
||||
position: fixed;
|
||||
background-color: rgb(245, 245, 245);
|
||||
width: 1335px;
|
||||
height: 780px;
|
||||
}
|
||||
|
||||
#left6 #blocklyDiv {
|
||||
height: 480px;
|
||||
width: 940px;
|
||||
}
|
||||
|
||||
#left6 .CodeMirror {
|
||||
border: 1px solid #eee;
|
||||
height: 200px;
|
||||
width: 1300px;
|
||||
}
|
||||
#left6 #codeArea {width: 99.5%; height: 15.4em;overflow:y;/* resize:none; */}
|
||||
|
||||
#left7 {
|
||||
/* height: 440px; width: 375px;float:left; */
|
||||
left: 5px;
|
||||
top: 5px;
|
||||
z-index: 200;
|
||||
position: fixed;
|
||||
background-color: rgb(245, 245, 245);
|
||||
width: 1335px;
|
||||
height: 780px;
|
||||
}
|
||||
#left7 .CodeMirror {
|
||||
/* border-top: 1px solid black;
|
||||
border-bottom: 1px solid black; */
|
||||
border: 1px solid #eee;
|
||||
height: 700px;
|
||||
width: 940px;
|
||||
}
|
||||
|
||||
.etable table,
|
||||
.etable table td {
|
||||
color: #000;
|
||||
cursor: auto;
|
||||
}
|
||||
|
||||
/* copy from github-css https://github.com/sindresorhus/github-markdown-css */
|
||||
.etable table {
|
||||
border-spacing: 0;
|
||||
border-collapse: collapse;
|
||||
}
|
||||
.etable table {
|
||||
margin-top: 0;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
.etable table {
|
||||
display: block;
|
||||
width: 100%;
|
||||
overflow: auto;
|
||||
}
|
||||
.etable table th {
|
||||
font-weight: 600;
|
||||
}
|
||||
.etable table th,
|
||||
.etable table td {
|
||||
padding: 6px 13px;
|
||||
border: 1px solid #dfe2e5;
|
||||
}
|
||||
.etable table tr {
|
||||
background-color: #fff;
|
||||
border-top: 1px solid #c6cbd1;
|
||||
}
|
||||
.etable table tr:nth-child(2n) {
|
||||
background-color: #f6f8fa;
|
||||
}
|
||||
/* copy end --------------------------------------------- */
|
||||
|
||||
.etable tr {width:100%}
|
||||
.etable tr > :nth-child(1) {width:20%}
|
||||
.etable tr > :nth-child(2) {width:20%}
|
||||
.etable tr > :nth-child(3) {width:60%}
|
||||
|
||||
.etable table {
|
||||
overflow: visible;
|
||||
}
|
||||
|
||||
.etable tr:not(:first-child) > :last-child:hover {
|
||||
border: 1px solid rgb(87, 198, 232);
|
||||
box-shadow: 0px 0px 3px rgb(87, 198, 232);
|
||||
}
|
||||
|
||||
.etable tr:not(:first-child) > :nth-child(2):hover,
|
||||
.etable tr:not(:first-child) > :nth-child(1):hover {
|
||||
border: 1px solid rgb(87, 232, 198);
|
||||
box-shadow: 0px 0px 3px rgb(87, 232, 198);
|
||||
}
|
||||
|
||||
.etable tr:not(:first-child) > :last-child {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
div.etableInputDiv {
|
||||
position: absolute;
|
||||
padding: 5px 0 0 5px;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
}
|
||||
|
||||
.etableInputDiv > * {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
background-color: rgba(255, 255, 255, 0);
|
||||
border: none;
|
||||
}
|
||||
|
||||
.etableInputDiv input {
|
||||
|
||||
}
|
||||
|
||||
.etableInputDiv select {
|
||||
|
||||
}
|
||||
|
||||
.etableInputDiv textarea {
|
||||
resize: none;
|
||||
}
|
||||
.etableInputDiv textarea:hover {
|
||||
margin: -5px;
|
||||
}
|
||||
547
_server/editor.js
Normal file
@ -0,0 +1,547 @@
|
||||
function editor() {
|
||||
this.version = "2.0";
|
||||
this.material = {};
|
||||
}
|
||||
|
||||
editor.prototype.init = function(callback){
|
||||
var afterCoreReset = function(){
|
||||
|
||||
main.editor.disableGlobalAnimate=false;//允许GlobalAnimate
|
||||
/* core.setHeroMoveTriggerInterval(); */
|
||||
|
||||
editor.reset(function(){
|
||||
editor.drawMapBg();
|
||||
var mapArray = core.maps.save(core.status.maps,core.status.floorId);
|
||||
editor.map = mapArray.map(function(v){return v.map(function(v){return editor.ids[[editor.indexs[parseInt(v)][0]]]})});
|
||||
editor.updateMap();
|
||||
editor.currentFloorId=core.status.floorId;
|
||||
editor.currentFloorData = core.floors[core.status.floorId];
|
||||
|
||||
if (Boolean(callback))callback();
|
||||
});
|
||||
}
|
||||
|
||||
var afterMainInit = function(){
|
||||
core.floors=JSON.parse(JSON.stringify(core.floors,function(k,v){if(v instanceof Function){return v.toString()}else return v}));
|
||||
core.data=JSON.parse(JSON.stringify(core.data,function(k,v){if(v instanceof Function){return v.toString()}else return v}));
|
||||
data_a1e2fb4a_e986_4524_b0da_9b7ba7c0874d=JSON.parse(JSON.stringify(data_a1e2fb4a_e986_4524_b0da_9b7ba7c0874d,function(k,v){if(v instanceof Function){return v.toString()}else return v}));
|
||||
editor.main=main;
|
||||
editor.core=core;
|
||||
editor.fs=fs;
|
||||
editor_file = editor_file(editor, function() {
|
||||
editor.file=editor_file;
|
||||
editor_mode = editor_mode(editor);
|
||||
editor.mode=editor_mode;
|
||||
editor.material.images=core.material.images;
|
||||
editor.listen(); // 开始监听事件
|
||||
core.resetStatus(core.firstData.hero, null, core.firstData.floorId, null, core.initStatus.maps);
|
||||
core.changeFloor(core.status.floorId, null, core.firstData.hero.loc, null, function() {
|
||||
afterCoreReset();
|
||||
}, true);
|
||||
core.events.setInitData(null);
|
||||
});
|
||||
}
|
||||
afterMainInit();
|
||||
}
|
||||
|
||||
editor.prototype.reset = function(callback){
|
||||
editor.idsInit(core.maps, core.icons.icons); // 初始化图片素材信息
|
||||
editor.drawInitData(core.icons.icons); // 初始化绘图
|
||||
if(Boolean(callback))callback();
|
||||
}
|
||||
|
||||
editor.prototype.idsInit = function(maps, icons){
|
||||
editor.ids = [0];
|
||||
editor.indexs = [];
|
||||
var MAX_NUM = 400;
|
||||
var getInfoById = function(id){
|
||||
var block = maps.initBlock(0, 0, id);
|
||||
if(hasOwnProp(block, 'event')){
|
||||
return block;
|
||||
}
|
||||
}
|
||||
var point = 0;
|
||||
for(var i=0; i<MAX_NUM; i++){
|
||||
var indexBlock = getInfoById(i);
|
||||
editor.indexs[i] = [];
|
||||
if(indexBlock){
|
||||
var id = indexBlock.event.id;
|
||||
var indexId = indexBlock.id;
|
||||
var allCls = Object.keys(icons);
|
||||
for(var j=0; j<allCls.length; j++){
|
||||
if(id in icons[allCls[j]] ){
|
||||
editor.ids.push({'idnum':indexId,'id':id,'images':allCls[j],'y':icons[allCls[j]][id]});
|
||||
point++;
|
||||
editor.indexs[i].push(point);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
editor.indexs[0]=[0];
|
||||
}
|
||||
editor.prototype.drawInitData = function (icons) {
|
||||
var ratio=1;
|
||||
var images=editor.material.images;
|
||||
var maxHeight=700;
|
||||
var sumWidth=0;
|
||||
editor.widthsX={};
|
||||
// var imgNames = Object.keys(images); //还是固定顺序吧;
|
||||
var imgNames = ["terrains", "animates", "enemys", "enemy48", "items", "npcs", "npc48", "autotile"];
|
||||
|
||||
for(var ii=0; ii<imgNames.length; ii++){
|
||||
var img=imgNames[ii], tempy = 0;
|
||||
if(img == 'autotile'){
|
||||
var autotiles = images[img];
|
||||
for(var im in autotiles){
|
||||
tempy += autotiles[im].height;
|
||||
}
|
||||
editor.widthsX[img]=[img, sumWidth/32, (sumWidth+3*32)/32, tempy];
|
||||
sumWidth += 3*32;
|
||||
maxHeight = Math.max(maxHeight, tempy);
|
||||
continue;
|
||||
}
|
||||
if(img == 'terrains'){
|
||||
editor.widthsX[img]=[img, sumWidth/32, (sumWidth+images[img].width)/32, images[img].height+32]
|
||||
sumWidth += images[img].width;
|
||||
maxHeight = Math.max(maxHeight, images[img].height+32);
|
||||
continue;
|
||||
}
|
||||
editor.widthsX[img]=[img, sumWidth/32, (sumWidth+images[img].width)/32, images[img].height];
|
||||
sumWidth += images[img].width;
|
||||
maxHeight = Math.max(maxHeight, images[img].height);
|
||||
}
|
||||
var fullWidth=~~(sumWidth*ratio);
|
||||
var fullHeight=~~(maxHeight*ratio);
|
||||
|
||||
if (fullWidth > edata.width) edata.style.width = (edata.width = fullWidth)/ratio + 'px';
|
||||
edata.style.height = (edata.height = fullHeight)/ratio + 'px';
|
||||
var dc = edata.getContext('2d');
|
||||
var nowx = 0;
|
||||
var nowy = 0;
|
||||
for(var ii=0; ii<imgNames.length; ii++){
|
||||
var img=imgNames[ii];
|
||||
if(img == 'terrains'){
|
||||
dc.drawImage(images[img], nowx, 32);
|
||||
nowx += images[img].width;
|
||||
continue;
|
||||
}
|
||||
if(img == 'autotile'){
|
||||
var autotiles = images[img];
|
||||
for(var im in autotiles){
|
||||
dc.drawImage(autotiles[im], nowx, nowy);
|
||||
nowy += autotiles[im].height;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
dc.drawImage(images[img], nowx, 0)
|
||||
nowx += images[img].width;
|
||||
}
|
||||
bgSelect.bgs = Object.keys(icons.terrains);
|
||||
//editor.drawMapBg();
|
||||
//editor.mapInit();
|
||||
}
|
||||
editor.prototype.mapInit = function(){
|
||||
var ec = document.getElementById('event').getContext('2d');
|
||||
ec.clearRect(0, 0, 416, 416);
|
||||
editor.map = [];
|
||||
for(var y=0; y<13; y++){
|
||||
editor.map[y] = [];
|
||||
for(var x = 0; x<13; x++){
|
||||
editor.map[y][x] = 0;
|
||||
}
|
||||
}
|
||||
editor.currentFloorData.map=editor.map;
|
||||
editor.currentFloorData.firstArrive=[];
|
||||
editor.currentFloorData.events={};
|
||||
editor.currentFloorData.changeFloor={};
|
||||
editor.currentFloorData.afterBattle={};
|
||||
editor.currentFloorData.afterGetItem={};
|
||||
editor.currentFloorData.afterOpenDoor={};
|
||||
editor.currentFloorData.cannotMove={};
|
||||
}
|
||||
editor.prototype.drawMapBg = function(img){
|
||||
var bgc = bg.getContext('2d');
|
||||
if (!core.isset(editor.bgY) || editor.bgY == 0){
|
||||
editor.main.editor.drawMapBg();
|
||||
return;
|
||||
}
|
||||
|
||||
for (var ii = 0; ii < 13; ii++)
|
||||
for (var jj = 0; jj < 13; jj++) {
|
||||
bgc.clearRect(ii*32, jj*32, 32, 32);
|
||||
bgc.drawImage(editor.material.images['terrains'], 0, 32*(editor.bgY||0), 32, 32, ii*32, jj*32, 32, 32);
|
||||
}
|
||||
if(img){
|
||||
bgc.drawImage(img, 0, 0, 416, 416);
|
||||
}
|
||||
}
|
||||
|
||||
editor.prototype.updateMap = function(){
|
||||
var blocks = main.editor.mapIntoBlocks(editor.map.map(function(v){return v.map(function(v){return v.idnum||v||0})}),{'events':{},'changeFloor':{}});
|
||||
core.status.thisMap.blocks = blocks;
|
||||
main.editor.updateMap();
|
||||
|
||||
var drawTile = function(ctx, x, y, tileInfo){ // 绘制一个普通块
|
||||
|
||||
//ctx.clearRect(x*32, y*32, 32, 32);
|
||||
if(tileInfo == 0) return;
|
||||
|
||||
if(typeof(tileInfo) == typeof([][0]) || !hasOwnProp(tileInfo, 'idnum')) {//未定义块画红块
|
||||
if(typeof(tileInfo) != typeof([][0]) && hasOwnProp(tileInfo, 'images')){
|
||||
ctx.drawImage(editor.material.images[tileInfo.images], 0, tileInfo.y*32, 32, 32, x*32, y*32, 32, 32);
|
||||
}
|
||||
ctx.strokeStyle = 'red';
|
||||
var OFFSET = 2;
|
||||
ctx.lineWidth = OFFSET;
|
||||
ctx.strokeRect(x*32+OFFSET, y*32+OFFSET, 32-OFFSET*2, 32-OFFSET*2);
|
||||
ctx.font = "30px Verdana";
|
||||
ctx.textAlign = 'center'
|
||||
ctx.fillStyle = 'red';
|
||||
ctx.fillText("?", x*32+16, y*32+27);
|
||||
return;
|
||||
}
|
||||
//ctx.drawImage(editor.material.images[tileInfo.images], 0, tileInfo.y*32, 32, 32, x*32, y*32, 32, 32);
|
||||
}
|
||||
/*
|
||||
// autotile的相关处理
|
||||
var indexArrs = [ //16种组合的图块索引数组; // 将autotile分割成48块16*16的小块; 数组索引即对应各个小块
|
||||
// +----+----+----+----+----+----+
|
||||
[10, 9, 4, 3 ], //0 bin:0000 | 1 | 2 | 3 | 4 | 5 | 6 |
|
||||
[10, 9, 4, 13], //1 bin:0001 +----+----+----+----+----+----+
|
||||
[10, 9, 18, 3 ], //2 bin:0010 | 7 | 8 | 9 | 10 | 11 | 12 |
|
||||
[10, 9, 16, 15], //3 bin:0011 +----+----+----+----+----+----+
|
||||
[10, 43, 4, 3 ], //4 bin:0100 | 13 | 14 | 15 | 16 | 17 | 18 |
|
||||
[10, 31, 4, 25], //5 bin:0101 +----+----+----+----+----+----+
|
||||
[10, 7, 2, 3 ], //6 bin:0110 | 19 | 20 | 21 | 22 | 23 | 24 |
|
||||
[10, 31, 16, 5 ], //7 bin:0111 +----+----+----+----+----+----+
|
||||
[48, 9, 4, 3 ], //8 bin:1000 | 25 | 26 | 27 | 28 | 29 | 30 |
|
||||
[ 8, 9, 4, 1 ], //9 bin:1001 +----+----+----+----+----+----+
|
||||
[36, 9, 30, 3 ], //10 bin:1010 | 31 | 32 | 33 | 34 | 35 | 36 |
|
||||
[36, 9, 6, 15], //11 bin:1011 +----+----+----+----+----+----+
|
||||
[46, 45, 4, 3 ], //12 bin:1100 | 37 | 38 | 39 | 40 | 41 | 42 |
|
||||
[46, 11, 4, 25], //13 bin:1101 +----+----+----+----+----+----+
|
||||
[12, 45, 30, 3 ], //14 bin:1110 | 43 | 44 | 45 | 46 | 47 | 48 |
|
||||
[34, 33, 28, 27] //15 bin:1111 +----+----+----+----+----+----+
|
||||
];
|
||||
var drawBlockByIndex = function(ctx, dx, dy, autotileImg, index){ //index为autotile的图块索引1-48
|
||||
var sx = 16*((index-1)%6), sy = 16*(~~((index-1)/6));
|
||||
ctx.drawImage(autotileImg, sx, sy, 16, 16, dx, dy, 16, 16);
|
||||
}
|
||||
var isAutotile = function(info){
|
||||
if(typeof(info)=='object' && hasOwnProp(info, 'images') && info.images=='autotile') return true;
|
||||
return false;
|
||||
}
|
||||
var getAutotileAroundId = function(currId, x, y){ //与autotile当前idnum一致返回1,否则返回0
|
||||
if(x>=0 && y >=0 && x<13 && y<13 && isAutotile(editor.map[y][x]) && editor.map[y][x].idnum == currId)
|
||||
return 1;
|
||||
else if(x<0 || y<0 || x>12 || y>12) return 1; //边界外视为通用autotile,这样好看些
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
var checkAround = function(x, y){ // 得到周围四个32*32块(周围每块都包含当前块的1/4,不清楚的话画下图你就明白)的数组索引
|
||||
var currId = editor.map[y][x].idnum;
|
||||
var pointBlock = [];
|
||||
for(var i=0; i<4; i++){
|
||||
var bsum = 0;
|
||||
var offsetx = i%2, offsety = ~~(i/2);
|
||||
for(var j=0; j<4; j++){
|
||||
var mx = j%2, my = ~~(j/2);
|
||||
var b = getAutotileAroundId(currId, x+offsetx+mx-1, y+offsety+my-1);
|
||||
bsum += b*(Math.pow(2, 3-j));
|
||||
}
|
||||
pointBlock.push(bsum);
|
||||
}
|
||||
return pointBlock;
|
||||
}
|
||||
var addIndexToAutotileInfo = function(x, y){
|
||||
var indexArr = [];
|
||||
var pointBlocks = checkAround(x, y);
|
||||
for(var i=0; i<4; i++){
|
||||
var arr = indexArrs[pointBlocks[i]]
|
||||
indexArr.push(arr[3-i]);
|
||||
}
|
||||
editor.map[y][x].blockIndex = indexArr;
|
||||
}
|
||||
var drawAutotile = function(ctx, x, y, info){ // 绘制一个autotile
|
||||
ctx.clearRect(x*32, y*32, 32, 32);
|
||||
//修正四个边角的固定搭配
|
||||
if(info.blockIndex[0] == 13){
|
||||
if(info.blockIndex[1] == 16) info.blockIndex[1] = 14;
|
||||
if(info.blockIndex[2] == 31) info.blockIndex[2] = 19;
|
||||
}
|
||||
if(info.blockIndex[1] == 18){
|
||||
if(info.blockIndex[0] == 15) info.blockIndex[0] = 17;
|
||||
if(info.blockIndex[3] == 36) info.blockIndex[3] = 24;
|
||||
}
|
||||
if(info.blockIndex[2] == 43){
|
||||
if(info.blockIndex[0] == 25) info.blockIndex[0] = 37;
|
||||
if(info.blockIndex[3] == 46) info.blockIndex[3] = 44;
|
||||
}
|
||||
if(info.blockIndex[3] == 48){
|
||||
if(info.blockIndex[1] == 30) info.blockIndex[1] = 42;
|
||||
if(info.blockIndex[2] == 45) info.blockIndex[2] = 47;
|
||||
}
|
||||
for(var i=0; i<4; i++){
|
||||
var index = info.blockIndex[i];
|
||||
var dx = x*32 + 16*(i%2), dy = y*32 + 16*(~~(i/2));
|
||||
drawBlockByIndex(ctx, dx, dy, editor.material.images[info.images][info.id], index);
|
||||
}
|
||||
}
|
||||
*/
|
||||
// 绘制地图 start
|
||||
var eventCtx = document.getElementById('event').getContext("2d");
|
||||
for(var y=0; y<13; y++)
|
||||
for(var x=0; x<13; x++){
|
||||
var tileInfo = editor.map[y][x];
|
||||
if(false && isAutotile(tileInfo)){
|
||||
addIndexToAutotileInfo(x, y);
|
||||
drawAutotile(eventCtx, x, y, tileInfo);
|
||||
}else drawTile(eventCtx, x, y, tileInfo);
|
||||
}
|
||||
// 绘制地图 end
|
||||
}
|
||||
|
||||
editor.prototype.changeFloor = function(floorId,callback) {
|
||||
editor.currentFloorData.map = editor.map.map(function(v){return v.map(function(v){return v.idnum||v||0})});
|
||||
core.changeFloor(floorId, null, core.firstData.hero.loc, null, function(){
|
||||
editor.drawMapBg();
|
||||
var mapArray = core.maps.save(core.status.maps,core.status.floorId);
|
||||
editor.map = mapArray.map(function(v){return v.map(function(v){return editor.ids[[editor.indexs[parseInt(v)][0]]]})});
|
||||
editor.updateMap();
|
||||
editor.currentFloorId=core.status.floorId;
|
||||
editor.currentFloorData = core.floors[core.status.floorId];
|
||||
editor_mode.floor();
|
||||
if (core.isset(callback))callback();
|
||||
});
|
||||
}
|
||||
|
||||
editor.prototype.guid = function() {
|
||||
return 'id_'+'xxxxxxxx_xxxx_4xxx_yxxx_xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
|
||||
var r = Math.random()*16|0, v = c == 'x' ? r : (r&0x3|0x8);
|
||||
return v.toString(16);
|
||||
});
|
||||
}
|
||||
|
||||
editor.prototype.listen = function() {
|
||||
|
||||
var uc = eui.getContext('2d');
|
||||
|
||||
function fillPos(pos) {
|
||||
uc.fillStyle = '#' + ~~(Math.random() * 8) + ~~(Math.random() * 8) + ~~(Math.random() * 8);
|
||||
uc.fillRect(pos.x * 32 + 12, pos.y * 32 + 12, 8, 8);
|
||||
}//在格子内画一个随机色块
|
||||
|
||||
function eToLoc(e) {
|
||||
var scrollLeft = document.documentElement.scrollLeft || document.body.scrollLeft
|
||||
var scrollTop = document.documentElement.scrollTop || document.body.scrollTop
|
||||
editor.loc = {
|
||||
'x': scrollLeft+e.clientX - mid.offsetLeft-mapEdit.offsetLeft,
|
||||
'y': scrollTop+e.clientY - mid.offsetTop-mapEdit.offsetTop,
|
||||
'size': 32
|
||||
};
|
||||
return editor.loc; }//返回可用的组件内坐标
|
||||
|
||||
function locToPos(loc) {
|
||||
editor.pos = { 'x': ~~(loc.x / loc.size), 'y': ~~(loc.y / loc.size) }
|
||||
return editor.pos;
|
||||
}
|
||||
|
||||
var holdingPath = 0;
|
||||
var stepPostfix = null;//用于存放寻路检测的第一个点之后的后续移动
|
||||
|
||||
var mouseOutCheck = 2;
|
||||
function clear1() {
|
||||
if (mouseOutCheck > 1) {
|
||||
mouseOutCheck--;
|
||||
setTimeout(clear1, 1000);
|
||||
return;
|
||||
}
|
||||
holdingPath = 0;
|
||||
stepPostfix = [];
|
||||
uc.clearRect(0, 0, 416, 416);
|
||||
}//用于鼠标移出canvas时的自动清除状态
|
||||
|
||||
eui.onmousedown = function (e) {
|
||||
if(!selectBox.isSelected) {
|
||||
var loc = eToLoc(e);
|
||||
var pos = locToPos(loc);
|
||||
editor_mode.onmode('nextChange');
|
||||
editor_mode.onmode('loc');
|
||||
editor_mode.loc();
|
||||
tip.whichShow = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
holdingPath = 1;
|
||||
mouseOutCheck = 2;
|
||||
setTimeout(clear1);
|
||||
e.stopPropagation();
|
||||
uc.clearRect(0, 0, 416, 416);
|
||||
var loc = eToLoc(e);
|
||||
var pos = locToPos(loc);
|
||||
stepPostfix = [];
|
||||
stepPostfix.push(pos);
|
||||
fillPos(pos);
|
||||
}
|
||||
|
||||
eui.onmousemove = function (e) {
|
||||
if(!selectBox.isSelected) {
|
||||
// tip.whichShow = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
if (holdingPath == 0) { return; }
|
||||
mouseOutCheck = 2;
|
||||
e.stopPropagation();
|
||||
var loc = eToLoc(e);
|
||||
var pos = locToPos(loc);
|
||||
var pos0 = stepPostfix[stepPostfix.length - 1]
|
||||
var directionDistance = [pos.y - pos0.y, pos0.x - pos.x, pos0.y - pos.y, pos.x - pos0.x]
|
||||
var max = 0, index = 4;
|
||||
for (var i = 0; i < 4; i++) {
|
||||
if (directionDistance[i] > max) {
|
||||
index = i;
|
||||
max = directionDistance[i];
|
||||
}
|
||||
}
|
||||
var pos = [{ 'x': 0, 'y': 1 }, { 'x': -1, 'y': 0 }, { 'x': 0, 'y': -1 }, { 'x': 1, 'y': 0 }, false][index]
|
||||
if (pos) {
|
||||
pos.x += pos0.x;
|
||||
pos.y += pos0.y;
|
||||
stepPostfix.push(pos);
|
||||
fillPos(pos);
|
||||
}
|
||||
}
|
||||
|
||||
eui.onmouseup = function (e) {
|
||||
if(!selectBox.isSelected) {
|
||||
tip.whichShow = 1;
|
||||
return;
|
||||
}
|
||||
holdingPath = 0;
|
||||
e.stopPropagation();
|
||||
var loc = eToLoc(e);
|
||||
if (stepPostfix.length) {
|
||||
preMapData = JSON.parse(JSON.stringify(editor.map));
|
||||
currDrawData.pos = JSON.parse(JSON.stringify(stepPostfix));
|
||||
currDrawData.info = JSON.parse(JSON.stringify(editor.info));
|
||||
reDo = null;
|
||||
// console.log(stepPostfix);
|
||||
for (var ii = 0; ii < stepPostfix.length; ii++)
|
||||
editor.map[stepPostfix[ii].y][stepPostfix[ii].x] = editor.info;
|
||||
// console.log(editor.map);
|
||||
editor.updateMap();
|
||||
holdingPath = 0;
|
||||
stepPostfix = [];
|
||||
uc.clearRect(0, 0, 416, 416);
|
||||
}
|
||||
}
|
||||
|
||||
var preMapData = {};
|
||||
var currDrawData = {
|
||||
pos: [],
|
||||
info: {}
|
||||
};
|
||||
var reDo = null;
|
||||
document.body.onkeydown = function(e) {
|
||||
// 禁止快捷键的默认行为
|
||||
if( e.ctrlKey && ( e.keyCode == 90 || e.keyCode == 89 ) )
|
||||
e.preventDefault();
|
||||
//Ctrl+z 撤销上一步undo
|
||||
if(e.keyCode == 90 && e.ctrlKey && preMapData && currDrawData.pos.length){
|
||||
editor.map = JSON.parse(JSON.stringify(preMapData));
|
||||
editor.updateMap();
|
||||
reDo = JSON.parse(JSON.stringify(currDrawData));
|
||||
currDrawData = {pos: [],info: {}};
|
||||
preMapData = null;
|
||||
}
|
||||
//Ctrl+y 重做一步redo
|
||||
if(e.keyCode == 89 && e.ctrlKey && reDo && reDo.pos.length){
|
||||
preMapData = JSON.parse(JSON.stringify(editor.map));
|
||||
for(var j=0; j<reDo.pos.length;j++)
|
||||
editor.map[reDo.pos[j].y][reDo.pos[j].x] = JSON.parse(JSON.stringify(reDo.info));
|
||||
|
||||
editor.updateMap();
|
||||
currDrawData = JSON.parse(JSON.stringify(reDo));
|
||||
reDo = null;
|
||||
}
|
||||
}
|
||||
|
||||
edata.onmousedown = function (e) {
|
||||
e.stopPropagation();
|
||||
var scrollLeft = document.documentElement.scrollLeft || document.body.scrollLeft;
|
||||
var scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
|
||||
var loc = {
|
||||
'x': scrollLeft + e.clientX + iconLib.scrollLeft - right.offsetLeft-iconLib.offsetLeft,
|
||||
'y': scrollTop + e.clientY + iconLib.scrollTop - right.offsetTop-iconLib.offsetTop,
|
||||
'size': 32
|
||||
};
|
||||
editor.loc = loc;
|
||||
var pos = locToPos(loc);
|
||||
for (var spriter in editor.widthsX){
|
||||
if(pos.x>=editor.widthsX[spriter][1] && pos.x<editor.widthsX[spriter][2]){
|
||||
var ysize = spriter.indexOf('48')===-1?32:48;
|
||||
loc.ysize = ysize;
|
||||
pos.y = ~~(loc.y / loc.ysize);
|
||||
pos.x=editor.widthsX[spriter][1];
|
||||
pos.images = editor.widthsX[spriter][0];
|
||||
var autotiles = editor.material.images['autotile'];
|
||||
if(pos.images=='autotile'){
|
||||
var imNames = Object.keys(autotiles);
|
||||
if((pos.y+1)*ysize > editor.widthsX[spriter][3])
|
||||
pos.y = ~~(editor.widthsX[spriter][3]/ysize)-4;
|
||||
else{
|
||||
for(var i=0; i<imNames.length; i++){
|
||||
if(pos.y >= 4*i && pos.y < 4*(i+1)){
|
||||
pos.images = imNames[i];
|
||||
pos.y = 4*i;
|
||||
}
|
||||
}
|
||||
}
|
||||
}else if((pos.y+1)*ysize > editor.widthsX[spriter][3])
|
||||
pos.y = ~~(editor.widthsX[spriter][3]/ysize)-1;
|
||||
|
||||
selectBox.isSelected = true;
|
||||
// console.log(pos,editor.material.images[pos.images].height)
|
||||
dataSelection.style.left = pos.x*32 +'px';
|
||||
dataSelection.style.top = pos.y*ysize +'px';
|
||||
dataSelection.style.height = ysize-6+'px';
|
||||
|
||||
if(pos.x==0&&pos.y==0){
|
||||
// editor.info={idnum:0, id:'empty','images':'清除块', 'y':0};
|
||||
editor.info=0;
|
||||
}else{
|
||||
if(hasOwnProp(autotiles, pos.images)) editor.info={'images':pos.images, 'y':0};
|
||||
else if(pos.images == 'terrains') editor.info={'images':pos.images, 'y':pos.y-1};
|
||||
else editor.info={'images':pos.images, 'y':pos.y};
|
||||
|
||||
for (var ii=0;ii<editor.ids.length;ii++){
|
||||
if( ( editor.info.images==editor.ids[ii].images
|
||||
&& editor.info.y==editor.ids[ii].y )
|
||||
|| (hasOwnProp(autotiles, pos.images) && editor.info.images==editor.ids[ii].id
|
||||
&& editor.info.y==editor.ids[ii].y)){
|
||||
|
||||
editor.info = editor.ids[ii];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
tip.infos = JSON.parse(JSON.stringify(editor.info));
|
||||
editor_mode.onmode('nextChange');
|
||||
editor_mode.onmode('emenyitem');
|
||||
editor_mode.emenyitem();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}//绑定事件
|
||||
|
||||
/*
|
||||
editor.loc
|
||||
editor.pos
|
||||
editor.info
|
||||
始终是最后一次点击的结果
|
||||
注意editor.info可能因为点击其他地方而被清空
|
||||
*/
|
||||
|
||||
editor = new editor();
|
||||
393
_server/editor_blockly.js
Normal file
@ -0,0 +1,393 @@
|
||||
editor_blockly = function(){
|
||||
|
||||
var editor_blockly = {};
|
||||
|
||||
initscript=String.raw`
|
||||
(function(){
|
||||
var getCategory = function(name){
|
||||
for(var node of document.getElementById('toolbox').children) {
|
||||
if(node.getAttribute('name')==name) return node;
|
||||
}
|
||||
}
|
||||
|
||||
var toolboxObj = {
|
||||
'entry':[
|
||||
MotaActionFunctions.actionParser.parse([
|
||||
"欢迎使用事件编辑器",
|
||||
"本事件触发一次后会消失",
|
||||
{"type": "hide", "time": 500},
|
||||
],'event'),
|
||||
MotaActionBlocks['changeFloor_m'].xmlText(),
|
||||
MotaActionFunctions.actionParser.parse({"type": "choices", "choices": [
|
||||
{"text": "攻击+\${point}", "action": [
|
||||
{"type": "setValue", "name": "status:atk", "value": "status:atk+\${point}"},
|
||||
]},
|
||||
{"text": "防御+\${2*point}", "action": [
|
||||
{"type": "setValue", "name": "status:def", "value": "status:def+\${2*point}"},
|
||||
]},
|
||||
{"text": "生命+\${200*point}", "action": [
|
||||
{"type": "setValue", "name": "status:hp", "value": "status:hp+\${200*point}"},
|
||||
]},
|
||||
]},'point'),
|
||||
MotaActionFunctions.actionParser.parse({
|
||||
"id": "moneyShop1",
|
||||
"name": "贪婪之神",
|
||||
"icon": "blueShop",
|
||||
"textInList": "1F金币商店",
|
||||
"use": "money",
|
||||
"need": "20+10*times*(times+1)",
|
||||
"text": "勇敢的武士啊,给我\${need}金币就可以:",
|
||||
"choices": [
|
||||
{"text": "生命+800", "effect": "status:hp+=800"},
|
||||
{"text": "攻击+4", "effect": "status:atk+=4"},
|
||||
{"text": "防御+4", "effect": "status:def+=4"},
|
||||
{"text": "魔防+10", "effect": "status:mdef+=10"}
|
||||
]
|
||||
},'shop'),
|
||||
MotaActionBlocks['afterBattle_m'].xmlText(),
|
||||
MotaActionBlocks['afterGetItem_m'].xmlText(),
|
||||
MotaActionBlocks['afterOpenDoor_m'].xmlText(),
|
||||
MotaActionBlocks['firstArrive_m'].xmlText(),
|
||||
],
|
||||
'statement':[
|
||||
'<label text="显示文字"></label>',
|
||||
MotaActionBlocks['text_0_s'].xmlText(),
|
||||
MotaActionBlocks['text_1_s'].xmlText(),
|
||||
MotaActionFunctions.actionParser.parseList({"type": "choices", "text": "是否跳过剧情", "choices": [
|
||||
{"text": "是", "action": []},
|
||||
{"text": "否", "action": [
|
||||
{"type": "autoText", "text": "\\t[小妖精,fairy]双击方块进入多行编辑\\n用户无法跳过自动剧情文本,大段剧情文本请添加“是否跳过剧情”的提示\\n自动剧情文本\\n自动剧情文本\\n自动剧情文本", "time" :3000},
|
||||
{"type": "autoText", "text": "(可以右键方块后点复制)", "time" :3000},
|
||||
]},
|
||||
]}),
|
||||
MotaActionBlocks['setText_s'].xmlText(),
|
||||
MotaActionBlocks['showImage_0_s'].xmlText(),
|
||||
MotaActionBlocks['showImage_1_s'].xmlText(),
|
||||
MotaActionBlocks['tip_s'].xmlText(),
|
||||
MotaActionBlocks['openShop_s'].xmlText(),
|
||||
MotaActionBlocks['win_s'].xmlText(),
|
||||
MotaActionBlocks['lose_s'].xmlText(),
|
||||
MotaActionBlocks['choices_s'].xmlText([
|
||||
'选择剑或者盾','流浪者','man',MotaActionBlocks['choicesContext'].xmlText([
|
||||
'剑',MotaActionFunctions.actionParser.parseList([{"type": "openDoor", "loc": [3,3]}]),
|
||||
MotaActionBlocks['choicesContext'].xmlText([
|
||||
'盾',MotaActionFunctions.actionParser.parseList([{"type": "openDoor", "loc": [9,3]}]),
|
||||
])
|
||||
])
|
||||
]),
|
||||
'<label text="数据相关"></label>',
|
||||
MotaActionBlocks['setValue_s'].xmlText(),
|
||||
MotaActionBlocks['input_s'].xmlText(),
|
||||
MotaActionBlocks['update_s'].xmlText(),
|
||||
MotaActionBlocks['moveHero_s'].xmlText(),
|
||||
MotaActionBlocks['changeFloor_s'].xmlText(),
|
||||
MotaActionBlocks['changePos_0_s'].xmlText(),
|
||||
MotaActionBlocks['changePos_1_s'].xmlText(),
|
||||
MotaActionBlocks['battle_s'].xmlText(),
|
||||
MotaActionBlocks['openDoor_s'].xmlText(),
|
||||
MotaActionBlocks['setBlock_s'].xmlText(),
|
||||
'<label text="事件控制"></label>',
|
||||
MotaActionBlocks['if_s'].xmlText(),
|
||||
MotaActionBlocks['revisit_s'].xmlText(),
|
||||
MotaActionBlocks['exit_s'].xmlText(),
|
||||
MotaActionBlocks['show_s'].xmlText(),
|
||||
MotaActionBlocks['hide_s'].xmlText(),
|
||||
MotaActionBlocks['trigger_s'].xmlText(),
|
||||
MotaActionBlocks['move_s'].xmlText(),
|
||||
MotaActionBlocks['disableShop_s'].xmlText(),
|
||||
'<label text="特效/声音"></label>',
|
||||
MotaActionBlocks['sleep_s'].xmlText(),
|
||||
MotaActionBlocks['animate_s'].xmlText(),
|
||||
MotaActionBlocks['setFg_0_s'].xmlText(),
|
||||
MotaActionBlocks['setFg_1_s'].xmlText(),
|
||||
MotaActionBlocks['setWeather_s'].xmlText(),
|
||||
MotaActionBlocks['playBgm_s'].xmlText(),
|
||||
MotaActionBlocks['pauseBgm_s'].xmlText(),
|
||||
MotaActionBlocks['resumeBgm_s'].xmlText(),
|
||||
MotaActionBlocks['playSound_s'].xmlText(),
|
||||
'<label text="其他"></label>',
|
||||
MotaActionBlocks['function_s'].xmlText(),
|
||||
],
|
||||
'value':[
|
||||
MotaActionBlocks['setValue_s'].xmlText(),
|
||||
MotaActionBlocks['expression_arithmetic_0'].xmlText(),
|
||||
MotaActionBlocks['negate_e'].xmlText(),
|
||||
MotaActionBlocks['bool_e'].xmlText(),
|
||||
MotaActionBlocks['idString_e'].xmlText(),
|
||||
MotaActionBlocks['idString_1_e'].xmlText(),
|
||||
MotaActionBlocks['idString_2_e'].xmlText(),
|
||||
MotaActionBlocks['evalString_e'].xmlText(),
|
||||
],
|
||||
'template':[
|
||||
'<label text="检测音乐如果没有开启则系统提示开启"></label>',
|
||||
MotaActionFunctions.actionParser.parseList({"type": "if", "condition": "!core.musicStatus.bgmStatus",
|
||||
"true": [
|
||||
"\t[系统提示]你当前音乐处于关闭状态,本塔开音乐游戏效果更佳"
|
||||
],
|
||||
"false": []
|
||||
}),
|
||||
'<label text="战前剧情"></label>',
|
||||
MotaActionFunctions.actionParser.parse({
|
||||
"trigger": "action",
|
||||
"displayDamage": true,
|
||||
"data": [
|
||||
' ... 战前剧情',
|
||||
{"type": "battle", "id": "greenSlime"},
|
||||
' ... 战后剧情;请注意上面的强制战斗不会使怪物消失',
|
||||
'需要下一句来调用{"type": "hide"}来隐藏事件',
|
||||
{"type": "hide"},
|
||||
]
|
||||
},'event'),
|
||||
'<label text="打怪掉落道具"></label>',
|
||||
MotaActionFunctions.actionParser.parse([
|
||||
'怪物变成了黄钥匙(黄钥匙idnum是21)',
|
||||
'打怪变成可对话的NPC: https://ckcz123.github.io/mota-js/#/event?id=%e6%89%93%e6%80%aa%e5%8f%98%e6%88%90%e5%8f%af%e5%af%b9%e8%af%9d%e7%9a%84npc%ef%bc%88%e6%80%aa%e7%89%a9-gtnpc%ef%bc%89',
|
||||
{"type": "setBlock", "number": 21}
|
||||
],'afterBattle'),
|
||||
'<label text="打怪开门"></label>',
|
||||
MotaActionFunctions.actionParser.parse([
|
||||
{"type": "setValue", "name": "flag:__door_name__", "value": "flag:__door_name__+1"},
|
||||
{"type": "if", "condition": "flag:__door_name__==2",
|
||||
"true": [
|
||||
{"type": "openDoor", "loc": [10,5]}
|
||||
],
|
||||
"false": []
|
||||
},
|
||||
],'afterBattle'),
|
||||
'<label text="获得圣水后变成墙"></label>',
|
||||
MotaActionFunctions.actionParser.parse({
|
||||
"trigger": "action",
|
||||
"noPass": true,
|
||||
"data": [
|
||||
{"type": "if", "condition": "flag:hasSuperPotion",
|
||||
"true": [],
|
||||
"false": [
|
||||
{"type":"setValue", "name":"status:hp", "value":"status:hp*2"},
|
||||
{"type":"setBlock", "number": 1},
|
||||
{"type":"setValue", "name":"flag:hasSuperPotion", "value": "true"}
|
||||
]
|
||||
}
|
||||
]
|
||||
},'event'),
|
||||
|
||||
],
|
||||
}
|
||||
var toolboxgap = '<sep gap="5"></sep>'
|
||||
//xml_text = MotaActionFunctions.actionParser.parse(obj,type||'event')
|
||||
//MotaActionBlocks['idString_e'].xmlText()
|
||||
|
||||
for (var name in toolboxObj){
|
||||
getCategory(name).innerHTML = toolboxObj[name].join(toolboxgap);
|
||||
}
|
||||
|
||||
var workspace = Blockly.inject('blocklyDiv',{
|
||||
media: '_server/blockly/media/',
|
||||
toolbox: document.getElementById('toolbox'),
|
||||
zoom:{
|
||||
controls: true,
|
||||
wheel: true,//false
|
||||
startScale: 1.0,
|
||||
maxScale: 3,
|
||||
minScale: 0.3,
|
||||
scaleSpeed: 1.08
|
||||
},
|
||||
trashcan: false,
|
||||
});
|
||||
|
||||
var doubleClickCheck=[[0,'abc']];
|
||||
function omitedcheckUpdateFunction(event) {
|
||||
//console.log(event);
|
||||
if(event.type==='ui'){
|
||||
var newClick = [new Date().getTime(),event.blockId];
|
||||
var lastClick = doubleClickCheck.shift();
|
||||
doubleClickCheck.push(newClick);
|
||||
if(newClick[0]-lastClick[0]<500){
|
||||
if(newClick[1]===lastClick[1]){
|
||||
editor_blockly.doubleClickBlock(newClick[1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
try {
|
||||
var code = Blockly.JavaScript.workspaceToCode(workspace);
|
||||
codeAreaHL.setValue(code);
|
||||
} catch (error) {
|
||||
codeAreaHL.setValue(String(error));
|
||||
if (error instanceof OmitedError){
|
||||
var blockName = error.blockName;
|
||||
var varName = error.varName;
|
||||
var block = error.block;
|
||||
}
|
||||
console.log(error);
|
||||
}
|
||||
}
|
||||
|
||||
workspace.addChangeListener(omitedcheckUpdateFunction);
|
||||
|
||||
workspace.addChangeListener(Blockly.Events.disableOrphans);
|
||||
|
||||
editor_blockly.workspace = workspace;
|
||||
|
||||
MotaActionFunctions.workspace = function(){
|
||||
return editor_blockly.workspace;
|
||||
}
|
||||
})();
|
||||
`;
|
||||
|
||||
var input_='';
|
||||
editor_blockly.runOne = function (){
|
||||
//var printf = console.log;
|
||||
//var printf = function(){};
|
||||
var grammerFile = input_;
|
||||
converter = new Converter().init();
|
||||
converter.generBlocks(grammerFile);
|
||||
//printf(converter.blocks);
|
||||
converter.renderGrammerName();
|
||||
//converter.generToolbox();
|
||||
converter.generMainFile();
|
||||
//printf(converter.mainFile.join(''));
|
||||
console.log(converter);
|
||||
|
||||
|
||||
|
||||
var script = document.createElement('script');
|
||||
//var initscript = document.getElementById('initscript').innerText;
|
||||
script.innerHTML = converter.mainFile[5]+initscript;
|
||||
document.body.appendChild(script);
|
||||
}
|
||||
var xhr=new XMLHttpRequest();
|
||||
xhr.onreadystatechange = function (){
|
||||
if(xhr.readyState!=4) return;
|
||||
if(xhr.status!=200) {
|
||||
alert("无法在file://下加载");
|
||||
return;
|
||||
}
|
||||
input_=xhr.responseText;
|
||||
editor_blockly.runOne();
|
||||
}
|
||||
xhr.open('GET','_server/blockly/MotaAction.g4',true);
|
||||
xhr.send(null);
|
||||
|
||||
codeAreaHL = CodeMirror.fromTextArea(document.getElementById("codeArea"), {
|
||||
lineNumbers: true,
|
||||
matchBrackets: true,
|
||||
lineWrapping: true,
|
||||
continueComments: "Enter",
|
||||
extraKeys: {"Ctrl-Q": "toggleComment"}
|
||||
});
|
||||
|
||||
editor_blockly.showXML = function () {
|
||||
var xml = Blockly.Xml.workspaceToDom(editor_blockly.workspace);
|
||||
var xml_text = Blockly.Xml.domToPrettyText(xml);
|
||||
console.log(xml_text);
|
||||
var xml_text = Blockly.Xml.domToText(xml);
|
||||
console.log(xml_text);
|
||||
console.log(xml);
|
||||
}
|
||||
|
||||
editor_blockly.runCode = function () {
|
||||
// Generate JavaScript code and run it.
|
||||
window.LoopTrap = 1000;
|
||||
Blockly.JavaScript.INFINITE_LOOP_TRAP =
|
||||
'if (--window.LoopTrap == 0) throw "Infinite loop.";\n';
|
||||
var code = Blockly.JavaScript.workspaceToCode(editor_blockly.workspace);
|
||||
Blockly.JavaScript.INFINITE_LOOP_TRAP = null;
|
||||
try {
|
||||
eval('obj=' + code);
|
||||
console.log(obj);
|
||||
} catch (e) {
|
||||
alert(e);
|
||||
}
|
||||
}
|
||||
|
||||
editor_blockly.parse = function () {
|
||||
MotaActionFunctions.parse(
|
||||
eval('obj=' + codeAreaHL.getValue().replace(/[<>&]/g,function(c){return {'<':'<','>':'>','&':'&'}[c];})),
|
||||
document.getElementById('entryType').value
|
||||
);
|
||||
}
|
||||
|
||||
editor_blockly.id='';
|
||||
|
||||
editor_blockly.import = function(id_){
|
||||
var thisTr = document.getElementById(id_);
|
||||
if(!thisTr)return false;
|
||||
var input = thisTr.children[2].children[0].children[0];
|
||||
var field = thisTr.children[0].getAttribute('title');
|
||||
var type = {
|
||||
"['events']":'event',
|
||||
"['changeFloor']":'changeFloor',
|
||||
"['afterBattle']":'afterBattle',
|
||||
"['afterGetItem']":'afterGetItem',
|
||||
"['afterOpenDoor']":'afterOpenDoor',
|
||||
|
||||
//"['firstData']['shops']":'shop',
|
||||
"--shop--未完成数组的处理":'shop',
|
||||
|
||||
"['firstArrive']":'firstArrive',
|
||||
"['firstData']['startText']":'firstArrive',
|
||||
|
||||
"--point--未完成数据转移":'point',
|
||||
}[field];
|
||||
if(!type)return false;
|
||||
editor_blockly.id=id_;
|
||||
codeAreaHL.setValue(input.value);
|
||||
document.getElementById('entryType').value = type;
|
||||
editor_blockly.parse();
|
||||
editor_blockly.show();
|
||||
return true;
|
||||
}
|
||||
|
||||
editor_blockly.show = function(){document.getElementById('left6').style='';}
|
||||
editor_blockly.hide = function(){document.getElementById('left6').style='z-index:-1;opacity: 0;';}
|
||||
|
||||
editor_blockly.cancel = function(){
|
||||
editor_blockly.id='';
|
||||
editor_blockly.hide();
|
||||
}
|
||||
|
||||
editor_blockly.confirm = function (){
|
||||
if(!editor_blockly.id){
|
||||
editor_blockly.id='';
|
||||
return;
|
||||
}
|
||||
var setvalue = function(value){
|
||||
var thisTr = document.getElementById(editor_blockly.id);
|
||||
editor_blockly.id='';
|
||||
var input = thisTr.children[2].children[0].children[0];
|
||||
input.value = value;
|
||||
editor_blockly.hide();
|
||||
input.onchange();
|
||||
}
|
||||
if(codeAreaHL.getValue()===''){
|
||||
setvalue('null');
|
||||
return;
|
||||
}
|
||||
var code = Blockly.JavaScript.workspaceToCode(editor_blockly.workspace);
|
||||
eval('var obj=' + code);
|
||||
setvalue(JSON.stringify(obj));
|
||||
}
|
||||
|
||||
editor_blockly.doubleClickBlock = function (blockId){
|
||||
var b=editor_blockly.workspace.getBlockById(blockId);
|
||||
//console.log(b);
|
||||
var textStringDict = {
|
||||
'text_0_s':'EvalString_0',
|
||||
'text_1_s':'EvalString_2',
|
||||
'autoText_s':'EvalString_2',
|
||||
'choices_s':'EvalString_0',
|
||||
'function_s':'RawEvalString_0',
|
||||
}
|
||||
var f=b?textStringDict[b.type]:null;
|
||||
if(f){
|
||||
var value = b.getFieldValue(f);
|
||||
//多行编辑
|
||||
editor_multi.multiLineEdit(value,b,f,function(newvalue,b,f){
|
||||
if(textStringDict[b.type]!=='RawEvalString_0'){}
|
||||
b.setFieldValue(newvalue.split('\n').join('\\n'),f);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return editor_blockly;
|
||||
}
|
||||
//editor_blockly=editor_blockly();
|
||||
@ -1,63 +1,608 @@
|
||||
(function(){
|
||||
|
||||
editor_file = {};
|
||||
editor_file.getFloorFileList = function(editor,callback){
|
||||
if (isset(callback)) callback(['simple0.js','simple1.js','simple2.js'],null);
|
||||
}
|
||||
//callback(Array<String>,err:String)
|
||||
editor_file.loadFloorFile = function(editor,filename,callback){
|
||||
if (isset(callback)) callback('',null);
|
||||
}
|
||||
//callback(String,err:String)
|
||||
editor_file.saveFloorFile = function(editor,callback){
|
||||
if (isset(callback)) callback(null);
|
||||
}
|
||||
//callback(err:String)
|
||||
editor_file.saveFloorFile = function(editor,saveAsFilename,callback){
|
||||
if (isset(callback)) callback(null);
|
||||
}
|
||||
//callback(err:String)
|
||||
editor_file.changeIdAndIdnum = function(editor,id,idnum,callback){
|
||||
if (isset(callback)) callback(null);
|
||||
}
|
||||
//callback(err:String)
|
||||
editor_file.editItem = function(editor,id,callback){
|
||||
if (isset(callback)) callback('',null);
|
||||
}
|
||||
//callback(String,err:String)
|
||||
editor_file.editEnemy = function(editor,id,callback){
|
||||
if (isset(callback)) callback({'name': '初级巫师', 'hp': 100, 'atk': 120, 'def': 0, 'money': 16, 'experience': 0, 'special': 15, 'value': 100},null);
|
||||
}
|
||||
//callback(obj,err:String)
|
||||
editor_file.editLoc = function(editor,x,y,input_value,callback){
|
||||
if (isset(callback)) callback({"events":` [ // 守着道具的老人
|
||||
"\t[老人,man]这些是本样板支持的所有的道具。\n\n道具分为三类:items, constants, tools。\nitems 为即捡即用类道具,例如宝石、血瓶、剑盾等。\nconstants 为永久道具,例如怪物手册、楼层传送器、幸运金币等。\ntools 为消耗类道具,例如破墙镐、炸弹、中心对称飞行器等。\n\n后两类道具在工具栏中可以看到并使用。",
|
||||
"\t[老人,man]有关道具效果,定义在items.js中。\n目前大多数道具已有默认行为,如有自定义的需求则需在items.js中修改代码。",
|
||||
"\t[老人,man]constants 和 tools 各最多只允许12种,多了会导致图标溢出。",
|
||||
"\t[老人,man]拾取道具结束后可触发 afterGetItem 事件。\n\n有关事件的各种信息在下一层会有更为详细的说明。",
|
||||
{"type": "hide", "time": 500} // 消失
|
||||
],`,"changeFloor":"","afterBattle":"","afterGetItem":"","afterOpenDoor":""},null);
|
||||
}
|
||||
//callback(obj,err:String)
|
||||
editor_file.editFloor = function(editor,input_value,callback){
|
||||
if (isset(callback)) callback({"floorId": "sample0",
|
||||
"title": "样板 0 层",
|
||||
"name": "0",
|
||||
"canFlyTo": true,
|
||||
"canUseQuickShop": true,
|
||||
"defaultGround": "ground",
|
||||
"firstArrive":` [ // 第一次到该楼层触发的事件
|
||||
"\t[样板提示]首次到达某层可以触发 firstArrive 事件,该事件可类似于RMXP中的“自动执行脚本”。\n\n本事件支持一切的事件类型,常常用来触发对话,例如:",
|
||||
"\t[hero]我是谁?我从哪来?我又要到哪去?",
|
||||
"\t[仙子,fairy]你问我...?我也不知道啊...",
|
||||
"本层主要对道具、门、怪物等进行介绍,有关事件的各种信息在下一层会有更为详细的说明。",
|
||||
],`},null);
|
||||
}
|
||||
//callback(obj,err:String)
|
||||
var isset = function (val) {
|
||||
if (val == undefined || val == null) {
|
||||
return false;
|
||||
}
|
||||
return true
|
||||
}
|
||||
})();
|
||||
editor_file = function(editor, callback){
|
||||
|
||||
var editor_file = {};
|
||||
|
||||
|
||||
var commentjs={
|
||||
'comment':'comment',
|
||||
'data.comment':'dataComment',
|
||||
'functions.comment':'functionsComment',
|
||||
}
|
||||
for(var key in commentjs){
|
||||
(function(key){
|
||||
var value = commentjs[key];
|
||||
var script = document.createElement('script');
|
||||
if (window.location.href.indexOf('_server')!==-1)
|
||||
script.src = '../project/'+key+'.js';
|
||||
else
|
||||
script.src = 'project/'+key+'.js';
|
||||
document.body.appendChild(script);
|
||||
script.onload = function () {
|
||||
editor_file[value]=eval(key.replace('.','_')+'_c456ea59_6018_45ef_8bcc_211a24c627dc');
|
||||
var loaded = Boolean(callback);
|
||||
for(var key_ in commentjs){loaded = loaded && editor_file[commentjs[key_]]}
|
||||
if (loaded)callback();
|
||||
}
|
||||
})(key);
|
||||
}
|
||||
|
||||
|
||||
editor_file.getFloorFileList = function(callback){
|
||||
if (!isset(callback)) {printe('未设置callback');throw('未设置callback')};
|
||||
/* var fs = editor.fs;
|
||||
fs.readdir('project/floors',function(err, data){
|
||||
callback([data,err]);
|
||||
}); */
|
||||
callback([editor.core.floorIds,null]);
|
||||
}
|
||||
//callback([Array<String>,err:String])
|
||||
editor_file.loadFloorFile = function(filename,callback){
|
||||
//filename不含'/'不含'.js'
|
||||
if (!isset(callback)) {printe('未设置callback');throw('未设置callback')};
|
||||
/* var fs = editor.fs;
|
||||
fs.readFile('project/floors/'+filename+'.js','utf-8',function(err, data){
|
||||
if (err!=null){callback(err);return;}
|
||||
data=data.split('=');
|
||||
data=[data[0],data.slice(1).join('=')];
|
||||
var varnameId = data[0].split('.').slice(-1)[0].trim();
|
||||
var filenameId = filename.split('/').slice(-1)[0].split('\\').slice(-1)[0];
|
||||
eval('b3917d1d_71c2_41f2_a8aa_481b215ffb99='+data[1]);
|
||||
var floorData = b3917d1d_71c2_41f2_a8aa_481b215ffb99;
|
||||
delete(b3917d1d_71c2_41f2_a8aa_481b215ffb99);
|
||||
var floorId = floorData.floorId;
|
||||
if (varnameId!=filenameId || filenameId!=floorId){
|
||||
callback('文件名,第一行的变量名以及floorId不一致');
|
||||
return;
|
||||
}
|
||||
editor.currentFloorId = floorId;
|
||||
editor.currentFloorData = floorData;
|
||||
callback(null)
|
||||
}); */
|
||||
editor.currentFloorId=editor.core.status.floorId;
|
||||
editor.currentFloorData = editor.core.floors[editor.currentFloorId];
|
||||
}
|
||||
//callback(err:String)
|
||||
editor_file.saveFloorFile = function(callback){
|
||||
if (!isset(callback)) {printe('未设置callback');throw('未设置callback')};
|
||||
/* if (!isset(editor.currentFloorId) || !isset(editor.currentFloorData)) {
|
||||
callback('未选中文件或无数据');
|
||||
} */
|
||||
var filename = 'project/floors/' + editor.currentFloorId + '.js';
|
||||
var datastr = ['main.floors.' , editor.currentFloorId , '=\n{'];
|
||||
editor.currentFloorData.map = editor.map.map(function(v){return v.map(function(v){return v.idnum||v||0})});
|
||||
for(var ii in editor.currentFloorData)
|
||||
if (editor.currentFloorData.hasOwnProperty(ii)) {
|
||||
if (ii=='map')
|
||||
datastr=datastr.concat(['\n"',ii,'": [\n',formatMap(editor.currentFloorData[ii]),'\n],']);
|
||||
else
|
||||
datastr=datastr.concat(['\n"',ii,'": ',JSON.stringify(editor.currentFloorData[ii],null,4),',']);
|
||||
}
|
||||
datastr=datastr.concat(['\n}']);
|
||||
datastr=datastr.join('');
|
||||
fs.writeFile(filename,encode(datastr),'base64',function(err, data){
|
||||
callback(err);
|
||||
});
|
||||
}
|
||||
//callback(err:String)
|
||||
editor_file.saveFloorFileAs = function(saveAsFilename,callback){
|
||||
//saveAsFilename不含'/'不含'.js'
|
||||
if (!isset(callback)) {printe('未设置callback');throw('未设置callback')};
|
||||
if (!isset(editor.currentFloorData)) {
|
||||
callback('无数据');
|
||||
}
|
||||
editor.currentFloorData.map = editor.map.map(function(v){return v.map(function(v){return v.idnum||v||0})});
|
||||
editor.currentFloorData=JSON.parse(JSON.stringify(editor.currentFloorData));
|
||||
editor.currentFloorData.floorId=saveAsFilename;
|
||||
editor.currentFloorId=saveAsFilename;
|
||||
editor_file.saveFloorFile(callback);
|
||||
}
|
||||
//callback(err:String)
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
editor_file.changeIdAndIdnum = function(id,idnum,info,callback){
|
||||
if (!isset(callback)) {printe('未设置callback');throw('未设置callback')};
|
||||
//检查maps中是否有重复的idnum或id
|
||||
var change = -1;
|
||||
for(var ii in editor.core.maps.blocksInfo){
|
||||
if (ii==idnum) {
|
||||
//暂时只允许创建新的不允许修改已有的
|
||||
//if (info.idnum==idnum){change=ii;break;}//修改id
|
||||
callback('idnum重复了');
|
||||
return;
|
||||
}
|
||||
if (editor.core.maps.blocksInfo[ii].id==id) {
|
||||
//if (info.id==id){change=ii;break;}//修改idnum
|
||||
callback('id重复了');
|
||||
return;
|
||||
}
|
||||
}
|
||||
/*
|
||||
if (change!=-1 && change!=idnum){//修改idnum
|
||||
editor.core.maps.blocksInfo[idnum] = editor.core.maps.blocksInfo[change];
|
||||
delete(editor.core.maps.blocksInfo[change]);
|
||||
} else if (change==idnum) {//修改id
|
||||
var oldid = editor.core.maps.blocksInfo[idnum].id;
|
||||
editor.core.maps.blocksInfo[idnum].id = id;
|
||||
for(var ii in editor.core.icons.icons){
|
||||
if (ii.hasOwnProperty(oldid)){
|
||||
ii[id]=ii[oldid];
|
||||
delete(ii[oldid]);
|
||||
}
|
||||
}
|
||||
} else {//创建新的
|
||||
editor.core.maps.blocksInfo[idnum]={'cls': info.images, 'id':id};
|
||||
editor.core.icons.icons[info.images][id]=info.y;
|
||||
}
|
||||
*/
|
||||
var templist=[];
|
||||
var tempcallback = function (err) {
|
||||
templist.push(err);
|
||||
if (templist.length ==2 ) {
|
||||
if (templist[0]!=null || templist[1]!=null)
|
||||
callback((templist[0]||'')+'\n'+(templist[1]||''));
|
||||
//这里如果一个成功一个失败会出严重bug
|
||||
else
|
||||
callback(null);
|
||||
}
|
||||
}
|
||||
saveSetting('maps',[["add","['"+idnum+"']",{'cls': info.images, 'id':id}]],tempcallback);
|
||||
saveSetting('icons',[["add","['"+info.images+"']['"+id+"']",info.y]],tempcallback);
|
||||
if(info.images==='items'){
|
||||
saveSetting('items',[["change"/*其实应该是add*/,"['items']['"+id+"']",editor_file.comment.items_template]],function(err){if(err){printe(err);throw(err)}});
|
||||
}
|
||||
if(info.images==='enemys'){
|
||||
saveSetting('enemys',[["change"/*其实应该是add*/,"['enemys']['"+id+"']",editor_file.comment.enemys_template]],function(err){if(err){printe(err);throw(err)}});
|
||||
}
|
||||
|
||||
callback(null);
|
||||
}
|
||||
//callback(err:String)
|
||||
editor_file.editItem = function(id,actionList,callback){
|
||||
/*actionList:[
|
||||
["change","['items']['name']","红宝石的新名字"],
|
||||
["add","['items']['新的和name同级的属性']",123],
|
||||
["change","['itemEffectTip']","',攻击力+'+editor.core.values.redJewel"],
|
||||
]
|
||||
为[]时只查询不修改
|
||||
*/
|
||||
if (!isset(callback)) {printe('未设置callback');throw('未设置callback')};
|
||||
if (isset(actionList) && actionList.length > 0){
|
||||
actionList.forEach(function (value) {
|
||||
var tempindex = value[1].indexOf(']')+1;
|
||||
value[1] = [value[1].slice(0,tempindex),"['"+id+"']",value[1].slice(tempindex)].join('');
|
||||
});
|
||||
saveSetting('items',actionList,function (err) {
|
||||
callback([
|
||||
{'items':(function(){
|
||||
var locObj=Object.assign({},editor.core.items.items[id]);
|
||||
Object.keys(editor_file.comment.items.items).forEach(function(v){
|
||||
if (!isset(editor.core.items.items[id][v]))
|
||||
/* locObj[v]=editor.core.items.items[id][v];
|
||||
else */
|
||||
locObj[v]=null;
|
||||
});
|
||||
return locObj;
|
||||
})(),
|
||||
'itemEffect':editor.core.items.itemEffect[id],'itemEffectTip':editor.core.items.itemEffectTip[id]},
|
||||
editor_file.comment.items,
|
||||
err]);
|
||||
});
|
||||
} else {
|
||||
callback([
|
||||
{'items':(function(){
|
||||
var locObj=Object.assign({},editor.core.items.items[id]);
|
||||
Object.keys(editor_file.comment.items.items).forEach(function(v){
|
||||
if (!isset(editor.core.items.items[id][v]))
|
||||
/* locObj[v]=editor.core.items.items[id][v];
|
||||
else */
|
||||
locObj[v]=null;
|
||||
});
|
||||
return locObj;
|
||||
})(),
|
||||
'itemEffect':editor.core.items.itemEffect[id],'itemEffectTip':editor.core.items.itemEffectTip[id]},
|
||||
editor_file.comment.items,
|
||||
null]);
|
||||
}
|
||||
//只有items.cls是items的才有itemEffect和itemEffectTip,keys和constants和tools只有items
|
||||
}
|
||||
//callback([obj,commentObj,err:String])
|
||||
editor_file.editEnemy = function(id,actionList,callback){
|
||||
/*actionList:[
|
||||
["change","['name']","初级巫师的新名字"],
|
||||
["add","['新的和name同级的属性']",123],
|
||||
["change","['bomb']",null],
|
||||
]
|
||||
为[]时只查询不修改
|
||||
*/
|
||||
if (!isset(callback)) {printe('未设置callback');throw('未设置callback')};
|
||||
if (isset(actionList) && actionList.length > 0){
|
||||
actionList.forEach(function (value) {
|
||||
value[1] = "['"+id+"']"+value[1];
|
||||
});
|
||||
saveSetting('enemys',actionList,function (err) {
|
||||
callback([
|
||||
(function(){
|
||||
var locObj=Object.assign({},editor.core.enemys.enemys[id]);
|
||||
Object.keys(editor_file.comment.enemys).forEach(function(v){
|
||||
if (!isset(editor.core.enemys.enemys[id][v]))
|
||||
/* locObj[v]=editor.core.enemys.enemys[id][v];
|
||||
else */
|
||||
locObj[v]=null;
|
||||
});
|
||||
return locObj;
|
||||
})(),
|
||||
editor_file.comment.enemys,
|
||||
err]);
|
||||
});
|
||||
} else {
|
||||
callback([
|
||||
(function(){
|
||||
var locObj=Object.assign({},editor.core.enemys.enemys[id]);
|
||||
Object.keys(editor_file.comment.enemys).forEach(function(v){
|
||||
if (!isset(editor.core.enemys.enemys[id][v]))
|
||||
/* locObj[v]=editor.core.enemys.enemys[id][v];
|
||||
else */
|
||||
locObj[v]=null;
|
||||
});
|
||||
return locObj;
|
||||
})(),
|
||||
editor_file.comment.enemys,
|
||||
null]);
|
||||
}
|
||||
}
|
||||
//callback([obj,commentObj,err:String])
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
editor_file.editLoc = function(x,y,actionList,callback){
|
||||
/*actionList:[
|
||||
["change","['events']",["\t[老人,magician]领域、夹击。\n请注意领域怪需要设置value为伤害数值,可参见样板中初级巫师的写法。"]],
|
||||
["change","['afterBattle']",null],
|
||||
]
|
||||
为[]时只查询不修改
|
||||
*/
|
||||
if (!isset(callback)) {printe('未设置callback');throw('未设置callback')};
|
||||
if (isset(actionList) && actionList.length > 0){
|
||||
actionList.forEach(function (value) {
|
||||
value[1] = value[1]+"['"+x+","+y+"']";
|
||||
});
|
||||
saveSetting('floors',actionList,function (err) {
|
||||
callback([
|
||||
(function(){
|
||||
var locObj={};
|
||||
Object.keys(editor_file.comment.floors.loc).forEach(function(v){
|
||||
if (isset(editor.currentFloorData[v][x+','+y]))
|
||||
locObj[v]=editor.currentFloorData[v][x+','+y];
|
||||
else
|
||||
locObj[v]=null;
|
||||
});
|
||||
return locObj;
|
||||
})(),
|
||||
editor_file.comment.floors.loc,
|
||||
err]);
|
||||
});
|
||||
} else {
|
||||
callback([
|
||||
(function(){
|
||||
var locObj={};
|
||||
Object.keys(editor_file.comment.floors.loc).forEach(function(v){
|
||||
if (isset(editor.currentFloorData[v][x+','+y]))
|
||||
locObj[v]=editor.currentFloorData[v][x+','+y];
|
||||
else
|
||||
locObj[v]=null;
|
||||
});
|
||||
return locObj;
|
||||
})(),
|
||||
editor_file.comment.floors.loc,
|
||||
null]);
|
||||
}
|
||||
|
||||
}
|
||||
//callback([obj,commentObj,err:String])
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
editor_file.editFloor = function(actionList,callback){
|
||||
/*actionList:[
|
||||
["change","['title']",'样板 3 层'],
|
||||
["change","['color']",null],
|
||||
]
|
||||
为[]时只查询不修改
|
||||
*/
|
||||
if (!isset(callback)) {printe('未设置callback');throw('未设置callback')};
|
||||
if (isset(actionList) && actionList.length > 0){
|
||||
saveSetting('floors',actionList,function (err) {
|
||||
callback([
|
||||
(function(){
|
||||
var locObj=Object.assign({},editor.currentFloorData);
|
||||
Object.keys(editor_file.comment.floors.floor).forEach(function(v){
|
||||
if (!isset(editor.currentFloorData[v]))
|
||||
/* locObj[v]=editor.currentFloorData[v];
|
||||
else */
|
||||
locObj[v]=null;
|
||||
});
|
||||
Object.keys(editor_file.comment.floors.loc).forEach(function(v){
|
||||
delete(locObj[v]);
|
||||
});
|
||||
delete(locObj.map);
|
||||
return locObj;
|
||||
})(),
|
||||
editor_file.comment.floors.floor,
|
||||
err]);
|
||||
});
|
||||
} else {
|
||||
callback([
|
||||
(function(){
|
||||
var locObj=Object.assign({},editor.currentFloorData);
|
||||
Object.keys(editor_file.comment.floors.floor).forEach(function(v){
|
||||
if (!isset(editor.currentFloorData[v]))
|
||||
/* locObj[v]=editor.currentFloorData[v];
|
||||
else */
|
||||
locObj[v]=null;
|
||||
});
|
||||
Object.keys(editor_file.comment.floors.loc).forEach(function(v){
|
||||
delete(locObj[v]);
|
||||
});
|
||||
delete(locObj.map);
|
||||
return locObj;
|
||||
})(),
|
||||
editor_file.comment.floors.floor,
|
||||
null]);
|
||||
}
|
||||
}
|
||||
//callback([obj,commentObj,err:String])
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
editor_file.editTower = function(actionList,callback){
|
||||
/*actionList:[
|
||||
["change","['firstData']['version']",'Ver 1.0.1 (Beta)'],
|
||||
["change","['values']['lavaDamage']",200],
|
||||
]
|
||||
为[]时只查询不修改
|
||||
*/
|
||||
if (!isset(callback)) {printe('未设置callback');throw('未设置callback')};
|
||||
if (isset(actionList) && actionList.length > 0){
|
||||
saveSetting('data',actionList,function (err) {
|
||||
callback([
|
||||
(function(){
|
||||
var locObj=Object.assign({'main':{}},editor.core.data);
|
||||
Object.keys(editor_file.dataComment.main).forEach(function(v){
|
||||
if (isset(editor.main[v]))
|
||||
locObj.main[v]=editor.main[v];
|
||||
else
|
||||
locObj[v]=null;
|
||||
});
|
||||
return locObj;
|
||||
})(),
|
||||
editor_file.dataComment,
|
||||
err]);
|
||||
});
|
||||
} else {
|
||||
callback([
|
||||
(function(){
|
||||
var locObj=Object.assign({'main':{}},editor.core.data);
|
||||
Object.keys(editor_file.dataComment.main).forEach(function(v){
|
||||
if (isset(editor.main[v]))
|
||||
locObj.main[v]=editor.main[v];
|
||||
else
|
||||
locObj[v]=null;
|
||||
});
|
||||
return locObj;
|
||||
})(),
|
||||
editor_file.dataComment,
|
||||
null]);
|
||||
}
|
||||
}
|
||||
//callback([obj,commentObj,err:String])
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
var fmap = {};
|
||||
var fjson = JSON.stringify(functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a,function(k,v){if(v instanceof Function){var id_ = editor.guid();fmap[id_]=v.toString();return id_;}else return v},4);
|
||||
var fobj = JSON.parse(fjson);
|
||||
editor_file.functionsMap = fmap;
|
||||
editor_file.functionsJSON = fjson;
|
||||
var buildlocobj = function(locObj){
|
||||
for(var key in locObj){
|
||||
if(typeof(locObj[key])!==typeof(''))buildlocobj(locObj[key]);
|
||||
else locObj[key]=fmap[locObj[key]];
|
||||
}
|
||||
};
|
||||
|
||||
editor_file.editFunctions = function(actionList,callback){
|
||||
/*actionList:[
|
||||
["change","['events']['afterChangeLight']","function(x,y){console.log(x,y)}"],
|
||||
["change","['ui']['drawAbout']","function(){...}"],
|
||||
]
|
||||
为[]时只查询不修改
|
||||
*/
|
||||
if (!isset(callback)) {printe('未设置callback');throw('未设置callback')};
|
||||
if (isset(actionList) && actionList.length > 0){
|
||||
saveSetting('functions',actionList,function (err) {
|
||||
callback([
|
||||
(function(){
|
||||
var locObj=JSON.parse(fjson);
|
||||
buildlocobj(locObj);
|
||||
return locObj;
|
||||
})(),
|
||||
editor_file.functionsComment,
|
||||
err]);
|
||||
});
|
||||
} else {
|
||||
callback([
|
||||
(function(){
|
||||
var locObj=JSON.parse(fjson);
|
||||
buildlocobj(locObj);
|
||||
return locObj;
|
||||
})(),
|
||||
editor_file.functionsComment,
|
||||
null]);
|
||||
}
|
||||
}
|
||||
//callback([obj,commentObj,err:String])
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
var isset = function (val) {
|
||||
if (val == undefined || val == null) {
|
||||
return false;
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
var formatMap = function(mapArr){
|
||||
//把13*13或者1*169数组格式化
|
||||
var formatArrStr = '';
|
||||
var arr = JSON.stringify(mapArr).replace(/\s+/g, '').split('],[');
|
||||
for(var i =0; i<13; i++){
|
||||
var a = [];
|
||||
formatArrStr +=' [';
|
||||
if(i==0||i==12) a = arr[i].split(/\D+/).join(' ').trim().split(' ');
|
||||
else a = arr[i].split(/\D+/);
|
||||
for(var k=0; k<13; k++){
|
||||
var num = parseInt(a[k]);
|
||||
formatArrStr += Array(Math.max(4-String(num).length,0)).join(' ')+num+(k==12?'':',');
|
||||
}
|
||||
formatArrStr += ']'+(i==12?'':',\n');
|
||||
}
|
||||
return formatArrStr;
|
||||
}
|
||||
|
||||
var encode = function (str) {
|
||||
return btoa(encodeURIComponent(str).replace(/%([0-9A-F]{2})/g, function(match, p1) {
|
||||
return String.fromCharCode(parseInt(p1, 16))
|
||||
}))
|
||||
}
|
||||
|
||||
var saveSetting = function(file,actionList,callback) {
|
||||
//console.log(file);
|
||||
//console.log(actionList);
|
||||
actionList.forEach(function (value) {
|
||||
if (value[0]!='change' && file!='icons' && file!='maps') {printe('目前只支持change');throw('目前只支持change')};
|
||||
});
|
||||
|
||||
if (file=='icons') {
|
||||
actionList.forEach(function (value) {
|
||||
if (value[0]!='add')return;
|
||||
eval("icons_4665ee12_3a1f_44a4_bea3_0fccba634dc1"+value[1]+'='+JSON.stringify(value[2]));
|
||||
});
|
||||
var datastr='icons_4665ee12_3a1f_44a4_bea3_0fccba634dc1 = \n';
|
||||
datastr+=JSON.stringify(icons_4665ee12_3a1f_44a4_bea3_0fccba634dc1,null,4);
|
||||
fs.writeFile('project/icons.js',encode(datastr),'base64',function(err, data){
|
||||
callback(err);
|
||||
});
|
||||
return;
|
||||
}
|
||||
if (file=='maps') {
|
||||
actionList.forEach(function (value) {
|
||||
if (value[0]!='add')return;
|
||||
eval("maps_90f36752_8815_4be8_b32b_d7fad1d0542e"+value[1]+'='+JSON.stringify(value[2]));
|
||||
});
|
||||
var datastr='maps_90f36752_8815_4be8_b32b_d7fad1d0542e = \n';
|
||||
datastr+=JSON.stringify(maps_90f36752_8815_4be8_b32b_d7fad1d0542e,null,4);
|
||||
fs.writeFile('project/maps.js',encode(datastr),'base64',function(err, data){
|
||||
callback(err);
|
||||
});
|
||||
return;
|
||||
}
|
||||
if (file=='items') {
|
||||
actionList.forEach(function (value) {
|
||||
if (value[0]!='change')return;
|
||||
eval("items_296f5d02_12fd_4166_a7c1_b5e830c9ee3a"+value[1]+'='+JSON.stringify(value[2]));
|
||||
});
|
||||
var datastr='items_296f5d02_12fd_4166_a7c1_b5e830c9ee3a = \n';
|
||||
datastr+=JSON.stringify(items_296f5d02_12fd_4166_a7c1_b5e830c9ee3a,null,4);
|
||||
fs.writeFile('project/items.js',encode(datastr),'base64',function(err, data){
|
||||
callback(err);
|
||||
});
|
||||
return;
|
||||
}
|
||||
if (file=='enemys') {
|
||||
actionList.forEach(function (value) {
|
||||
if (value[0]!='change')return;
|
||||
eval("enemys_fcae963b_31c9_42b4_b48c_bb48d09f3f80"+value[1]+'='+JSON.stringify(value[2]));
|
||||
});
|
||||
var datastr='enemys_fcae963b_31c9_42b4_b48c_bb48d09f3f80 = \n';
|
||||
var emap={};
|
||||
var estr = JSON.stringify(enemys_fcae963b_31c9_42b4_b48c_bb48d09f3f80,function(k,v){if(v.hp!=null){var id_ = editor.guid();emap[id_]=JSON.stringify(v);return id_;}else return v},4);
|
||||
for(var id_ in emap){
|
||||
estr = estr.replace('"'+id_+'"',emap[id_])
|
||||
}
|
||||
datastr+=estr;
|
||||
fs.writeFile('project/enemys.js',encode(datastr),'base64',function(err, data){
|
||||
callback(err);
|
||||
});
|
||||
return;
|
||||
}
|
||||
if (file=='data') {
|
||||
actionList.forEach(function (value) {
|
||||
if (value[0]!='change')return;
|
||||
eval("data_a1e2fb4a_e986_4524_b0da_9b7ba7c0874d"+value[1]+'='+JSON.stringify(value[2]));
|
||||
});
|
||||
var datastr='data_a1e2fb4a_e986_4524_b0da_9b7ba7c0874d = \n';
|
||||
datastr+=JSON.stringify(data_a1e2fb4a_e986_4524_b0da_9b7ba7c0874d,null,4);
|
||||
fs.writeFile('project/data.js',encode(datastr),'base64',function(err, data){
|
||||
callback(err);
|
||||
});
|
||||
return;
|
||||
}
|
||||
if (file=='functions') {
|
||||
actionList.forEach(function (value) {
|
||||
if (value[0]!='change')return;
|
||||
eval("fmap[fobj"+value[1]+']='+JSON.stringify(value[2]));
|
||||
});
|
||||
var fraw = fjson;
|
||||
for(var id_ in fmap){
|
||||
fraw = fraw.replace('"'+id_+'"',fmap[id_])
|
||||
}
|
||||
var datastr='functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a = \n';
|
||||
datastr+=fraw;
|
||||
fs.writeFile('project/functions.js',encode(datastr),'base64',function(err, data){
|
||||
callback(err);
|
||||
});
|
||||
return;
|
||||
}
|
||||
if (file=='floors') {
|
||||
actionList.forEach(function (value) {
|
||||
if (value[0]!='change')return;
|
||||
eval("editor.currentFloorData"+value[1]+'='+JSON.stringify(value[2]));
|
||||
});
|
||||
editor_file.saveFloorFile(callback);
|
||||
return;
|
||||
}
|
||||
callback('出错了,要设置的文件名不识别');
|
||||
}
|
||||
|
||||
/*
|
||||
$select({\"values\":[\"keys\",\"items\",\"constants\",\"tools\"]})$end
|
||||
$range(thiseval==~~thiseval &&thiseval>0)$end
|
||||
$leaf(true)$end
|
||||
$select({\"values\":[true]})$end
|
||||
$select({\"values\":[false]})$end
|
||||
$select({\"values\":[true,false]})$end
|
||||
|
||||
*/
|
||||
|
||||
/*
|
||||
所有注释中的特殊指令
|
||||
$range(evalstr:thiseval)$end
|
||||
限制取值范围,要求修改后的eval(evalstr)为true
|
||||
$leaf(evalstr:thiseval)$end
|
||||
强制指定为叶节点,如果eval(evalstr)为true
|
||||
|
||||
//以下几个中选一个 [
|
||||
$select(evalstr)$end
|
||||
渲染成<select>,选项为数组eval(evalstr)['values']
|
||||
$input(evalstr)$end
|
||||
渲染成<input>
|
||||
$textarea(evalstr)$end
|
||||
渲染成<textarea>
|
||||
默认选项为$textarea()$end
|
||||
// ]
|
||||
|
||||
*/
|
||||
return editor_file;
|
||||
}
|
||||
//editor_file = editor_file(editor);
|
||||
511
_server/editor_mode.js
Normal file
@ -0,0 +1,511 @@
|
||||
editor_mode = function(editor){
|
||||
var core = editor.core;
|
||||
|
||||
function editor_mode(){
|
||||
this.ids={
|
||||
'loc':'left2',
|
||||
'emenyitem':'left3',
|
||||
'floor':'left4',
|
||||
'tower':'left5',
|
||||
'functions':'left8',
|
||||
|
||||
'map':'left',
|
||||
'appendpic':'left1',
|
||||
}
|
||||
this._ids={}
|
||||
this.dom={}
|
||||
this.actionList=[];
|
||||
this.mode='';
|
||||
this.info={};
|
||||
this.appendPic={};
|
||||
}
|
||||
editor_mode.prototype.init = function(callback){
|
||||
if (Boolean(callback))callback();
|
||||
}
|
||||
|
||||
editor_mode.prototype.init_dom_ids = function(callback){
|
||||
|
||||
Object.keys(editor_mode.ids).forEach(function(v){
|
||||
editor_mode.dom[v]=document.getElementById(editor_mode.ids[v]);
|
||||
editor_mode._ids[editor_mode.ids[v]]=v;
|
||||
});
|
||||
|
||||
if (Boolean(callback))callback();
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
editor_mode.prototype.objToTable = function(obj,commentObj){
|
||||
var outstr=["\n<tr><td>条目</td><td>注释</td><td>值</td></tr>\n"];
|
||||
var guids=[];
|
||||
var checkIsLeaf = function(obj,commentObj,field){
|
||||
var thiseval = eval('obj'+field);
|
||||
if (thiseval == null || thiseval == undefined)return true;//null,undefined
|
||||
if (typeof(thiseval) == typeof(''))return true;//字符串
|
||||
if (Object.keys(thiseval).length == 0)return true;//数字,true,false,空数组,空对象
|
||||
try {
|
||||
var comment = eval('commentObj'+field);
|
||||
if( comment.indexOf('$leaf') != -1){
|
||||
evalstr = comment.split('$leaf')[1].split('$end')[0];
|
||||
if(eval(evalstr) === true)return true;
|
||||
}
|
||||
} catch (error) {}
|
||||
return false;
|
||||
}
|
||||
//深度优先遍历
|
||||
var recursionParse = function(tfield) {
|
||||
for(var ii in eval("obj"+tfield)){
|
||||
var field = tfield+"['"+ii+"']";
|
||||
var isleaf = checkIsLeaf(obj,commentObj,field);
|
||||
if (isleaf) {
|
||||
var leafnode = editor_mode.objToTr(obj,commentObj,field);
|
||||
outstr.push(leafnode[0]);
|
||||
guids.push(leafnode[1]);
|
||||
} else {
|
||||
outstr.push(["<tr><td>----</td><td>----</td><td>",field,"</td></tr>\n"].join(''));
|
||||
recursionParse(field);
|
||||
}
|
||||
}
|
||||
}
|
||||
recursionParse("");
|
||||
var checkRange = function(comment,thiseval){
|
||||
if( comment.indexOf('$range') !== -1){
|
||||
var evalstr = comment.split('$range')[1].split('$end')[0];
|
||||
return eval(evalstr);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
var listen = function(guids) {
|
||||
guids.forEach(function(guid){
|
||||
// tr>td[title=field]
|
||||
// >td[title=comment]
|
||||
// >td>div>input[value=thsieval]
|
||||
var thisTr = document.getElementById(guid);
|
||||
var input = thisTr.children[2].children[0].children[0];
|
||||
var field = thisTr.children[0].getAttribute('title');
|
||||
var comment = thisTr.children[1].getAttribute('title');
|
||||
input.onchange = function(){
|
||||
var node = thisTr.parentNode;
|
||||
while (!editor_mode._ids.hasOwnProperty(node.getAttribute('id'))) {
|
||||
node = node.parentNode;
|
||||
}
|
||||
editor_mode.onmode(editor_mode._ids[node.getAttribute('id')]);
|
||||
var thiseval=null;
|
||||
try{
|
||||
thiseval = JSON.parse(input.value);
|
||||
}catch(ee){
|
||||
printe(field+' : '+ee);
|
||||
throw ee;
|
||||
}
|
||||
if(checkRange(comment,thiseval)){
|
||||
editor_mode.addAction(['change',field,thiseval]);
|
||||
} else {
|
||||
printe(field+' : 输入的值不合要求,请鼠标放置在注释上查看说明');
|
||||
}
|
||||
}
|
||||
input.ondblclick = function(){
|
||||
if(!editor_blockly.import(guid))
|
||||
if(!editor_multi.import(guid)){}
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
return {"HTML":outstr.join(''),"guids":guids,"listen":listen};
|
||||
}
|
||||
|
||||
editor_mode.prototype.objToTr = function(obj,commentObj,field){
|
||||
var guid = editor.guid();
|
||||
var thiseval = eval('obj'+field);
|
||||
var comment = '';
|
||||
try {
|
||||
comment = eval('commentObj'+field);
|
||||
} catch (error) {}
|
||||
if(!comment)comment='';
|
||||
|
||||
var charlength=10;
|
||||
|
||||
var shortField = field.split("']").slice(-2)[0].split("['").slice(-1)[0];
|
||||
shortField = (shortField.length<charlength?shortField:shortField.slice(0,charlength)+'...');
|
||||
|
||||
var commentHTMLescape=comment.split('').map(function(v){return '&#'+v.charCodeAt(0)+';'}).join('');
|
||||
var shortCommentHTMLescape=(comment.length<charlength?commentHTMLescape:comment.slice(0,charlength).split('').map(function(v){return '&#'+v.charCodeAt(0)+';'}).join('')+'...');
|
||||
|
||||
var outstr=['<tr id="',guid,'"><td title="',field,'">',shortField,'</td>',
|
||||
'<td title="',commentHTMLescape,'">',shortCommentHTMLescape,'</td>',
|
||||
'<td><div class="etableInputDiv">',editor_mode.objToTd(thiseval,comment,field),'</div></td></tr>\n',
|
||||
];
|
||||
return [outstr.join(''),guid];
|
||||
}
|
||||
|
||||
editor_mode.prototype.objToTd = function(thiseval,comment,field){
|
||||
if( comment.indexOf('$select') != -1){
|
||||
var evalstr = comment.split('$select')[1].split('$end')[0];
|
||||
var values = eval(evalstr)['values'];
|
||||
var outstr = ['<select>\n',"<option value='",JSON.stringify(thiseval),"'>",JSON.stringify(thiseval),'</option>\n'];
|
||||
values.forEach(function(v){
|
||||
outstr.push(["<option value='",JSON.stringify(v),"'>",JSON.stringify(v),'</option>\n'].join(''))
|
||||
});
|
||||
outstr.push('</select>');
|
||||
return outstr.join('');
|
||||
} else if( comment.indexOf('$input') != -1){
|
||||
return ["<input spellcheck='false' value='",JSON.stringify(thiseval),"'/>\n"].join('');
|
||||
} else {
|
||||
//rows='",rows,"'
|
||||
var num = 0;//editor_mode.indent(field);
|
||||
return ["<textarea spellcheck='false' >",JSON.stringify(thiseval,null,num),'</textarea>\n'].join('');
|
||||
}
|
||||
}
|
||||
|
||||
editor_mode.prototype.indent = function(field){
|
||||
var num = 4;
|
||||
if(field.indexOf("['main']")===0)return 0;
|
||||
if(field.indexOf("['flyRange']")!==-1)return 0;
|
||||
if(field==="['special']")return 0;
|
||||
return num;
|
||||
}
|
||||
|
||||
editor_mode.prototype.addAction = function(action){
|
||||
editor_mode.actionList.push(action);
|
||||
}
|
||||
|
||||
editor_mode.prototype.doActionList = function(mode,actionList){
|
||||
if (actionList.length==0)return;
|
||||
printf('修改中...');
|
||||
switch (mode) {
|
||||
case 'loc':
|
||||
|
||||
editor.file.editLoc(editor_mode.pos.x,editor_mode.pos.y,actionList,function(objs_){/*console.log(objs_);*/if(objs_.slice(-1)[0]!=null){printe(objs_.slice(-1)[0]);throw(objs_.slice(-1)[0])};printf('修改成功')});
|
||||
break;
|
||||
case 'emenyitem':
|
||||
|
||||
if (editor_mode.info.images=='enemys'){
|
||||
editor.file.editEnemy(editor_mode.info.id,actionList,function(objs_){/*console.log(objs_);*/if(objs_.slice(-1)[0]!=null){printe(objs_.slice(-1)[0]);throw(objs_.slice(-1)[0])};printf('修改成功')});
|
||||
} else if (editor_mode.info.images=='items'){
|
||||
editor.file.editItem(editor_mode.info.id,actionList,function(objs_){/*console.log(objs_);*/if(objs_.slice(-1)[0]!=null){printe(objs_.slice(-1)[0]);throw(objs_.slice(-1)[0])};printf('修改成功')});
|
||||
}
|
||||
break;
|
||||
case 'floor':
|
||||
|
||||
editor.file.editFloor(actionList,function(objs_){/*console.log(objs_);*/if(objs_.slice(-1)[0]!=null){printe(objs_.slice(-1)[0]);throw(objs_.slice(-1)[0])};printf('修改成功')});
|
||||
break;
|
||||
case 'tower':
|
||||
|
||||
editor.file.editTower(actionList,function(objs_){/*console.log(objs_);*/if(objs_.slice(-1)[0]!=null){printe(objs_.slice(-1)[0]);throw(objs_.slice(-1)[0])};printf('修改成功')});
|
||||
break;
|
||||
case 'functions':
|
||||
|
||||
editor.file.editFunctions(actionList,function(objs_){/*console.log(objs_);*/if(objs_.slice(-1)[0]!=null){printe(objs_.slice(-1)[0]);throw(objs_.slice(-1)[0])};printf('修改成功')});
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
editor_mode.prototype.onmode = function (mode) {
|
||||
if (editor_mode.mode!=mode) {
|
||||
console.log('change mode into : '+mode);
|
||||
if(mode==='save')editor_mode.doActionList(editor_mode.mode,editor_mode.actionList);
|
||||
if(editor_mode.mode==='nextChange' && mode)editor_mode.showMode(mode);
|
||||
editor_mode.mode=mode;
|
||||
editor_mode.actionList=[];
|
||||
}
|
||||
}
|
||||
|
||||
editor_mode.prototype.showMode = function (mode) {
|
||||
for(var name in this.dom){
|
||||
editor_mode.dom[name].style='z-index:-1;opacity: 0;';
|
||||
}
|
||||
editor_mode.dom[mode].style='';
|
||||
if(editor_mode[mode])editor_mode[mode]();
|
||||
document.getElementById('editModeSelect').value=mode;
|
||||
var tips = tip_in_showMode;
|
||||
if(!selectBox.isSelected)printf('tips: '+tips[~~(tips.length*Math.random())]);
|
||||
}
|
||||
|
||||
editor_mode.prototype.loc = function(callback){
|
||||
//editor.pos={x: 0, y: 0};
|
||||
if (!core.isset(editor.pos))return;
|
||||
editor_mode.pos=editor.pos;
|
||||
document.getElementById('pos_a6771a78_a099_417c_828f_0a24851ebfce').innerText=editor_mode.pos.x+','+editor_mode.pos.y;
|
||||
|
||||
var objs=[];
|
||||
editor.file.editLoc(editor_mode.pos.x,editor_mode.pos.y,[],function(objs_){objs=objs_;/*console.log(objs_)*/});
|
||||
//只查询不修改时,内部实现不是异步的,所以可以这么写
|
||||
var tableinfo=editor_mode.objToTable(objs[0],objs[1]);
|
||||
document.getElementById('table_3d846fc4_7644_44d1_aa04_433d266a73df').innerHTML=tableinfo.HTML;
|
||||
tableinfo.listen(tableinfo.guids);
|
||||
|
||||
if (Boolean(callback))callback();
|
||||
}
|
||||
|
||||
editor_mode.prototype.emenyitem = function(callback){
|
||||
//editor.info=editor.ids[editor.indexs[201]];
|
||||
if (!core.isset(editor.info))return;
|
||||
|
||||
if(Object.keys(editor.info).length!==0)editor_mode.info=editor.info;//避免editor.info被清空导致无法获得是物品还是怪物
|
||||
|
||||
if (!core.isset(editor_mode.info.id)){
|
||||
document.getElementById('table_a3f03d4c_55b8_4ef6_b362_b345783acd72').innerHTML='';
|
||||
document.getElementById('newIdIdnum').style.display='';
|
||||
return;
|
||||
}
|
||||
document.getElementById('newIdIdnum').style.display='none';
|
||||
|
||||
var objs=[];
|
||||
if (editor_mode.info.images=='enemys'){
|
||||
editor.file.editEnemy(editor_mode.info.id,[],function(objs_){objs=objs_;/*console.log(objs_)*/});
|
||||
} else if (editor_mode.info.images=='items'){
|
||||
editor.file.editItem(editor_mode.info.id,[],function(objs_){objs=objs_;/*console.log(objs_)*/});
|
||||
} else {
|
||||
document.getElementById('table_a3f03d4c_55b8_4ef6_b362_b345783acd72').innerHTML='';
|
||||
return;
|
||||
}
|
||||
//只查询不修改时,内部实现不是异步的,所以可以这么写
|
||||
var tableinfo=editor_mode.objToTable(objs[0],objs[1]);
|
||||
document.getElementById('table_a3f03d4c_55b8_4ef6_b362_b345783acd72').innerHTML=tableinfo.HTML;
|
||||
tableinfo.listen(tableinfo.guids);
|
||||
|
||||
if (Boolean(callback))callback();
|
||||
}
|
||||
|
||||
editor_mode.prototype.floor = function(callback){
|
||||
var objs=[];
|
||||
editor.file.editFloor([],function(objs_){objs=objs_;/*console.log(objs_)*/});
|
||||
//只查询不修改时,内部实现不是异步的,所以可以这么写
|
||||
var tableinfo=editor_mode.objToTable(objs[0],objs[1]);
|
||||
document.getElementById('table_4a3b1b09_b2fb_4bdf_b9ab_9f4cdac14c74').innerHTML=tableinfo.HTML;
|
||||
tableinfo.listen(tableinfo.guids);
|
||||
if (Boolean(callback))callback();
|
||||
}
|
||||
|
||||
editor_mode.prototype.tower = function(callback){
|
||||
var objs=[];
|
||||
editor.file.editTower([],function(objs_){objs=objs_;/*console.log(objs_)*/});
|
||||
//只查询不修改时,内部实现不是异步的,所以可以这么写
|
||||
var tableinfo=editor_mode.objToTable(objs[0],objs[1]);
|
||||
document.getElementById('table_b6a03e4c_5968_4633_ac40_0dfdd2c9cde5').innerHTML=tableinfo.HTML;
|
||||
tableinfo.listen(tableinfo.guids);
|
||||
if (Boolean(callback))callback();
|
||||
}
|
||||
|
||||
editor_mode.prototype.functions = function(callback){
|
||||
var objs=[];
|
||||
editor.file.editFunctions([],function(objs_){objs=objs_;/*console.log(objs_)*/});
|
||||
//只查询不修改时,内部实现不是异步的,所以可以这么写
|
||||
var tableinfo=editor_mode.objToTable(objs[0],objs[1]);
|
||||
document.getElementById('table_e260a2be_5690_476a_b04e_dacddede78b3').innerHTML=tableinfo.HTML;
|
||||
tableinfo.listen(tableinfo.guids);
|
||||
if (Boolean(callback))callback();
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
editor_mode.prototype.listen = function(callback){
|
||||
|
||||
var newIdIdnum = document.getElementById('newIdIdnum');
|
||||
newIdIdnum.children[2].onclick = function(){
|
||||
if (newIdIdnum.children[0].value && newIdIdnum.children[1].value){
|
||||
var id = newIdIdnum.children[0].value;
|
||||
var idnum = parseInt(newIdIdnum.children[1].value);
|
||||
editor.file.changeIdAndIdnum(id,idnum,editor_mode.info,function(err){
|
||||
if(err){printe(err);throw(err)}
|
||||
printe('添加id的idnum成功,请F5刷新编辑器');
|
||||
});
|
||||
} else {
|
||||
printe('请输入id和idnum');
|
||||
}
|
||||
}
|
||||
|
||||
var selectFloor = document.getElementById('selectFloor');
|
||||
editor.file.getFloorFileList(function(floors){
|
||||
var outstr=[];
|
||||
floors[0].forEach(function(floor){
|
||||
outstr.push(["<option value='",floor,"'>",floor,'</option>\n'].join(''));
|
||||
});
|
||||
selectFloor.innerHTML=outstr.join('');
|
||||
selectFloor.value=core.status.floorId;
|
||||
selectFloor.onchange = function(){
|
||||
editor_mode.onmode('nextChange');
|
||||
editor_mode.onmode('floor');
|
||||
editor.changeFloor(selectFloor.value);
|
||||
}
|
||||
});
|
||||
|
||||
var saveFloor = document.getElementById('saveFloor');
|
||||
saveFloor.onclick = function(){
|
||||
editor_mode.onmode('');
|
||||
editor.file.saveFloorFile(function(err){if(err){printe(err);throw(err)};printf('保存成功');});
|
||||
}
|
||||
|
||||
var saveFloorAs = document.getElementById('saveFloorAs');
|
||||
var saveAsName = document.getElementById('saveAsName');
|
||||
saveFloorAs.onclick = function(){
|
||||
if (!saveAsName.value)return;
|
||||
editor_mode.onmode('');
|
||||
editor.file.saveFloorFileAs(saveAsName.value,function(err){
|
||||
if(err){printe(err);throw(err)}
|
||||
core.floorIds.push(saveAsName.value);
|
||||
editor.file.editTower([['change',"['main']['floorIds']",core.floorIds]],function(objs_){/*console.log(objs_);*/if(objs_.slice(-1)[0]!=null){printe(objs_.slice(-1)[0]);throw(objs_.slice(-1)[0])};printe('另存为成功,请F5刷新编辑器生效');});
|
||||
});
|
||||
}
|
||||
|
||||
var ratio=1;
|
||||
var appendPicCanvas = document.getElementById('appendPicCanvas');
|
||||
var bg = appendPicCanvas.children[0];
|
||||
var source = appendPicCanvas.children[1];
|
||||
var picClick = appendPicCanvas.children[2];
|
||||
var sprite = appendPicCanvas.children[3];
|
||||
var appendPicSelection = document.getElementById('appendPicSelection');
|
||||
|
||||
var selectAppend = document.getElementById('selectAppend');
|
||||
var selectAppend_str=[];
|
||||
["terrains", "animates", "enemys", "enemy48", "items", "npcs", "npc48"].forEach(function(image){
|
||||
selectAppend_str.push(["<option value='",image,"'>",image,'</option>\n'].join(''));
|
||||
});
|
||||
selectAppend.innerHTML=selectAppend_str.join('');
|
||||
selectAppend.onchange = function(){
|
||||
var value = selectAppend.value;
|
||||
var ysize = selectAppend.value.indexOf('48')===-1?32:48;
|
||||
editor_mode.appendPic.imageName = value;
|
||||
var img = editor.material.images[value];
|
||||
editor_mode.appendPic.toImg = img;
|
||||
var num = ~~img.width/32;
|
||||
editor_mode.appendPic.num = num;
|
||||
editor_mode.appendPic.index = 0;
|
||||
var selectStr = '';
|
||||
for(var ii=0;ii<num;ii++){
|
||||
appendPicSelection.children[ii].style='left:0;top:0;height:'+(ysize-6)+'px';
|
||||
selectStr+='{"x":0,"y":0},'
|
||||
}
|
||||
editor_mode.appendPic.selectPos = eval('['+selectStr+']');
|
||||
for(var jj=num;jj<4;jj++){
|
||||
appendPicSelection.children[jj].style='display:none';
|
||||
}
|
||||
sprite.style.width = (sprite.width = img.width)/ratio + 'px';
|
||||
sprite.style.height = (sprite.height = img.height+ysize)/ratio + 'px';
|
||||
sprite.getContext('2d').drawImage(img, 0, 0);
|
||||
}
|
||||
selectAppend.onchange();
|
||||
|
||||
var selectFileBtn = document.getElementById('selectFileBtn');
|
||||
selectFileBtn.onclick = function(){
|
||||
var loadImage = function (content, callback) {
|
||||
var image = new Image();
|
||||
try {
|
||||
image.src = content;
|
||||
if (image.complete) {
|
||||
callback(image);
|
||||
return;
|
||||
}
|
||||
image.onload = function () {
|
||||
callback(image);
|
||||
}
|
||||
}
|
||||
catch (e) {
|
||||
printe(e);
|
||||
}
|
||||
}
|
||||
core.readFile(function(content){
|
||||
loadImage(content,function(image){
|
||||
editor_mode.appendPic.img = image;
|
||||
editor_mode.appendPic.width = image.width;
|
||||
editor_mode.appendPic.height = image.height;
|
||||
var ysize = selectAppend.value.indexOf('48')===-1?32:48;
|
||||
for(var ii=0;ii<3;ii++){
|
||||
var newsprite = appendPicCanvas.children[ii];
|
||||
newsprite.style.width = (newsprite.width = Math.floor(image.width/32)*32)/ratio + 'px';
|
||||
newsprite.style.height = (newsprite.height = Math.floor(image.height/ysize)*ysize)/ratio + 'px';
|
||||
}
|
||||
|
||||
//画灰白相间的格子
|
||||
var bgc = bg.getContext('2d');
|
||||
var colorA = ["#f8f8f8", "#cccccc"];
|
||||
var colorIndex;
|
||||
var sratio=4;
|
||||
for (var ii = 0; ii < image.width/32*sratio; ii++){
|
||||
colorIndex = 1-ii%2;
|
||||
for (var jj = 0; jj < image.height/32*sratio; jj++) {
|
||||
bgc.fillStyle = colorA[colorIndex];
|
||||
colorIndex = 1 - colorIndex;
|
||||
bgc.fillRect(ii * 32/sratio, jj * 32/sratio, 32/sratio, 32/sratio);
|
||||
}
|
||||
}
|
||||
|
||||
//把导入的图片画出
|
||||
source.getContext('2d').drawImage(image, 0, 0);
|
||||
|
||||
//重置临时变量
|
||||
selectAppend.onchange();
|
||||
});
|
||||
},null,'img');
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
var left1 = document.getElementById('left1');
|
||||
var eToLoc = function (e) {
|
||||
var scrollLeft = document.documentElement.scrollLeft || document.body.scrollLeft
|
||||
var scrollTop = document.documentElement.scrollTop || document.body.scrollTop
|
||||
var loc = {
|
||||
'x': scrollLeft+e.clientX + appendPicCanvas.scrollLeft - left1.offsetLeft-appendPicCanvas.offsetLeft,
|
||||
'y': scrollTop+e.clientY + appendPicCanvas.scrollTop - left1.offsetTop-appendPicCanvas.offsetTop,
|
||||
'size': 32,
|
||||
'ysize': selectAppend.value.indexOf('48')===-1?32:48
|
||||
};
|
||||
return loc;
|
||||
}//返回可用的组件内坐标
|
||||
|
||||
var locToPos = function (loc) {
|
||||
var pos = { 'x': ~~(loc.x / loc.size), 'y': ~~(loc.y / loc.ysize) ,'ysize': loc.ysize}
|
||||
return pos;
|
||||
}
|
||||
|
||||
picClick.onclick = function(e){
|
||||
var loc = eToLoc(e);
|
||||
var pos = locToPos(loc);
|
||||
console.log(e,loc,pos);
|
||||
var num = editor_mode.appendPic.num;
|
||||
var ii = editor_mode.appendPic.index;
|
||||
if(ii+1>=num)editor_mode.appendPic.index=ii+1-num;
|
||||
else editor_mode.appendPic.index++;
|
||||
editor_mode.appendPic.selectPos[ii]=pos;
|
||||
appendPicSelection.children[ii].style=[
|
||||
'left:',pos.x*32,'px;',
|
||||
'top:',pos.y*pos.ysize,'px;',
|
||||
'height:',pos.ysize-6,'px;'
|
||||
].join('');
|
||||
}
|
||||
|
||||
var appendConfirm = document.getElementById('appendConfirm');
|
||||
appendConfirm.onclick = function(){
|
||||
var ysize = selectAppend.value.indexOf('48')===-1?32:48;
|
||||
var sprited = sprite.getContext('2d');
|
||||
//sprited.drawImage(img, 0, 0);
|
||||
var height = editor_mode.appendPic.toImg.height;
|
||||
var sourced = source.getContext('2d');
|
||||
for(var ii=0,v;v=editor_mode.appendPic.selectPos[ii];ii++){
|
||||
var imgData=sourced.getImageData(v.x*32,v.y*ysize,32,ysize);
|
||||
sprited.putImageData(imgData,ii*32,height);
|
||||
}
|
||||
var imgbase64 = sprite.toDataURL().split(',')[1];
|
||||
fs.writeFile('./project/images/'+editor_mode.appendPic.imageName+'.png',imgbase64,'base64',function(err,data){
|
||||
if(err){printe(err);throw(err)}
|
||||
printe('追加素材成功,请F5刷新编辑器');
|
||||
});
|
||||
}
|
||||
|
||||
var editModeSelect = document.getElementById('editModeSelect');
|
||||
editModeSelect.onchange = function(){
|
||||
editor_mode.onmode('nextChange');
|
||||
editor_mode.onmode(editModeSelect.value);
|
||||
}
|
||||
|
||||
if (Boolean(callback))callback();
|
||||
}
|
||||
|
||||
var editor_mode = new editor_mode();
|
||||
editor_mode.init_dom_ids();
|
||||
|
||||
return editor_mode;
|
||||
}
|
||||
//editor_mode = editor_mode(editor);
|
||||
104
_server/editor_multi.js
Normal file
@ -0,0 +1,104 @@
|
||||
editor_multi = function(){
|
||||
|
||||
var editor_multi = {};
|
||||
|
||||
var codeEditor = CodeMirror.fromTextArea(document.getElementById("multiLineCode"), {
|
||||
lineNumbers: true,
|
||||
matchBrackets: true,
|
||||
lineWrapping: true,
|
||||
continueComments: "Enter",
|
||||
extraKeys: {"Ctrl-Q": "toggleComment"}
|
||||
});
|
||||
|
||||
editor_multi.id='';
|
||||
editor_multi.isString=false;
|
||||
|
||||
editor_multi.show = function(){document.getElementById('left7').style='';}
|
||||
editor_multi.hide = function(){document.getElementById('left7').style='z-index:-1;opacity: 0;';}
|
||||
|
||||
editor_multi.indent = function(field){
|
||||
if(editor && editor.mode && editor.mode.indent)return editor.mode.indent(field);
|
||||
return 4;
|
||||
}
|
||||
|
||||
editor_multi.import = function(id_){
|
||||
var thisTr = document.getElementById(id_);
|
||||
if(!thisTr)return false;
|
||||
var input = thisTr.children[2].children[0].children[0];
|
||||
var field = thisTr.children[0].getAttribute('title');
|
||||
if(!input.type || input.type!=='textarea')return false;
|
||||
editor_multi.id=id_;
|
||||
editor_multi.isString=false;
|
||||
if(input.value.slice(0,1)==='"'){
|
||||
editor_multi.isString=true;
|
||||
codeEditor.setValue(JSON.parse(input.value)||'');
|
||||
} else {
|
||||
var num = editor_multi.indent(field);
|
||||
eval('var tobj='+(input.value||'null'));
|
||||
var tmap={};
|
||||
var tstr = JSON.stringify(tobj,function(k,v){if(typeof(v)===typeof('') && v.slice(0,8)==='function'){var id_ = editor.guid();tmap[id_]=v.toString();return id_;}else return v},num);
|
||||
for(var id_ in tmap){
|
||||
tstr = tstr.replace('"'+id_+'"',tmap[id_])
|
||||
}
|
||||
codeEditor.setValue(tstr||'');
|
||||
}
|
||||
editor_multi.show();
|
||||
return true;
|
||||
}
|
||||
|
||||
editor_multi.cancel = function(){
|
||||
editor_multi.hide();
|
||||
editor_multi.id='';
|
||||
multiLineArgs=[null,null,null];
|
||||
}
|
||||
|
||||
editor_multi.confirm = function (){
|
||||
if(!editor_multi.id){
|
||||
editor_multi.id='';
|
||||
return;
|
||||
}
|
||||
if(editor_multi.id==='callFromBlockly'){
|
||||
editor_multi.id='';
|
||||
editor_multi.multiLineDone();
|
||||
return;
|
||||
}
|
||||
var setvalue = function(value){
|
||||
var thisTr = document.getElementById(editor_multi.id);
|
||||
editor_multi.id='';
|
||||
var input = thisTr.children[2].children[0].children[0];
|
||||
if(editor_multi.isString){
|
||||
input.value = JSON.stringify(value);
|
||||
} else {
|
||||
eval('var tobj='+(value||'null'));
|
||||
var tmap={};
|
||||
var tstr = JSON.stringify(tobj,function(k,v){if(v instanceof Function){var id_ = editor.guid();tmap[id_]=v.toString();return id_;}else return v},4);
|
||||
for(var id_ in tmap){
|
||||
tstr = tstr.replace('"'+id_+'"',JSON.stringify(tmap[id_]))
|
||||
}
|
||||
input.value = tstr;
|
||||
}
|
||||
editor_multi.hide();
|
||||
input.onchange();
|
||||
}
|
||||
setvalue(codeEditor.getValue()||'');
|
||||
}
|
||||
|
||||
var multiLineArgs=[null,null,null];
|
||||
editor_multi.multiLineEdit = function(value,b,f,callback){
|
||||
editor_multi.id='callFromBlockly';
|
||||
codeEditor.setValue(value.split('\\n').join('\n')||'');
|
||||
multiLineArgs[0]=b;
|
||||
multiLineArgs[1]=f;
|
||||
multiLineArgs[2]=callback;
|
||||
editor_multi.show();
|
||||
}
|
||||
editor_multi.multiLineDone = function(){
|
||||
editor_multi.hide();
|
||||
if(!multiLineArgs[0] || !multiLineArgs[1] || !multiLineArgs[2])return;
|
||||
var newvalue = codeEditor.getValue()||'';
|
||||
multiLineArgs[2](newvalue,multiLineArgs[0],multiLineArgs[1])
|
||||
}
|
||||
|
||||
return editor_multi;
|
||||
}
|
||||
//editor_multi=editor_multi();
|
||||
@ -1,5 +1,26 @@
|
||||
// vue 相关处理
|
||||
|
||||
document.body.onmousedown = function(e){
|
||||
//console.log(e);
|
||||
var eid=[];
|
||||
e.path.forEach(function(node){
|
||||
if(!node.getAttribute)return;
|
||||
var id_ = node.getAttribute('id');
|
||||
if (id_){
|
||||
if(['left','left1','left2','left3','left4','left5','left8'].indexOf(id_)!==-1)eid.push('edit');
|
||||
eid.push(id_);
|
||||
}
|
||||
});
|
||||
//console.log(eid);
|
||||
if(eid.indexOf('edit')===-1){
|
||||
if(eid.indexOf('tip')===-1)selectBox.isSelected = false;
|
||||
}
|
||||
//editor.mode.onmode('');
|
||||
editor.info = {};
|
||||
}
|
||||
iconLib.onmousedown = function(e){
|
||||
e.stopPropagation();
|
||||
}
|
||||
var exportM = new Vue({
|
||||
el: '#exportM',
|
||||
data: {
|
||||
@ -166,6 +187,7 @@ var clear = new Vue({
|
||||
methods: {
|
||||
clearMap: function(){
|
||||
editor.mapInit();
|
||||
editor.updateMap();
|
||||
clearTimeout(editArea.formatTimer);
|
||||
clearTimeout(tip.timer);
|
||||
pout.value = '';
|
||||
@ -175,6 +197,30 @@ var clear = new Vue({
|
||||
}
|
||||
}
|
||||
})
|
||||
printf = function(str_,type) {
|
||||
selectBox.isSelected = false;
|
||||
if(!type){
|
||||
tip.whichShow=11;
|
||||
} else {
|
||||
tip.whichShow=12;
|
||||
}
|
||||
setTimeout(function(){
|
||||
if(!type){
|
||||
tip.msgs[11]=String(str_);
|
||||
tip.whichShow=12;
|
||||
} else {
|
||||
tip.msgs[10]=String(str_);
|
||||
tip.whichShow=11;
|
||||
}
|
||||
},1);
|
||||
}
|
||||
printe = function(str_){printf(str_,'error')}
|
||||
tip_in_showMode = [
|
||||
'涉及图片的更改需要F5刷新浏览器来生效',
|
||||
'文本域可以通过双击,在文本编辑器或事件编辑器中编辑',
|
||||
'事件编辑器中的显示文本和自定义脚本的方块也可以双击',
|
||||
"画出的地图要点击\"保存地图\"才会写入到文件中",
|
||||
];
|
||||
var tip = new Vue({
|
||||
el: '#tip',
|
||||
data: {
|
||||
@ -196,6 +242,8 @@ var tip = new Vue({
|
||||
"修改成功!可点击复制按钮复制地图数组到剪切板",
|
||||
"选择背景图片失败!文件名格式错误或图片不存在!",
|
||||
"更新背景图片成功!",
|
||||
"11:警告",
|
||||
"12:成功"
|
||||
],
|
||||
mapMsg: '',
|
||||
whichShow: 0,
|
||||
|
||||
89
docs/V2.0.md
Normal file
@ -0,0 +1,89 @@
|
||||
# V2.0版本介绍
|
||||
|
||||
?> 目前版本**v2.0**,上次更新时间:* {docsify-updated} *
|
||||
|
||||
目前样板已经更新到V2.0版本,本章将对V2.0的一些内容进行介绍。
|
||||
|
||||
请确保已经看过前面的几个文档(2.0都有部分更新),前面已经描述过的东西这里将不再赘述。
|
||||
|
||||
也欢迎通过看B站的视频教程来具体了解2.0版本的使用方法。
|
||||
|
||||
## 目录结构的改变
|
||||
|
||||
在1.x中,所有数据和逻辑都是一体的,例如怪物数据和怪物伤害计算公式等等。这导致样板的版本更新时会十分不便。
|
||||
|
||||
在2.0中,我们将数据和逻辑进行了分离,拆分成了libs和project两个目录。
|
||||
|
||||
- libs目录为游戏核心库文件,包括一些游戏逻辑等内容
|
||||
- project目录为针对每个塔的目录,是和游戏逻辑是分离的。
|
||||
|
||||
我们只需要修改project目录下的各项内容,而无需去动libs目录(有特殊需求除外);
|
||||
将来如果想把塔迁移到新的版本上,也只需要迁移project即可。
|
||||
|
||||
另外一点的就是,我们将libs目录中的core.js进行了拆分,从而使每个文件的具体工作更加一目了然,也避免了接近6K行的大文件会导致打开IDE的卡顿问题。
|
||||
|
||||
## 全GUI造塔
|
||||
|
||||
在1.X版本中,我们提供了一个地图编辑器。但是它的功能十分弱,只能进行绘图的功能,实际的各项操作还是需要通过VSCode打开js文件实际进行编写代码。
|
||||
|
||||
但是在2.0中,我们大大拓展了地图编辑器的功能,从而达到了“全GUI造塔”的功能,用户再也不用手动打开任何一个文件进行编辑了。
|
||||
|
||||
GUI界面分为`地图编辑器`,`事件编辑器`和`文本编辑器`。
|
||||
|
||||
!> 即使现在可以全GUI造塔,也强烈建议对1.X的造塔方式进行了解,因为这是一切的基础。
|
||||
|
||||
### 地图编辑器
|
||||
|
||||
地图编辑器分为三个区域,左侧的`编辑区`,中间的`画布区`,右侧的`素材区`。
|
||||
|
||||
画布区下方有切换地图和编辑器模式的下拉菜单,点击`保存地图`后画布的内容才会真正写入到js文件中。
|
||||
|
||||
在素材区点击图块时,会选中该图块,此时tips会显示该图块的信息,编辑区会进入图块属性模式,怪物或物品可以直接在里面编辑数值。如果图块的数字和ID没有被定义,则可以直接在左侧定义,**定义新图块后需要保存并刷新页面后才能生效**。
|
||||
|
||||
在tips中有图块信息时,在画布上点击或拖拽可以把图块画上去,可以使用ctrl+Z撤销操作以及对应的ctrl+Y恢复撤销。擦除方块可以使用素材区最左上角的擦除块。
|
||||
|
||||
点击界面中的空白,tips中的图块信息会被清空,此时再点击画布上的点,则编辑器会进入地图选点模式。此模式下可以编辑改点的`events`,`afterBattle`,`changeFloor`等事件或者是`canMove`来改变各方向的通行状态。
|
||||
|
||||
切换地图会使编辑区进入楼层属性模式,这里可以修改首次到达该楼层时会触发的事件`firstArrive`,楼层显示的名称,默认的前景背景图片,默认天气和色调等等。
|
||||
|
||||
!> 这里不允许编辑楼层的ID,需要修改ID的场合请直接改js文件,并保持三个标识符完全一致。`data.js`中的`floorIds`也需要对应进行修改。
|
||||
|
||||
全塔属性中编辑整个塔为单位的属性,例如起始剧情`startText`,`name`,提供哪些难度,主角的起始属性,全局商店,各种数值以及系统FLAG等。**创建新塔时需要认真编辑这里面的所有选项。**
|
||||
|
||||
脚本编辑模式可以修改常用的需要更改的函数。例如,给不同的难度设置不同的内容`setInitData`,加点`addPoint`,以及修改游戏中的关于界面`drawAbout`等等。
|
||||
|
||||
追加素材模式可以导入一个图片到该标签的画板中,然后依次点击画板中的图块,点追加就可以按顺序把这些图片添加到对应的画布区素材的最下方,**需要刷新来生效**。
|
||||
|
||||
地图编辑模式中可以导入来自地图生成器的地图数组,同时创建新楼层需要在这里通过另存为来实现,可以点清除地图把另存为出的新楼层清空。
|
||||
|
||||
!> 编辑区的表格可以直接修改,推荐通过双击,在事件编辑器和文本编辑器中进行编辑。编辑区中的修改需要点保存才会生效。
|
||||
|
||||
### 事件编辑器
|
||||
|
||||
地图选点中的事件类表格,以及楼层属性中的`firstArrive`和全塔属性的`startText`,在双击时会进入事件编辑器,是由[antlr-blockly](https://github.com/zhaouv/antlr-blockly)生成的图块式的可视化编辑器.
|
||||
|
||||
把左侧的方块拖到面板中,下方就会实时的显示对应的js的代码(以及数值不正确时的提示).
|
||||
|
||||
每个方块点击右键会展开一个菜单,点帮助可以跳转到此文档中对应的内容。利用好复制功能可以极大提高编辑的效率。注释选项请不要使用,编辑器并不会保留这里的注释。
|
||||
|
||||
`template`中提供了一些模板事件,例如战前剧情,打怪开门。
|
||||
|
||||
`显示文章`的两个方块,以及`自动剧情文本`,`选项`和`自定义JS脚本`这5个方块,可以通过双击在文本编辑器中(以多行的方式)编辑其中的文字。
|
||||
|
||||
### 文本编辑器
|
||||
|
||||
事件编辑器之外的内容双击后由文本编辑器来编辑,是有js高亮支持的多行文本编辑器[CodeMirror](https://github.com/codemirror/CodeMirror),点confirm即可使编辑的文本替换到表格中。
|
||||
|
||||
### 拓展地图编辑器
|
||||
|
||||
> 面向有一定编程基础的用户
|
||||
|
||||
修改`project/`下的`*comment.js`可以让地图编辑器对自己添加的属性有更好的支持.例如:
|
||||
+ 给`comment.js`中`enemys`加入新的键值对,就可以更方便的给怪物在UI界面中添加对应的值.
|
||||
+ 在`data.comment.js`中把自己添加的内容标记为叶节点,不再在表格中展开到最末端.
|
||||
|
||||
地图编辑器的部分API见`_server/README.md`
|
||||
|
||||
## 部分事件和API更新
|
||||
|
||||
在2.0中,有部分的事件和API存在更新,也增加了包括48x32素材的支持,在这里将不再赘述,请仔细阅读前面的几个文档进行了解。
|
||||
@ -3,4 +3,5 @@
|
||||
- [元件说明](element)
|
||||
- [事件](event)
|
||||
- [个性化](personalization)
|
||||
- [V2.0版本介绍](V2.0)
|
||||
- [附录:API列表](api)
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
# 元件说明
|
||||
|
||||
?> 目前版本**v1.4.1**,上次更新时间:* {docsify-updated} *
|
||||
?> 目前版本**v2.0**,上次更新时间:* {docsify-updated} *
|
||||
|
||||
在本章中,将对样板里的各个元件进行说明。各个元件主要包括道具、门、怪物、楼梯等等。
|
||||
|
||||
@ -37,7 +37,7 @@
|
||||
|
||||
怪物可以有特殊属性,每个怪物可以有多个自定义属性。
|
||||
|
||||
怪物的特殊属性所对应的数字(special)在下面的`getSpecialText`中定义,请勿对已有的属性进行修改。
|
||||
怪物的特殊属性所对应的数字(special)在`libs/enemys.js`中的`getSpecialText`中定义,请勿对已有的属性进行修改。
|
||||
|
||||
``` js
|
||||
enemys.prototype.getSpecialText = function (enemyId) {
|
||||
@ -66,6 +66,8 @@ enemys.prototype.getSpecialText = function (enemyId) {
|
||||
if (this.hasSpecial(special, 19)) text.push("自爆");
|
||||
if (this.hasSpecial(special, 20)) text.push("无敌");
|
||||
if (this.hasSpecial(special, 21)) text.push("退化");
|
||||
if (this.hasSpecial(special, 22)) text.push("固伤");
|
||||
if (this.hasSpecial(special, 23)) text.push("重生");
|
||||
return text.join(" ");
|
||||
}
|
||||
```
|
||||
@ -125,6 +127,8 @@ N连击怪物的special是6,且我们可以为它定义n代表实际连击数
|
||||
|
||||

|
||||
|
||||
固伤怪则需要在后面增加`damage`选项,代表战前扣血数值。
|
||||
|
||||
如有额外需求,可参见[自定义怪物属性](personalization#自定义自定义怪物属性),里面讲了如何设置一个新的怪物属性。
|
||||
|
||||
## 路障,楼梯,传送门
|
||||
@ -153,10 +157,10 @@ floorId指定的是目标楼层的唯一标识符(ID)。
|
||||
|
||||
现在我们的H5魔塔支持播放动画,也支持天气系统了。
|
||||
|
||||
要播放动画,你需要先使用“RM动画导出器”将动画导出,放在animates目录下,然后在main.js中定义。
|
||||
要播放动画,你需要先使用“RM动画导出器”将动画导出,放在animates目录下,然后再data.js中定义。
|
||||
|
||||
``` js
|
||||
this.animates = [// 在此存放所有可能使用的动画,必须是animate格式,在这里不写后缀名
|
||||
"animates": [// 在此存放所有可能使用的动画,必须是animate格式,在这里不写后缀名
|
||||
// 动画必须放在animates目录下;文件名不能使用中文,不能带空格或特殊字符
|
||||
"hand", "sword", "zone", "yongchang", "thunder" // 根据需求自行添加
|
||||
]
|
||||
@ -164,8 +168,6 @@ this.animates = [// 在此存放所有可能使用的动画,必须是animate
|
||||
|
||||
!> 动画必须是animate格式,名称不能使用中文,不能带空格或特殊字符。
|
||||
|
||||
目前暂时不支持带旋转和翻转的帧。
|
||||
|
||||
导出动画时可能会进行一些压缩以节省流量,因此清晰度可能不如原版。
|
||||
|
||||
动画播放时,是按照每秒20帧的速度(即50ms/帧)。
|
||||
@ -192,13 +194,13 @@ this.animates = [// 在此存放所有可能使用的动画,必须是animate
|
||||
要播放音乐和音效,你需要将对应的文件放在sounds目录下,然后在main.js中进行定义
|
||||
|
||||
``` js
|
||||
this.bgms = [ // 在此存放所有的bgm,和文件名一致。第一项为默认播放项
|
||||
"bgms": [ // 在此存放所有的bgm,和文件名一致。第一项为默认播放项
|
||||
// 音频名不能使用中文,不能带空格或特殊字符;可以直接改名拼音就好
|
||||
'058-Slow01.mid', 'bgm.mp3', 'qianjin.mid', 'star.mid'
|
||||
'bgm.mp3', 'qianjin.mid', 'star.mid',
|
||||
];
|
||||
this.sounds = [ // 在此存放所有的SE,和文件名一致
|
||||
"sounds": [ // 在此存放所有的SE,和文件名一致
|
||||
// 音频名不能使用中文,不能带空格或特殊字符;可以直接改名拼音就好
|
||||
'floor.mp3', 'attack.ogg', 'door.ogg', 'item.ogg'
|
||||
'floor.mp3', 'attack.ogg', 'door.ogg', 'item.ogg', 'zone.ogg'
|
||||
]
|
||||
```
|
||||
|
||||
@ -245,7 +247,7 @@ this.sounds = [ // 在此存放所有的SE,和文件名一致
|
||||
- **[ESC]** 打开/关闭系统菜单
|
||||
- **[H]** 打开帮助页面
|
||||
- **[Z]** 转向
|
||||
- **[R]** 回退
|
||||
- **[R]** 回放录像
|
||||
- **[SPACE]** 轻按(仅在轻按开关打开时有效)
|
||||
- **[1]** 快捷使用破墙镐
|
||||
- **[2]** 快捷使用炸弹/圣锤
|
||||
|
||||
107
docs/event.md
@ -1,6 +1,6 @@
|
||||
# 事件
|
||||
|
||||
?> 目前版本**v1.4.1**,上次更新时间:* {docsify-updated} *
|
||||
?> 目前版本**v2.0**,上次更新时间:* {docsify-updated} *
|
||||
|
||||
本章内将对样板所支持的事件进行介绍。
|
||||
|
||||
@ -20,6 +20,13 @@
|
||||
|
||||
在事件列表中使用`type: show`和`type: hide`可以将一个禁用事件启用,或将一个启用事件给禁用。
|
||||
|
||||
## 关于V2.0的重要说明
|
||||
|
||||
在V2.0版本中,所有事件均可以使用blockly来进行块的可视化编辑。
|
||||
|
||||
它能通过拖动、复制粘贴等方式帮助你快速生成事件列表,而不用手动打大量字符。
|
||||
|
||||
但是,仍然强烈建议要对每个事件的写法进行了解。
|
||||
|
||||
## 自定义事件
|
||||
|
||||
@ -615,13 +622,13 @@ loc可忽略,如果忽略则显示为事件当前点。
|
||||
|
||||
``` js
|
||||
"x,y": [ // 实际执行的事件列表
|
||||
{"type": "showImage", "name": "bg", "loc": [231,297]}, // 在(231,297)显示bg.png
|
||||
{"type": "showImage", "name": "1", "loc": [109,167]}, // 在(109,167)显示1.png
|
||||
{"type": "showImage", "name": "bg.jpg", "loc": [231,297]}, // 在(231,297)显示bg.jpg
|
||||
{"type": "showImage", "name": "1.png", "loc": [109,167]}, // 在(109,167)显示1.png
|
||||
{"type": "showImage"} // 如果不指定name则清除所有图片。
|
||||
]
|
||||
```
|
||||
|
||||
name为图片名。**请确保图片在main.js中的this.pngs中被定义过。**
|
||||
name为图片名。**请确保图片在data.js中的images中被定义过。**
|
||||
|
||||
loc为图片左上角坐标,以像素为单位进行计算。
|
||||
|
||||
@ -769,10 +776,12 @@ move完毕后移动的NPC/怪物一定会消失,只不过可以通过immediate
|
||||
|
||||
### win: 获得胜利
|
||||
|
||||
`{"type": "win", "reason": "xxx"}` 将会直接调用events.js中的win函数,并将reason作为参数传入。
|
||||
`{"type": "win", "reason": "xxx"}` 将会直接调用events.js中的win函数,并将reason作为结局传入。
|
||||
|
||||
该事件会显示获胜页面,并重新游戏。
|
||||
|
||||
!> 如果`reason`不为空,则会以reason作为获胜的结局!
|
||||
|
||||
### lose: 游戏失败
|
||||
|
||||
`{"type": "lose", "reason": "xxx"}` 将会直接调用`events.js`中的lose函数,并将reason作为参数传入。
|
||||
@ -1059,19 +1068,24 @@ core.insertAction(list) //往当前事件列表中插入一系列事件。使用
|
||||
|
||||
打败怪物后可以进行加点。
|
||||
|
||||
如果要对某个怪物进行加点操作,则首先需要修改该怪物的点数值,即在怪物定义的后面添加`point`,代表怪物本身的加点数值。
|
||||
要启用加点,首先需要在`data.js`中将`enableAddPoint`置为true。
|
||||
|
||||
如果要对某个怪物进行加点操作,则首先需要修改该怪物的`point`数值,代表怪物本身的加点数值。
|
||||
|
||||
``` js
|
||||
... 'def': 0, 'money': 1, 'experience': 1, 'special': 0, 'point': 1}, // 在怪物后面添加point代表怪物的加点数
|
||||
... 'def': 0, 'money': 1, 'experience': 1, 'point': 1, 'special': 0}, // 在怪物后面添加point代表怪物的加点数
|
||||
```
|
||||
|
||||
然后在`events.js`文件中找到`addPoint`函数。它将返回一个choices事件。修改此函数为我们需要的加点项即可。
|
||||
然后在`functions.js`文件中找到`addPoint`函数。它将返回一个choices事件。修改此函数为我们需要的加点项即可。
|
||||
|
||||
!> V2.0版本可以直接在“脚本编辑 - 加点事件”中双击进行修改!
|
||||
|
||||
``` js
|
||||
////// 加点 //////
|
||||
events.prototype.addPoint = function (enemy) {
|
||||
var point = enemy.point; // 获得该怪物的point
|
||||
if (!core.isset(point) || point<=0) return [];
|
||||
////// 加点事件 //////
|
||||
"addPoint" : function (enemy) {
|
||||
// 加点事件
|
||||
var point = enemy.point;
|
||||
if (!core.flags.enableAddPoint || !core.isset(point) || point<=0) return [];
|
||||
|
||||
// 加点,返回一个choices事件
|
||||
return [
|
||||
@ -1230,11 +1244,13 @@ events.prototype.addPoint = function (enemy) {
|
||||
|
||||
上面的afterBattle事件只对和怪物进行战斗后才有会被处理。
|
||||
|
||||
如果我们想在使用炸弹后也能触发一些事件(如开门),则可以在`events.js`里面的`afterUseBomb`函数进行处理:
|
||||
如果我们想在使用炸弹后也能触发一些事件(如开门),则可以在`functions.js`里面的`afterUseBomb`函数进行处理:
|
||||
|
||||
!> V2.0版本可以直接在“脚本编辑 - 使用炸弹后的事件”中双击进行修改!
|
||||
|
||||
``` js
|
||||
////// 使用炸弹/圣锤后的事件 //////
|
||||
events.prototype.afterUseBomb = function () {
|
||||
"afterUseBomb": function () {
|
||||
// 这是一个使用炸弹也能开门的例子
|
||||
if (core.status.floorId=='xxx' && core.terrainExists(x0,y0,'specialDoor') // 某个楼层,该机关门存在
|
||||
&& !core.enemyExists(x1,y1) && !core.enemyExists(x2,y2)) // 且守门的怪物都不存在
|
||||
@ -1262,11 +1278,11 @@ events.prototype.afterUseBomb = function () {
|
||||
|
||||
!> 推箱子的前方不允许存在任何事件(花除外),包括已经禁用的自定义事件。
|
||||
|
||||
推完箱子后将触发events.js中的afterPushBox事件,你可以在这里进行开门判断。
|
||||
推完箱子后将触发functions.js中的afterPushBox事件,你可以在这里进行开门判断。
|
||||
|
||||
``` js
|
||||
////// 推箱子后的事件 //////
|
||||
events.prototype.afterPushBox = function () {
|
||||
"afterPushBox" = function () {
|
||||
|
||||
var noBoxLeft = function () {
|
||||
// 地图上是否还存在未推到的箱子,如果不存在则返回true,存在则返回false
|
||||
@ -1290,6 +1306,33 @@ events.prototype.afterPushBox = function () {
|
||||
}
|
||||
```
|
||||
|
||||
## 怪物数据的动态修改
|
||||
|
||||
有时候我们可能还需要在游戏过程中动态修改怪物数据,例如50层魔塔的封印魔王,或者根据难度分歧来调整最终Boss的属性数据。
|
||||
|
||||
而在我们的存档中,是不会对怪物数据进行存储的,只会存各个变量和Flag,因此我们需要在读档后根据变量或Flag来调整怪物数据。
|
||||
|
||||
我们可以在functions.js中的`afterLoadData`进行处理。
|
||||
|
||||
``` js
|
||||
////// 读档事件后,载入事件前,可以执行的操作 //////
|
||||
"afterLoadData" : function(data) {
|
||||
// 读档事件后,载入事件前,可以执行的操作
|
||||
if (core.hasFlag("fengyin")) { // 如果存在封印(flag为真)
|
||||
core.material.enemys.blackKing.hp/=10; // 将怪物的血量变成原来的十分之一
|
||||
// ...
|
||||
}
|
||||
// 同样难度分歧可以类似写 if (core.getFlag('hard', 0)==3) {...
|
||||
}
|
||||
|
||||
// 在封印时,可以调用setValue将该flag置为真,然后调用自定义脚本 core.afterLoadData() 即可。
|
||||
"x,y": [ // 封印
|
||||
{"type": "setValue", "name": "flag:fengyin", "value": "true"},
|
||||
{"type": "function", "function": function() {
|
||||
core.afterLoadData();
|
||||
}}
|
||||
]
|
||||
```
|
||||
|
||||
## 战前剧情
|
||||
|
||||
@ -1361,7 +1404,7 @@ events.prototype.afterPushBox = function () {
|
||||
|
||||
``` js
|
||||
////// 不同难度分别设置初始属性 //////
|
||||
events.prototype.setInitData = function (hard) {
|
||||
"setInitData": function (hard) {
|
||||
if (hard=='Easy') { // 简单难度
|
||||
core.setFlag('hard', 1); // 可以用flag:hard来获得当前难度
|
||||
// 可以在此设置一些初始福利,比如设置初始生命值可以调用:
|
||||
@ -1386,7 +1429,7 @@ events.prototype.setInitData = function (hard) {
|
||||
|
||||
``` js
|
||||
////// 游戏获胜事件 //////
|
||||
events.prototype.win = function(reason) {
|
||||
"win": function(reason) {
|
||||
core.ui.closePanel();
|
||||
var replaying = core.status.replay.replaying;
|
||||
core.stopReplay();
|
||||
@ -1396,19 +1439,21 @@ events.prototype.win = function(reason) {
|
||||
core.drawText([
|
||||
"\t[恭喜通关]你的分数是${status:hp}。"
|
||||
], function () {
|
||||
core.events.gameOver('', replaying);
|
||||
core.events.gameOver(reason||'', replaying);
|
||||
})
|
||||
});
|
||||
}
|
||||
```
|
||||
|
||||
其参数reason为获胜原因(即type:win事件里面的reason参数)。你可以在这里修改自己的获胜界面显示的文字。
|
||||
其参数reason为获胜原因(即type:win事件里面的reason参数)。
|
||||
|
||||
!> 如果reason不为空,则将会作为结局名!
|
||||
|
||||
当失败(`{"type": "lose"}`,或者被怪强制战斗打死、被领域怪扣血死、中毒导致扣血死,路障导致扣血死等等)事件发生时,将调用`events.js`中的`lose`事件。其直接显示一段文字,并重新开始游戏。
|
||||
|
||||
``` js
|
||||
////// 游戏失败事件 //////
|
||||
events.prototype.lose = function(reason) {
|
||||
"lose": function(reason) {
|
||||
core.ui.closePanel();
|
||||
var replaying = core.status.replay.replaying;
|
||||
core.stopReplay();
|
||||
@ -1424,26 +1469,6 @@ events.prototype.lose = function(reason) {
|
||||
|
||||
其参数reason为失败原因。你可以在这里修改失败界面时显示的文字。
|
||||
|
||||
如果要设置多种不同的结局,只需要在win的传参中把`core.events.gameOver('', replaying);`的空字符串改成具体的结局名。
|
||||
|
||||
例如:
|
||||
|
||||
``` js
|
||||
events.prototype.win = function(reason) { // 传入参数"reason"为结局名
|
||||
// ... 上略
|
||||
], function () {
|
||||
core.events.gameOver(reason, replaying); // 使用reason作为结局名
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
// 然后在事件可以调用
|
||||
{"type": "win", "reason": "TRUE END"}, // TE结局
|
||||
{"type": "win", "reason": "NORMAL END"} // NE结局
|
||||
```
|
||||
|
||||
上面这个例子中,我们直接把reason作为结局名的参数传入gameOver函数,这样的话就可以直接在{"type": "win"}中加上"reason"代表具体的结局。
|
||||
|
||||
==========================================================================================
|
||||
|
||||
[继续阅读下一章:个性化](personalization)
|
||||
|
||||
|
Before Width: | Height: | Size: 32 KiB After Width: | Height: | Size: 5.7 KiB |
|
Before Width: | Height: | Size: 7.1 KiB After Width: | Height: | Size: 6.2 KiB |
@ -1,18 +1,37 @@
|
||||
# 个性化
|
||||
|
||||
?> 目前版本**v1.4.1**,上次更新时间:* {docsify-updated} *
|
||||
?> 目前版本**v2.0**,上次更新时间:* {docsify-updated} *
|
||||
|
||||
有时候只靠样板本身可能是不够的。我们需要一些个性化、自定义的素材,道具效果,怪物属性,等等。
|
||||
|
||||
## 图层的说明
|
||||
|
||||
HTML5魔塔是使用画布(canvas)来绘制,存在若干个图层,它们之间有一个覆盖关系,后面的图层将覆盖前面的图层。
|
||||
|
||||
所有图层从低往高依次如下:
|
||||
|
||||
- bg:背景层;绘制地面素材,或者作为背景的图片素材
|
||||
- event:事件层;所有事件(道具、墙壁、NPC、怪物等)都绘制在这一层进行处理
|
||||
- hero:勇士层;主要用来绘制勇士
|
||||
- event2:事件2层;本层主要用来绘制48x32的图片素材的上半部分(避免和勇士错位),也可以用来绘制该层的前景图片素材
|
||||
- fg:显伤层;主要用来绘制怪物显伤和领域显伤
|
||||
- animate:动画层;主要用来绘制动画,图块的淡入/淡出效果,图块的移动。showImage事件绘制的图片也是在这一层。
|
||||
- weather:天气层;主要用来绘制天气(雨/雪)
|
||||
- curtain:色调层;用来控制当前楼层的画面色调
|
||||
- ui:UI层;用来绘制一切UI窗口,如剧情文本、怪物手册、楼传器、系统菜单等等
|
||||
- data:数据层;用来绘制一些顶层的或更新比较快的数据,如左上角的提示,战斗界面中数据的变化等等。
|
||||
|
||||
## 自定义素材
|
||||
|
||||
所有素材的图片都在`images`目录下。
|
||||
- `animates.png` 为所有动画效果。主要是星空熔岩,开门,毒网,传送门之类的效果。为四帧。
|
||||
- `autotile.png` 为Autotile块。
|
||||
- `enemys.png` 为所有怪物的图片。其对应的数字,从上至下依次是会从201开始计算(即,绿色史莱姆为201,小蝙蝠为205,依次类推)。请注意,动画效果为两帧,一般是原始四帧中的1和3。(四帧中12相同,34相同,因此只取1和3即可)
|
||||
- `enemys.png` 为所有怪物的图片。
|
||||
- `enemy48.png` 为所有48x32怪物的图片。
|
||||
- `heros.png` 为勇士行走图。
|
||||
- `items.png` 为所有道具的图标。
|
||||
- `npcs.png` 为所有NPC的图标,也是两帧。
|
||||
- `npcs.png` 为所有NPC的图标。
|
||||
- `npc48.png` 为所有48x32的NPC图标。
|
||||
- `terrains.png` 为所有地形的图标。
|
||||
|
||||
系统会读取`icon.js`文件,并获取每个ID对应的图标所在的位置。
|
||||
@ -23,40 +42,38 @@
|
||||
|
||||
如果你需要某个素材已经存在,则可以直接将其覆盖images目录下的同名文件,就能看到效果。
|
||||
|
||||
### 使用自己的图片作为某层楼的背景素材
|
||||
### 使用自己的图片作为某层楼的背景/前景素材
|
||||
|
||||
由于HTML5功能(素材)有限,导致了对很多比较复杂的素材(比如房子内)等无法有着较好的绘图方式。
|
||||
|
||||
为了解决这个问题,我们允许用户自己放置一张或多张图片作为某一层的背景素材。
|
||||
|
||||
要启用这个功能,我们首先需要在`main.js`中将可能的图片进行加载。
|
||||
要启用这个功能,我们首先需要在`data.js`中将可能的图片进行加载。
|
||||
|
||||
``` js
|
||||
this.pngs = [ // 在此存放所有可能使用的图片,只能是png格式,可以不写后缀名
|
||||
"images": [ // 在此存放所有可能使用的图片
|
||||
// 图片可以被作为背景图(的一部分),也可以直接用自定义事件进行显示。
|
||||
// 图片名不能使用中文,不能带空格或特殊字符;可以直接改名拼音就好
|
||||
// 建议对于较大的图片,在网上使用在线的“图片压缩工具(http://compresspng.com/zh/)”来进行压缩,以节省流量
|
||||
"bg", // 依次向后添加
|
||||
"bg.jpg", "house.png", "bed.png"// 依次向后添加
|
||||
];
|
||||
```
|
||||
|
||||
!> 背景素材只支持png格式。
|
||||
!> 请使用网上的一些[在线图片压缩工具](http://compresspng.com/zh/)对图片进行压缩,以节省流量。
|
||||
|
||||
!> 请使用网上的一些[在线图片压缩工具](http://compresspng.com/zh/)对png图片进行压缩,以节省流量。一张500KB的png图片可以被压缩到20-30KB,显示效果不会有太大差异。
|
||||
|
||||
之后,我们可以在每层剧本的`"png"`里来定义该层的默认背景图片素材。
|
||||
之后,我们可以在每层剧本的`"images"`里来定义该层的默认背景图片素材。
|
||||
|
||||
``` js
|
||||
"png": [[x,y,"bg"]], // 背景图;你可以选择一张或多张png图片来作为背景素材。
|
||||
"png": [], // 无任何背景图
|
||||
"png": [[1,1,"house"], [6,7,"house2"]] // 在(1,1)放一个house.png,且(6,7)放house2.png
|
||||
"images": [[x,y,"bg.jpg",false]], // 背景图;你可以选择一张或多张图片来作为背景/前景素材。
|
||||
"images": [], // 无任何背景图
|
||||
"images": [[1,1,"house.png",false], [6,7,"bed.png",true]] // 在(1,1)放一个house.png在背景层,且(6,7)放bed.png在前景层
|
||||
```
|
||||
|
||||
png为一个数组,代表当前层所有作为背景素材的图片信息。
|
||||
images为一个数组,代表当前层所有作为背景素材的图片信息。
|
||||
|
||||
每一项为一个三元组,分别为该背景素材的x,y和图片名。其中x和y分别为横纵坐标,在0-12之间;图片名则必须在上面的this.pngs中定义过。
|
||||
每一项为一个四元组,分别为该背景素材的x,y,图片名和是否为前景。其中x和y分别为横纵坐标,在0-12之间;图片名则必须在上面的images中定义过。
|
||||
|
||||
你的图片背景素材将会覆盖原来本身的背景层。
|
||||
如果第四项为true,则会在前景层(event2)上绘制,能覆盖勇士,常常用来作为柱子的上半部分等情况。
|
||||
|
||||
**如果你需要让某些点不可通行(比如你建了个房子,墙壁和家具等位置不让通行),则需在`events`中指定`{"noPass": false}`,参见[自定义事件](event#自定义事件)的写法。
|
||||
|
||||
@ -84,6 +101,8 @@ png为一个数组,代表当前层所有作为背景素材的图片信息。
|
||||
|
||||
这是因为,该素材没有被定义,无法被游戏所识别。
|
||||
|
||||
!> 在V2.0中,我们可以简单的在地图编辑器中新增素材的ID和数字,但是仍然**强烈建议**对素材的机制进行了解。
|
||||
|
||||
#### 素材的机制
|
||||
|
||||
本塔所有的素材都拥有三个属性:**ID**,**索引**,**数字**。
|
||||
@ -93,7 +112,7 @@ png为一个数组,代表当前层所有作为背景素材的图片信息。
|
||||
|
||||
**`ID-索引` 对应关系定义在icons.js文件中。该文件将唯一确定一个ID在图片上所在的位置。**
|
||||
|
||||
**`ID-数字` 对应关系定义在maps.js文件的getBlock函数中。该函数将唯一确定一个ID对应的数字是多少。**
|
||||
**`ID-数字` 对应关系定义在maps.js文件中。该函数将唯一确定一个ID对应的数字是多少。**
|
||||
|
||||
如果需要添加一个素材到游戏,则必须为其分配一个唯一标识符,并同时修改`icons.js`和`maps.js`两个文件。
|
||||
|
||||
@ -108,7 +127,7 @@ png为一个数组,代表当前层所有作为背景素材的图片信息。
|
||||
3. 修改对应楼层的剧本文件的`defaultGround`项,改成新的ID。
|
||||
|
||||
**如果你要在游戏内使用本地形,则操作如下:**
|
||||
3. 指定一个数字,在maps.js的getBlock函数下类似进行添加。
|
||||
3. 指定一个数字,在maps.js中类似进行添加。
|
||||
|
||||
#### 新添加Autotile
|
||||
|
||||
@ -116,24 +135,26 @@ png为一个数组,代表当前层所有作为背景素材的图片信息。
|
||||
|
||||
1. 将新的Autotile图片复制到images目录下。
|
||||
2. 进入icons.js,在autotile分类下进行添加该文件的名称,索引简单的写0。
|
||||
3. 指定一个数字,在maps.js的getBlock函数下类似进行添加。
|
||||
3. 指定一个数字,在maps.js中类似进行添加。
|
||||
|
||||
!> Autotile的ID和文件名完全相同!且其ID/文件名不能含有中文、空格或特殊字符。
|
||||
|
||||
!> V2.0版本不能在地图编辑器中添加Autotile,请按上面的操作来执行。
|
||||
|
||||
#### 新添加道具
|
||||
|
||||
如果你需要新增一个未被定义的道具:
|
||||
|
||||
1. 指定一个唯一的英文ID,不能和现有的重复。
|
||||
2. 进入icons.js,在items分类下进行添加索引(对应图标在图片上的位置,即index)
|
||||
3. 指定一个数字,在maps.js的getBlock下类似进行添加。
|
||||
3. 指定一个数字,在maps.js中类似进行添加。
|
||||
4. 在items.js中仿照其他道具,来添加道具的信息。
|
||||
|
||||
有关如何自行实现一个道具的效果,参见[自定义道具效果](#自定义道具效果)。
|
||||
|
||||
#### 新添加怪物
|
||||
|
||||
如果我们需要新添加怪物,请在enemys.png中新增一行,然后复制粘贴上四帧怪物图的**1和3帧**。
|
||||
如果我们需要新添加怪物,请在enemys.png中新增一行。
|
||||
|
||||
你可以通过便捷PS工具的“更改色相”来将红头怪变成橙头怪等。
|
||||
|
||||
@ -141,9 +162,11 @@ png为一个数组,代表当前层所有作为背景素材的图片信息。
|
||||
|
||||
1. 指定一个唯一的英文ID,不能和enemys中现有的重复。
|
||||
2. 进入icons.js,在enemys分类下进行添加索引(对应图标在图片上的位置,即index)
|
||||
3. 在maps.js的getBlock下继续进行添加。请注意其ID为200开始的顺序,即如果新增一行为261,依次类推
|
||||
3. 在maps.js中继续进行添加。
|
||||
4. 在enemys.js中仿照其他怪物,来添加怪物的信息。
|
||||
|
||||
!> 如果是48x32的怪物素材,请放在enemy48.png中,然后在icons.js的enemy48下添加索引。
|
||||
|
||||
有关如何自行实现一个怪物的特殊属性或伤害计算公式,参见[怪物的特殊属性](#怪物的特殊属性)。
|
||||
|
||||
#### 新添加NPC
|
||||
@ -152,6 +175,8 @@ png为一个数组,代表当前层所有作为背景素材的图片信息。
|
||||
2. 进入icons.js,在npcs分类下进行添加索引(对应图标在图片上的位置,即index)
|
||||
3. 指定一个数字,在maps.js的getBlock下类似进行添加。
|
||||
|
||||
!> 如果是48x32的怪物素材,请放在npc48.png中,然后在icons.js的npc48下添加索引。
|
||||
|
||||
### 地图生成器使用自定义素材
|
||||
|
||||
地图生成器是直接从js文件中读取数字-图标对应关系的。
|
||||
@ -168,30 +193,24 @@ png为一个数组,代表当前层所有作为背景素材的图片信息。
|
||||
|
||||
对于即捡即用类道具,如宝石、血瓶、剑盾等,我们可以简单地修改`data.js`中的value一栏即可。
|
||||
|
||||
如果你有更高级的需求(例如每个区域的效果不同),则需要编辑`items.js`文件。具体方式是:
|
||||
如果你想要同种宝石在不同层效果不同的话,可以进行如下操作:
|
||||
|
||||
1. 在楼层的item_ratio中定义宝石的比率(比如1-10的写1,11-20层写2等)
|
||||
2. 修改获得道具的itemEffect函数(在items.js中的itemEffect中编辑,V2.0中也可以使用编辑器)
|
||||
|
||||
1. 找到`getItemEffect`函数;所有即捡即用类道具的效果都在这里实现。
|
||||
2. 算道具效果系数,或应该增加的值。
|
||||
``` js
|
||||
items.prototype.getItemEffect = function(itemId, itemNum) {
|
||||
var itemCls = core.material.items[itemId].cls;
|
||||
// 消耗品
|
||||
if (itemCls === 'items') {
|
||||
var floor = parseInt(core.status.thisMap.name); // 获得当前楼层。此name和剧本中的name完全一致。
|
||||
var ratio = 1; // 道具效果系数
|
||||
if (floor>=11 && floor<=20 ) ratio = 2; // 11-20F(二区),道具效果翻倍
|
||||
if (floor>=21 && floor<=30 ) ratio = 3; // 21-30F(二区),道具效果三倍
|
||||
// ... 根据自己的需要来写
|
||||
|
||||
if (itemId === 'redJewel') core.status.hero.atk += core.values.redJewel * ratio; // 将初始效果乘以倍数
|
||||
if (itemId === 'blueJewel') core.status.hero.def += core.values.blueJewel * ratio; // 将初始效果乘以倍数
|
||||
if (itemId === 'greenJewel') core.status.hero.mdef += core.values.greenJewel * ratio; // 将初始效果乘以倍数
|
||||
if (itemId == 'yellowJewel') { // 黄宝石属性:需自己定义
|
||||
// ... 下略
|
||||
// ratio为楼层的item_ratio值,可以进行翻倍宝石属性
|
||||
core.status.hero.atk += core.values.redJewel * ratio
|
||||
```
|
||||
3. 修改同样修改下面的`getItemEffectTip`函数,使提示文字相应变动。
|
||||
|
||||
!> **请注意这里`core.status.thisMap.name`获取的是当前层中,你在剧本文件里写的name那一项(即状态栏中的层数显示)。然后可以通过几个简单的if来判断应该增加的值。**
|
||||
这里我们可以直接写ratio来取用该楼层中定义的`item_ratio`的值。
|
||||
|
||||
如果不是倍数增加(比如线性增加)也可以类似来写
|
||||
|
||||
``` js
|
||||
// 一个二倍线性增加的例子
|
||||
core.status.hero.atk += core.values.redJewel + 2*ratio
|
||||
```
|
||||
|
||||
### 消耗类道具(cls: tools);永久类道具(cls: constants)
|
||||
|
||||
@ -214,12 +233,10 @@ events.prototype.passNet = function (data) {
|
||||
|
||||
### 实战!拿到神圣盾后免疫吸血、领域、夹击效果
|
||||
|
||||
1. 在getItemEffect中修改拿到神圣盾时的效果,标记一个自定义Flag。
|
||||
1. 在itemEffect中修改拿到神圣盾时的效果,标记一个自定义Flag。
|
||||
``` js
|
||||
if (itemId === 'shield5') {
|
||||
core.status.hero.def += core.values.shield5;
|
||||
core.setFlag("shield5", true); // 增加一个自定义Flag:已经拿到神圣盾
|
||||
}
|
||||
core.status.hero.def += core.values.shield5 * ratio;
|
||||
core.setFlag("shield5", true); // 增加一个自定义Flag:已经拿到神圣盾
|
||||
```
|
||||
2. 免疫吸血效果:在`enemys.js`的伤害计算中,编辑成如果存在神圣盾标记,吸血伤害为0。
|
||||
``` js
|
||||
@ -241,10 +258,10 @@ enemys.prototype.calDamage = function (monster, hero_hp, hero_atk, hero_def, her
|
||||
}
|
||||
// ... 下略
|
||||
```
|
||||
3. 免疫领域、夹击、阻击效果:在`core.js`中,找到checkBlock函数,并编辑成如果有神圣盾标记,则将伤害变成0。
|
||||
3. 免疫领域、夹击、阻击效果:在`control.js`中,找到checkBlock函数,并编辑成如果有神圣盾标记,则将伤害变成0。
|
||||
``` js
|
||||
// 检查领域、夹击、阻击事件
|
||||
core.prototype.checkBlock = function () {
|
||||
control.prototype.checkBlock = function () {
|
||||
var x=core.getHeroLoc('x'), y=core.getHeroLoc('y');
|
||||
var damage = core.status.checkBlock.damage[13*x+y];
|
||||
if (damage>0) {
|
||||
@ -271,9 +288,9 @@ core.prototype.checkBlock = function () {
|
||||
|
||||
如果要修改伤害计算公式,请修改下面的calDamage函数。请注意,如果无法战斗,该函数必须返回`999999999`。
|
||||
|
||||
对于毒衰弱怪物的战斗后结算在`events.js`中的afterBattle函数中。
|
||||
对于毒衰弱怪物的战斗后结算在`functions.js`中的afterBattle函数中。
|
||||
|
||||
对于领域、夹击、阻击怪物的检查在`events.js`中的checkBlock函数中。
|
||||
对于领域、夹击、阻击怪物的检查在`control.js`中的checkBlock函数中。
|
||||
|
||||
`getCritical`, `getCriticalDamage`和`getDefDamage`三个函数依次计算的是该怪物的临界值、临界减伤和1防减伤。也可以适当进行修改。
|
||||
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
# 快速上手
|
||||
|
||||
?> 目前版本**v1.4.1**,上次更新时间:* {docsify-updated} *
|
||||
?> 目前版本**v2.0**,上次更新时间:* {docsify-updated} *
|
||||
|
||||
在这一节中,将详细介绍做一部塔的流程。现在,让我们来做一部单层塔!
|
||||
|
||||
@ -12,9 +12,18 @@
|
||||
- Chrome浏览器。其他浏览器可能会导致本地服务器产生闪退等现象。
|
||||
- 一个很好的文本编辑器。推荐带有高亮染色、错误提示等效果。例如:WebStorm,VSCode,或者至少也要Sublime Text。
|
||||
- ([VSCode下载地址](https://code.visualstudio.com/),群里的群文件中也有,强烈推荐之。)
|
||||
- **2.0版本可以不需要,但是仍然强烈推荐有一个,从而能对H5造塔有更深的了解。**
|
||||
|
||||
只要满足了上述条件,你就可以开始做自己的塔啦!
|
||||
|
||||
## V2.0的使用
|
||||
|
||||
目前版本已经更新到V2.0,在2.0版本中,我们可以进行全GUI造塔。
|
||||
|
||||
下面的文档主要是讲如何通过代码编辑的方式来造,仍然强烈建议进行阅读从而有着一定的了解。
|
||||
|
||||
如果想直接知道如何在V2.0造塔,可以直接参见[V2.0版本介绍](V2.0)的说明,或者看[B站视频教程](http://www.bilibili.com/video/av17608025/)。
|
||||
|
||||
## 启动HTTP服务
|
||||
|
||||
在根目录下有一个“启动服务.exe”,运行之。
|
||||
@ -25,6 +34,7 @@
|
||||
* “地图编辑器”允许你以可视化的方式进行编辑地图。
|
||||
* “便捷PS工具”能让你很方便的对自定义素材进行添加。参见[自定义素材](personalization#自定义素材)。
|
||||
* “地图生成器”能让你从已有的截图(如RMXP项目)中立刻生成可被本样板识别的地图数据。
|
||||
* “RM动画导出器”能让你从RMXP中导出动画而被H5魔塔使用。
|
||||
* “JS代码压缩工具”能对JS代码进行压缩,从而减少IO请求数和文件大小。
|
||||
* “伤害和临界值计算器”是一个很便捷的小工具,能对怪物的伤害和临界值进行计算。
|
||||
|
||||
@ -34,7 +44,7 @@
|
||||
|
||||
类似于RMXP,本塔每层楼都是一个“剧本”,剧本内主要定义了本层的地图和各种事件。主函数将读取每个剧本,并生成实际的地图供游戏使用。
|
||||
|
||||
我们打开 `libs/floors/` 目录,这个目录是所有剧本的目录。我们需要指定一个楼层名,例如MT1;然后,我们可以将`MT0.js`(模板)复制重命名为为`MT1.js`,并使用文本编辑器打开。
|
||||
我们打开 `project/floors/` 目录,这个目录是所有剧本的目录。我们需要指定一个楼层名,例如MT1;然后,我们可以将`MT0.js`(模板)复制重命名为为`MT1.js`,并使用文本编辑器打开。
|
||||
|
||||

|
||||
|
||||
@ -43,11 +53,14 @@
|
||||
具体样板文件的每个要素如下:
|
||||
- **`floorId`** 楼层唯一标识符;必须和文件名,以及 `main.floors.xxx` 完全一致
|
||||
- **`title`** 楼层中文名,将在切换楼层时进行显示
|
||||
- **`name`** 楼层再状态栏显示的名称
|
||||
- **`canFlyTo`** 当前楼层可否被楼传器飞到。如果该层不能飞到,则也在该层也不允许使用楼传器。
|
||||
- **`canUseQuickShop`** 当前楼层可否使用快捷商店。
|
||||
- **`defaultGround`** 该层的背景(地面)素材。需要是在`icon.js`里`terrains`中定义的一个ID,如`ground`, `grass2`等等。
|
||||
- **`color`** 该层的画面色调。本项可选,如果不写则色调为默认值(无色调),否则是一个RGBA数组,比如`[255,0,0,0.3]`等。
|
||||
- **`defaultGround`** 该层的背景(地面)素材。
|
||||
- **`images`** 该层默认显示的前景/背景图片
|
||||
- **`color`** 该层的画面色调。
|
||||
- **`bgm`** 到达该层后默认播放的BGM。本项可忽略。
|
||||
- **`item_ratio`** 该层的宝石/血瓶倍率
|
||||
- **`map`** 本层地图,需要是13x13数组,建议使用地图生成器或者可视化地图编辑器制作。
|
||||
- **`firstArrive`** 第一次到该楼层触发的事件
|
||||
- **`events`** 该楼的所有可能事件列表
|
||||
@ -55,6 +68,7 @@
|
||||
- **`afterBattle`** 战斗后可能触发的事件列表
|
||||
- **`afterGetItem`** 获得道具后可能触发的事件列表
|
||||
- **`afterOpenDoor`** 开完门后可能触发的事件列表
|
||||
- **`cannotMove`** 每个图块不可通行的方向,也就是悬崖效果
|
||||
|
||||
我们最终的任务其实是,将每个楼层的剧本(地图&事件)给写完即可。
|
||||
|
||||
@ -72,12 +86,14 @@
|
||||
|
||||
然后可以在上面任意进行绘制地图。
|
||||
|
||||
!> **如果地图的数字和ID未被定义,则会进行提示:数字和ID未被定义!此时可能需要手动在icons.js和maps.js中定义对应的数字和ID。请参见[自定义素材](personalization#自定义素材)。**
|
||||
!> **如果地图的数字和ID未被定义,则会进行提示:数字和ID未被定义!此时要对素材的ID和数字进行定义,请参见[自定义素材](personalization#自定义素材)。**
|
||||
|
||||
绘制地图完毕后,点击"导出地图",即可在左边看到对应的JSON数组,并且已经复制到了剪切板。将其粘贴到剧本中的map位置即可。
|
||||
|
||||

|
||||
|
||||
!> V2.0版本可以直接将当前地图进行保存或另存为,不需要这样手动打开进行编辑。
|
||||
|
||||
### 从RMXP导入已有的地图
|
||||
|
||||
如果我们想复刻一个现有的,已经被RMXP所制作的塔,也有很便捷的方式,那就是用到我们的“地图生成器”。
|
||||
@ -117,6 +133,8 @@
|
||||
|
||||
我们打开`data.js`文件,这里面定义了各种全局属性和勇士初始值。
|
||||
|
||||
!> V2.0版本可以直接在地图编辑器的`全塔属性`中进行修改!
|
||||
|
||||
我们可以将本塔标题改名为“1层小塔”,
|
||||
|
||||
游戏的唯一标识符叫onefloor,然后可以直接修改勇士的各项初始数据.
|
||||
@ -139,12 +157,12 @@
|
||||
|
||||
其他的几项暂时不会被涉及到,因此不用考虑。
|
||||
|
||||
全局变量修改完毕后,我们需要告诉主函数加载该楼层。打开`main.js`(该文件和index.html同级),找到`this.floorIds`项,将其值改为楼层ID即MT1。
|
||||
|
||||

|
||||
全局变量修改完毕后,我们需要告诉主函数加载该楼层。打开`data.js`,找到`floorIds`项,将其值改为楼层ID即MT1。
|
||||
|
||||
最后一步就是录入怪物数据。打开`enemys.js`文件,依次输入你在本塔内使用到的所有怪物的攻防血的数据。其中怪物的特殊属性(special项)与该文件下面的getSpecialText对应。
|
||||
|
||||
!> V2.0版本可以直接在“图块属性”一栏进行修改怪物属性!
|
||||
|
||||

|
||||
|
||||
只需要修改自己用到的怪物属性即可,其他没有用到的怪物完全无所谓。
|
||||
@ -177,7 +195,7 @@
|
||||
|
||||
1. 截图请务必刚好截取13x13的图片,并需要保证每个位置必须为32x32像素。一般无放缩的RMXP符合条件。
|
||||
2. 游戏的唯一标识符name请务必修改。如果不修改可能会导致存档出现异常。
|
||||
3. 别忘了main.js中要修改floorIds指明所用到的所有楼层哦~
|
||||
3. 别忘了data.js中要修改floorIds指明所用到的所有楼层哦~
|
||||
|
||||
下面是几个常见的FAQ:
|
||||
|
||||
|
||||
699
drawMapGUI.html
@ -1,698 +1 @@
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<link href="_server/css/editor.css" rel="stylesheet">
|
||||
</head>
|
||||
<body>
|
||||
<div class="main">
|
||||
<div id="left">
|
||||
<div id="arrEditor">
|
||||
<table class="col" id='arrColMark'></table>
|
||||
<table class="row" id='arrRowMark'></table>
|
||||
<div id="editArea" v-cloak>
|
||||
<textarea cols="10" rows="10" id="pout" v-model="mapArr"></textarea>
|
||||
<p class="warnText" v-if="error">{{ errors[error-1] }}</p>
|
||||
</div>
|
||||
<div id="editTip" v-cloak>
|
||||
<input class='btn' type="button" value="复制地图" v-on:click="copyMap"/>
|
||||
</div>
|
||||
</div>
|
||||
<div id="objDataEditor">
|
||||
|
||||
</div>
|
||||
<div id="eventEditor">
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div id="mid">
|
||||
<table class="col" id='mapColMark'></table>
|
||||
<table class="row" id='mapRowMark'></table>
|
||||
<div class="map" id="mapEdit">
|
||||
<canvas class='gameCanvas' id='bg' width='416' height='416' style='z-index:1'></canvas>
|
||||
<canvas class='gameCanvas' id='eventLayer' width='416' height='416' style='z-index:2'></canvas>
|
||||
<canvas class='gameCanvas' id='ui' width='416' height='416' style='z-index:100'></canvas>
|
||||
</div>
|
||||
<div class="tools">
|
||||
<div id="tip" v-cloak >
|
||||
<div v-if="isSelectedBlock" >
|
||||
<p v-if="isClearBlock" class="infoText">当前选择为清除块,可擦除地图上块</p>
|
||||
<div v-else>
|
||||
<p v-if="hasId">图块编号:<span class="infoText">{{ infos['idnum'] }}</span></p>
|
||||
<p v-if="hasId">图块ID:<span class="infoText">{{ infos['id'] }}</span></p>
|
||||
<p v-else class="warnText">该图块无对应的数字或ID存在,请先前往icons.js和maps.js中进行定义!</p>
|
||||
<p>图块所在素材:<span class="infoText">{{ infos['images'] + (isAutotile ? '( '+infos['id']+' )' : '') }}</span></p>
|
||||
<p>图块索引:<span class="infoText">{{ infos['y'] }}</span></p>
|
||||
</div>
|
||||
</div>
|
||||
<div v-else>
|
||||
<p v-if="whichShow" v-bind:class="[ (whichShow%2) ? 'warnText' : 'successText']">{{ mapMsg }}</p>
|
||||
</div>
|
||||
</div>
|
||||
<input class='btn' id='clear' type="button" value="清除地图" v-on:click="clearMap"/>
|
||||
<input class='btn' type="button" value="导出地图" id="exportM" v-on:click="exportMap"/>
|
||||
|
||||
<div id="bgSelect" v-cloak>
|
||||
<span>当前地板: </span>
|
||||
<select v-model="selectedBg">
|
||||
<option disabled value="">请选择地板</option>
|
||||
<option v-for="bg in bgs" v-bind:value="bg">
|
||||
{{ bg }}
|
||||
</option>
|
||||
</select>
|
||||
<div class="selectpng">
|
||||
<input class='input' id='pin' v-model="imgname" placeholder="请输入自定义背景文件名"/>
|
||||
<input class='btn' type="button" value="确定" v-on:click="updatebg"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="right">
|
||||
<div id="iconLib">
|
||||
<canvas class='gameCanvas' id='data' width='416' height='416' style='z-index:0'></canvas>
|
||||
<div id="selectBox">
|
||||
<div id='dataSelection' v-show="isSelected" v-cloak></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
// 生成定位编号
|
||||
(function(){
|
||||
var colNum = ' ';
|
||||
for(var i=0; i<13; i++){
|
||||
var tpl = '<td>'+i+'<div class="colBlock" style="left:'+(i*32+1)+'px;"></div></td>';
|
||||
colNum += tpl;
|
||||
}
|
||||
arrColMark.innerHTML = '<tr>'+colNum+'</tr>';
|
||||
mapColMark.innerHTML = '<tr>'+colNum+'</tr>';
|
||||
var rowNum = ' ';
|
||||
for(var i=0; i<13; i++){
|
||||
var tpl = '<tr><td>'+i+'<div class="rowBlock" style="top:'+(i*32+1)+'px;"></div></td></tr>';
|
||||
rowNum += tpl;
|
||||
}
|
||||
arrRowMark.innerHTML = rowNum;
|
||||
mapRowMark.innerHTML = rowNum;
|
||||
})();
|
||||
</script>
|
||||
|
||||
<!-- =========================================================== -->
|
||||
|
||||
<script src='_server/vendor/vue.min.js'></script>
|
||||
<script src='_server/vendor/polyfill.min.js'></script>
|
||||
<!-- <script src="https://cdn.bootcss.com/vue/2.5.13/vue.js"></script> -->
|
||||
<script src='_server/fs.js'></script>
|
||||
<!-- <script src='_server/editor_file.js'></script> -->
|
||||
<script src='_server/vm.js'></script>
|
||||
<script>
|
||||
|
||||
//所有全局量
|
||||
__all__=['Vue','fs','printf','editor','main','core'];
|
||||
__id__=['printOut','arrRowMark','mapRowMark','data','bg','dataSelection'];
|
||||
__Vue__=['exportM','editArea','editTip','clear','tip','selectBox'];
|
||||
|
||||
var hasOwnProperty = Object.prototype.hasOwnProperty;
|
||||
function hasOwnProp (obj, key) {
|
||||
return hasOwnProperty.call(obj, key)
|
||||
}
|
||||
|
||||
var main={'instance':{}};
|
||||
var core={};
|
||||
|
||||
function editor() {
|
||||
this.version = "1.3.2";
|
||||
this.material = {};
|
||||
}
|
||||
// 重构这一堆回调
|
||||
editor.prototype.init = function(){
|
||||
var mapsjsUrl = 'libs/maps.js';
|
||||
var iconsjsUrl = 'libs/icons.js';
|
||||
|
||||
var p1 = editor.loadjs(mapsjsUrl).then(function(){ // 加载maps.js
|
||||
return new maps(); //实例化maps
|
||||
});
|
||||
var p2 = editor.loadjs(iconsjsUrl) // 加载icons.js
|
||||
.then(function(){ // 实例化并获取icons
|
||||
var ic = new icons();
|
||||
ic.init();
|
||||
return ic.getIcons();
|
||||
});
|
||||
var p3 = p2.then(function(icons){ // 加载所有图片
|
||||
return editor.loadAllImgs(icons);
|
||||
})
|
||||
.catch(function(err){
|
||||
console.log('发生错误!', err);
|
||||
});
|
||||
|
||||
Promise.all([p1, p2, p3])
|
||||
.then(function(results){
|
||||
var maps = results[0], icons = results[1];
|
||||
editor.idsInit(maps, icons); // 初始化图片素材信息
|
||||
editor.drawInitData(icons); // 初始化绘图
|
||||
editor.listen(); // 开始监听事件
|
||||
})
|
||||
}
|
||||
|
||||
editor.prototype.loadjs = function(url){
|
||||
return new Promise(function(resolve, reject){
|
||||
var script = document.createElement('script');
|
||||
script.src = url + '?' + editor.version;
|
||||
document.body.appendChild(script);
|
||||
script.onload = function () {
|
||||
resolve( console.log(url+"加载完成"));
|
||||
}
|
||||
script.onerror = function(){
|
||||
reject(new Error('Load js error at '+url))
|
||||
}
|
||||
});
|
||||
}
|
||||
editor.prototype.loadImg = function(url){
|
||||
return new Promise(function(resolve, reject){
|
||||
var img = new Image();
|
||||
img.src = url;
|
||||
img.onload = function(){
|
||||
resolve(img);
|
||||
}
|
||||
img.onerror = function(){
|
||||
reject(new Error('Load image error at '+url));
|
||||
}
|
||||
})
|
||||
}
|
||||
editor.prototype.loadAllImgs = function(icons){
|
||||
editor.material.images = {};
|
||||
var imgs = Object.keys(icons);
|
||||
var autotiles = null;
|
||||
if(hasOwnProp(icons, 'hero')){ // hero 图片不加载
|
||||
var index = imgs.indexOf('hero');
|
||||
imgs.splice(index, 1);
|
||||
}
|
||||
if(hasOwnProp(icons, 'autotile')){
|
||||
editor.material.images['autotile'] = {};
|
||||
var index = imgs.indexOf('autotile');
|
||||
imgs.splice(index, 1);
|
||||
autotiles = Object.keys(icons.autotile);
|
||||
imgs = imgs.concat(autotiles);
|
||||
}
|
||||
var p = imgs.map(function(im){
|
||||
var url = 'images/'+im+'.png'
|
||||
return editor.loadImg(url).then(function(image){
|
||||
if(autotiles.indexOf(im) >= 0){
|
||||
editor.material.images['autotile'][im] = image;
|
||||
}else editor.material.images[im] = image;
|
||||
}).catch(function(err){
|
||||
console.log('发生错误!', err);
|
||||
});
|
||||
});
|
||||
|
||||
return Promise.all(p);
|
||||
}
|
||||
editor.prototype.idsInit = function(maps, icons){
|
||||
editor.ids = [0];
|
||||
editor.indexs = [];
|
||||
var MAX_NUM = 400;
|
||||
var getInfoById = function(id){
|
||||
var block = maps.getBlock(0, 0, id);
|
||||
if(hasOwnProp(block, 'event')){
|
||||
return block;
|
||||
}
|
||||
}
|
||||
var point = 0;
|
||||
for(var i=0; i<MAX_NUM; i++){
|
||||
var indexBlock = getInfoById(i);
|
||||
editor.indexs[i] = [];
|
||||
if(indexBlock){
|
||||
var id = indexBlock.event.id;
|
||||
var indexId = indexBlock.id;
|
||||
var allCls = Object.keys(icons);
|
||||
for(var j=0; j<allCls.length; j++){
|
||||
if(id in icons[allCls[j]] ){
|
||||
editor.ids.push({'idnum':indexId,'id':id,'images':allCls[j],'y':icons[allCls[j]][id]});
|
||||
point++;
|
||||
editor.indexs[i].push(point);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
editor.prototype.drawInitData = function (icons) {
|
||||
var ratio=1;
|
||||
var images=editor.material.images;
|
||||
var maxHeight=700;
|
||||
var sumWidth=0;
|
||||
editor.widthsX={};
|
||||
// var imgNames = Object.keys(images); //还是固定顺序吧;
|
||||
var imgNames = ["terrains", "animates", "enemys", "items", "npcs", "autotile"];
|
||||
|
||||
for(var ii=0; ii<imgNames.length; ii++){
|
||||
var img=imgNames[ii], tempy = 0;
|
||||
if(img == 'autotile'){
|
||||
var autotiles = images[img];
|
||||
for(var im in autotiles){
|
||||
tempy += autotiles[im].height;
|
||||
}
|
||||
editor.widthsX[img]=[img, sumWidth/32, (sumWidth+3*32)/32, tempy];
|
||||
sumWidth += 3*32;
|
||||
maxHeight = Math.max(maxHeight, tempy);
|
||||
continue;
|
||||
}
|
||||
if(img == 'terrains'){
|
||||
editor.widthsX[img]=[img, sumWidth/32, (sumWidth+images[img].width)/32, images[img].height+32]
|
||||
sumWidth += images[img].width;
|
||||
maxHeight = Math.max(maxHeight, images[img].height+32);
|
||||
continue;
|
||||
}
|
||||
editor.widthsX[img]=[img, sumWidth/32, (sumWidth+images[img].width)/32, images[img].height];
|
||||
sumWidth += images[img].width;
|
||||
maxHeight = Math.max(maxHeight, images[img].height);
|
||||
}
|
||||
var fullWidth=~~(sumWidth*ratio);
|
||||
var fullHeight=~~(maxHeight*ratio);
|
||||
|
||||
if (fullWidth > data.width) data.style.width = (data.width = fullWidth)/ratio + 'px';
|
||||
data.style.height = (data.height = fullHeight)/ratio + 'px';
|
||||
var dc = data.getContext('2d');
|
||||
var nowx = 0;
|
||||
var nowy = 0;
|
||||
for(var ii=0; ii<imgNames.length; ii++){
|
||||
var img=imgNames[ii];
|
||||
if(img == 'terrains'){
|
||||
dc.drawImage(images[img], nowx, 32);
|
||||
nowx += images[img].width;
|
||||
continue;
|
||||
}
|
||||
if(img == 'autotile'){
|
||||
var autotiles = images[img];
|
||||
for(var im in autotiles){
|
||||
dc.drawImage(autotiles[im], nowx, nowy);
|
||||
nowy += autotiles[im].height;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
dc.drawImage(images[img], nowx, 0)
|
||||
nowx += images[img].width;
|
||||
}
|
||||
bgSelect.bgs = Object.keys(icons.terrains);
|
||||
editor.drawMapBg();
|
||||
editor.mapInit();
|
||||
}
|
||||
editor.prototype.mapInit = function(){
|
||||
var ec = eventLayer.getContext('2d');
|
||||
ec.clearRect(0, 0, 416, 416);
|
||||
editor.map = [];
|
||||
for(var y=0; y<13; y++){
|
||||
editor.map[y] = [];
|
||||
for(var x = 0; x<13; x++){
|
||||
editor.map[y][x] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
editor.prototype.drawMapBg = function(img){
|
||||
var bgc = bg.getContext('2d');
|
||||
|
||||
for (var ii = 0; ii < 13; ii++)
|
||||
for (var jj = 0; jj < 13; jj++) {
|
||||
bgc.clearRect(ii*32, jj*32, 32, 32);
|
||||
bgc.drawImage(editor.material.images['terrains'], 0, 32*(editor.bgY||0), 32, 32, ii*32, jj*32, 32, 32);
|
||||
}
|
||||
if(img){
|
||||
bgc.drawImage(img, 0, 0, 416, 416);
|
||||
}
|
||||
}
|
||||
editor.prototype.updateMap = function(){
|
||||
|
||||
var drawTile = function(ctx, x, y, tileInfo){ // 绘制一个普通块
|
||||
|
||||
ctx.clearRect(x*32, y*32, 32, 32);
|
||||
if(tileInfo == 0) return;
|
||||
|
||||
if(typeof(tileInfo) == typeof([][0]) || !hasOwnProp(tileInfo, 'idnum')) {//未定义块画红块
|
||||
if(typeof(tileInfo) != typeof([][0]) && hasOwnProp(tileInfo, 'images')){
|
||||
ctx.drawImage(editor.material.images[tileInfo.images], 0, tileInfo.y*32, 32, 32, x*32, y*32, 32, 32);
|
||||
}
|
||||
ctx.strokeStyle = 'red';
|
||||
var OFFSET = 2;
|
||||
ctx.lineWidth = OFFSET;
|
||||
ctx.strokeRect(x*32+OFFSET, y*32+OFFSET, 32-OFFSET*2, 32-OFFSET*2);
|
||||
ctx.font = "30px Verdana";
|
||||
ctx.textAlign = 'center'
|
||||
ctx.fillStyle = 'red';
|
||||
ctx.fillText("?", x*32+16, y*32+27);
|
||||
return;
|
||||
}
|
||||
ctx.drawImage(editor.material.images[tileInfo.images], 0, tileInfo.y*32, 32, 32, x*32, y*32, 32, 32);
|
||||
}
|
||||
|
||||
// autotile的相关处理
|
||||
var indexArrs = [ //16种组合的图块索引数组; // 将autotile分割成48块16*16的小块; 数组索引即对应各个小块
|
||||
// +----+----+----+----+----+----+
|
||||
[10, 9, 4, 3 ], //0 bin:0000 | 1 | 2 | 3 | 4 | 5 | 6 |
|
||||
[10, 9, 4, 13], //1 bin:0001 +----+----+----+----+----+----+
|
||||
[10, 9, 18, 3 ], //2 bin:0010 | 7 | 8 | 9 | 10 | 11 | 12 |
|
||||
[10, 9, 16, 15], //3 bin:0011 +----+----+----+----+----+----+
|
||||
[10, 43, 4, 3 ], //4 bin:0100 | 13 | 14 | 15 | 16 | 17 | 18 |
|
||||
[10, 31, 4, 25], //5 bin:0101 +----+----+----+----+----+----+
|
||||
[10, 7, 2, 3 ], //6 bin:0110 | 19 | 20 | 21 | 22 | 23 | 24 |
|
||||
[10, 31, 16, 5 ], //7 bin:0111 +----+----+----+----+----+----+
|
||||
[48, 9, 4, 3 ], //8 bin:1000 | 25 | 26 | 27 | 28 | 29 | 30 |
|
||||
[ 8, 9, 4, 1 ], //9 bin:1001 +----+----+----+----+----+----+
|
||||
[36, 9, 30, 3 ], //10 bin:1010 | 31 | 32 | 33 | 34 | 35 | 36 |
|
||||
[36, 9, 6, 15], //11 bin:1011 +----+----+----+----+----+----+
|
||||
[46, 45, 4, 3 ], //12 bin:1100 | 37 | 38 | 39 | 40 | 41 | 42 |
|
||||
[46, 11, 4, 25], //13 bin:1101 +----+----+----+----+----+----+
|
||||
[12, 45, 30, 3 ], //14 bin:1110 | 43 | 44 | 45 | 46 | 47 | 48 |
|
||||
[34, 33, 28, 27] //15 bin:1111 +----+----+----+----+----+----+
|
||||
];
|
||||
var drawBlockByIndex = function(ctx, dx, dy, autotileImg, index){ //index为autotile的图块索引1-48
|
||||
var sx = 16*((index-1)%6), sy = 16*(~~((index-1)/6));
|
||||
ctx.drawImage(autotileImg, sx, sy, 16, 16, dx, dy, 16, 16);
|
||||
}
|
||||
var isAutotile = function(info){
|
||||
if(typeof(info)=='object' && hasOwnProp(info, 'images') && info.images=='autotile') return true;
|
||||
return false;
|
||||
}
|
||||
var getAutotileAroundId = function(currId, x, y){ //与autotile当前idnum一致返回1,否则返回0
|
||||
if(x>=0 && y >=0 && x<13 && y<13 && isAutotile(editor.map[y][x]) && editor.map[y][x].idnum == currId)
|
||||
return 1;
|
||||
else if(x<0 || y<0 || x>12 || y>12) return 1; //边界外视为通用autotile,这样好看些
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
var checkAround = function(x, y){ // 得到周围四个32*32块(周围每块都包含当前块的1/4,不清楚的话画下图你就明白)的数组索引
|
||||
var currId = editor.map[y][x].idnum;
|
||||
var pointBlock = [];
|
||||
for(var i=0; i<4; i++){
|
||||
var bsum = 0;
|
||||
var offsetx = i%2, offsety = ~~(i/2);
|
||||
for(var j=0; j<4; j++){
|
||||
var mx = j%2, my = ~~(j/2);
|
||||
var b = getAutotileAroundId(currId, x+offsetx+mx-1, y+offsety+my-1);
|
||||
bsum += b*(Math.pow(2, 3-j));
|
||||
}
|
||||
pointBlock.push(bsum);
|
||||
}
|
||||
return pointBlock;
|
||||
}
|
||||
var addIndexToAutotileInfo = function(x, y){
|
||||
var indexArr = [];
|
||||
var pointBlocks = checkAround(x, y);
|
||||
for(var i=0; i<4; i++){
|
||||
var arr = indexArrs[pointBlocks[i]]
|
||||
indexArr.push(arr[3-i]);
|
||||
}
|
||||
editor.map[y][x].blockIndex = indexArr;
|
||||
}
|
||||
var drawAutotile = function(ctx, x, y, info){ // 绘制一个autotile
|
||||
ctx.clearRect(x*32, y*32, 32, 32);
|
||||
//修正四个边角的固定搭配
|
||||
if(info.blockIndex[0] == 13){
|
||||
if(info.blockIndex[1] == 16) info.blockIndex[1] = 14;
|
||||
if(info.blockIndex[2] == 31) info.blockIndex[2] = 19;
|
||||
}
|
||||
if(info.blockIndex[1] == 18){
|
||||
if(info.blockIndex[0] == 15) info.blockIndex[0] = 17;
|
||||
if(info.blockIndex[3] == 36) info.blockIndex[3] = 24;
|
||||
}
|
||||
if(info.blockIndex[2] == 43){
|
||||
if(info.blockIndex[0] == 25) info.blockIndex[0] = 37;
|
||||
if(info.blockIndex[3] == 46) info.blockIndex[3] = 44;
|
||||
}
|
||||
if(info.blockIndex[3] == 48){
|
||||
if(info.blockIndex[1] == 30) info.blockIndex[1] = 42;
|
||||
if(info.blockIndex[2] == 45) info.blockIndex[2] = 47;
|
||||
}
|
||||
for(var i=0; i<4; i++){
|
||||
var index = info.blockIndex[i];
|
||||
var dx = x*32 + 16*(i%2), dy = y*32 + 16*(~~(i/2));
|
||||
drawBlockByIndex(ctx, dx, dy, editor.material.images[info.images][info.id], index);
|
||||
}
|
||||
}
|
||||
|
||||
// 绘制地图 start
|
||||
var eventCtx = eventLayer.getContext("2d");
|
||||
for(var y=0; y<13; y++)
|
||||
for(var x=0; x<13; x++){
|
||||
var tileInfo = editor.map[y][x];
|
||||
if(isAutotile(tileInfo)){
|
||||
addIndexToAutotileInfo(x, y);
|
||||
drawAutotile(eventCtx, x, y, tileInfo);
|
||||
}else drawTile(eventCtx, x, y, tileInfo);
|
||||
}
|
||||
// 绘制地图 end
|
||||
}
|
||||
editor.prototype.listen = function() {
|
||||
|
||||
var uc = ui.getContext('2d');
|
||||
|
||||
function fillPos(pos) {
|
||||
uc.fillStyle = '#' + ~~(Math.random() * 8) + ~~(Math.random() * 8) + ~~(Math.random() * 8);
|
||||
uc.fillRect(pos.x * 32 + 12, pos.y * 32 + 12, 8, 8);
|
||||
}//在格子内画一个随机色块
|
||||
|
||||
function eToLoc(e) {
|
||||
var scrollLeft = document.documentElement.scrollLeft || document.body.scrollLeft
|
||||
var scrollTop = document.documentElement.scrollTop || document.body.scrollTop
|
||||
editor.loc = {
|
||||
'x': scrollLeft+e.clientX - mid.offsetLeft-mapEdit.offsetLeft,
|
||||
'y': scrollTop+e.clientY - mid.offsetTop-mapEdit.offsetTop,
|
||||
'size': 32
|
||||
};
|
||||
return editor.loc; }//返回可用的组件内坐标
|
||||
|
||||
function locToPos(loc) {
|
||||
editor.pos = { 'x': ~~(loc.x / loc.size), 'y': ~~(loc.y / loc.size) }
|
||||
return editor.pos;
|
||||
}
|
||||
|
||||
var holdingPath = 0;
|
||||
var stepPostfix = null;//用于存放寻路检测的第一个点之后的后续移动
|
||||
|
||||
var mouseOutCheck = 2;
|
||||
function clear1() {
|
||||
if (mouseOutCheck > 1) {
|
||||
mouseOutCheck--;
|
||||
setTimeout(clear1, 1000);
|
||||
return;
|
||||
}
|
||||
holdingPath = 0;
|
||||
stepPostfix = [];
|
||||
uc.clearRect(0, 0, 416, 416);
|
||||
}//用于鼠标移出canvas时的自动清除状态
|
||||
|
||||
ui.onmousedown = function (e) {
|
||||
if(!selectBox.isSelected) {
|
||||
tip.whichShow = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
holdingPath = 1;
|
||||
mouseOutCheck = 2;
|
||||
setTimeout(clear1);
|
||||
e.stopPropagation();
|
||||
uc.clearRect(0, 0, 416, 416);
|
||||
var loc = eToLoc(e);
|
||||
var pos = locToPos(loc)
|
||||
stepPostfix = [];
|
||||
stepPostfix.push(pos);
|
||||
fillPos(pos);
|
||||
}
|
||||
|
||||
ui.onmousemove = function (e) {
|
||||
if(!selectBox.isSelected) {
|
||||
// tip.whichShow = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
if (holdingPath == 0) { return; }
|
||||
mouseOutCheck = 2;
|
||||
e.stopPropagation();
|
||||
var loc = eToLoc(e);
|
||||
var pos = locToPos(loc);
|
||||
var pos0 = stepPostfix[stepPostfix.length - 1]
|
||||
var directionDistance = [pos.y - pos0.y, pos0.x - pos.x, pos0.y - pos.y, pos.x - pos0.x]
|
||||
var max = 0, index = 4;
|
||||
for (var i = 0; i < 4; i++) {
|
||||
if (directionDistance[i] > max) {
|
||||
index = i;
|
||||
max = directionDistance[i];
|
||||
}
|
||||
}
|
||||
var pos = [{ 'x': 0, 'y': 1 }, { 'x': -1, 'y': 0 }, { 'x': 0, 'y': -1 }, { 'x': 1, 'y': 0 }, false][index]
|
||||
if (pos) {
|
||||
pos.x += pos0.x;
|
||||
pos.y += pos0.y;
|
||||
stepPostfix.push(pos);
|
||||
fillPos(pos);
|
||||
}
|
||||
}
|
||||
|
||||
ui.onmouseup = function (e) {
|
||||
if(!selectBox.isSelected) {
|
||||
tip.whichShow = 1;
|
||||
return;
|
||||
}
|
||||
holdingPath = 0;
|
||||
e.stopPropagation();
|
||||
var loc = eToLoc(e);
|
||||
if (stepPostfix.length) {
|
||||
preMapData = JSON.parse(JSON.stringify(editor.map));
|
||||
currDrawData.pos = JSON.parse(JSON.stringify(stepPostfix));
|
||||
currDrawData.info = JSON.parse(JSON.stringify(editor.info));
|
||||
reDo = null;
|
||||
// console.log(stepPostfix);
|
||||
for (var ii = 0; ii < stepPostfix.length; ii++)
|
||||
editor.map[stepPostfix[ii].y][stepPostfix[ii].x] = editor.info;
|
||||
// console.log(editor.map);
|
||||
editor.updateMap();
|
||||
holdingPath = 0;
|
||||
stepPostfix = [];
|
||||
uc.clearRect(0, 0, 416, 416);
|
||||
}
|
||||
}
|
||||
|
||||
var preMapData = {};
|
||||
var currDrawData = {
|
||||
pos: [],
|
||||
info: {}
|
||||
};
|
||||
var reDo = null;
|
||||
document.body.onkeydown = function(e) {
|
||||
// 禁止快捷键的默认行为
|
||||
if( e.ctrlKey && ( e.keyCode == 90 || e.keyCode == 89 ) )
|
||||
e.preventDefault();
|
||||
//Ctrl+z 撤销上一步undo
|
||||
if(e.keyCode == 90 && e.ctrlKey && preMapData && currDrawData.pos.length){
|
||||
editor.map = JSON.parse(JSON.stringify(preMapData));
|
||||
editor.updateMap();
|
||||
reDo = JSON.parse(JSON.stringify(currDrawData));
|
||||
currDrawData = {pos: [],info: {}};
|
||||
preMapData = null;
|
||||
}
|
||||
//Ctrl+y 重做一步redo
|
||||
if(e.keyCode == 89 && e.ctrlKey && reDo && reDo.pos.length){
|
||||
preMapData = JSON.parse(JSON.stringify(editor.map));
|
||||
for(var j=0; j<reDo.pos.length;j++)
|
||||
editor.map[reDo.pos[j].y][reDo.pos[j].x] = JSON.parse(JSON.stringify(reDo.info));
|
||||
|
||||
editor.updateMap();
|
||||
currDrawData = JSON.parse(JSON.stringify(reDo));
|
||||
reDo = null;
|
||||
}
|
||||
}
|
||||
|
||||
data.onmousedown = function (e) {
|
||||
e.stopPropagation();
|
||||
var scrollLeft = document.documentElement.scrollLeft || document.body.scrollLeft
|
||||
var scrollTop = document.documentElement.scrollTop || document.body.scrollTop
|
||||
var loc = {
|
||||
'x': scrollLeft + e.clientX + iconLib.scrollLeft - right.offsetLeft-iconLib.offsetLeft,
|
||||
'y': scrollTop + e.clientY + iconLib.scrollTop - right.offsetTop-iconLib.offsetTop,
|
||||
'size': 32
|
||||
};
|
||||
editor.loc = loc;
|
||||
var pos = locToPos(loc);
|
||||
for (var spriter in editor.widthsX){
|
||||
if(pos.x>=editor.widthsX[spriter][1] && pos.x<editor.widthsX[spriter][2]){
|
||||
pos.x=editor.widthsX[spriter][1];
|
||||
pos.images = editor.widthsX[spriter][0];
|
||||
var autotiles = editor.material.images['autotile'];
|
||||
if(pos.images=='autotile'){
|
||||
var imNames = Object.keys(autotiles);
|
||||
if((pos.y+1)*32 > editor.widthsX[spriter][3])
|
||||
pos.y = ~~(editor.widthsX[spriter][3]/32)-4;
|
||||
else{
|
||||
for(var i=0; i<imNames.length; i++){
|
||||
if(pos.y >= 4*i && pos.y < 4*(i+1)){
|
||||
pos.images = imNames[i];
|
||||
pos.y = 4*i;
|
||||
}
|
||||
}
|
||||
}
|
||||
}else if((pos.y+1)*32 > editor.widthsX[spriter][3])
|
||||
pos.y = ~~(editor.widthsX[spriter][3]/32)-1;
|
||||
|
||||
selectBox.isSelected = true;
|
||||
// console.log(pos,editor.material.images[pos.images].height)
|
||||
dataSelection.style.left = pos.x*32 +'px';
|
||||
dataSelection.style.top = pos.y*32 +'px';
|
||||
|
||||
if(pos.x==0&&pos.y==0){
|
||||
// editor.info={idnum:0, id:'empty','images':'清除块', 'y':0};
|
||||
editor.info=0;
|
||||
}else{
|
||||
if(hasOwnProp(autotiles, pos.images)) editor.info={'images':pos.images, 'y':0};
|
||||
else if(pos.images == 'terrains') editor.info={'images':pos.images, 'y':pos.y-1};
|
||||
else editor.info={'images':pos.images, 'y':pos.y};
|
||||
|
||||
for (var ii=0;ii<editor.ids.length;ii++){
|
||||
if( ( editor.info.images==editor.ids[ii].images
|
||||
&& editor.info.y==editor.ids[ii].y )
|
||||
|| (hasOwnProp(autotiles, pos.images) && editor.info.images==editor.ids[ii].id
|
||||
&& editor.info.y==editor.ids[ii].y)){
|
||||
|
||||
editor.info = editor.ids[ii];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
tip.infos = JSON.parse(JSON.stringify(editor.info));
|
||||
}
|
||||
}
|
||||
}
|
||||
document.body.onmousedown = function(e){
|
||||
selectBox.isSelected = false;
|
||||
editor.info = {};
|
||||
}
|
||||
iconLib.onmousedown = function(e){
|
||||
e.stopPropagation();
|
||||
}
|
||||
}//绑定事件
|
||||
editor.prototype.locInfo = function(){
|
||||
|
||||
}
|
||||
/*
|
||||
editor.updateMap
|
||||
|
||||
editor.loc
|
||||
editor.pos
|
||||
editor.info
|
||||
始终是最后一次点击的结果
|
||||
注意editor.info可能因为点击其他地方而被清空
|
||||
*/
|
||||
var editor = new editor();
|
||||
editor.init();
|
||||
editor.fs=fs;
|
||||
// editor.file=editor_file;
|
||||
</script>
|
||||
<script>
|
||||
// 文件相关操作
|
||||
// var promisify = function (fn, receiver) {
|
||||
// return function () {
|
||||
// for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
|
||||
// args[_key] = arguments[_key];
|
||||
// }
|
||||
// return new Promise(function (resolve, reject) {
|
||||
// fn.apply(receiver, [].concat(args, [function (res, err) {
|
||||
// return err ? reject(err) : resolve(res);
|
||||
// }]));
|
||||
// });
|
||||
// };
|
||||
// };
|
||||
// var fns = Object.keys(editor.file);
|
||||
// var promiseFns = {};
|
||||
// fns.forEach(function(fn){
|
||||
// promiseFns[fn] = promisify(editor.file[fn], editor.file)
|
||||
// });
|
||||
// editor.promiseFiles = Object.assign(promiseFns);
|
||||
|
||||
// editor.promiseFiles.getFloorFileList(editor)
|
||||
// .then(function(filelist){
|
||||
// editFile4map.filelist = filelist;
|
||||
// })
|
||||
// .catch(function(err){
|
||||
// console.log(err);
|
||||
// })
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
<html><body><script>window.location='editor.html'</script></body></html>
|
||||
392
editor.html
Normal file
@ -0,0 +1,392 @@
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<link href="_server/css/editor.css" rel="stylesheet">
|
||||
<link href="_server/CodeMirror/codemirror.css" rel="stylesheet">
|
||||
<link href="_server/css/editor_mode.css" rel="stylesheet">
|
||||
</head>
|
||||
<body>
|
||||
<div class="main">
|
||||
<div id="left" style="z-index:-1;opacity: 0;"><!-- map -->
|
||||
<div id="arrEditor">
|
||||
<table class="col" id='arrColMark'></table>
|
||||
<table class="row" id='arrRowMark'></table>
|
||||
<div id="editArea" v-cloak>
|
||||
<textarea cols="10" rows="10" id="pout" v-model="mapArr"></textarea>
|
||||
<p class="warnText" v-if="error">{{ errors[error-1] }}</p>
|
||||
</div>
|
||||
<div id="editTip" v-cloak>
|
||||
<br>
|
||||
<input type="button" value="当前地图另存为" id='saveFloorAs'/>
|
||||
<input id='saveAsName' placeholder="输入新楼层id"/>
|
||||
<input class='btn' type="button" value="复制地图" v-on:click="copyMap"/>
|
||||
</div>
|
||||
<div style="position: absolute;right: 10px;bottom:70px;">
|
||||
<input class='btn' id='clear' type="button" value="清除地图" v-on:click="clearMap"/>
|
||||
<input class='btn' type="button" value="导出地图" id="exportM" v-on:click="exportMap"/>
|
||||
</div>
|
||||
</div>
|
||||
<div id="objDataEditor">
|
||||
|
||||
</div>
|
||||
<div id="eventEditor">
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div id="left1" class='leftTab' style="z-index:-1;opacity: 0;"><div ><!-- appendpic -->
|
||||
<h3>追加素材</h3>
|
||||
<p>
|
||||
<input id="selectFileBtn" type="button" value="导入文件到画板"/>
|
||||
<select id="selectAppend"></select><!-- ["terrains", "animates", "enemys", "enemy48", "items", "npcs", "npc48"] -->
|
||||
<input id="appendConfirm" type="button" value="追加"/>
|
||||
</p>
|
||||
<div id="appendPicCanvas" style="position:relative;overflow: auto;height:470px;">
|
||||
<canvas style="position:absolute"></canvas><!-- 用于画出灰白相间背景 -->
|
||||
<canvas style="position:absolute"></canvas><!-- 用于画出选中文件 -->
|
||||
<canvas style="position:absolute;z-index:100"></canvas><!-- 用于响应鼠标点击 -->
|
||||
<canvas style="position:absolute;display:none;"></canvas><!-- 画出追加后的sprite用于储存 -->
|
||||
<div id="appendPicSelection">
|
||||
<div class="appendSelection"><span style="top: 0; left: 2px;">1</span></div>
|
||||
<div class="appendSelection"><span style="top: 0; left: 14px;">2</span></div>
|
||||
<div class="appendSelection"><span style="top: 12px; left: 2px;">3</span></div>
|
||||
<div class="appendSelection"><span style="top: 12px; left: 14px;">4</span></div>
|
||||
</div>
|
||||
</div>
|
||||
</div></div>
|
||||
<div id="left2" class='leftTab' style="z-index:-1;opacity: 0;"><div><!-- loc -->
|
||||
<h3>地图选点 <button onclick="editor.mode.onmode('save')">save</button></h3>
|
||||
<p id='pos_a6771a78_a099_417c_828f_0a24851ebfce'>0,0</p>
|
||||
<div class='etable'>
|
||||
<table>
|
||||
<tbody id='table_3d846fc4_7644_44d1_aa04_433d266a73df'>
|
||||
<tr><td>条目</td><td>注释</td><td>值</td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div></div>
|
||||
<div id="left3" class='leftTab' style="z-index:-1;opacity: 0;"><div><!-- emenyitem -->
|
||||
<h3>图块属性 <button onclick="editor.mode.onmode('save')">save</button></h3>
|
||||
<div id='newIdIdnum'><!-- id and idnum -->
|
||||
<input placeholder="输入新id"/>
|
||||
<input placeholder="输入新idnum"/>
|
||||
<button>save</button>
|
||||
</div>
|
||||
<div><!-- enemy and item -->
|
||||
<div class='etable'>
|
||||
<table>
|
||||
<tbody id='table_a3f03d4c_55b8_4ef6_b362_b345783acd72'>
|
||||
<tr><td>条目</td><td>注释</td><td>值</td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div></div>
|
||||
<div id="left4" class='leftTab' style="z-index:-1;opacity: 0;"><div><!-- floor -->
|
||||
<h3>楼层属性 <button onclick="editor.mode.onmode('save')">save</button></h3>
|
||||
<div class='etable'>
|
||||
<table>
|
||||
<tbody id='table_4a3b1b09_b2fb_4bdf_b9ab_9f4cdac14c74'>
|
||||
<tr><td>条目</td><td>注释</td><td>值</td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div></div>
|
||||
<div id="left5" class='leftTab' style="z-index:-1;opacity: 0;"><div><!-- tower -->
|
||||
<h3>全塔属性 <button onclick="editor.mode.onmode('save')">save</button></h3>
|
||||
<div class='etable'>
|
||||
<table>
|
||||
<tbody id='table_b6a03e4c_5968_4633_ac40_0dfdd2c9cde5'>
|
||||
<tr><td>条目</td><td>注释</td><td>值</td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div></div>
|
||||
<div id="left6" class='leftTab' style="z-index:-1;opacity: 0;"><div><!-- eventsEditor -->
|
||||
<h3>事件编辑器
|
||||
<button onclick="editor_blockly.showXML()">Show XML</button>
|
||||
<button onclick="editor_blockly.runCode()">console.log(obj=code)</button>
|
||||
<select id="entryType" disabled="disabled">
|
||||
<option value="event">event</option>
|
||||
<option value="changeFloor">changeFloor</option>
|
||||
<option value="point">point</option>
|
||||
<option value="shop">shop</option>
|
||||
<option value="afterBattle">afterBattle</option>
|
||||
<option value="afterGetItem">afterGetItem</option>
|
||||
<option value="afterOpenDoor">afterOpenDoor</option>
|
||||
<option value="firstArrive">firstArrive</option>
|
||||
</select>
|
||||
<button onclick="editor_blockly.parse()">parse</button>
|
||||
<button onclick="editor_blockly.confirm()">confirm</button>
|
||||
<button onclick="editor_blockly.cancel()">cancel</button>
|
||||
<xml id="toolbox" style="display:none">
|
||||
<category name="entry"></category>
|
||||
<category name="statement"></category>
|
||||
<category name="value"></category>
|
||||
<category name="template"></category>
|
||||
</xml>
|
||||
</h3>
|
||||
<div style="position: relative;">
|
||||
<div id="blocklyDiv"></div>
|
||||
<textarea id="codeArea" spellcheck="false"></textarea>
|
||||
</div>
|
||||
</div></div>
|
||||
<div id="left7" style="z-index:-1;opacity: 0;"><div><!-- 多行文本编辑器 -->
|
||||
<button onclick="editor_multi.confirm()">confirm</button>
|
||||
<button onclick="editor_multi.cancel()">cancel</button>
|
||||
<textarea id="multiLineCode" name="multiLineCode"></textarea>
|
||||
</div></div>
|
||||
<div id="left8" class='leftTab' style="z-index:-1;opacity: 0;"><div><!-- functions -->
|
||||
<h3>脚本编辑 <button onclick="editor.mode.onmode('save')">save</button></h3>
|
||||
<div class='etable'>
|
||||
<table>
|
||||
<tbody id='table_e260a2be_5690_476a_b04e_dacddede78b3'>
|
||||
<tr><td>条目</td><td>注释</td><td>值</td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div></div>
|
||||
<div id="mid">
|
||||
<table class="col" id='mapColMark'></table>
|
||||
<table class="row" id='mapRowMark'></table>
|
||||
<div class="map" id="mapEdit">
|
||||
<canvas class='gameCanvas' id='bg' width='416' height='416'></canvas>
|
||||
<canvas class='gameCanvas' id='event' width='416' height='416'></canvas>
|
||||
<canvas class='gameCanvas' id='event2' width='416' height='416'></canvas>
|
||||
<canvas class='egameCanvas' id='eui' width='416' height='416' style='z-index:100'></canvas>
|
||||
</div>
|
||||
<div class="tools">
|
||||
<div id="tip" v-cloak >
|
||||
<div v-if="isSelectedBlock" >
|
||||
<p v-if="isClearBlock" class="infoText">当前选择为清除块,可擦除地图上块</p>
|
||||
<div v-else>
|
||||
<p v-if="hasId">图块编号:<span class="infoText">{{ infos['idnum'] }}</span></p>
|
||||
<p v-if="hasId">图块ID:<span class="infoText">{{ infos['id'] }}</span></p>
|
||||
<p v-else class="warnText">该图块无对应的数字或ID存在,请先前往icons.js和maps.js中进行定义!</p>
|
||||
<p>图块所在素材:<span class="infoText">{{ infos['images'] + (isAutotile ? '( '+infos['id']+' )' : '') }}</span></p>
|
||||
<p>图块索引:<span class="infoText">{{ infos['y'] }}</span></p>
|
||||
</div>
|
||||
</div>
|
||||
<div v-else>
|
||||
<p v-if="whichShow" v-bind:class="[ (whichShow%2) ? 'warnText' : 'successText']">{{ mapMsg }}</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<select id="editModeSelect">
|
||||
<option value="map">地图编辑</option>
|
||||
<option value="loc">地图选点</option>
|
||||
<option value="emenyitem">图块属性</option>
|
||||
<option value="floor">楼层属性</option>
|
||||
<option value="tower">全塔属性</option>
|
||||
<option value="functions">脚本编辑</option>
|
||||
<option value="appendpic">追加素材</option>
|
||||
</select>
|
||||
<br><br><br><br>
|
||||
<select id="selectFloor"></select>
|
||||
<input type="button" value="保存地图" id='saveFloor'/>
|
||||
<!-- -->
|
||||
<div id="bgSelect" v-cloak style="display:none">
|
||||
<span>当前地板: </span>
|
||||
<select v-model="selectedBg">
|
||||
<option disabled value="">请选择地板</option>
|
||||
<option v-for="bg in bgs" v-bind:value="bg">
|
||||
{{ bg }}
|
||||
</option>
|
||||
</select>
|
||||
<div class="selectpng">
|
||||
<input class='input' id='pin' v-model="imgname" placeholder="请输入自定义背景文件名"/>
|
||||
<input class='btn' type="button" value="确定" v-on:click="updatebg"/>
|
||||
</div>
|
||||
</div>
|
||||
<!-- -->
|
||||
</div>
|
||||
</div>
|
||||
<div id="right">
|
||||
<div id="iconLib">
|
||||
<canvas class='egameCanvas' id='edata' width='416' height='416' style='z-index:0'></canvas>
|
||||
<div id="selectBox">
|
||||
<div id='dataSelection' v-show="isSelected" v-cloak></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- <script>/* -->
|
||||
<div id='gameGroup' style='display:none'>
|
||||
<p id='mainTips'>请稍后...</p>
|
||||
<div id='startPanel'>
|
||||
<div id='startTop'>
|
||||
<div id='startTopProgressBar'>
|
||||
<div id='startTopProgress'></div>
|
||||
</div>
|
||||
<p id='startTopLoadTips'>资源即将开始加载</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>
|
||||
</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 src='project/images/floor.png' id="img-floor">
|
||||
<p class='statusLabel' id='floor'></p>
|
||||
</div>
|
||||
<div class="status" id="lvCol">
|
||||
<img src='project/images/lv.png' id="img-lv">
|
||||
<p class='statusLabel' id='lv'></p>
|
||||
</div>
|
||||
<div class="status" id='hpmaxCol'>
|
||||
<img src='project/images/hpmax.png' id="img-hpmax">
|
||||
<p class='statusLabel' id='hpmax'></p>
|
||||
</div>
|
||||
<div class="status">
|
||||
<img src='project/images/hp.png' id="img-hp">
|
||||
<p class='statusLabel' id='hp'></p>
|
||||
</div>
|
||||
<div class="status">
|
||||
<img src='project/images/atk.png' id="img-atk">
|
||||
<p class='statusLabel' id='atk'></p>
|
||||
</div>
|
||||
<div class="status">
|
||||
<img src='project/images/def.png' id="img-def">
|
||||
<p class='statusLabel' id='def'></p>
|
||||
</div>
|
||||
<div class="status" id="mdefCol">
|
||||
<img src='project/images/mdef.png' id="img-mdef">
|
||||
<p class='statusLabel' id='mdef'></p>
|
||||
</div>
|
||||
<div class="status" id="moneyCol">
|
||||
<img src='project/images/money.png' id="img-money">
|
||||
<p class='statusLabel' id='money'></p>
|
||||
</div>
|
||||
<div class="status" id="expCol">
|
||||
<img src='project/images/experience.png' id="img-experience">
|
||||
<p class='statusLabel' id='experience'></p>
|
||||
</div>
|
||||
<div class="status" id="upCol">
|
||||
<img src='project/images/up.png' id="img-up">
|
||||
<p class='statusLabel' id='up'></p>
|
||||
</div>
|
||||
<div class="status">
|
||||
<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>
|
||||
</div>
|
||||
<div class="status" id="debuffCol">
|
||||
<span class='statusLabel' id='poison' style="color: #AFFCA8;"></span>
|
||||
<span class='statusLabel' id='weak' style="color: #FECCD0;"></span>
|
||||
<span class='statusLabel' id='curse' style="color: #C2F4E7;"></span>
|
||||
</div>
|
||||
</div>
|
||||
<div id="toolBar" class="clearfix">
|
||||
<img src="project/images/book.png" class="tools" id='img-book'>
|
||||
<img src="project/images/fly.png" class="tools" id='img-fly'>
|
||||
<img src="project/images/toolbox.png" class="tools" id='img-toolbox'>
|
||||
<img src="project/images/shop.png" class="tools" id='img-shop'>
|
||||
<img src="project/images/save.png" class="tools" id='img-save'>
|
||||
<img src="project/images/load.png" class="tools" id='img-load'>
|
||||
<img src="project/images/settings.png" class="tools" id='img-settings'>
|
||||
<p class="statusLabel tools" id="hard"></p>
|
||||
</div>
|
||||
<div id="curtain"></div>
|
||||
<!-- <canvas class='gameCanvas' id='bg' width='416' height='416'></canvas> -->
|
||||
<!-- <canvas class='gameCanvas' id='event' width='416' height='416'></canvas> -->
|
||||
<canvas class='gameCanvas' id='hero' width='416' height='416'></canvas>
|
||||
<!-- <canvas class='gameCanvas' id='event2' width='416' height='416'></canvas> -->
|
||||
<canvas class='gameCanvas' id='fg' width='416' height='416'></canvas>
|
||||
<canvas class='gameCanvas' id='animate' width='416' height='416'></canvas>
|
||||
<canvas class='gameCanvas' id='weather' width='416' height='416'></canvas>
|
||||
<canvas class='gameCanvas' id='ui' width='416' height='416'></canvas>
|
||||
<canvas class='gameCanvas' id='data' width='416' height='416'>此浏览器不支持HTML5</canvas>
|
||||
</div>
|
||||
<!-- */</script> -->
|
||||
<script>
|
||||
// 生成定位编号
|
||||
(function(){
|
||||
var colNum = ' ';
|
||||
for(var i=0; i<13; i++){
|
||||
var tpl = '<td>'+i+'<div class="colBlock" style="left:'+(i*32+1)+'px;"></div></td>';
|
||||
colNum += tpl;
|
||||
}
|
||||
arrColMark.innerHTML = '<tr>'+colNum+'</tr>';
|
||||
mapColMark.innerHTML = '<tr>'+colNum+'</tr>';
|
||||
var rowNum = ' ';
|
||||
for(var i=0; i<13; i++){
|
||||
var tpl = '<tr><td>'+i+'<div class="rowBlock" style="top:'+(i*32+1)+'px;"></div></td></tr>';
|
||||
rowNum += tpl;
|
||||
}
|
||||
arrRowMark.innerHTML = rowNum;
|
||||
mapRowMark.innerHTML = rowNum;
|
||||
})();
|
||||
</script>
|
||||
|
||||
<!-- =========================================================== -->
|
||||
|
||||
<script src='_server/vendor/vue.min.js'></script>
|
||||
<!-- <script src="https://cdn.bootcss.com/vue/2.5.13/vue.js"></script> -->
|
||||
<script src='_server/vendor/polyfill.min.js'></script>
|
||||
<script src='_server/fs.js'></script>
|
||||
<script src='_server/editor_file.js'></script>
|
||||
<script src='_server/editor_mode.js'></script>
|
||||
<script src='_server/vm.js'></script>
|
||||
<script id='mainScript' src='main.js'></script>
|
||||
<script>
|
||||
//所有全局量
|
||||
__all__=['Vue','fs','editor_file','editor_mode','main','core','hasOwnProp','printf','printe','editor','converter','ActionParser','MotaActionFunctions','MotaActionBlocks'];
|
||||
__id__=['editArea','arrRowMark','mapRowMark','data','bg','dataSelection','blocklyDiv','codeAreaHL','entryType'];
|
||||
__Vue__=['exportM','editArea','editTip','clear','tip','selectBox'];
|
||||
//var event = document.getElementById('event');
|
||||
|
||||
var hasOwnProperty = Object.prototype.hasOwnProperty;
|
||||
function hasOwnProp (obj, key) {
|
||||
return hasOwnProperty.call(obj, key)
|
||||
}
|
||||
</script>
|
||||
<script src='_server/editor.js'></script>
|
||||
<script>
|
||||
main.init('editor', function() {
|
||||
editor.init(function(){
|
||||
editor.pos={x: 0, y: 0};
|
||||
editor.mode.loc();
|
||||
editor.info=editor.ids[editor.indexs[201]];
|
||||
editor.mode.emenyitem();
|
||||
editor.mode.floor();
|
||||
editor.mode.tower();
|
||||
editor.mode.functions();
|
||||
editor.mode.showMode('floor');
|
||||
editor.mode.listen();
|
||||
editor_multi=editor_multi();
|
||||
editor_blockly=editor_blockly();
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
|
||||
//main.listen();
|
||||
</script>
|
||||
|
||||
<!-- hightlight textarea -->
|
||||
<script src='_server/editor_multi.js'></script>
|
||||
<!-- blockly -->
|
||||
<script src="_server/blockly/Converter.bundle.min.js"></script>
|
||||
<script src="_server/blockly/blockly_compressed.js"></script>
|
||||
<script src="_server/blockly/blocks_compressed.js"></script>
|
||||
<script src="_server/blockly/javascript_compressed.js"></script>
|
||||
<script src="_server/blockly/zh-hans.js"></script>
|
||||
<script src='_server/editor_blockly.js'></script>
|
||||
<script src="_server/CodeMirror/codeMirror.bundle.min.js"></script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
Before Width: | Height: | Size: 20 KiB |
BIN
images/bg.png
|
Before Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 20 KiB |
|
Before Width: | Height: | Size: 55 KiB |
|
Before Width: | Height: | Size: 29 KiB |
51
index.html
@ -25,20 +25,15 @@
|
||||
</div>
|
||||
<p id='startTopLoadTips'>资源即将开始加载</p>
|
||||
</div>
|
||||
<img id='startBackground' src='images/bg.png'>
|
||||
<!-- 标题界面;可以改style的color使标题改变颜色 -->
|
||||
<p id='startLogo' style="color: black"></p>
|
||||
<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'>
|
||||
<span class='startButton' id='easyLevel'>简单</span>
|
||||
<span class='startButton' id='normalLevel'>普通</span>
|
||||
<span class='startButton' id='hardLevel'>困难</span>
|
||||
</div>
|
||||
<div id='levelChooseButtons'></div>
|
||||
</div>
|
||||
</div>
|
||||
<div id='floorMsgGroup'>
|
||||
@ -48,39 +43,43 @@
|
||||
</div>
|
||||
<div id='statusBar' class="clearfix">
|
||||
<div class="status" id="floorCol">
|
||||
<img src='images/floor.png' id="img-floor">
|
||||
<img src='project/images/floor.png' id="img-floor">
|
||||
<p class='statusLabel' id='floor'></p>
|
||||
</div>
|
||||
<div class="status" id="lvCol">
|
||||
<img src='images/lv.png' id="img-lv">
|
||||
<img src='project/images/lv.png' id="img-lv">
|
||||
<p class='statusLabel' id='lv'></p>
|
||||
</div>
|
||||
<div class="status" id='hpmaxCol'>
|
||||
<img src='project/images/hpmax.png' id="img-hpmax">
|
||||
<p class='statusLabel' id='hpmax'></p>
|
||||
</div>
|
||||
<div class="status">
|
||||
<img src='images/hp.png' id="img-hp">
|
||||
<img src='project/images/hp.png' id="img-hp">
|
||||
<p class='statusLabel' id='hp'></p>
|
||||
</div>
|
||||
<div class="status">
|
||||
<img src='images/atk.png' id="img-atk">
|
||||
<img src='project/images/atk.png' id="img-atk">
|
||||
<p class='statusLabel' id='atk'></p>
|
||||
</div>
|
||||
<div class="status">
|
||||
<img src='images/def.png' id="img-def">
|
||||
<img src='project/images/def.png' id="img-def">
|
||||
<p class='statusLabel' id='def'></p>
|
||||
</div>
|
||||
<div class="status" id="mdefCol">
|
||||
<img src='images/mdef.png' id="img-mdef">
|
||||
<img src='project/images/mdef.png' id="img-mdef">
|
||||
<p class='statusLabel' id='mdef'></p>
|
||||
</div>
|
||||
<div class="status" id="moneyCol">
|
||||
<img src='images/money.png' id="img-money">
|
||||
<img src='project/images/money.png' id="img-money">
|
||||
<p class='statusLabel' id='money'></p>
|
||||
</div>
|
||||
<div class="status" id="expCol">
|
||||
<img src='images/experience.png' id="img-experience">
|
||||
<img src='project/images/experience.png' id="img-experience">
|
||||
<p class='statusLabel' id='experience'></p>
|
||||
</div>
|
||||
<div class="status" id="upCol">
|
||||
<img src='images/up.png' id="img-up">
|
||||
<img src='project/images/up.png' id="img-up">
|
||||
<p class='statusLabel' id='up'></p>
|
||||
</div>
|
||||
<div class="status">
|
||||
@ -95,26 +94,28 @@
|
||||
</div>
|
||||
</div>
|
||||
<div id="toolBar" class="clearfix">
|
||||
<img src="images/book.png" class="tools" id='img-book'>
|
||||
<img src="images/fly.png" class="tools" id='img-fly'>
|
||||
<img src="images/toolbox.png" class="tools" id='img-toolbox'>
|
||||
<img src="images/shop.png" class="tools" id='img-shop'>
|
||||
<img src="images/save.png" class="tools" id='img-save'>
|
||||
<img src="images/load.png" class="tools" id='img-load'>
|
||||
<img src="images/settings.png" class="tools" id='img-settings'>
|
||||
<img src="project/images/book.png" class="tools" id='img-book'>
|
||||
<img src="project/images/fly.png" class="tools" id='img-fly'>
|
||||
<img src="project/images/toolbox.png" class="tools" id='img-toolbox'>
|
||||
<img src="project/images/shop.png" class="tools" id='img-shop'>
|
||||
<img src="project/images/save.png" class="tools" id='img-save'>
|
||||
<img src="project/images/load.png" class="tools" id='img-load'>
|
||||
<img src="project/images/settings.png" class="tools" id='img-settings'>
|
||||
<p class="statusLabel tools" id="hard"></p>
|
||||
</div>
|
||||
<div id="curtain"></div>
|
||||
<canvas class='gameCanvas' id='bg' width='416' height='416'></canvas>
|
||||
<canvas class='gameCanvas' id='event' width='416' height='416'></canvas>
|
||||
<canvas class='gameCanvas' id='fg' width='416' height='416'></canvas>
|
||||
<canvas class='gameCanvas' id='hero' width='416' height='416'></canvas>
|
||||
<canvas class='gameCanvas' id='event2' width='416' height='416'></canvas>
|
||||
<canvas class='gameCanvas' id='fg' width='416' height='416'></canvas>
|
||||
<canvas class='gameCanvas' id='animate' width='416' height='416'></canvas>
|
||||
<canvas class='gameCanvas' id='weather' width='416' height='416'></canvas>
|
||||
<canvas class='gameCanvas' id='ui' width='416' height='416'></canvas>
|
||||
<canvas class='gameCanvas' id='data' width='416' height='416'>此浏览器不支持HTML5</canvas>
|
||||
</div>
|
||||
<script id='mainScript' src='main.js'></script>
|
||||
<script>main.init();main.listen();</script>
|
||||
<script src='libs/thirdparty/mid.min.js'></script>
|
||||
</body>
|
||||
</html>
|
||||
1967
libs/actions.js
Normal file
2491
libs/control.js
Normal file
4921
libs/core.js
184
libs/data.js
@ -1,186 +1,14 @@
|
||||
function data() {
|
||||
|
||||
this.init();
|
||||
}
|
||||
|
||||
data.prototype.init = function() {
|
||||
this.firstData = {
|
||||
"title": "魔塔样板", // 游戏名,将显示在标题页面以及切换楼层的界面中
|
||||
"name": "template", // 游戏的唯一英文标识符。由英文、数字、下划线组成,不能超过20个字符。
|
||||
"version": "Ver 1.4.1", // 当前游戏版本;版本不一致的存档不能通用。
|
||||
"floorId": "sample0", // 初始楼层ID
|
||||
"hero": { // 勇士初始数据
|
||||
"name": "阳光", // 勇士名;可以改成喜欢的
|
||||
'lv': 1, // 初始等级,该项必须为正整数
|
||||
"hp": 1000, // 初始生命值
|
||||
"atk": 100, // 初始攻击
|
||||
"def": 100, // 初始防御
|
||||
"mdef": 100, // 初始魔防
|
||||
"money": 100, // 初始金币
|
||||
"experience": 0, // 初始经验
|
||||
"items": { // 初始道具个数
|
||||
"keys": {
|
||||
"yellowKey": 0,
|
||||
"blueKey": 0,
|
||||
"redKey": 0
|
||||
},
|
||||
"constants": {},
|
||||
"tools": {}
|
||||
},
|
||||
"flyRange": [], // 初始可飞的楼层;一般留空数组即可
|
||||
"loc": {"direction": "up", "x": 6, "y": 10}, // 勇士初始位置
|
||||
"flags": { // 游戏过程中的变量或flags
|
||||
"poison": false, // 毒
|
||||
"weak": false, // 衰
|
||||
"curse": false, // 咒
|
||||
},
|
||||
"steps": 0, // 行走步数统计
|
||||
},
|
||||
"startText": [ // 游戏开始前剧情。如果无剧情直接留一个空数组即可。
|
||||
"Hi,欢迎来到 HTML5 魔塔样板!\n\n本样板由艾之葵制作,可以让你在不会写任何代码\n的情况下也能做出属于自己的H5魔塔!",
|
||||
"这里游戏开始时的剧情。\n定义在data.js的startText处。\n\n你可以在这里写上自己的内容。",
|
||||
"赶快来试一试吧!"
|
||||
],
|
||||
"shops": [ // 定义全局商店(即快捷商店)
|
||||
{
|
||||
"id": "moneyShop1", // 商店唯一ID
|
||||
"name": "贪婪之神", // 商店名称(标题)
|
||||
"icon": "blueShop", // 商店图标,在icons.js中的npc一项定义
|
||||
"textInList": "1F金币商店", // 在快捷商店栏中显示的名称
|
||||
"use": "money", // 商店所要使用的。只能是"money"或"experience"。
|
||||
"need": "20+10*times*(times+1)", // 商店需要的金币/经验数值;可以是一个表达式,以times作为参数计算。
|
||||
// 这里用到的times为该商店的已经的访问次数。首次访问该商店时times的值为0。
|
||||
// 上面的例子是50层商店的计算公式。你也可以写任意其他的计算公式,只要以times作为参数即可。
|
||||
// 例如: "need": "25" 就是恒定需要25金币的商店; "need": "20+2*times" 就是第一次访问要20金币,以后每次递增2金币的商店。
|
||||
// 如果是对于每个选项有不同的计算公式,写 "need": "-1" 即可。可参见下面的经验商店。
|
||||
"text": "勇敢的武士啊,给我${need}金币就可以:", // 显示的文字,需手动加换行符。可以使用${need}表示上面的need值。
|
||||
"choices": [ // 商店的选项
|
||||
{"text": "生命+800", "effect": "status:hp+=800"},
|
||||
// 如果有多个effect以分号分开,参见下面的经验商店
|
||||
{"text": "攻击+4", "effect": "status:atk+=4"},
|
||||
{"text": "防御+4", "effect": "status:def+=4"},
|
||||
{"text": "魔防+10", "effect": "status:mdef+=10"}
|
||||
// effect只能对status和item进行操作,不能修改flag值。
|
||||
// 必须是X+=Y的形式,其中Y可以是一个表达式,以status:xxx或item:xxx为参数
|
||||
// 其他effect样例:
|
||||
// "item:yellowKey+=1" 黄钥匙+1
|
||||
// "item:pickaxe+=3" 破墙镐+3
|
||||
// "status:hp+=2*(status:atk+status:def)" 将生命提升攻防和的数值的两倍
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "expShop1", // 商店唯一ID
|
||||
"name": "经验之神",
|
||||
"icon": "pinkShop",
|
||||
"textInList": "1F经验商店",
|
||||
"use": "experience", // 该商店使用的是经验进行计算
|
||||
"need": "-1", // 如果是对于每个选项所需要的数值不同,这里直接写-1,然后下面选项里给定具体数值
|
||||
"text": "勇敢的武士啊,给我若干经验就可以:",
|
||||
"choices": [
|
||||
// 在choices中写need,可以针对每个选项都有不同的需求。
|
||||
// 这里的need同样可以以times作为参数,比如 "need": "100+20*times"
|
||||
{"text": "等级+1", "need": "100", "effect": "status:lv+=1;status:hp+=1000;status:atk+=7;status:def+=7"},
|
||||
// 多个effect直接以分号分开即可。如上面的意思是生命+1000,攻击+7,防御+7。
|
||||
{"text": "攻击+5", "need": "30", "effect": "status:atk+=5"},
|
||||
{"text": "防御+5", "need": "30", "effect": "status:def+=5"},
|
||||
]
|
||||
}
|
||||
],
|
||||
"levelUp": [ // 经验升级所需要的数值,是一个数组
|
||||
{}, // 第一项为初始等级,可以简单留空,也可以写name
|
||||
|
||||
// 每一个里面可以含有三个参数 need, name, effect
|
||||
// need为所需要的经验数值,是一个正整数。请确保need所需的依次递增
|
||||
// name为该等级的名称,也可以省略代表使用系统默认值;本项将显示在状态栏中
|
||||
// effect为本次升级所执行的操作,可由若干项组成,由分号分开
|
||||
// 其中每一项写法和上面的商店完全相同,同样必须是X+=Y的形式,Y是一个表达式,同样可以使用status:xxx或item:xxx代表勇士的某项数值/道具个数
|
||||
{"need": 20, "name": "第二级", "effect": "status:hp+=2*(status:atk+status:def);status:atk+=10;status:def+=10"}, // 先将生命提升攻防和的2倍;再将攻击+10,防御+10
|
||||
|
||||
// effect也允许写一个function,代表本次升级将会执行的操作
|
||||
{"need": 40, "effect": function () {
|
||||
core.insertAction("恭喜升级!");
|
||||
core.status.hero.hp *= 2;
|
||||
core.status.hero.atk += 100;
|
||||
core.status.hero.def += 100;
|
||||
}},
|
||||
|
||||
// 依次往下写需要的数值即可
|
||||
]
|
||||
}
|
||||
// 各种数值;一些数值可以在这里设置
|
||||
this.values = {
|
||||
/****** 角色相关 ******/
|
||||
"HPMAX": 999999, // HP上限;-1则无上限
|
||||
"lavaDamage": 100, // 经过血网受到的伤害
|
||||
"poisonDamage": 10, // 中毒后每步受到的伤害
|
||||
"weakValue": 20, // 衰弱状态下攻防减少的数值
|
||||
/****** 道具相关 ******/
|
||||
"redJewel": 3, // 红宝石加攻击的数值
|
||||
"blueJewel": 3, // 蓝宝石加防御的数值
|
||||
"greenJewel": 5, // 绿宝石加魔防的数值
|
||||
"redPotion": 100, // 红血瓶加血数值
|
||||
"bluePotion": 250, // 蓝血瓶加血数值
|
||||
"yellowPotion": 500, // 黄血瓶加血数值
|
||||
"greenPotion": 800, // 绿血瓶加血数值
|
||||
"sword0": 0, // 默认装备折断的剑的攻击力
|
||||
"shield0": 0, // 默认装备残破的盾的防御力
|
||||
"sword1": 10, // 铁剑加攻数值
|
||||
"shield1": 10, // 铁盾加防数值
|
||||
"sword2": 20, // 银剑加攻数值
|
||||
"shield2": 20, // 银盾加防数值
|
||||
"sword3": 40, // 骑士剑加攻数值
|
||||
"shield3": 40, // 骑士盾加防数值
|
||||
"sword4": 80, // 圣剑加攻数值
|
||||
"shield4": 80, // 圣盾加防数值
|
||||
"sword5": 160, // 神圣剑加攻数值
|
||||
"shield5": 160, // 神圣盾加防数值
|
||||
"moneyPocket": 500, // 金钱袋加金币的数值
|
||||
/****** 怪物相关 ******/
|
||||
'breakArmor': 0.9, // 破甲的比例(战斗前,怪物附加角色防御的x%作为伤害)
|
||||
'counterAttack': 0.1, // 反击的比例(战斗时,怪物每回合附加角色攻击的x%作为伤害,无视角色防御)
|
||||
'purify': 3, // 净化的比例(战斗前,怪物附加勇士魔防的x倍作为伤害)
|
||||
'hatred': 2, // 仇恨属性中,每杀死一个怪物获得的仇恨值
|
||||
/****** 系统相关 ******/
|
||||
'animateSpeed': 500, // 动画时间
|
||||
}
|
||||
// 系统FLAG,在游戏运行中中请不要修改它。
|
||||
this.flags = {
|
||||
/****** 状态栏相关 ******/
|
||||
"enableFloor": true, // 是否在状态栏显示当前楼层
|
||||
"enableLv": true, // 是否在状态栏显示当前等级
|
||||
"enableMDef": true, // 是否在状态栏及战斗界面显示魔防(护盾)
|
||||
"enableMoney": true, // 是否在状态栏、怪物手册及战斗界面显示金币
|
||||
"enableExperience": true, // 是否在状态栏、怪物手册及战斗界面显示经验
|
||||
"enableLevelUp": true, // 是否允许等级提升(进阶);如果上面enableExperience为false,则此项恒视为false
|
||||
"enableDebuff": true, // 是否涉及毒衰咒;如果此项为false则不会在状态栏中显示毒衰咒的debuff
|
||||
////// 上述的几个开关将直接影响状态栏的显示效果 //////
|
||||
/****** 道具相关 ******/
|
||||
"flyNearStair": true, // 是否需要在楼梯边使用传送器
|
||||
"pickaxeFourDirections": true, // 使用破墙镐是否四个方向都破坏;如果false则只破坏面前的墙壁
|
||||
"bombFourDirections": true, // 使用炸弹是否四个方向都会炸;如果false则只炸面前的怪物(即和圣锤等价)
|
||||
"bigKeyIsBox": false, // 如果此项为true,则视为钥匙盒,红黄蓝钥匙+1;若为false,则视为大黄门钥匙
|
||||
"equipment": false, // 剑和盾是否直接作为装备。如果此项为true,则作为装备,需要在道具栏使用,否则将直接加属性。
|
||||
"enableDeleteItem": true, // 是否允许删除(丢弃)道具
|
||||
/****** 怪物相关 ******/
|
||||
"enableNegativeDamage": true, // 是否支持负伤害(回血)
|
||||
"hatredDecrease": true, // 是否在和仇恨怪战斗后减一半的仇恨值,此项为false则和仇恨怪不会扣减仇恨值。
|
||||
"betweenAttackCeil": false, // 夹击方式是向上取整还是向下取整。如果此项为true则为向上取整,为false则为向下取整
|
||||
/****** 系统相关 ******/
|
||||
"startDirectly": false, // 点击“开始游戏”后是否立刻开始游戏而不显示难度选择界面
|
||||
"canOpenBattleAnimate": true, // 是否允许用户开启战斗过程;如果此项为false,则下面两项均强制视为false
|
||||
"showBattleAnimateConfirm": true, // 是否在游戏开始时提供“是否开启战斗动画”的选项
|
||||
"battleAnimate": true, // 是否默认显示战斗动画;用户可以手动在菜单栏中开关
|
||||
"displayEnemyDamage": true, // 是否地图怪物显伤;用户可以手动在菜单栏中开关
|
||||
"displayExtraDamage": true, // 是否地图高级显伤(领域、夹击等);用户可以手动在菜单栏中开关
|
||||
"enableGentleClick": true, // 是否允许轻触(获得面前物品)
|
||||
"potionWhileRouting": false, // 寻路算法是否经过血瓶;如果该项为false,则寻路算法会自动尽量绕过血瓶
|
||||
"enableViewMaps": true, // 是否支持在菜单栏中查看所有楼层的地图
|
||||
"portalWithoutTrigger": true, // 是否支持穿透。所谓穿透,即当自动寻路经过楼梯时,不触发楼层转换事件而是穿过它。
|
||||
"enableMoveDirectly": true, // 是否允许瞬间移动
|
||||
}
|
||||
this.firstData = data_a1e2fb4a_e986_4524_b0da_9b7ba7c0874d.firstData;
|
||||
this.values = data_a1e2fb4a_e986_4524_b0da_9b7ba7c0874d.values;
|
||||
this.flags = data_a1e2fb4a_e986_4524_b0da_9b7ba7c0874d.flags;
|
||||
//delete(data_a1e2fb4a_e986_4524_b0da_9b7ba7c0874d);
|
||||
}
|
||||
|
||||
data.prototype.getFirstData = function() {
|
||||
return core.clone(this.firstData);
|
||||
}
|
||||
|
||||
main.instance.data = new data();
|
||||
}
|
||||
@ -1,72 +1,12 @@
|
||||
function enemys() {
|
||||
|
||||
this.init();
|
||||
}
|
||||
|
||||
////// 初始化 //////
|
||||
enemys.prototype.init = function () {
|
||||
// 怪物属性初始化定义:
|
||||
this.enemys = {
|
||||
'greenSlime': {'name': '绿头怪', 'hp': 100, 'atk': 120, 'def': 0, 'money': 1, 'experience': 1, 'special': [1,5,7,8]},
|
||||
'redSlime': {'name': '红头怪', 'hp': 0, 'atk': 0, 'def': 0, 'money': 0, 'experience': 0, 'special': 0},
|
||||
'blackSlime': {'name': '青头怪', 'hp': 0, 'atk': 0, 'def': 0, 'money': 0, 'experience': 0, 'special': 0},
|
||||
'slimelord': {'name': '怪王', 'hp': 100, 'atk': 120, 'def': 0, 'money': 10, 'experience': 0, 'special': [1,9]},
|
||||
'bat': {'name': '小蝙蝠', 'hp': 100, 'atk': 120, 'def': 0, 'money': 2, 'experience': 0, 'special': 1},
|
||||
'bigBat': {'name': '大蝙蝠', 'hp': 0, 'atk': 0, 'def': 0, 'money': 0, 'experience': 0, 'special': 0},
|
||||
'redBat': {'name': '红蝙蝠', 'hp': 100, 'atk': 120, 'def': 0, 'money': 5, 'experience': 0, 'special': 4},
|
||||
'vampire': {'name': '冥灵魔王', 'hp': 0, 'atk': 0, 'def': 0, 'money': 0, 'experience': 0, 'special': 0},
|
||||
'skeleton': {'name': '骷髅人', 'hp': 0, 'atk': 0, 'def': 0, 'money': 0, 'experience': 0, 'special': 0},
|
||||
'skeletonSoilder': {'name': '骷髅士兵', 'hp': 0, 'atk': 0, 'def': 0, 'money': 0, 'experience': 0, 'special': 0},
|
||||
'skeletonCaptain': {'name': '骷髅队长', 'hp': 0, 'atk': 0, 'def': 0, 'money': 0, 'experience': 0, 'special': 0},
|
||||
'ghostSkeleton': {'name': '冥队长', 'hp': 100, 'atk': 120, 'def': 0, 'money': 8, 'experience': 0, 'special': 7},
|
||||
'zombie': {'name': '兽人', 'hp': 0, 'atk': 0, 'def': 0, 'money': 0, 'experience': 0, 'special': 0},
|
||||
'zombieKnight': {'name': '兽人武士', 'hp': 0, 'atk': 0, 'def': 0, 'money': 0, 'experience': 0, 'special': 0},
|
||||
'rock': {'name': '石头人', 'hp': 100, 'atk': 120, 'def': 0, 'money': 4, 'experience': 0, 'special': 3},
|
||||
'slimeMan': {'name': '影子战士', 'hp': 100, 'atk': 0, 'def': 0, 'money': 11, 'experience': 0, 'special': [10,21], 'atkValue': 2, 'defValue': 3}, // 退化怪可以在后面写atkValue和defValue表示退化的数值
|
||||
'bluePriest': {'name': '初级法师', 'hp': 100, 'atk': 120, 'def': 0, 'money': 3, 'experience': 0, 'special': 2, 'point': 1}, // 'point'可以在打败怪物后进行加点,详见文档说明。
|
||||
'redPriest': {'name': '高级法师', 'hp': 0, 'atk': 0, 'def': 0, 'money': 0, 'experience': 0, 'special': 0},
|
||||
'brownWizard': {'name': '初级巫师', 'hp': 100, 'atk': 120, 'def': 0, 'money': 16, 'experience': 0, 'special': 15, 'value': 100, 'range': 2}, // 领域怪需要加value表示领域伤害的数值;range可选,代表领域伤害的范围;不加默认为1
|
||||
'redWizard': {'name': '高级巫师', 'hp': 1000, 'atk': 1200, 'def': 0, 'money': 160, 'experience': 0, 'special': 15, 'value': 200, 'zoneSquare': true}, // zoneSquare可选,代表是否九宫格伤害,true为是九宫格伤害,false或不设置为十字伤害
|
||||
'yellowGuard': {'name': '初级卫兵', 'hp': 100, 'atk': 120, 'def': 0, 'money': 10, 'experience': 0, 'special': 0},
|
||||
'blueGuard': {'name': '中级卫兵', 'hp': 0, 'atk': 0, 'def': 0, 'money': 0, 'experience': 0, 'special': 0},
|
||||
'redGuard': {'name': '高级卫兵', 'hp': 0, 'atk': 0, 'def': 0, 'money': 0, 'experience': 0, 'special': 0},
|
||||
'swordsman': {'name': '双手剑士', 'hp': 100, 'atk': 120, 'def': 0, 'money': 6, 'experience': 0, 'special': 5},
|
||||
'soldier': {'name': '冥战士', 'hp': 0, 'atk': 0, 'def': 0, 'money': 0, 'experience': 0, 'special': 0},
|
||||
'yellowKnight': {'name': '金骑士', 'hp': 0, 'atk': 0, 'def': 0, 'money': 0, 'experience': 0, 'special': 0},
|
||||
'redKnight': {'name': '红骑士', 'hp': 0, 'atk': 0, 'def': 0, 'money': 0, 'experience': 0, 'special': 0},
|
||||
'darkKnight': {'name': '黑骑士', 'hp': 0, 'atk': 0, 'def': 0, 'money': 0, 'experience': 0, 'special': 0},
|
||||
'blackKing': {'name': '黑衣魔王', 'hp': 1000, 'atk': 500, 'def': 0, 'money': 1000, 'experience': 1000, 'special': 0, 'bomb': false}, // 加入 'bomb': false 代表该怪物不可被炸弹或圣锤炸掉
|
||||
'yellowKing': {'name': '黄衣魔王', 'hp': 0, 'atk': 0, 'def': 0, 'money': 0, 'experience': 0, 'special': 0},
|
||||
'greenKing': {'name': '青衣武士', 'hp': 0, 'atk': 0, 'def': 0, 'money': 0, 'experience': 0, 'special': 0},
|
||||
'blueKnight': {'name': '蓝骑士', 'hp': 100, 'atk': 120, 'def': 0, 'money': 9, 'experience': 0, 'special': 8},
|
||||
'goldSlime': {'name': '黄头怪', 'hp': 0, 'atk': 0, 'def': 0, 'money': 0, 'experience': 0, 'special': 0},
|
||||
'poisonSkeleton': {'name': '紫骷髅', 'hp': 0, 'atk': 0, 'def': 0, 'money': 0, 'experience': 0, 'special': 0},
|
||||
'poisonBat': {'name': '紫蝙蝠', 'hp': 100, 'atk': 120, 'def': 0, 'money': 14, 'experience': 0, 'special': 13},
|
||||
'steelRock': {'name': '铁面人', 'hp': 0, 'atk': 0, 'def': 0, 'money': 0, 'experience': 0, 'special': 0},
|
||||
'skeletonPriest': {'name': '骷髅法师', 'hp': 100, 'atk': 100, 'def': 0, 'money': 0, 'experience': 0, 'special': 18, 'value': 20},
|
||||
'skeletonKing': {'name': '骷髅王', 'hp': 0, 'atk': 0, 'def': 0, 'money': 0, 'experience': 0, 'special': 0},
|
||||
'skeletonWizard': {'name': '骷髅巫师', 'hp': 0, 'atk': 0, 'def': 0, 'money': 0, 'experience': 0, 'special': 0},
|
||||
'redSkeletonCaption': {'name': '骷髅武士', 'hp': 0, 'atk': 0, 'def': 0, 'money': 0, 'experience': 0, 'special': 0},
|
||||
'badHero': {'name': '迷失勇者', 'hp': 0, 'atk': 0, 'def': 0, 'money': 0, 'experience': 0, 'special': 0},
|
||||
'demon': {'name': '魔神武士', 'hp': 0, 'atk': 0, 'def': 0, 'money': 0, 'experience': 0, 'special': 0},
|
||||
'demonPriest': {'name': '魔神法师', 'hp': 0, 'atk': 0, 'def': 0, 'money': 0, 'experience': 0, 'special': 0},
|
||||
'goldHornSlime': {'name': '金角怪', 'hp': 0, 'atk': 0, 'def': 0, 'money': 0, 'experience': 0, 'special': 0},
|
||||
'redKing': {'name': '红衣魔王', 'hp': 0, 'atk': 0, 'def': 0, 'money': 0, 'experience': 0, 'special': 0},
|
||||
'whiteKing': {'name': '白衣武士', 'hp': 100, 'atk': 120, 'def': 0, 'money': 17, 'experience': 0, 'special': 16},
|
||||
'blackMagician': {'name': '黑暗大法师', 'hp': 100, 'atk': 120, 'def': 0, 'money': 12, 'experience': 0, 'special': 11, 'value': 1/3, 'add': true, 'bomb': false}, // 吸血怪需要在后面添加value代表吸血比例;添加add: true可以将吸血的伤害加到自身
|
||||
'silverSlime': {'name': '银头怪', 'hp': 100, 'atk': 120, 'def': 0, 'money': 15, 'experience': 0, 'special': 14},
|
||||
'swordEmperor': {'name': '剑圣', 'hp': 0, 'atk': 0, 'def': 0, 'money': 0, 'experience': 0, 'special': 0},
|
||||
'whiteHornSlime': {'name': '尖角怪', 'hp': 0, 'atk': 0, 'def': 0, 'money': 0, 'experience': 0, 'special': 0},
|
||||
'badPrincess': {'name': '痛苦魔女', 'hp': 0, 'atk': 0, 'def': 0, 'money': 0, 'experience': 0, 'special': 0},
|
||||
'badFairy': {'name': '黑暗仙子', 'hp': 0, 'atk': 0, 'def': 0, 'money': 0, 'experience': 0, 'special': 0},
|
||||
'grayPriest': {'name': '中级法师', 'hp': 0, 'atk': 0, 'def': 0, 'money': 0, 'experience': 0, 'special': 0},
|
||||
'redSwordsman': {'name': '剑王', 'hp': 100, 'atk': 120, 'def': 0, 'money': 7, 'experience': 0, 'special': 6, 'n': 8}, // 多连击需要在后面指定n代表是几连击
|
||||
'whiteGhost': {'name': '水银战士', 'hp': 0, 'atk': 0, 'def': 0, 'money': 0, 'experience': 0, 'special': 0},
|
||||
'poisonZombie': {'name': '绿兽人', 'hp': 100, 'atk': 120, 'def': 0, 'money': 13, 'experience': 0, 'special': 12},
|
||||
'magicDragon': {'name': '魔龙', 'hp': 0, 'atk': 0, 'def': 0, 'money': 0, 'experience': 0, 'special': 0},
|
||||
'octopus': {'name': '血影', 'hp': 0, 'atk': 0, 'def': 0, 'money': 0, 'experience': 0, 'special': 0},
|
||||
'darkFairy': {'name': '仙子', 'hp': 0, 'atk': 0, 'def': 0, 'money': 0, 'experience': 0, 'special': 0},
|
||||
'greenKnight': {'name': '强盾骑士', 'hp': 0, 'atk': 0, 'def': 0, 'money': 0, 'experience': 0, 'special': 0},
|
||||
}
|
||||
this.enemys = enemys_fcae963b_31c9_42b4_b48c_bb48d09f3f80;
|
||||
//delete(enemys_fcae963b_31c9_42b4_b48c_bb48d09f3f80);
|
||||
}
|
||||
|
||||
////// 获得一个或所有怪物数据 //////
|
||||
@ -119,6 +59,7 @@ enemys.prototype.getSpecialText = function (enemyId) {
|
||||
if (this.hasSpecial(special, 20)) text.push("无敌");
|
||||
if (this.hasSpecial(special, 21)) text.push("退化");
|
||||
if (this.hasSpecial(special, 22)) text.push("固伤");
|
||||
if (this.hasSpecial(special, 23)) text.push("重生");
|
||||
return text;
|
||||
}
|
||||
|
||||
@ -159,9 +100,10 @@ enemys.prototype.getSpecialHint = function (enemy, special) {
|
||||
case 20: return "无敌:勇士无法打败怪物,除非拥有十字架";
|
||||
case 21: return "退化:战斗后勇士永久下降"+(enemy.atkValue||0)+"点攻击和"+(enemy.defValue||0)+"点防御";
|
||||
case 22: return "固伤:战斗前,怪物对勇士造成"+(enemy.damage||0)+"点固定伤害,无视勇士魔防。";
|
||||
case 23: return "重生:怪物被击败后,角色转换楼层则怪物将再次出现";
|
||||
default: break;
|
||||
}
|
||||
return ""
|
||||
return "";
|
||||
}
|
||||
|
||||
////// 获得某个怪物的伤害 //////
|
||||
@ -228,6 +170,10 @@ enemys.prototype.getDefDamage = function (monsterId) {
|
||||
enemys.prototype.calDamage = function (monster, hero_hp, hero_atk, hero_def, hero_mdef) {
|
||||
|
||||
var mon_hp = monster.hp, mon_atk = monster.atk, mon_def = monster.def, mon_special = monster.special;
|
||||
hero_hp=Math.max(0, hero_hp);
|
||||
hero_atk=Math.max(0, hero_atk);
|
||||
hero_def=Math.max(0, hero_def);
|
||||
hero_mdef=Math.max(0, hero_mdef);
|
||||
|
||||
if (this.hasSpecial(mon_special, 20) && !core.hasItem("cross")) // 如果是无敌属性,且勇士未持有十字架
|
||||
return 999999999; // 返回无限大
|
||||
@ -300,19 +246,19 @@ enemys.prototype.getCurrentEnemys = function (floorId) {
|
||||
var used = {};
|
||||
var mapBlocks = core.status.maps[floorId].blocks;
|
||||
for (var b = 0; b < mapBlocks.length; b++) {
|
||||
if (core.isset(mapBlocks[b].event) && !(core.isset(mapBlocks[b].enable) && !mapBlocks[b].enable) && mapBlocks[b].event.cls == 'enemys') {
|
||||
if (core.isset(mapBlocks[b].event) && !(core.isset(mapBlocks[b].enable) && !mapBlocks[b].enable)
|
||||
&& mapBlocks[b].event.cls.indexOf('enemy')==0) {
|
||||
var monsterId = mapBlocks[b].event.id;
|
||||
if (core.isset(used[monsterId])) continue;
|
||||
|
||||
var monster = core.material.enemys[monsterId];
|
||||
var mon_hp = monster.hp, mon_atk = monster.atk, mon_def = monster.def;
|
||||
// 坚固
|
||||
if (this.hasSpecial(monster.special, 3) && mon_def < core.status.hero.atk - 1)
|
||||
mon_def = core.status.hero.atk - 1;
|
||||
if (this.hasSpecial(monster.special, 10)) {
|
||||
mon_atk=core.status.hero.atk;
|
||||
mon_def=core.status.hero.def;
|
||||
}
|
||||
if (this.hasSpecial(monster.special, 3) && mon_def < core.status.hero.atk - 1)
|
||||
mon_def = core.status.hero.atk - 1;
|
||||
|
||||
var specialText = core.enemys.getSpecialText(monsterId);
|
||||
if (specialText.length>=3) specialText = "多属性...";
|
||||
@ -345,6 +291,4 @@ enemys.prototype.getCurrentEnemys = function (floorId) {
|
||||
return a.damage - b.damage;
|
||||
});
|
||||
return enemys;
|
||||
}
|
||||
|
||||
main.instance.enemys = new enemys();
|
||||
}
|
||||
1793
libs/events.js
228
libs/icons.js
@ -1,232 +1,12 @@
|
||||
function icons() {
|
||||
|
||||
this.init();
|
||||
}
|
||||
|
||||
icons.prototype.init = function () {
|
||||
this.icons = {
|
||||
'hero': {
|
||||
'down': {'loc': 0, 'stop': 0, 'leftFoot': 1, 'rightFoot': 3},
|
||||
'left': {'loc': 1, 'stop': 0, 'leftFoot': 1, 'rightFoot': 3},
|
||||
'right': {'loc': 2, 'stop': 0, 'leftFoot': 1, 'rightFoot': 3},
|
||||
'up': {'loc': 3, 'stop': 0, 'leftFoot': 1, 'rightFoot': 3}
|
||||
},
|
||||
'terrains': {
|
||||
'ground': 0,
|
||||
'grass': 1,
|
||||
'grass2': 2,
|
||||
'yellowWall': 3,
|
||||
'whiteWall': 4,
|
||||
'blueWall': 5,
|
||||
'snowGround': 6,
|
||||
'ground2': 7,
|
||||
'ground3': 8,
|
||||
'ground4': 9,
|
||||
'sand': 10,
|
||||
'ground5': 11,
|
||||
'yellowWall2': 12,
|
||||
'whiteWall2': 13,
|
||||
'blueWall2': 14,
|
||||
'blockWall': 15,
|
||||
'grayWall': 16,
|
||||
'white': 17,
|
||||
'ground6': 18,
|
||||
'soil': 19,
|
||||
'star': 20,
|
||||
'lava': 21,
|
||||
'ice': 22,
|
||||
'downFloor': 23,
|
||||
'upFloor': 24,
|
||||
'yellowDoor': 25,
|
||||
'blueDoor': 26,
|
||||
'redDoor': 27,
|
||||
'greenDoor': 28,
|
||||
'specialDoor': 29,
|
||||
'steelDoor': 30,
|
||||
'blueShop-left': 31,
|
||||
'blueShop-right': 32,
|
||||
'pinkShop-left': 33,
|
||||
'pinkShop-right': 34,
|
||||
'arrowUp': 35,
|
||||
'arrowDown': 36,
|
||||
'arrowLeft': 37,
|
||||
'arrowRight': 38,
|
||||
'light': 39,
|
||||
'darkLight': 40,
|
||||
'ski': 41,
|
||||
'flower': 42,
|
||||
'box': 43,
|
||||
'boxed': 44
|
||||
},
|
||||
'animates': {
|
||||
'star': 0,
|
||||
'lava': 1,
|
||||
'waterWall': 2,
|
||||
'yellowDoor': 3,
|
||||
'blueDoor': 4,
|
||||
'redDoor': 5,
|
||||
'greenDoor': 6,
|
||||
'specialDoor': 7,
|
||||
'blueWallDoor': 8,
|
||||
'yellowWallDoor': 9,
|
||||
'whiteWallDoor': 10,
|
||||
'steelDoor': 11,
|
||||
'lavaDoor': 12,
|
||||
'grayLavaDoor': 13,
|
||||
'starDoor': 14,
|
||||
'mockBlueWallDoor': 15,
|
||||
'mockYellowWallDoor': 16,
|
||||
'mockWhiteWallDoor': 17,
|
||||
'iceYellowWallDoor': 18,
|
||||
'starPortal': 19,
|
||||
'exclamation': 20,
|
||||
'portal': 21,
|
||||
'switch': 22,
|
||||
'lavaNet': 23,
|
||||
'poisonNet': 24,
|
||||
'weakNet': 25,
|
||||
'curseNet': 26,
|
||||
'downPortal': 27,
|
||||
'leftPortal': 28,
|
||||
'rightPortal': 29,
|
||||
'upPortal': 30,
|
||||
'water': 31,
|
||||
},
|
||||
'npcs': {
|
||||
'man': 0,
|
||||
'woman': 1,
|
||||
'thief': 2,
|
||||
'fairy': 3,
|
||||
'magician': 4,
|
||||
'womanMagician': 5,
|
||||
'oldMan': 6,
|
||||
'child': 7,
|
||||
'wood': 8,
|
||||
'pinkShop': 9,
|
||||
'blueShop': 10,
|
||||
'princess': 11
|
||||
},
|
||||
'enemys': {
|
||||
'greenSlime': 0,
|
||||
'redSlime': 1,
|
||||
'blackSlime': 2,
|
||||
'slimelord': 3,
|
||||
'bat': 4,
|
||||
'bigBat': 5,
|
||||
'redBat': 6,
|
||||
'vampire': 7,
|
||||
'skeleton': 8,
|
||||
'skeletonSoilder': 9,
|
||||
'skeletonCaptain': 10,
|
||||
'ghostSkeleton': 11,
|
||||
'zombie': 12,
|
||||
'zombieKnight': 13,
|
||||
'rock': 14,
|
||||
'slimeMan': 15,
|
||||
'bluePriest': 16,
|
||||
'redPriest': 17,
|
||||
'brownWizard': 18,
|
||||
'redWizard': 19,
|
||||
'yellowGuard': 20,
|
||||
'blueGuard': 21,
|
||||
'redGuard': 22,
|
||||
'swordsman': 23,
|
||||
'soldier': 24,
|
||||
'yellowKnight': 25,
|
||||
'redKnight': 26,
|
||||
'darkKnight': 27,
|
||||
'blackKing': 28,
|
||||
'yellowKing': 29,
|
||||
'greenKing': 30,
|
||||
'blueKnight': 31,
|
||||
'goldSlime': 32,
|
||||
'poisonSkeleton': 33,
|
||||
'poisonBat': 34,
|
||||
'steelRock': 35,
|
||||
'skeletonPriest': 36,
|
||||
'skeletonKing': 37,
|
||||
'skeletonWizard': 38,
|
||||
'redSkeletonCaption': 39,
|
||||
'badHero': 40,
|
||||
'demon': 41,
|
||||
'demonPriest': 42,
|
||||
'goldHornSlime': 43,
|
||||
'redKing': 44,
|
||||
'whiteKing': 45,
|
||||
'blackMagician': 46,
|
||||
'silverSlime': 47,
|
||||
'swordEmperor': 48,
|
||||
'whiteHornSlime': 49,
|
||||
'badPrincess': 50,
|
||||
'badFairy': 51,
|
||||
'grayPriest': 52,
|
||||
'redSwordsman': 53,
|
||||
'whiteGhost': 54,
|
||||
'poisonZombie': 55,
|
||||
'magicDragon': 56,
|
||||
'octopus': 57,
|
||||
'darkFairy': 58,
|
||||
'greenKnight': 59,
|
||||
},
|
||||
'items': {
|
||||
'yellowKey': 0,
|
||||
'blueKey': 1,
|
||||
'redKey': 2,
|
||||
'greenKey': 3,
|
||||
'steelKey': 4,
|
||||
'bigKey': 6,
|
||||
'redJewel': 16,
|
||||
'blueJewel': 17,
|
||||
'greenJewel': 18,
|
||||
'yellowJewel': 19,
|
||||
'redPotion': 20,
|
||||
'bluePotion': 21,
|
||||
'greenPotion': 22,
|
||||
'yellowPotion': 23,
|
||||
'sword0': 60,
|
||||
'sword1': 50,
|
||||
'sword2': 51,
|
||||
'sword3': 52,
|
||||
'sword4': 53,
|
||||
'sword5': 54,
|
||||
'shield0': 61,
|
||||
'shield1': 55,
|
||||
'shield2': 56,
|
||||
'shield3': 57,
|
||||
'shield4': 58,
|
||||
'shield5': 59,
|
||||
'book': 9,
|
||||
'fly': 12,
|
||||
'pickaxe': 45,
|
||||
'icePickaxe': 44,
|
||||
'bomb': 43,
|
||||
'centerFly': 13,
|
||||
'upFly': 15,
|
||||
'downFly': 14,
|
||||
'coin': 11,
|
||||
'snow': 41,
|
||||
'cross': 40,
|
||||
'superPotion': 29,
|
||||
'earthquake': 8,
|
||||
'poisonWine': 24,
|
||||
'weakWine': 25,
|
||||
'curseWine': 27,
|
||||
'superWine': 28,
|
||||
'knife': 42,
|
||||
'moneyPocket': 46,
|
||||
'shoes': 47,
|
||||
'hammer': 48
|
||||
},
|
||||
'autotile': { // 所有的Autotile列表;后面的index简单取0即可
|
||||
'autotile': 0,
|
||||
'autotile1': 0,
|
||||
'autotile2': 0,
|
||||
'autotile3': 0,
|
||||
}
|
||||
}
|
||||
this.icons = icons_4665ee12_3a1f_44a4_bea3_0fccba634dc1;
|
||||
//delete(icons_4665ee12_3a1f_44a4_bea3_0fccba634dc1);
|
||||
}
|
||||
|
||||
icons.prototype.getIcons = function () {
|
||||
return this.icons;
|
||||
}
|
||||
|
||||
main.instance.icons = new icons();
|
||||
}
|
||||
179
libs/items.js
@ -1,65 +1,13 @@
|
||||
function items() {
|
||||
|
||||
this.init();
|
||||
}
|
||||
|
||||
////// 初始化 //////
|
||||
items.prototype.init = function () {
|
||||
this.items = {
|
||||
// 钥匙
|
||||
'yellowKey': {'cls': 'keys', 'name': '黄钥匙'},
|
||||
'blueKey': {'cls': 'keys', 'name': '蓝钥匙'},
|
||||
'redKey': {'cls': 'keys', 'name': '红钥匙'},
|
||||
|
||||
// 宝石、血瓶
|
||||
'redJewel': {'cls': 'items', 'name': '红宝石'},
|
||||
'blueJewel': {'cls': 'items', 'name': '蓝宝石'},
|
||||
'greenJewel': {'cls': 'items', 'name': '绿宝石'},
|
||||
'yellowJewel': {'cls': 'items', 'name': '黄宝石'},
|
||||
'redPotion': {'cls': 'items', 'name': '红血瓶'},
|
||||
'bluePotion': {'cls': 'items', 'name': '蓝血瓶'},
|
||||
'yellowPotion': {'cls': 'items', 'name': '黄血瓶'},
|
||||
'greenPotion': {'cls': 'items', 'name': '绿血瓶'},
|
||||
'sword1': {'cls': 'items', 'name': '铁剑'},
|
||||
'sword2': {'cls': 'items', 'name': '银剑'},
|
||||
'sword3': {'cls': 'items', 'name': '骑士剑'},
|
||||
'sword4': {'cls': 'items', 'name': '圣剑'},
|
||||
'sword5': {'cls': 'items', 'name': '神圣剑'},
|
||||
'shield1': {'cls': 'items', 'name': '铁盾'},
|
||||
'shield2': {'cls': 'items', 'name': '银盾'},
|
||||
'shield3': {'cls': 'items', 'name': '骑士盾'},
|
||||
'shield4': {'cls': 'items', 'name': '圣盾'},
|
||||
'shield5': {'cls': 'items', 'name': '神圣盾'},
|
||||
'superPotion': {'cls': 'items', 'name': '圣水'},
|
||||
'moneyPocket': {'cls': 'items', 'name': '金钱袋'},
|
||||
|
||||
// 物品
|
||||
'sword0': {'cls': 'constants', 'name': '折断的剑', 'text': '没有任何作用的剑,相当于脱掉装备。'},
|
||||
'shield0': {'cls': 'constants', 'name': '残破的盾', 'text': '没有任何作用的盾,相当于脱掉装备。'},
|
||||
'book': {'cls': 'constants', 'name': '怪物手册', 'text': '可以查看当前楼层各怪物属性'},
|
||||
'fly': {'cls': 'constants', 'name': '楼层传送器', 'text': '可以自由往来去过的楼层'},
|
||||
'coin': {'cls': 'constants', 'name': '幸运金币', 'text': '持有时打败怪物可得双倍金币'},
|
||||
'snow': {'cls': 'constants', 'name': '冰冻徽章', 'text': '可以将四周的熔岩变成平地'},
|
||||
'cross': {'cls': 'constants', 'name': '十字架', 'text': '持有后无视怪物的无敌属性'},
|
||||
'knife': {'cls': 'constants', 'name': '屠龙匕首', 'text': '该道具尚未被定义'},
|
||||
'shoes': {'cls': 'constants', 'name': '绿鞋', 'text': '持有时无视负面地形'},
|
||||
|
||||
// 道具
|
||||
'bigKey': {'cls': 'tools', 'name': '大黄门钥匙', 'text': '可以开启当前层所有黄门'},
|
||||
'greenKey': {'cls': 'tools', 'name': '绿钥匙', 'text': '可以打开一扇绿门'},
|
||||
'steelKey': {'cls': 'tools', 'name': '铁门钥匙', 'text': '可以打开一扇铁门'},
|
||||
'pickaxe': {'cls': 'tools', 'name': '破墙镐', 'text': '可以破坏勇士面前的墙'},
|
||||
'icePickaxe': {'cls': 'tools', 'name': '破冰镐', 'text': '可以破坏勇士面前的一堵冰墙'},
|
||||
'bomb': {'cls': 'tools', 'name': '炸弹', 'text': '可以炸掉勇士面前的怪物'},
|
||||
'centerFly': {'cls': 'tools', 'name': '中心对称飞行器', 'text': '可以飞向当前楼层中心对称的位置'},
|
||||
'upFly': {'cls': 'tools', 'name': '上楼器', 'text': '可以飞往楼上的相同位置'},
|
||||
'downFly': {'cls': 'tools', 'name': '下楼器', 'text': '可以飞往楼下的相同位置'},
|
||||
'earthquake': {'cls': 'tools', 'name': '地震卷轴', 'text': '可以破坏当前层的所有墙'},
|
||||
'poisonWine': {'cls': 'tools', 'name': '解毒药水', 'text': '可以解除中毒状态'},
|
||||
'weakWine': {'cls': 'tools', 'name': '解衰药水', 'text': '可以解除衰弱状态'},
|
||||
'curseWine': {'cls': 'tools', 'name': '解咒药水', 'text': '可以解除诅咒状态'},
|
||||
'superWine': {'cls': 'tools', 'name': '万能药水', 'text': '可以解除所有不良状态'},
|
||||
'hammer': {'cls': 'tools', 'name': '圣锤', 'text': '可以炸掉勇士面前的怪物'}
|
||||
}
|
||||
this.items = items_296f5d02_12fd_4166_a7c1_b5e830c9ee3a.items;
|
||||
this.itemEffect = items_296f5d02_12fd_4166_a7c1_b5e830c9ee3a.itemEffect;
|
||||
this.itemEffectTip = items_296f5d02_12fd_4166_a7c1_b5e830c9ee3a.itemEffectTip;
|
||||
//delete(items_296f5d02_12fd_4166_a7c1_b5e830c9ee3a);
|
||||
}
|
||||
|
||||
////// 获得所有道具 //////
|
||||
@ -88,43 +36,13 @@ items.prototype.getItems = function () {
|
||||
return this.items;
|
||||
}
|
||||
|
||||
main.instance.items = new items();
|
||||
|
||||
////// “即捡即用类”道具的使用效果 //////
|
||||
items.prototype.getItemEffect = function(itemId, itemNum) {
|
||||
var itemCls = core.material.items[itemId].cls;
|
||||
// 消耗品
|
||||
if (itemCls === 'items') {
|
||||
if (itemId === 'redJewel') core.status.hero.atk += core.values.redJewel;
|
||||
if (itemId === 'blueJewel') core.status.hero.def += core.values.blueJewel;
|
||||
if (itemId === 'greenJewel') core.status.hero.mdef += core.values.greenJewel;
|
||||
if (itemId == 'yellowJewel') { // 黄宝石属性:需自己定义
|
||||
core.status.hero.hp+=1000;
|
||||
core.status.hero.atk+=6;
|
||||
core.status.hero.def+=6;
|
||||
core.status.hero.mdef+=10;
|
||||
}
|
||||
if (itemId === 'redPotion') core.status.hero.hp += core.values.redPotion;
|
||||
if (itemId === 'bluePotion') core.status.hero.hp += core.values.bluePotion;
|
||||
if (itemId === 'yellowPotion') core.status.hero.hp += core.values.yellowPotion;
|
||||
if (itemId === 'greenPotion') core.status.hero.hp += core.values.greenPotion;
|
||||
if (itemId === 'sword1') core.status.hero.atk += core.values.sword1;
|
||||
if (itemId === 'sword2') core.status.hero.atk += core.values.sword2;
|
||||
if (itemId == 'sword3') core.status.hero.atk += core.values.sword3;
|
||||
if (itemId == 'sword4') core.status.hero.atk += core.values.sword4;
|
||||
if (itemId === 'sword5') core.status.hero.atk += core.values.sword5;
|
||||
if (itemId === 'shield1') core.status.hero.def += core.values.shield1;
|
||||
if (itemId === 'shield2') core.status.hero.def += core.values.shield2;
|
||||
if (itemId === 'shield3') core.status.hero.def += core.values.shield3;
|
||||
if (itemId === 'shield4') core.status.hero.def += core.values.shield4;
|
||||
if (itemId === 'shield5') core.status.hero.def += core.values.shield5;
|
||||
if (itemId === 'bigKey') { // 只有是钥匙盒才会执行这一步
|
||||
core.status.hero.items.keys.yellowKey++;
|
||||
core.status.hero.items.keys.blueKey++;
|
||||
core.status.hero.items.keys.redKey++;
|
||||
}
|
||||
if (itemId == 'superPotion') core.status.hero.hp *= 2;
|
||||
if (itemId == 'moneyPocket') core.status.hero.money += core.values.moneyPocket;
|
||||
var ratio = parseInt(core.floors[core.status.floorId].item_ratio) || 1;
|
||||
if (itemId in this.itemEffect)eval(this.itemEffect[itemId]);
|
||||
}
|
||||
else {
|
||||
core.addItem(itemId, itemNum);
|
||||
@ -133,27 +51,10 @@ items.prototype.getItemEffect = function(itemId, itemNum) {
|
||||
|
||||
////// “即捡即用类”道具的文字提示 //////
|
||||
items.prototype.getItemEffectTip = function(itemId) {
|
||||
if (itemId == 'redJewel') return ",攻击+"+core.values.redJewel;
|
||||
if (itemId == 'blueJewel') return ",防御+"+core.values.blueJewel;
|
||||
if (itemId == 'greenJewel') return ",魔防+"+core.values.greenJewel;
|
||||
if (itemId == 'yellowJewel') return ",全属性提升";
|
||||
if (itemId == 'redPotion') return ",生命+"+core.values.redPotion;
|
||||
if (itemId == 'bluePotion') return ",生命+"+core.values.bluePotion;
|
||||
if (itemId == 'yellowPotion') return ",生命+"+core.values.yellowPotion;
|
||||
if (itemId == 'greenPotion') return ",生命+"+core.values.greenPotion;
|
||||
if (!core.flags.equipment && itemId == 'sword1') return ",攻击+"+core.values.sword1;
|
||||
if (!core.flags.equipment && itemId == 'sword2') return ",攻击+"+core.values.sword2;
|
||||
if (!core.flags.equipment && itemId == 'sword3') return ",攻击+"+core.values.sword3;
|
||||
if (!core.flags.equipment && itemId == 'sword4') return ",攻击+"+core.values.sword4;
|
||||
if (!core.flags.equipment && itemId == 'sword5') return ",攻击+"+core.values.sword5;
|
||||
if (!core.flags.equipment && itemId == 'shield1') return ",防御+"+core.values.shield1;
|
||||
if (!core.flags.equipment && itemId == 'shield2') return ",防御+"+core.values.shield2;
|
||||
if (!core.flags.equipment && itemId == 'shield3') return ",防御+"+core.values.shield3;
|
||||
if (!core.flags.equipment && itemId == 'shield4') return ",防御+"+core.values.shield4;
|
||||
if (!core.flags.equipment && itemId == 'shield5') return ",防御+"+core.values.shield5;
|
||||
if (itemId === 'bigKey') return ",全钥匙+1";
|
||||
if (itemId === 'superPotion') return ",生命值翻倍";
|
||||
if (itemId == 'moneyPocket') return ",金币+"+core.values.moneyPocket;
|
||||
var ratio = parseInt(core.floors[core.status.floorId].item_ratio) || 1;
|
||||
if (itemId in this.itemEffectTip && (!this.items[itemId].isEquipment || !core.flags.equipment)) {
|
||||
return eval(this.itemEffectTip[itemId]);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
@ -299,7 +200,7 @@ items.prototype.canUseItem = function (itemId) {
|
||||
var ids = [];
|
||||
for (var i in core.status.thisMap.blocks) {
|
||||
var block = core.status.thisMap.blocks[i];
|
||||
if (core.isset(block.event) && !(core.isset(block.enable) && !block.enable) && block.event.cls == 'enemys' && Math.abs(block.x-core.status.hero.loc.x)+Math.abs(block.y-core.status.hero.loc.y)<=1) {
|
||||
if (core.isset(block.event) && !(core.isset(block.enable) && !block.enable) && block.event.cls.indexOf('enemy')==0 && Math.abs(block.x-core.status.hero.loc.x)+Math.abs(block.y-core.status.hero.loc.y)<=1) {
|
||||
var enemy = core.material.enemys[block.event.id];
|
||||
if (core.isset(enemy.bomb) && !enemy.bomb) continue;
|
||||
if (core.flags.bombFourDirections || (block.x==core.nextX() && block.y==core.nextY()))
|
||||
@ -316,7 +217,7 @@ items.prototype.canUseItem = function (itemId) {
|
||||
// 圣锤
|
||||
for (var i in core.status.thisMap.blocks) {
|
||||
var block = core.status.thisMap.blocks[i];
|
||||
if (core.isset(block.event) && !(core.isset(block.enable) && !block.enable) && block.event.cls == 'enemys' && block.x==core.nextX() && block.y==core.nextY()) {
|
||||
if (core.isset(block.event) && !(core.isset(block.enable) && !block.enable) && block.event.cls.indexOf('enemy')==0 && block.x==core.nextX() && block.y==core.nextY()) {
|
||||
var enemy = core.material.enemys[block.event.id];
|
||||
if (core.isset(enemy.bomb) && !enemy.bomb) continue;
|
||||
core.status.event.data = [i];
|
||||
@ -418,3 +319,57 @@ items.prototype.canUseItem = function (itemId) {
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
////// 获得某个物品的个数 //////
|
||||
items.prototype.itemCount = function (itemId) {
|
||||
if (!core.isset(itemId) || !core.isset(core.material.items[itemId])) return 0;
|
||||
var itemCls = core.material.items[itemId].cls;
|
||||
if (itemCls=="items") return 0;
|
||||
return core.isset(core.status.hero.items[itemCls][itemId]) ? core.status.hero.items[itemCls][itemId] : 0;
|
||||
}
|
||||
|
||||
////// 是否存在某个物品 //////
|
||||
items.prototype.hasItem = function (itemId) {
|
||||
return core.itemCount(itemId) > 0;
|
||||
}
|
||||
|
||||
////// 设置某个物品的个数 //////
|
||||
items.prototype.setItem = function (itemId, itemNum) {
|
||||
var itemCls = core.material.items[itemId].cls;
|
||||
if (itemCls == 'items') return;
|
||||
if (!core.isset(core.status.hero.items[itemCls])) {
|
||||
core.status.hero.items[itemCls] = {};
|
||||
}
|
||||
core.status.hero.items[itemCls][itemId] = itemNum;
|
||||
if (itemCls!='keys' && itemNum==0) {
|
||||
delete core.status.hero.items[itemCls][itemId];
|
||||
}
|
||||
}
|
||||
|
||||
////// 删除某个物品 //////
|
||||
items.prototype.removeItem = function (itemId) {
|
||||
if (!core.hasItem(itemId)) return false;
|
||||
var itemCls = core.material.items[itemId].cls;
|
||||
core.status.hero.items[itemCls][itemId]--;
|
||||
if (itemCls!='keys' && core.status.hero.items[itemCls][itemId]==0) {
|
||||
delete core.status.hero.items[itemCls][itemId];
|
||||
}
|
||||
core.updateStatusBar();
|
||||
return true;
|
||||
}
|
||||
|
||||
////// 增加某个物品的个数 //////
|
||||
items.prototype.addItem = function (itemId, itemNum) {
|
||||
var itemData = core.material.items[itemId];
|
||||
var itemCls = itemData.cls;
|
||||
if (itemCls == 'items') return;
|
||||
if (!core.isset(core.status.hero.items[itemCls])) {
|
||||
core.status.hero.items[itemCls] = {};
|
||||
core.status.hero.items[itemCls][itemId] = 0;
|
||||
}
|
||||
else if (!core.isset(core.status.hero.items[itemCls][itemId])) {
|
||||
core.status.hero.items[itemCls][itemId] = 0;
|
||||
}
|
||||
core.status.hero.items[itemCls][itemId] += itemNum;
|
||||
}
|
||||
|
||||
|
||||
224
libs/loader.js
Normal file
@ -0,0 +1,224 @@
|
||||
/*
|
||||
loader.js:负责对资源的加载
|
||||
|
||||
*/
|
||||
|
||||
function loader() {
|
||||
this.init();
|
||||
}
|
||||
|
||||
loader.prototype.init = function () {
|
||||
|
||||
}
|
||||
|
||||
////// 设置加载进度条进度 //////
|
||||
loader.prototype.setStartProgressVal = function (val) {
|
||||
core.dom.startTopProgress.style.width = val + '%';
|
||||
}
|
||||
|
||||
////// 设置加载进度条提示文字 //////
|
||||
loader.prototype.setStartLoadTipText = function (text) {
|
||||
core.dom.startTopLoadTips.innerHTML = text;
|
||||
}
|
||||
|
||||
loader.prototype.load = function (callback) {
|
||||
|
||||
// 加载图片
|
||||
core.loader.loadImages(core.materials, core.material.images, function () {
|
||||
// 加载png图片
|
||||
core.material.images.images = {};
|
||||
core.loader.loadImages(core.images, core.material.images.images, function () {
|
||||
// 加载autotile
|
||||
core.material.images.autotile = {};
|
||||
core.loader.loadImages(Object.keys(core.material.icons.autotile), core.material.images.autotile, function () {
|
||||
core.loader.loadAnimates();
|
||||
core.loader.loadMusic();
|
||||
if (core.isset(callback))
|
||||
callback();
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
loader.prototype.loadImages = function (names, toSave, callback) {
|
||||
if (names.length==0) {
|
||||
if (core.isset(callback)) callback();
|
||||
return;
|
||||
}
|
||||
var items = 0;
|
||||
for (var i=0;i<names.length;i++) {
|
||||
this.loadImage(names[i], function (id, image) {
|
||||
core.loader.setStartLoadTipText('正在加载图片 ' + id + "...");
|
||||
toSave[id] = image;
|
||||
items++;
|
||||
core.loader.setStartProgressVal(items * (100 / names.length));
|
||||
if (items == names.length) {
|
||||
if (core.isset(callback)) callback();
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
loader.prototype.loadImage = function (imgName, callback) {
|
||||
try {
|
||||
var name=imgName;
|
||||
if (name.indexOf(".")<0)
|
||||
name=name+".png";
|
||||
var image = new Image();
|
||||
image.src = 'project/images/' + name + "?v=" + main.version;
|
||||
if (image.complete) {
|
||||
callback(imgName, image);
|
||||
return;
|
||||
}
|
||||
image.onload = function () {
|
||||
callback(imgName, image);
|
||||
}
|
||||
}
|
||||
catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
|
||||
loader.prototype.loadAnimates = function () {
|
||||
core.animates.forEach(function (t) {
|
||||
core.http('GET', 'project/animates/' + t + ".animate", null, function (content) {
|
||||
try {
|
||||
content = JSON.parse(content);
|
||||
var data = {};
|
||||
data.ratio = content.ratio;
|
||||
data.images = [];
|
||||
data.images_rev = [];
|
||||
content.bitmaps.forEach(function (t2) {
|
||||
if (!core.isset(t2) || t2 == "") {
|
||||
data.images.push(null);
|
||||
}
|
||||
else {
|
||||
try {
|
||||
var image = new Image();
|
||||
image.src = t2;
|
||||
data.images.push(image);
|
||||
} catch (e) {
|
||||
data.images.push(null);
|
||||
}
|
||||
}
|
||||
})
|
||||
data.frame = content.frame_max;
|
||||
data.frames = [];
|
||||
content.frames.forEach(function (t2) {
|
||||
var info = [];
|
||||
t2.forEach(function (t3) {
|
||||
info.push({
|
||||
'index': t3[0],
|
||||
'x': t3[1],
|
||||
'y': t3[2],
|
||||
'zoom': t3[3],
|
||||
'opacity': t3[4],
|
||||
'mirror': t3[5] || 0,
|
||||
'angle': t3[6] || 0,
|
||||
})
|
||||
})
|
||||
data.frames.push(info);
|
||||
})
|
||||
core.material.animates[t] = data;
|
||||
}
|
||||
catch (e) {
|
||||
console.log(e);
|
||||
core.material.animates[t] = null;
|
||||
}
|
||||
}, function (e) {
|
||||
console.log(e);
|
||||
core.material.animates[t] = null;
|
||||
}, "text/plain; charset=x-user-defined")
|
||||
})
|
||||
}
|
||||
|
||||
////// 加载音频 //////
|
||||
loader.prototype.loadMusic = function () {
|
||||
|
||||
core.bgms.forEach(function (t) {
|
||||
|
||||
// 判断是不是mid
|
||||
if (/^.*\.mid$/i.test(t)) {
|
||||
|
||||
if (core.musicStatus.audioContext!=null) {
|
||||
core.material.bgms[t] = 'loading';
|
||||
|
||||
core.http('GET', 'project/sounds/'+t, null, function (data) {
|
||||
try {
|
||||
var ff = [];
|
||||
var mx = data.length;
|
||||
for (var z = 0; z < mx; z++)
|
||||
ff[z] = String.fromCharCode(data.charCodeAt(z) & 255);
|
||||
var shouldStart = core.material.bgms[t] == 'starting';
|
||||
core.material.bgms[t] = AudioPlayer(core.musicStatus.audioContext, Replayer(MidiFile(ff.join("")), Synth(44100)), true);
|
||||
|
||||
if (shouldStart)
|
||||
core.playBgm(t);
|
||||
}
|
||||
catch (e) {
|
||||
console.log(e);
|
||||
core.material.bgms[t] = null;
|
||||
}
|
||||
}, function (e) {
|
||||
console.log(e);
|
||||
core.material.bgms[t] = null;
|
||||
}, "text/plain; charset=x-user-defined")
|
||||
|
||||
}
|
||||
else {
|
||||
core.material.bgms[t] = null;
|
||||
}
|
||||
}
|
||||
else {
|
||||
var music = new Audio();
|
||||
music.preload = core.musicStatus.startDirectly?'auto':'none';
|
||||
if (main.bgmRemote) music.src = 'https://gitee.com/ckcz123/h5music/raw/master/'+core.firstData.name+'/'+t;
|
||||
else music.src = 'project/sounds/'+t;
|
||||
music.loop = 'loop';
|
||||
core.material.bgms[t] = music;
|
||||
}
|
||||
});
|
||||
|
||||
core.sounds.forEach(function (t) {
|
||||
|
||||
if (core.musicStatus.audioContext != null) {
|
||||
var xhr = new XMLHttpRequest();
|
||||
xhr.open('GET', 'project/sounds/'+t, true);
|
||||
xhr.responseType = 'arraybuffer';
|
||||
xhr.onload = function(e) { //下载完成
|
||||
try {
|
||||
core.musicStatus.audioContext.decodeAudioData(this.response, function (buffer) {
|
||||
core.material.sounds[t] = buffer;
|
||||
}, function (e) {
|
||||
console.log(e);
|
||||
core.material.sounds[t] = null;
|
||||
})
|
||||
}
|
||||
catch (ee) {
|
||||
console.log(ee);
|
||||
core.material.sounds[t] = null;
|
||||
}
|
||||
};
|
||||
|
||||
xhr.ontimeout = function(e) {
|
||||
console.log(e);
|
||||
core.material.sounds[t] = null;
|
||||
}
|
||||
xhr.onerror = function(e) {
|
||||
console.log(e);
|
||||
core.material.sounds[t] = null;
|
||||
}
|
||||
xhr.send();
|
||||
}
|
||||
else {
|
||||
var music = new Audio();
|
||||
music.src = 'project/sounds/'+t;
|
||||
core.material.sounds[t] = music;
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
// 直接开始播放
|
||||
if (core.musicStatus.startDirectly && core.bgms.length>0)
|
||||
core.playBgm(core.bgms[0]);
|
||||
}
|
||||
916
libs/maps.js
@ -1,5 +1,11 @@
|
||||
function maps() {}
|
||||
maps.prototype.init = function() {}
|
||||
function maps() {
|
||||
this.init();
|
||||
}
|
||||
|
||||
maps.prototype.init = function() {
|
||||
this.blocksInfo = maps_90f36752_8815_4be8_b32b_d7fad1d0542e;
|
||||
//delete(maps_90f36752_8815_4be8_b32b_d7fad1d0542e);
|
||||
}
|
||||
|
||||
////// 加载某个楼层(从剧本或存档中) //////
|
||||
maps.prototype.loadFloor = function (floorId, map) {
|
||||
@ -10,23 +16,31 @@ maps.prototype.loadFloor = function (floorId, map) {
|
||||
content['title'] = floor.title;
|
||||
content['canFlyTo'] = floor.canFlyTo;
|
||||
if (!core.isset(map)) map=floor.map;
|
||||
var blocks = [];
|
||||
for (var i = 0; i < 13; i++) {
|
||||
for (var j = 0; j < 13; j++) {
|
||||
var block = this.getBlock(j, i, map[i][j]);
|
||||
this.addInfo(block);
|
||||
this.addEvent(block,j,i,floor.events[j+","+i])
|
||||
this.addChangeFloor(block,j,i,floor.changeFloor[j+","+i]);
|
||||
if (core.isset(block.event)) blocks.push(block);
|
||||
var mapIntoBlocks = function(map,maps,floor){
|
||||
var blocks = [];
|
||||
for (var i = 0; i < 13; i++) {
|
||||
for (var j = 0; j < 13; j++) {
|
||||
var block = maps.initBlock(j, i, map[i][j]);
|
||||
maps.addInfo(block);
|
||||
maps.addEvent(block,j,i,floor.events[j+","+i])
|
||||
maps.addChangeFloor(block,j,i,floor.changeFloor[j+","+i]);
|
||||
if (core.isset(block.event)) blocks.push(block);
|
||||
}
|
||||
}
|
||||
return blocks;
|
||||
}
|
||||
if (main.mode=='editor'){
|
||||
main.editor.mapIntoBlocks = function(map,floor){
|
||||
return mapIntoBlocks(map,core.maps,floor);
|
||||
}
|
||||
}
|
||||
// 事件处理
|
||||
content['blocks'] = blocks;
|
||||
content['blocks'] = mapIntoBlocks(map,this,floor);
|
||||
return content;
|
||||
}
|
||||
|
||||
////// 数字和ID的对应关系 //////
|
||||
maps.prototype.getBlock = function (x, y, id) {
|
||||
maps.prototype.initBlock = function (x, y, id) {
|
||||
var enable=null;
|
||||
id = ""+id;
|
||||
if (id.length>2) {
|
||||
@ -43,199 +57,7 @@ maps.prototype.getBlock = function (x, y, id) {
|
||||
var tmp = {'x': x, 'y': y, 'id': id};
|
||||
if (enable!=null) tmp.enable = enable;
|
||||
|
||||
////////////////////////// 地形部分 //////////////////////////
|
||||
|
||||
// 0-20 地形
|
||||
if (id == 1) tmp.event = {'cls': 'terrains', 'id': 'yellowWall'}; // 黄墙
|
||||
if (id == 2) tmp.event = {'cls': 'terrains', 'id': 'whiteWall'}; // 白墙
|
||||
if (id == 3) tmp.event = {'cls': 'terrains', 'id': 'blueWall'}; // 蓝墙
|
||||
if (id == 4) tmp.event = {'cls': 'animates', 'id': 'star', 'noPass': true}; // 星空
|
||||
if (id == 5) tmp.event = {'cls': 'animates', 'id': 'lava', 'noPass': true}; // 岩浆
|
||||
if (id == 6) tmp.event = {'cls': 'terrains', 'id': 'ice'}; // 冰面
|
||||
if (id == 7) tmp.event = {'cls': 'terrains', 'id': 'blueShop-left'}; // 蓝色商店左
|
||||
if (id == 8) tmp.event = {'cls': 'terrains', 'id': 'blueShop-right'}; // 蓝色商店右
|
||||
if (id == 9) tmp.event = {'cls': 'terrains', 'id': 'pinkShop-left'}; // 粉色商店左
|
||||
if (id == 10) tmp.event = {'cls': 'terrains', 'id': 'pinkShop-right'}; // 粉色商店左
|
||||
if (id == 11) tmp.event = {'cls': 'animates', 'id': 'lavaNet', 'noPass': false, 'trigger': 'passNet'}; // 血网
|
||||
if (id == 12) tmp.event = {'cls': 'animates', 'id': 'poisonNet', 'noPass': false, 'trigger': 'passNet'}; // 毒网
|
||||
if (id == 13) tmp.event = {'cls': 'animates', 'id': 'weakNet', 'noPass': false, 'trigger': 'passNet'}; // 衰网
|
||||
if (id == 14) tmp.event = {'cls': 'animates', 'id': 'curseNet', 'noPass': false, 'trigger': 'passNet'}; // 咒网
|
||||
if (id == 15) tmp.event = {'cls': 'animates', 'id': 'water', 'noPass': true}; // 水
|
||||
// 在这里添加更多地形
|
||||
// 如果空位不足,可以从180以后开始继续放,只要不和现有的数字冲突即可
|
||||
|
||||
// Autotile
|
||||
if (id == 20) tmp.event = {'cls': 'autotile', 'id': 'autotile', 'noPass': true}; // autotile
|
||||
// 更多的autotile从151到160等,只要不和现有的数字冲突即可
|
||||
if (id == 151) tmp.event = {'cls': 'autotile', 'id': 'autotile1', 'noPass': true};
|
||||
if (id == 152) tmp.event = {'cls': 'autotile', 'id': 'autotile2', 'noPass': true};
|
||||
if (id == 153) tmp.event = {'cls': 'autotile', 'id': 'autotile3', 'noPass': true};
|
||||
|
||||
////////////////////////// 物品部分 //////////////////////////
|
||||
|
||||
// 21-80 物品
|
||||
if (id == 21) tmp.event = {'cls': 'items', 'id': 'yellowKey'}; // 黄钥匙
|
||||
if (id == 22) tmp.event = {'cls': 'items', 'id': 'blueKey'}; // 蓝钥匙
|
||||
if (id == 23) tmp.event = {'cls': 'items', 'id': 'redKey'}; // 红钥匙
|
||||
if (id == 24) tmp.event = {'cls': 'items', 'id': 'greenKey'}; // 绿钥匙
|
||||
if (id == 25) tmp.event = {'cls': 'items', 'id': 'steelKey'}; // 铁门钥匙
|
||||
if (id == 26) tmp.event = {'cls': 'items', 'id': 'bigKey'}; // 大黄门钥匙(钥匙盒)
|
||||
if (id == 27) tmp.event = {'cls': 'items', 'id': 'redJewel'}; // 红宝石
|
||||
if (id == 28) tmp.event = {'cls': 'items', 'id': 'blueJewel'}; // 蓝宝石
|
||||
if (id == 29) tmp.event = {'cls': 'items', 'id': 'greenJewel'}; // 绿宝石
|
||||
if (id == 30) tmp.event = {'cls': 'items', 'id': 'yellowJewel'}; // 黄宝石
|
||||
if (id == 31) tmp.event = {'cls': 'items', 'id': 'redPotion'}; // 红血瓶
|
||||
if (id == 32) tmp.event = {'cls': 'items', 'id': 'bluePotion'}; // 蓝血瓶
|
||||
if (id == 33) tmp.event = {'cls': 'items', 'id': 'greenPotion'}; // 绿血瓶
|
||||
if (id == 34) tmp.event = {'cls': 'items', 'id': 'yellowPotion'}; // 黄血瓶
|
||||
if (id == 35) tmp.event = {'cls': 'items', 'id': 'sword1'}; // 铁剑
|
||||
if (id == 36) tmp.event = {'cls': 'items', 'id': 'shield1'}; // 铁盾
|
||||
if (id == 37) tmp.event = {'cls': 'items', 'id': 'sword2'}; // 银剑
|
||||
if (id == 38) tmp.event = {'cls': 'items', 'id': 'shield2'}; // 银盾
|
||||
if (id == 39) tmp.event = {'cls': 'items', 'id': 'sword3'}; // 骑士剑
|
||||
if (id == 40) tmp.event = {'cls': 'items', 'id': 'shield3'}; // 骑士盾
|
||||
if (id == 41) tmp.event = {'cls': 'items', 'id': 'sword4'}; // 圣剑
|
||||
if (id == 42) tmp.event = {'cls': 'items', 'id': 'shield4'}; // 圣盾
|
||||
if (id == 43) tmp.event = {'cls': 'items', 'id': 'sword5'}; // 神圣剑
|
||||
if (id == 44) tmp.event = {'cls': 'items', 'id': 'shield5'}; // 神圣盾
|
||||
if (id == 45) tmp.event = {'cls': 'items', 'id': 'book'}; // 怪物手册
|
||||
if (id == 46) tmp.event = {'cls': 'items', 'id': 'fly'}; // 楼层传送器
|
||||
if (id == 47) tmp.event = {'cls': 'items', 'id': 'pickaxe'}; // 破墙镐
|
||||
if (id == 48) tmp.event = {'cls': 'items', 'id': 'icePickaxe'}; // 破冰镐
|
||||
if (id == 49) tmp.event = {'cls': 'items', 'id': 'bomb'}; // 炸弹
|
||||
if (id == 50) tmp.event = {'cls': 'items', 'id': 'centerFly'}; // 中心对称
|
||||
if (id == 51) tmp.event = {'cls': 'items', 'id': 'upFly'}; // 上楼器
|
||||
if (id == 52) tmp.event = {'cls': 'items', 'id': 'downFly'}; // 下楼器
|
||||
if (id == 53) tmp.event = {'cls': 'items', 'id': 'coin'}; // 幸运金币
|
||||
if (id == 54) tmp.event = {'cls': 'items', 'id': 'snow'}; // 冰冻徽章
|
||||
if (id == 55) tmp.event = {'cls': 'items', 'id': 'cross'}; // 十字架
|
||||
if (id == 56) tmp.event = {'cls': 'items', 'id': 'superPotion'}; // 圣水
|
||||
if (id == 57) tmp.event = {'cls': 'items', 'id': 'earthquake'} // 地震卷轴
|
||||
if (id == 58) tmp.event = {'cls': 'items', 'id': 'poisonWine'} // 解毒药水
|
||||
if (id == 59) tmp.event = {'cls': 'items', 'id': 'weakWine'} // 解衰药水
|
||||
if (id == 60) tmp.event = {'cls': 'items', 'id': 'curseWine'} // 解咒药水
|
||||
if (id == 61) tmp.event = {'cls': 'items', 'id': 'superWine'} // 万能药水
|
||||
if (id == 62) tmp.event = {'cls': 'items', 'id': 'knife'} // 屠龙匕首
|
||||
if (id == 63) tmp.event = {'cls': 'items', 'id': 'moneyPocket'} // 金钱袋
|
||||
if (id == 64) tmp.event = {'cls': 'items', 'id': 'shoes'} // 绿鞋
|
||||
if (id == 65) tmp.event = {'cls': 'items', 'id': 'hammer'} // 圣锤
|
||||
|
||||
|
||||
////////////////////////// 门、楼梯、传送点部分 //////////////////////////
|
||||
|
||||
// 81-100 门
|
||||
if (id == 81) tmp.event = {'cls': 'terrains', 'id': 'yellowDoor', 'trigger': 'openDoor'}; // 黄门
|
||||
if (id == 82) tmp.event = {'cls': 'terrains', 'id': 'blueDoor', 'trigger': 'openDoor'}; // 蓝门
|
||||
if (id == 83) tmp.event = {'cls': 'terrains', 'id': 'redDoor', 'trigger': 'openDoor'}; // 红门
|
||||
if (id == 84) tmp.event = {'cls': 'terrains', 'id': 'greenDoor', 'trigger': 'openDoor'}; // 绿门
|
||||
if (id == 85) tmp.event = {'cls': 'terrains', 'id': 'specialDoor', 'trigger': 'openDoor'}; // 机关门左
|
||||
if (id == 86) tmp.event = {'cls': 'terrains', 'id': 'steelDoor', 'trigger': 'openDoor'}; // 铁门
|
||||
if (id == 87) tmp.event = {'cls': 'terrains', 'id': 'upFloor', 'noPass': false}; // 上楼梯
|
||||
if (id == 88) tmp.event = {'cls': 'terrains', 'id': 'downFloor', 'noPass': false}; // 下楼梯
|
||||
if (id == 89) tmp.event = {'cls': 'animates', 'id': 'portal', 'noPass': false}; // 传送门
|
||||
if (id == 90) tmp.event = {'cls': 'animates', 'id': 'starPortal', 'noPass': false}; // 星空传送门
|
||||
if (id == 91) tmp.event = {'cls': 'animates', 'id': 'upPortal', 'noPass': false}; // 上箭头
|
||||
if (id == 92) tmp.event = {'cls': 'animates', 'id': 'leftPortal', 'noPass': false}; // 左箭头
|
||||
if (id == 93) tmp.event = {'cls': 'animates', 'id': 'downPortal', 'noPass': false}; // 下箭头
|
||||
if (id == 94) tmp.event = {'cls': 'animates', 'id': 'rightPortal', 'noPass': false}; // 右箭头
|
||||
|
||||
|
||||
////////////////////////// NPC部分 //////////////////////////
|
||||
|
||||
// 121-150 NPC
|
||||
if (id == 121) tmp.event = {'cls': 'npcs', 'id': 'man'};
|
||||
if (id == 122) tmp.event = {'cls': 'npcs', 'id': 'woman'};
|
||||
if (id == 123) tmp.event = {'cls': 'npcs', 'id': 'thief'};
|
||||
if (id == 124) tmp.event = {'cls': 'npcs', 'id': 'fairy'};
|
||||
if (id == 125) tmp.event = {'cls': 'npcs', 'id': 'magician'};
|
||||
if (id == 126) tmp.event = {'cls': 'npcs', 'id': 'womanMagician'};
|
||||
if (id == 127) tmp.event = {'cls': 'npcs', 'id': 'oldMan'};
|
||||
if (id == 128) tmp.event = {'cls': 'npcs', 'id': 'child'};
|
||||
if (id == 129) tmp.event = {'cls': 'npcs', 'id': 'wood'};
|
||||
if (id == 130) tmp.event = {'cls': 'npcs', 'id': 'pinkShop'};
|
||||
if (id == 131) tmp.event = {'cls': 'npcs', 'id': 'blueShop'};
|
||||
if (id == 132) tmp.event = {'cls': 'npcs', 'id': 'princess'};
|
||||
|
||||
////////////////////////// 其他部分 //////////////////////////
|
||||
|
||||
// 161-200 其他(单向箭头、灯、箱子等等)
|
||||
if (id == 161) tmp.event = {'cls': 'terrains', 'id': 'arrowUp', 'noPass': false}; // 单向上箭头
|
||||
if (id == 162) tmp.event = {'cls': 'terrains', 'id': 'arrowDown', 'noPass': false}; // 单向下箭头
|
||||
if (id == 163) tmp.event = {'cls': 'terrains', 'id': 'arrowLeft', 'noPass': false}; // 单向左箭头
|
||||
if (id == 164) tmp.event = {'cls': 'terrains', 'id': 'arrowRight', 'noPass': false}; // 单向右箭头
|
||||
if (id == 165) tmp.event = {'cls': 'terrains', 'id': 'light', 'trigger': 'changeLight', 'noPass': false}; // 灯
|
||||
if (id == 166) tmp.event = {'cls': 'terrains', 'id': 'darkLight', 'noPass': true}; // 暗灯
|
||||
if (id == 167) tmp.event = {'cls': 'terrains', 'id': 'ski', 'trigger': 'ski', 'noPass': false}; // 滑冰
|
||||
if (id == 168) tmp.event = {'cls': 'terrains', 'id': 'flower', 'noPass': false}; // 花
|
||||
if (id == 169) tmp.event = {'cls': 'terrains', 'id': 'box', 'trigger': 'pushBox', 'noPass': true}; // 箱子
|
||||
if (id == 170) tmp.event = {'cls': 'terrains', 'id': 'boxed', 'trigger': 'pushBox', 'noPass': true}; // 完成的箱子
|
||||
|
||||
////////////////////////// 怪物部分 //////////////////////////
|
||||
|
||||
// 201-300 怪物
|
||||
if (id == 201) tmp.event = {'cls': 'enemys', 'id': 'greenSlime'};
|
||||
if (id == 202) tmp.event = {'cls': 'enemys', 'id': 'redSlime'};
|
||||
if (id == 203) tmp.event = {'cls': 'enemys', 'id': 'blackSlime'};
|
||||
if (id == 204) tmp.event = {'cls': 'enemys', 'id': 'slimelord'};
|
||||
if (id == 205) tmp.event = {'cls': 'enemys', 'id': 'bat'};
|
||||
if (id == 206) tmp.event = {'cls': 'enemys', 'id': 'bigBat'};
|
||||
if (id == 207) tmp.event = {'cls': 'enemys', 'id': 'redBat'};
|
||||
if (id == 208) tmp.event = {'cls': 'enemys', 'id': 'vampire'};
|
||||
if (id == 209) tmp.event = {'cls': 'enemys', 'id': 'skeleton'};
|
||||
if (id == 210) tmp.event = {'cls': 'enemys', 'id': 'skeletonSoilder'};
|
||||
if (id == 211) tmp.event = {'cls': 'enemys', 'id': 'skeletonCaptain'};
|
||||
if (id == 212) tmp.event = {'cls': 'enemys', 'id': 'ghostSkeleton'};
|
||||
if (id == 213) tmp.event = {'cls': 'enemys', 'id': 'zombie'};
|
||||
if (id == 214) tmp.event = {'cls': 'enemys', 'id': 'zombieKnight'};
|
||||
if (id == 215) tmp.event = {'cls': 'enemys', 'id': 'rock'};
|
||||
if (id == 216) tmp.event = {'cls': 'enemys', 'id': 'slimeMan'};
|
||||
if (id == 217) tmp.event = {'cls': 'enemys', 'id': 'bluePriest'};
|
||||
if (id == 218) tmp.event = {'cls': 'enemys', 'id': 'redPriest'};
|
||||
if (id == 219) tmp.event = {'cls': 'enemys', 'id': 'brownWizard'};
|
||||
if (id == 220) tmp.event = {'cls': 'enemys', 'id': 'redWizard'};
|
||||
if (id == 221) tmp.event = {'cls': 'enemys', 'id': 'yellowGuard'};
|
||||
if (id == 222) tmp.event = {'cls': 'enemys', 'id': 'blueGuard'};
|
||||
if (id == 223) tmp.event = {'cls': 'enemys', 'id': 'redGuard'};
|
||||
if (id == 224) tmp.event = {'cls': 'enemys', 'id': 'swordsman'};
|
||||
if (id == 225) tmp.event = {'cls': 'enemys', 'id': 'soldier'};
|
||||
if (id == 226) tmp.event = {'cls': 'enemys', 'id': 'yellowKnight'};
|
||||
if (id == 227) tmp.event = {'cls': 'enemys', 'id': 'redKnight'};
|
||||
if (id == 228) tmp.event = {'cls': 'enemys', 'id': 'darkKnight'};
|
||||
if (id == 229) tmp.event = {'cls': 'enemys', 'id': 'blackKing'};
|
||||
if (id == 230) tmp.event = {'cls': 'enemys', 'id': 'yellowKing'};
|
||||
if (id == 231) tmp.event = {'cls': 'enemys', 'id': 'greenKing'};
|
||||
if (id == 232) tmp.event = {'cls': 'enemys', 'id': 'blueKnight'};
|
||||
if (id == 233) tmp.event = {'cls': 'enemys', 'id': 'goldSlime'};
|
||||
if (id == 234) tmp.event = {'cls': 'enemys', 'id': 'poisonSkeleton'};
|
||||
if (id == 235) tmp.event = {'cls': 'enemys', 'id': 'poisonBat'};
|
||||
if (id == 236) tmp.event = {'cls': 'enemys', 'id': 'steelRock'};
|
||||
if (id == 237) tmp.event = {'cls': 'enemys', 'id': 'skeletonPriest'};
|
||||
if (id == 238) tmp.event = {'cls': 'enemys', 'id': 'skeletonKing'};
|
||||
if (id == 239) tmp.event = {'cls': 'enemys', 'id': 'skeletonWizard'};
|
||||
if (id == 240) tmp.event = {'cls': 'enemys', 'id': 'redSkeletonCaption'};
|
||||
if (id == 241) tmp.event = {'cls': 'enemys', 'id': 'badHero'};
|
||||
if (id == 242) tmp.event = {'cls': 'enemys', 'id': 'demon'};
|
||||
if (id == 243) tmp.event = {'cls': 'enemys', 'id': 'demonPriest'};
|
||||
if (id == 244) tmp.event = {'cls': 'enemys', 'id': 'goldHornSlime'};
|
||||
if (id == 245) tmp.event = {'cls': 'enemys', 'id': 'redKing'};
|
||||
if (id == 246) tmp.event = {'cls': 'enemys', 'id': 'whiteKing'};
|
||||
if (id == 247) tmp.event = {'cls': 'enemys', 'id': 'blackMagician'};
|
||||
if (id == 248) tmp.event = {'cls': 'enemys', 'id': 'silverSlime'};
|
||||
if (id == 249) tmp.event = {'cls': 'enemys', 'id': 'swordEmperor'};
|
||||
if (id == 250) tmp.event = {'cls': 'enemys', 'id': 'whiteHornSlime'};
|
||||
if (id == 251) tmp.event = {'cls': 'enemys', 'id': 'badPrincess'};
|
||||
if (id == 252) tmp.event = {'cls': 'enemys', 'id': 'badFairy'};
|
||||
if (id == 253) tmp.event = {'cls': 'enemys', 'id': 'grayPriest'};
|
||||
if (id == 254) tmp.event = {'cls': 'enemys', 'id': 'redSwordsman'};
|
||||
if (id == 255) tmp.event = {'cls': 'enemys', 'id': 'whiteGhost'};
|
||||
if (id == 256) tmp.event = {'cls': 'enemys', 'id': 'poisonZombie'};
|
||||
if (id == 257) tmp.event = {'cls': 'enemys', 'id': 'magicDragon'};
|
||||
if (id == 258) tmp.event = {'cls': 'enemys', 'id': 'octopus'};
|
||||
if (id == 259) tmp.event = {'cls': 'enemys', 'id': 'darkFairy'};
|
||||
if (id == 260) tmp.event = {'cls': 'enemys', 'id': 'greenKnight'};
|
||||
|
||||
////////////////////////// 待定... //////////////////////////
|
||||
// 目前ID暂时不要超过400
|
||||
if (id in this.blocksInfo) tmp.event = JSON.parse(JSON.stringify(this.blocksInfo[id]));
|
||||
|
||||
return tmp;
|
||||
}
|
||||
@ -243,14 +65,14 @@ maps.prototype.getBlock = function (x, y, id) {
|
||||
////// 添加一些信息到block上 //////
|
||||
maps.prototype.addInfo = function (block) {
|
||||
if (core.isset(block.event)) {
|
||||
if (block.event.cls == 'enemys' && block.event.trigger==undefined) {
|
||||
if (block.event.cls.indexOf("enemy")==0 && block.event.trigger==undefined) {
|
||||
block.event.trigger = 'battle';
|
||||
}
|
||||
if (block.event.cls == 'items' && block.event.trigger==undefined) {
|
||||
block.event.trigger = 'getItem';
|
||||
}
|
||||
if (block.event.noPass == undefined) {
|
||||
if (block.event.cls=='enemys' || block.event.cls=='terrains' || block.event.cls=='npcs') {
|
||||
if (block.event.cls.indexOf("enemy")==0 || block.event.cls.indexOf("npc")==0 || block.event.cls=='terrains') {
|
||||
block.event.noPass = true;
|
||||
}
|
||||
}
|
||||
@ -258,10 +80,13 @@ maps.prototype.addInfo = function (block) {
|
||||
if (block.event.cls=='enemys' || block.event.cls=='npcs') {
|
||||
block.event.animate = 2;
|
||||
}
|
||||
if (block.event.cls == 'animates') {
|
||||
if (block.event.cls == 'animates' || block.event.cls == 'enemy48' || block.event.cls == 'npc48') {
|
||||
block.event.animate = 4;
|
||||
}
|
||||
}
|
||||
block.event.height = 32;
|
||||
if (block.event.cls == 'enemy48' || block.event.cls == 'npc48')
|
||||
block.event.height = 48;
|
||||
}
|
||||
}
|
||||
|
||||
@ -380,4 +205,677 @@ maps.prototype.getMapArray = function (blockArray){
|
||||
return blocks;
|
||||
}
|
||||
|
||||
main.instance.maps = new maps();
|
||||
|
||||
|
||||
////// 勇士能否前往某方向 //////
|
||||
maps.prototype.canMoveHero = function(x,y,direction,floorId) {
|
||||
if (!core.isset(x)) x=core.getHeroLoc('x');
|
||||
if (!core.isset(y)) y=core.getHeroLoc('y');
|
||||
if (!core.isset(direction)) direction=core.getHeroLoc('direction');
|
||||
if (!core.isset(floorId)) floorId=core.status.floorId;
|
||||
|
||||
// 检查当前块的cannotMove
|
||||
if (core.isset(core.floors[floorId].cannotMove)) {
|
||||
var cannotMove = core.floors[floorId].cannotMove[x+","+y];
|
||||
if (core.isset(cannotMove) && cannotMove instanceof Array && cannotMove.indexOf(direction)>=0)
|
||||
return false;
|
||||
}
|
||||
|
||||
var nowBlock = core.getBlock(x,y,floorId);
|
||||
if (nowBlock!=null){
|
||||
nowId = nowBlock.block.event.id;
|
||||
var nowIsArrow = nowId.slice(0, 5).toLowerCase() == 'arrow';
|
||||
if(nowIsArrow){
|
||||
var nowArrow = nowId.slice(5).toLowerCase();
|
||||
if (direction != nowArrow) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
var scan = {
|
||||
'up': {'x': 0, 'y': -1},
|
||||
'left': {'x': -1, 'y': 0},
|
||||
'down': {'x': 0, 'y': 1},
|
||||
'right': {'x': 1, 'y': 0}
|
||||
};
|
||||
var nextBlock = core.getBlock(x+scan[direction].x,y+scan[direction].y,floorId);
|
||||
if (nextBlock!=null){
|
||||
nextId = nextBlock.block.event.id;
|
||||
// 遇到单向箭头处理
|
||||
var isArrow = nextId.slice(0, 5).toLowerCase() == 'arrow';
|
||||
if(isArrow){
|
||||
var nextArrow = nextId.slice(5).toLowerCase();
|
||||
if ( (scan[direction].x + scan[nextArrow].x) == 0 && (scan[direction].y + scan[nextArrow].y) == 0 ) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
////// 能否瞬间移动 //////
|
||||
maps.prototype.canMoveDirectly = function (destX,destY) {
|
||||
if (!core.flags.enableMoveDirectly) return false;
|
||||
|
||||
// 中毒状态:不能
|
||||
if (core.hasFlag('poison')) return false;
|
||||
|
||||
var fromX = core.getHeroLoc('x'), fromY = core.getHeroLoc('y');
|
||||
if (fromX==destX&&fromY==destY) return false;
|
||||
|
||||
if (core.getBlock(fromX,fromY)!=null||core.status.checkBlock.damage[13*fromX+fromY]>0)
|
||||
return false;
|
||||
|
||||
// BFS
|
||||
var visited=[], queue=[];
|
||||
visited[13*fromX+fromY]=true;
|
||||
queue.push(13*fromX+fromY);
|
||||
|
||||
var directions = [[-1,0],[1,0],[0,1],[0,-1]];
|
||||
while (queue.length>0) {
|
||||
var now=queue.shift(), nowX=parseInt(now/13), nowY=now%13;
|
||||
|
||||
for (var dir in directions) {
|
||||
var nx=nowX+directions[dir][0], ny=nowY+directions[dir][1];
|
||||
if (nx<0||nx>=13||ny<0||ny>=13||visited[13*nx+ny]||core.getBlock(nx,ny)!=null||core.status.checkBlock.damage[13*nx+ny]>0) continue;
|
||||
if (nx==destX&&ny==destY) return true;
|
||||
visited[13*nx+ny]=true;
|
||||
queue.push(13*nx+ny);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
maps.prototype.drawBlock = function (block, animate, dx, dy) {
|
||||
var cls = block.event.cls, height = block.event.height || 32;
|
||||
var blockIcon = core.material.icons[cls][block.event.id];
|
||||
var blockImage = core.material.images[cls];
|
||||
animate=(animate||0)%(block.event.animate||1);
|
||||
dx = dx || 0;
|
||||
dy = dy || 0;
|
||||
core.canvas.event.clearRect(block.x * 32 + dx, block.y * 32 + dy, 32, 32);
|
||||
core.canvas.event.drawImage(blockImage, animate * 32, blockIcon * height + height-32, 32, 32, block.x * 32 + dx, block.y * 32 + dy, 32, 32);
|
||||
if (height>32) {
|
||||
core.canvas.event2.clearRect(block.x * 32 + dx, block.y * 32 + 32 - height + dy, 32, height-32)
|
||||
core.canvas.event2.drawImage(blockImage, animate * 32, blockIcon * height, 32, height-32, block.x * 32 + dx, block.y*32 + 32 - height + dy, 32, height-32);
|
||||
}
|
||||
}
|
||||
|
||||
////// 绘制某张地图 //////
|
||||
maps.prototype.drawMap = function (mapName, callback) {
|
||||
core.clearMap('all');
|
||||
core.removeGlobalAnimate(null, null, true);
|
||||
var drawBg = function(){
|
||||
var groundId = core.floors[mapName].defaultGround || "ground";
|
||||
var blockIcon = core.material.icons.terrains[groundId];
|
||||
var blockImage = core.material.images.terrains;
|
||||
for (var x = 0; x < 13; x++) {
|
||||
for (var y = 0; y < 13; y++) {
|
||||
core.canvas.bg.drawImage(blockImage, 0, blockIcon * 32, 32, 32, x * 32, y * 32, 32, 32);
|
||||
}
|
||||
}
|
||||
|
||||
var images = [];
|
||||
if (core.isset(core.floors[mapName].images)) {
|
||||
images = core.floors[mapName].images;
|
||||
if (typeof images == 'string') {
|
||||
images = [[0, 0, images]];
|
||||
}
|
||||
}
|
||||
images.forEach(function (t) {
|
||||
var size=416, ratio=1;
|
||||
var dx=parseInt(t[0]), dy=parseInt(t[1]), p=t[2];
|
||||
if (core.isset(dx) && core.isset(dy) && core.isset(core.material.images.images[p])) {
|
||||
dx*=32; dy*=32;
|
||||
var image = core.material.images.images[p];
|
||||
if (!t[3])
|
||||
core.canvas.bg.drawImage(image, dx*ratio, dy*ratio, Math.min(size-dx*ratio, ratio*image.width), Math.min(size-dy*ratio, ratio*image.height));
|
||||
else
|
||||
core.canvas.event2.drawImage(image, dx*ratio, dy*ratio, Math.min(size-dx*ratio, ratio*image.width), Math.min(size-dy*ratio, ratio*image.height));
|
||||
}
|
||||
})
|
||||
|
||||
}
|
||||
if (main.mode=='editor'){
|
||||
main.editor.drawMapBg = function(){
|
||||
core.clearMap('bg', 0, 0, 416, 416);
|
||||
drawBg();
|
||||
}
|
||||
} else {
|
||||
drawBg();
|
||||
}
|
||||
|
||||
core.status.floorId = mapName;
|
||||
core.status.thisMap = core.status.maps[mapName];
|
||||
var drawEvent = function(){
|
||||
var mapData = core.status.maps[core.status.floorId];
|
||||
var mapBlocks = mapData.blocks;
|
||||
|
||||
var mapArray = core.maps.getMapArray(mapBlocks);
|
||||
for (var b = 0; b < mapBlocks.length; b++) {
|
||||
// 事件启用
|
||||
var block = mapBlocks[b];
|
||||
if (core.isset(block.event) && !(core.isset(block.enable) && !block.enable)) {
|
||||
if (block.event.cls == 'autotile') {
|
||||
core.drawAutotile(core.canvas.event, mapArray, block, 32, 0, 0);
|
||||
}
|
||||
else {
|
||||
if (block.event.id!='none') {
|
||||
core.drawBlock(block);
|
||||
core.addGlobalAnimate(block);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (main.mode=='editor'){
|
||||
main.editor.updateMap = function(){
|
||||
core.removeGlobalAnimate(null, null, true);
|
||||
core.clearMap('event', 0, 0, 416, 416);
|
||||
drawEvent();
|
||||
core.setGlobalAnimate(core.values.animateSpeed);
|
||||
}
|
||||
} else {
|
||||
drawEvent();
|
||||
}
|
||||
core.setGlobalAnimate(core.values.animateSpeed);
|
||||
if (core.isset(callback))
|
||||
callback();
|
||||
}
|
||||
|
||||
////// 绘制Autotile //////
|
||||
maps.prototype.drawAutotile = function(ctx, mapArr, block, size, left, top){
|
||||
var indexArrs = [ //16种组合的图块索引数组; // 将autotile分割成48块16*16的小块; 数组索引即对应各个小块
|
||||
// +----+----+----+----+----+----+
|
||||
[10, 9, 4, 3 ], //0 bin:0000 | 1 | 2 | 3 | 4 | 5 | 6 |
|
||||
[10, 9, 4, 13], //1 bin:0001 +----+----+----+----+----+----+
|
||||
[10, 9, 18, 3 ], //2 bin:0010 | 7 | 8 | 9 | 10 | 11 | 12 |
|
||||
[10, 9, 16, 15], //3 bin:0011 +----+----+----+----+----+----+
|
||||
[10, 43, 4, 3 ], //4 bin:0100 | 13 | 14 | 15 | 16 | 17 | 18 |
|
||||
[10, 31, 4, 25], //5 bin:0101 +----+----+----+----+----+----+
|
||||
[10, 7, 2, 3 ], //6 bin:0110 | 19 | 20 | 21 | 22 | 23 | 24 |
|
||||
[10, 31, 16, 5 ], //7 bin:0111 +----+----+----+----+----+----+
|
||||
[48, 9, 4, 3 ], //8 bin:1000 | 25 | 26 | 27 | 28 | 29 | 30 |
|
||||
[ 8, 9, 4, 1 ], //9 bin:1001 +----+----+----+----+----+----+
|
||||
[36, 9, 30, 3 ], //10 bin:1010 | 31 | 32 | 33 | 34 | 35 | 36 |
|
||||
[36, 9, 6, 15], //11 bin:1011 +----+----+----+----+----+----+
|
||||
[46, 45, 4, 3 ], //12 bin:1100 | 37 | 38 | 39 | 40 | 41 | 42 |
|
||||
[46, 11, 4, 25], //13 bin:1101 +----+----+----+----+----+----+
|
||||
[12, 45, 30, 3 ], //14 bin:1110 | 43 | 44 | 45 | 46 | 47 | 48 |
|
||||
[34, 33, 28, 27] //15 bin:1111 +----+----+----+----+----+----+
|
||||
];
|
||||
|
||||
var drawBlockByIndex = function(ctx, dx, dy, autotileImg, index, size){ //index为autotile的图块索引1-48
|
||||
var sx = 16*((index-1)%6), sy = 16*(~~((index-1)/6));
|
||||
ctx.drawImage(autotileImg, sx, sy, 16, 16, dx, dy, size/2, size/2);
|
||||
}
|
||||
var getAutotileAroundId = function(currId, x, y){
|
||||
if(x<0 || y<0 || x>12 || y>12) return 1;
|
||||
else return mapArr[y][x]==currId ? 1:0;
|
||||
}
|
||||
var checkAround = function(x, y){ // 得到周围四个32*32块(周围每块都包含当前块的1/4,不清楚的话画下图你就明白)的数组索引
|
||||
var currId = mapArr[y][x];
|
||||
var pointBlock = [];
|
||||
for(var i=0; i<4; i++){
|
||||
var bsum = 0;
|
||||
var offsetx = i%2, offsety = ~~(i/2);
|
||||
for(var j=0; j<4; j++){
|
||||
var mx = j%2, my = ~~(j/2);
|
||||
var b = getAutotileAroundId(currId, x+offsetx+mx-1, y+offsety+my-1);
|
||||
bsum += b*(Math.pow(2, 3-j));
|
||||
}
|
||||
pointBlock.push(bsum);
|
||||
}
|
||||
return pointBlock;
|
||||
}
|
||||
var getAutotileIndexs = function(x, y){
|
||||
var indexArr = [];
|
||||
var pointBlocks = checkAround(x, y);
|
||||
for(var i=0; i<4; i++){
|
||||
var arr = indexArrs[pointBlocks[i]]
|
||||
indexArr.push(arr[3-i]);
|
||||
}
|
||||
return indexArr;
|
||||
}
|
||||
// 开始绘制autotile
|
||||
var x = block.x, y = block.y;
|
||||
var pieceIndexs = getAutotileIndexs(x, y);
|
||||
|
||||
//修正四个边角的固定搭配
|
||||
if(pieceIndexs[0] == 13){
|
||||
if(pieceIndexs[1] == 16) pieceIndexs[1] = 14;
|
||||
if(pieceIndexs[2] == 31) pieceIndexs[2] = 19;
|
||||
}
|
||||
if(pieceIndexs[1] == 18){
|
||||
if(pieceIndexs[0] == 15) pieceIndexs[0] = 17;
|
||||
if(pieceIndexs[3] == 36) pieceIndexs[3] = 24;
|
||||
}
|
||||
if(pieceIndexs[2] == 43){
|
||||
if(pieceIndexs[0] == 25) pieceIndexs[0] = 37;
|
||||
if(pieceIndexs[3] == 46) pieceIndexs[3] = 44;
|
||||
}
|
||||
if(pieceIndexs[3] == 48){
|
||||
if(pieceIndexs[1] == 30) pieceIndexs[1] = 42;
|
||||
if(pieceIndexs[2] == 45) pieceIndexs[2] = 47;
|
||||
}
|
||||
for(var i=0; i<4; i++){
|
||||
var index = pieceIndexs[i];
|
||||
var dx = x*size + size/2*(i%2), dy = y*size + size/2*(~~(i/2));
|
||||
drawBlockByIndex(ctx, dx+left, dy+top, core.material.images['autotile'][block.event.id], index, size);
|
||||
}
|
||||
}
|
||||
|
||||
////// 某个点是否不可通行 //////
|
||||
maps.prototype.noPassExists = function (x, y, floorId) {
|
||||
var block = core.getBlock(x,y,floorId);
|
||||
if (block==null) return false;
|
||||
return core.isset(block.block.event.noPass) && block.block.event.noPass;
|
||||
}
|
||||
|
||||
////// 某个点是否在区域内且不可通行 //////
|
||||
maps.prototype.noPass = function (x, y) {
|
||||
return x<0 || x>12 || y<0 || y>12 || this.noPassExists(x,y);
|
||||
}
|
||||
|
||||
////// 某个点是否存在NPC //////
|
||||
maps.prototype.npcExists = function (x, y, floorId) {
|
||||
var block = this.getBlock(x,y,floorId);
|
||||
if (block==null) return false;
|
||||
return block.block.event.cls.indexOf('npc')==0;
|
||||
}
|
||||
|
||||
////// 某个点是否存在(指定的)地形 //////
|
||||
maps.prototype.terrainExists = function (x, y, id, floorId) {
|
||||
var block = this.getBlock(x,y,floorId);
|
||||
if (block==null) return false;
|
||||
return block.block.event.cls=='terrains' && (core.isset(id)?block.block.event.id==id:true);
|
||||
}
|
||||
|
||||
////// 某个点是否存在楼梯 //////
|
||||
maps.prototype.stairExists = function (x, y, floorId) {
|
||||
var block = this.getBlock(x,y,floorId);
|
||||
if (block==null) return false;
|
||||
return block.block.event.cls=='terrains' && (block.block.event.id=='upFloor' || block.block.event.id=='downFloor');
|
||||
}
|
||||
|
||||
////// 当前位置是否在楼梯边 //////
|
||||
maps.prototype.nearStair = function() {
|
||||
var x=core.getHeroLoc('x'), y=core.getHeroLoc('y');
|
||||
return this.stairExists(x,y) || this.stairExists(x-1,y) || this.stairExists(x,y-1) || this.stairExists(x+1,y) || this.stairExists(x,y+1);
|
||||
}
|
||||
|
||||
////// 某个点是否存在(指定的)怪物 //////
|
||||
maps.prototype.enemyExists = function (x, y, id,floorId) {
|
||||
var block = this.getBlock(x,y,floorId);
|
||||
if (block==null) return false;
|
||||
return block.block.event.cls.indexOf('enemy')==0 && (core.isset(id)?block.block.event.id==id:true);
|
||||
}
|
||||
|
||||
////// 获得某个点的block //////
|
||||
maps.prototype.getBlock = function (x, y, floorId, needEnable) {
|
||||
if (!core.isset(floorId)) floorId=core.status.floorId;
|
||||
if (!core.isset(needEnable)) needEnable=true;
|
||||
var blocks = core.status.maps[floorId].blocks;
|
||||
for (var n=0;n<blocks.length;n++) {
|
||||
if (blocks[n].x==x && blocks[n].y==y && core.isset(blocks[n].event)) {
|
||||
if (needEnable && core.isset(blocks[n].enable) && !blocks[n].enable) return null;
|
||||
return {"index": n, "block": blocks[n]};
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
////// 显示移动某块的动画,达到{“type”:”move”}的效果 //////
|
||||
maps.prototype.moveBlock = function(x,y,steps,time,immediateHide,callback) {
|
||||
time = time || 500;
|
||||
core.status.replay.animate=true;
|
||||
|
||||
core.clearMap('animate', 0, 0, 416, 416);
|
||||
|
||||
var block = core.getBlock(x,y,core.status.floorId,false);
|
||||
if (block==null) {// 不存在
|
||||
if (core.isset(callback)) callback();
|
||||
return;
|
||||
}
|
||||
|
||||
// 需要删除该块
|
||||
core.removeBlock(x,y);
|
||||
|
||||
core.clearMap('ui', 0, 0, 416, 416);
|
||||
core.setAlpha('ui', 1.0);
|
||||
|
||||
block=block.block;
|
||||
var blockIcon = core.material.icons[block.event.cls][block.event.id];
|
||||
var blockImage = core.material.images[block.event.cls];
|
||||
var height = block.event.height || 32;
|
||||
|
||||
var opacityVal = 1;
|
||||
core.setOpacity('animate', opacityVal);
|
||||
core.canvas.animate.drawImage(blockImage, 0, blockIcon * height, 32, height, block.x * 32, block.y * 32 +32 - height, 32, height);
|
||||
|
||||
// 要运行的轨迹:将steps展开
|
||||
var moveSteps=[];
|
||||
steps.forEach(function (e) {
|
||||
if (typeof e=="string") {
|
||||
moveSteps.push(e);
|
||||
}
|
||||
else {
|
||||
if (!core.isset(e.value)) {
|
||||
moveSteps.push(e.direction)
|
||||
}
|
||||
else {
|
||||
for (var i=0;i<e.value;i++) {
|
||||
moveSteps.push(e.direction);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
var nowX=32*x, nowY=32*y, step=0;
|
||||
var scan = {
|
||||
'up': {'x': 0, 'y': -1},
|
||||
'left': {'x': -1, 'y': 0},
|
||||
'down': {'x': 0, 'y': 1},
|
||||
'right': {'x': 1, 'y': 0}
|
||||
};
|
||||
|
||||
var animateValue = block.event.animate || 1;
|
||||
var animateCurrent = 0;
|
||||
var animateTime = 0;
|
||||
|
||||
var animate=window.setInterval(function() {
|
||||
|
||||
animateTime += time / 16 / core.status.replay.speed;
|
||||
if (animateTime >= core.values.animateSpeed) {
|
||||
animateCurrent++;
|
||||
animateTime = 0;
|
||||
if (animateCurrent>=animateValue) animateCurrent=0;
|
||||
}
|
||||
|
||||
// 已经移动完毕,消失
|
||||
if (moveSteps.length==0) {
|
||||
if (immediateHide) opacityVal=0;
|
||||
else opacityVal -= 0.06;
|
||||
core.setOpacity('animate', opacityVal);
|
||||
core.clearMap('animate', nowX, nowY-height+32, 32, height);
|
||||
core.canvas.animate.drawImage(blockImage, animateCurrent * 32, blockIcon * height, 32, height, nowX, nowY-height+32, 32, height);
|
||||
if (opacityVal<=0) {
|
||||
clearInterval(animate);
|
||||
core.clearMap('animate', 0, 0, 416, 416);
|
||||
core.setOpacity('animate', 1);
|
||||
core.status.replay.animate=false;
|
||||
if (core.isset(callback)) callback();
|
||||
}
|
||||
}
|
||||
else {
|
||||
// 移动中
|
||||
step++;
|
||||
nowX+=scan[moveSteps[0]].x*2;
|
||||
nowY+=scan[moveSteps[0]].y*2;
|
||||
core.clearMap('animate', nowX-32, nowY-32, 96, 96);
|
||||
// 绘制
|
||||
core.canvas.animate.drawImage(blockImage, animateCurrent * 32, blockIcon * height, 32, height, nowX, nowY-height+32, 32, height);
|
||||
if (step==16) {
|
||||
// 该移动完毕,继续
|
||||
step=0;
|
||||
moveSteps.shift();
|
||||
}
|
||||
}
|
||||
}, time / 16 / core.status.replay.speed);
|
||||
}
|
||||
|
||||
////// 显示/隐藏某个块时的动画效果 //////
|
||||
maps.prototype.animateBlock = function (loc,type,time,callback) {
|
||||
if (type!='hide') type='show';
|
||||
|
||||
core.clearMap('animate', 0, 0, 416, 416);
|
||||
|
||||
if (typeof loc[0] == 'number' && typeof loc[1] == 'number')
|
||||
loc = [loc];
|
||||
|
||||
var list = [];
|
||||
loc.forEach(function (t) {
|
||||
var block = core.getBlock(t[0],t[1],core.status.floorId,false);
|
||||
if (block==null) return;
|
||||
block=block.block;
|
||||
list.push({
|
||||
'x': t[0], 'y': t[1], 'height': block.event.height||32,
|
||||
'blockIcon': core.material.icons[block.event.cls][block.event.id],
|
||||
'blockImage': core.material.images[block.event.cls]
|
||||
})
|
||||
})
|
||||
|
||||
if (list.length==0) {
|
||||
if (core.isset(callback)) callback();
|
||||
return;
|
||||
}
|
||||
|
||||
core.status.replay.animate=true;
|
||||
var draw = function () {
|
||||
list.forEach(function (t) {
|
||||
core.canvas.animate.drawImage(t.blockImage, 0, t.blockIcon*t.height, 32, t.height, t.x*32, t.y*32+32-t.height, 32, t.height);
|
||||
})
|
||||
}
|
||||
|
||||
var opacityVal = 0;
|
||||
if (type=='hide') opacityVal=1;
|
||||
|
||||
core.setOpacity('animate', opacityVal);
|
||||
draw();
|
||||
|
||||
var animate = window.setInterval(function () {
|
||||
if (type=='show') opacityVal += 0.1;
|
||||
else opacityVal -= 0.1;
|
||||
core.setOpacity('animate', opacityVal);
|
||||
core.clearMap('animate',0,0,416,416);
|
||||
|
||||
draw();
|
||||
if (opacityVal >=1 || opacityVal<=0) {
|
||||
clearInterval(animate);
|
||||
core.clearMap('animate', 0, 0, 416, 416);
|
||||
core.setOpacity('animate', 1);
|
||||
core.status.replay.animate=false;
|
||||
if (core.isset(callback)) callback();
|
||||
}
|
||||
}, time / 10 / core.status.replay.speed);
|
||||
}
|
||||
|
||||
////// 将某个块从禁用变成启用状态 //////
|
||||
maps.prototype.showBlock = function(x, y, floodId) {
|
||||
floodId = floodId || core.status.floorId;
|
||||
var block = core.getBlock(x,y,floodId,false);
|
||||
if (block==null) return; // 不存在
|
||||
block=block.block;
|
||||
// 本身是禁用事件,启用之
|
||||
if (core.isset(block.enable) && !block.enable) {
|
||||
block.enable = true;
|
||||
// 在本层,添加动画
|
||||
if (floodId == core.status.floorId && core.isset(block.event)) {
|
||||
core.drawBlock(block);
|
||||
core.addGlobalAnimate(block);
|
||||
core.syncGlobalAnimate();
|
||||
}
|
||||
core.updateStatusBar();
|
||||
}
|
||||
}
|
||||
|
||||
////// 将某个块从启用变成禁用状态 //////
|
||||
maps.prototype.removeBlock = function (x, y, floorId) {
|
||||
floorId = floorId || core.status.floorId;
|
||||
|
||||
var block = core.getBlock(x,y,floorId,false);
|
||||
if (block==null) return; // 不存在
|
||||
|
||||
var index=block.index;
|
||||
|
||||
// 删除动画,清除地图
|
||||
if (floorId==core.status.floorId) {
|
||||
core.removeGlobalAnimate(x, y);
|
||||
core.canvas.event.clearRect(x * 32, y * 32, 32, 32);
|
||||
var height = 32;
|
||||
if (core.isset(block.block.event)) height=block.block.event.height||32;
|
||||
if (height>32)
|
||||
core.canvas.event2.clearRect(x * 32, y * 32 +32-height, 32, height-32);
|
||||
}
|
||||
|
||||
// 删除Index
|
||||
core.removeBlockById(index, floorId);
|
||||
core.updateFg();
|
||||
}
|
||||
|
||||
////// 根据block的索引删除该块 //////
|
||||
maps.prototype.removeBlockById = function (index, floorId) {
|
||||
|
||||
var blocks = core.status.maps[floorId].blocks, block = blocks[index];
|
||||
var x=block.x, y=block.y;
|
||||
|
||||
// 检查该点是否存在事件
|
||||
var event = core.floors[floorId].events[x+","+y];
|
||||
if (!core.isset(event))
|
||||
event = core.floors[floorId].changeFloor[x+","+y];
|
||||
|
||||
// 检查是否存在重生
|
||||
var isReborn = false;
|
||||
if (core.isset(block.event) && block.event.cls.indexOf('enemy')==0
|
||||
&& core.enemys.hasSpecial(core.material.enemys[block.event.id].special, 23))
|
||||
isReborn = true;
|
||||
|
||||
// 不存在事件,直接删除
|
||||
if (!isReborn && !core.isset(event)) {
|
||||
blocks.splice(index,1);
|
||||
return;
|
||||
}
|
||||
block.enable = false;
|
||||
}
|
||||
|
||||
////// 一次性删除多个block //////
|
||||
maps.prototype.removeBlockByIds = function (floorId, ids) {
|
||||
ids.sort(function (a,b) {return b-a}).forEach(function (id) {
|
||||
core.removeBlockById(id, floorId);
|
||||
});
|
||||
}
|
||||
|
||||
////// 添加一个全局动画 //////
|
||||
maps.prototype.addGlobalAnimate = function (b) {
|
||||
if (main.mode=='editor' && main.editor.disableGlobalAnimate) return;
|
||||
if (!core.isset(b.event) || !core.isset(b.event.animate) || b.event.animate==1) return;
|
||||
|
||||
var block = core.clone(b);
|
||||
block.status = 0;
|
||||
|
||||
core.status.globalAnimateObjs.push(block);
|
||||
|
||||
}
|
||||
|
||||
////// 删除一个或所有全局动画 //////
|
||||
maps.prototype.removeGlobalAnimate = function (x, y, all) {
|
||||
if (main.mode=='editor' && main.editor.disableGlobalAnimate) return;
|
||||
|
||||
if (all) {
|
||||
core.status.globalAnimateObjs = [];
|
||||
return;
|
||||
}
|
||||
|
||||
for (var t = 0; t < core.status.globalAnimateObjs.length; t++) {
|
||||
if (core.status.globalAnimateObjs[t].x == x && core.status.globalAnimateObjs[t].y == y) {
|
||||
core.status.globalAnimateObjs.splice(t, 1);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
////// 设置全局动画的显示效果 //////
|
||||
maps.prototype.setGlobalAnimate = function (speed) {
|
||||
if (main.mode=='editor' && main.editor.disableGlobalAnimate) return;
|
||||
core.syncGlobalAnimate();
|
||||
core.animateFrame.speed = speed;
|
||||
core.animateFrame.globalAnimate = true;
|
||||
}
|
||||
|
||||
////// 同步所有的全局动画效果 //////
|
||||
maps.prototype.syncGlobalAnimate = function () {
|
||||
core.status.globalAnimateObjs.forEach(function (t) {
|
||||
t.status=0;
|
||||
})
|
||||
}
|
||||
|
||||
////// 绘制UI层的box动画 //////
|
||||
maps.prototype.drawBoxAnimate = function () {
|
||||
for (var a = 0; a < core.status.boxAnimateObjs.length; a++) {
|
||||
var obj = core.status.boxAnimateObjs[a];
|
||||
obj.status = ((obj.status||0)+1)%obj.animate;
|
||||
core.clearMap('ui', obj.bgx, obj.bgy, obj.bgWidth, obj.bgHeight);
|
||||
core.fillRect('ui', obj.bgx, obj.bgy, obj.bgWidth, obj.bgHeight, core.animateFrame.background);
|
||||
core.canvas.ui.drawImage(obj.image, obj.status * 32, obj.pos,
|
||||
32, obj.height, obj.x, obj.y, 32, obj.height);
|
||||
}
|
||||
}
|
||||
|
||||
////// 绘制动画 //////
|
||||
maps.prototype.drawAnimate = function (name, x, y, callback) {
|
||||
|
||||
// 正在播放录像:不显示动画
|
||||
if (core.isset(core.status.replay) && core.status.replay.replaying) {
|
||||
if (core.isset(callback)) callback();
|
||||
return;
|
||||
}
|
||||
|
||||
// 检测动画是否存在
|
||||
if (!core.isset(core.material.animates[name]) || !core.isset(x) || !core.isset(y)) {
|
||||
if (core.isset(callback)) callback();
|
||||
return;
|
||||
}
|
||||
|
||||
// 清空animate层
|
||||
clearInterval(core.interval.animateInterval);
|
||||
core.clearMap('animate', 0, 0, 416, 416);
|
||||
|
||||
// 开始绘制
|
||||
var animate = core.material.animates[name];
|
||||
var ratio = animate.ratio;
|
||||
var centerX = 32*x+16, centerY = 32*y+16;
|
||||
var index=0;
|
||||
|
||||
var draw = function (index) {
|
||||
core.clearMap('animate', 0, 0, 416, 416);
|
||||
|
||||
var frame = animate.frames[index];
|
||||
frame.forEach(function (t) {
|
||||
var image = animate.images[t.index];
|
||||
if (!core.isset(image)) return;
|
||||
var realWidth = image.width * ratio * t.zoom / 100;
|
||||
var realHeight = image.height * ratio * t.zoom / 100;
|
||||
core.setAlpha('animate', t.opacity / 255);
|
||||
|
||||
var cx = centerX+t.x, cy=centerY+t.y;
|
||||
|
||||
if (!t.mirror && !t.angle) {
|
||||
core.canvas.animate.drawImage(image, cx-realWidth/2, cy-realHeight/2, realWidth, realHeight);
|
||||
}
|
||||
else {
|
||||
core.saveCanvas('animate');
|
||||
core.canvas.animate.translate(cx,cy);
|
||||
if (t.angle)
|
||||
core.canvas.animate.rotate(-t.angle*Math.PI/180);
|
||||
if (t.mirror)
|
||||
core.canvas.animate.scale(-1,1);
|
||||
core.canvas.animate.drawImage(image, -realWidth/2, -realHeight/2, realWidth, realHeight);
|
||||
core.loadCanvas('animate');
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
draw(index++);
|
||||
|
||||
core.interval.animateInterval = setInterval(function (t) {
|
||||
if (index == animate.frames.length) {
|
||||
clearInterval(core.interval.animateInterval);
|
||||
core.clearMap('animate', 0, 0, 416, 416);
|
||||
core.setAlpha('animate', 1);
|
||||
if (core.isset(callback)) callback();
|
||||
return;
|
||||
}
|
||||
draw(index++);
|
||||
}, 50);
|
||||
}
|
||||
487
libs/ui.js
@ -3,14 +3,146 @@
|
||||
* 包括:
|
||||
* 自动寻路、怪物手册、楼传器、存读档、菜单栏、NPC对话事件、等等
|
||||
*/
|
||||
function ui() {}
|
||||
function ui() {
|
||||
this.init();
|
||||
}
|
||||
|
||||
// 初始化UI
|
||||
ui.prototype.init = function () {
|
||||
this.uidata = functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a.ui;
|
||||
}
|
||||
|
||||
main.instance.ui = new ui();
|
||||
////////////////// 地图设置
|
||||
|
||||
////// 清除地图 //////
|
||||
ui.prototype.clearMap = function (map, x, y, width, height) {
|
||||
if (map == 'all') {
|
||||
for (var m in core.canvas) {
|
||||
core.canvas[m].clearRect(0, 0, 416, 416);
|
||||
}
|
||||
}
|
||||
else {
|
||||
core.canvas[map].clearRect(x||0, y||0, width||416, height||416);
|
||||
}
|
||||
}
|
||||
|
||||
////// 在某个canvas上绘制一段文字 //////
|
||||
ui.prototype.fillText = function (map, text, x, y, style, font) {
|
||||
if (core.isset(style)) {
|
||||
core.setFillStyle(map, style);
|
||||
}
|
||||
if (core.isset(font)) {
|
||||
core.setFont(map, font);
|
||||
}
|
||||
core.canvas[map].fillText(text, x, y);
|
||||
}
|
||||
|
||||
////// 在某个canvas上绘制一个矩形 //////
|
||||
ui.prototype.fillRect = function (map, x, y, width, height, style) {
|
||||
if (core.isset(style)) {
|
||||
core.setFillStyle(map, style);
|
||||
}
|
||||
core.canvas[map].fillRect(x, y, width, height);
|
||||
}
|
||||
|
||||
////// 在某个canvas上绘制一个矩形的边框 //////
|
||||
ui.prototype.strokeRect = function (map, x, y, width, height, style, lineWidth) {
|
||||
if (core.isset(style)) {
|
||||
core.setStrokeStyle(map, style);
|
||||
}
|
||||
if (core.isset(lineWidth)) {
|
||||
core.setLineWidth(map, lineWidth);
|
||||
}
|
||||
core.canvas[map].strokeRect(x, y, width, height);
|
||||
}
|
||||
|
||||
////// 在某个canvas上绘制一条线 //////
|
||||
ui.prototype.drawLine = function (map, x1, y1, x2, y2, style, lineWidth) {
|
||||
if (core.isset(style)) {
|
||||
core.setStrokeStyle(map, style);
|
||||
}
|
||||
if (core.isset(lineWidth)) {
|
||||
core.setLineWidth(map, lineWidth);
|
||||
}
|
||||
core.canvas[map].beginPath();
|
||||
core.canvas[map].moveTo(x1, y1);
|
||||
core.canvas[map].lineTo(x2, y2);
|
||||
core.canvas[map].closePath();
|
||||
core.canvas[map].stroke();
|
||||
}
|
||||
|
||||
////// 设置某个canvas的文字字体 //////
|
||||
ui.prototype.setFont = function (map, font) {
|
||||
core.canvas[map].font = font;
|
||||
}
|
||||
|
||||
////// 设置某个canvas的线宽度 //////
|
||||
ui.prototype.setLineWidth = function (map, lineWidth) {
|
||||
if (map == 'all') {
|
||||
for (var m in core.canvas) {
|
||||
core.canvas[m].lineWidth = lineWidth;
|
||||
}
|
||||
}
|
||||
core.canvas[map].lineWidth = lineWidth;
|
||||
}
|
||||
|
||||
////// 保存某个canvas状态 //////
|
||||
ui.prototype.saveCanvas = function (map) {
|
||||
core.canvas[map].save();
|
||||
}
|
||||
|
||||
////// 加载某个canvas状态 //////
|
||||
ui.prototype.loadCanvas = function (map) {
|
||||
core.canvas[map].restore();
|
||||
}
|
||||
|
||||
////// 设置某个canvas边框属性 //////
|
||||
ui.prototype.setStrokeStyle = function (map, style) {
|
||||
if (map == 'all') {
|
||||
for (var m in core.canvas) {
|
||||
core.canvas[m].strokeStyle = style;
|
||||
}
|
||||
}
|
||||
else {
|
||||
core.canvas[map].strokeStyle = style;
|
||||
}
|
||||
}
|
||||
|
||||
////// 设置某个canvas的alpha值 //////
|
||||
ui.prototype.setAlpha = function (map, alpha) {
|
||||
if (map == 'all') {
|
||||
for (var m in core.canvas) {
|
||||
core.canvas[m].globalAlpha = alpha;
|
||||
}
|
||||
}
|
||||
else core.canvas[map].globalAlpha = alpha;
|
||||
}
|
||||
|
||||
////// 设置某个canvas的透明度 //////
|
||||
ui.prototype.setOpacity = function (map, opacity) {
|
||||
if (map == 'all') {
|
||||
for (var m in core.canvas) {
|
||||
core.canvas[m].canvas.style.opacity = opacity;
|
||||
}
|
||||
}
|
||||
else core.canvas[map].canvas.style.opacity = opacity;
|
||||
}
|
||||
|
||||
////// 设置某个canvas的绘制属性(如颜色等) //////
|
||||
ui.prototype.setFillStyle = function (map, style) {
|
||||
if (map == 'all') {
|
||||
for (var m in core.canvas) {
|
||||
core.canvas[m].fillStyle = style;
|
||||
}
|
||||
}
|
||||
else {
|
||||
core.canvas[map].fillStyle = style;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
///////////////// UI绘制
|
||||
|
||||
////// 结束一切事件和绘制,关闭UI窗口,返回游戏进程 //////
|
||||
ui.prototype.closePanel = function () {
|
||||
@ -26,13 +158,115 @@ ui.prototype.closePanel = function () {
|
||||
core.status.event.interval = null;
|
||||
}
|
||||
|
||||
////// 左上角绘制一段提示 //////
|
||||
ui.prototype.drawTip = function (text, itemIcon) {
|
||||
var textX, textY, width, height, hide = false, opacityVal = 0;
|
||||
clearInterval(core.interval.tipAnimate);
|
||||
core.setFont('data', "16px Arial");
|
||||
core.setOpacity('data', 0);
|
||||
core.canvas.data.textAlign = 'left';
|
||||
if (!core.isset(itemIcon)) {
|
||||
textX = 16;
|
||||
textY = 18;
|
||||
width = textX + core.canvas.data.measureText(text).width + 16;
|
||||
height = 42;
|
||||
}
|
||||
else {
|
||||
textX = 44;
|
||||
textY = 18;
|
||||
width = textX + core.canvas.data.measureText(text).width + 8;
|
||||
height = 42;
|
||||
}
|
||||
core.interval.tipAnimate = window.setInterval(function () {
|
||||
if (hide) {
|
||||
opacityVal -= 0.1;
|
||||
}
|
||||
else {
|
||||
opacityVal += 0.1;
|
||||
}
|
||||
core.setOpacity('data', opacityVal);
|
||||
core.clearMap('data', 5, 5, 400, height);
|
||||
core.fillRect('data', 5, 5, width, height, '#000');
|
||||
if (core.isset(itemIcon)) {
|
||||
core.canvas.data.drawImage(core.material.images.items, 0, itemIcon * 32, 32, 32, 10, 8, 32, 32);
|
||||
}
|
||||
core.fillText('data', text, textX + 5, textY + 15, '#fff');
|
||||
if (opacityVal > 0.6 || opacityVal < 0) {
|
||||
if (hide) {
|
||||
core.clearMap('data', 5, 5, 400, height);
|
||||
core.setOpacity('data', 1);
|
||||
clearInterval(core.interval.tipAnimate);
|
||||
return;
|
||||
}
|
||||
else {
|
||||
if (!core.isset(core.timeout.getItemTipTimeout)) {
|
||||
core.timeout.getItemTipTimeout = window.setTimeout(function () {
|
||||
hide = true;
|
||||
core.timeout.getItemTipTimeout = null;
|
||||
}, 750);
|
||||
}
|
||||
opacityVal = 0.6;
|
||||
core.setOpacity('data', opacityVal);
|
||||
}
|
||||
}
|
||||
}, 30);
|
||||
}
|
||||
|
||||
////// 地图中间绘制一段文字 //////
|
||||
ui.prototype.drawText = function (contents, callback) {
|
||||
if (core.isset(contents)) {
|
||||
|
||||
// 合并
|
||||
if ((core.isset(core.status.event)&&core.status.event.id=='action') || (core.isset(core.status.replay)&&core.status.replay.replaying)) {
|
||||
core.insertAction(contents,null,null,callback);
|
||||
return;
|
||||
}
|
||||
|
||||
if (typeof contents == 'string') {
|
||||
contents = [{'content': contents}];
|
||||
}
|
||||
else if (contents instanceof Object && core.isset(contents.content)) {
|
||||
contents = [contents];
|
||||
}
|
||||
else if (!(contents instanceof Array)) {
|
||||
core.drawTip("出错了");
|
||||
console.log(contents);
|
||||
return;
|
||||
}
|
||||
|
||||
core.status.event = {'id': 'text', 'data': {'list': contents, 'callback': callback}};
|
||||
core.lockControl();
|
||||
|
||||
// wait the hero to stop
|
||||
core.stopAutomaticRoute();
|
||||
setTimeout(function() {
|
||||
core.drawText();
|
||||
}, 30);
|
||||
return;
|
||||
}
|
||||
|
||||
if (core.status.event.data.list.length==0) {
|
||||
var callback = core.status.event.data.callback;
|
||||
core.ui.closePanel(false);
|
||||
if (core.isset(callback)) callback();
|
||||
return;
|
||||
}
|
||||
|
||||
var data=core.status.event.data.list.shift();
|
||||
if (typeof data == 'string')
|
||||
core.ui.drawTextBox(data);
|
||||
else
|
||||
core.ui.drawTextBox(data.content, data.id);
|
||||
// core.drawTextBox(content);
|
||||
}
|
||||
|
||||
////// 绘制一个对话框 //////
|
||||
ui.prototype.drawTextBox = function(content) {
|
||||
|
||||
clearInterval(core.status.event.interval);
|
||||
|
||||
// 获得name, image, icon
|
||||
var id=null, name=null, image=null, icon=null;
|
||||
var id=null, name=null, image=null, icon=null, iconHeight=32, animate=null;
|
||||
if (content.indexOf("\t[")==0 || content.indexOf("\\t[")==0) {
|
||||
var index = content.indexOf("]");
|
||||
if (index>=0) {
|
||||
@ -45,11 +279,21 @@ ui.prototype.drawTextBox = function(content) {
|
||||
id=ss[0];
|
||||
// monster
|
||||
if (id!='hero') {
|
||||
var enemys = core.material.enemys[id];
|
||||
if (core.isset(enemys)) {
|
||||
if (core.isset(core.material.enemys[id])) {
|
||||
name = core.material.enemys[id].name;
|
||||
image = core.material.images.enemys;
|
||||
icon = core.material.icons.enemys[id];
|
||||
|
||||
if (core.isset(core.material.icons.enemy48[id])) {
|
||||
image = core.material.images.enemy48;
|
||||
icon = core.material.icons.enemy48[id];
|
||||
iconHeight = 48;
|
||||
animate=4;
|
||||
}
|
||||
else {
|
||||
image = core.material.images.enemys;
|
||||
icon = core.material.icons.enemys[id];
|
||||
iconHeight = 32;
|
||||
animate=2;
|
||||
}
|
||||
}
|
||||
else {
|
||||
name=id;
|
||||
@ -62,8 +306,18 @@ ui.prototype.drawTextBox = function(content) {
|
||||
else {
|
||||
id='npc';
|
||||
name=ss[0];
|
||||
image=core.material.images.npcs;
|
||||
icon=core.material.icons.npcs[ss[1]];
|
||||
if (core.isset(core.material.icons.npc48[ss[1]])) {
|
||||
image = core.material.images.npc48;
|
||||
icon = core.material.icons.npc48[ss[1]];
|
||||
iconHeight = 48;
|
||||
animate=4;
|
||||
}
|
||||
else {
|
||||
image = core.material.images.npcs;
|
||||
icon = core.material.icons.npcs[ss[1]];
|
||||
iconHeight = 32;
|
||||
animate=2;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -72,7 +326,7 @@ ui.prototype.drawTextBox = function(content) {
|
||||
|
||||
var textAttribute = core.status.textAttribute || core.initStatus.textAttribute;
|
||||
|
||||
var position = textAttribute.position, px=null, py=null, ydelta=0;
|
||||
var position = textAttribute.position, px=null, py=null, ydelta=iconHeight-32;
|
||||
if (content.indexOf("\b[")==0 || content.indexOf("\\b[")==0) {
|
||||
var index = content.indexOf("]");
|
||||
if (index>=0) {
|
||||
@ -121,7 +375,7 @@ ui.prototype.drawTextBox = function(content) {
|
||||
if (textAttribute.bold) font = "bold "+font;
|
||||
var contents = core.splitLines("ui", content, validWidth, font);
|
||||
|
||||
var height = 20 + 21*(contents.length+1) + (id=='hero'?core.material.icons.hero.height-10:core.isset(name)?32-10:0);
|
||||
var height = 20 + 21*(contents.length+1) + (id=='hero'?core.material.icons.hero.height-10:core.isset(name)?iconHeight-10:0);
|
||||
|
||||
|
||||
var xoffset = 6, yoffset = 22;
|
||||
@ -157,7 +411,7 @@ ui.prototype.drawTextBox = function(content) {
|
||||
core.fillRect('ui', left, top, right, height);
|
||||
core.strokeRect('ui', left - 1, top - 1, right + 1, height + 1, '#FFFFFF', 2);
|
||||
|
||||
var xoffset = 6;
|
||||
var xoffset = 9;
|
||||
|
||||
// draw triangle
|
||||
if (position=='up' && core.isset(px) && core.isset(py)) {
|
||||
@ -213,12 +467,16 @@ ui.prototype.drawTextBox = function(content) {
|
||||
else {
|
||||
core.fillText('ui', name, content_left, top + 30, null, 'bold 22px Verdana');
|
||||
if (core.isset(icon)) {
|
||||
core.strokeRect('ui', left + 15 - 1, top + 40 - 1, 34, 34, null, 2);
|
||||
|
||||
core.strokeRect('ui', left + 15 - 1, top + 40 - 1, 34, iconHeight + 2, null, 2);
|
||||
core.status.boxAnimateObjs = [];
|
||||
core.status.boxAnimateObjs.push({
|
||||
'bgx': left + 15, 'bgy': top + 40, 'bgsize': 32,
|
||||
'image': image, 'x': left + 15, 'y': top + 40, 'icon': icon
|
||||
'bgx': left + 15, 'bgy': top + 40, 'bgWidth': 32, 'bgHeight': iconHeight,
|
||||
'x': left+15, 'y': top+40, 'height': iconHeight, 'animate': animate,
|
||||
'image': image,
|
||||
'pos': icon*iconHeight
|
||||
});
|
||||
|
||||
core.drawBoxAnimate();
|
||||
}
|
||||
}
|
||||
@ -276,7 +534,7 @@ ui.prototype.drawChoices = function(content, choices) {
|
||||
if (length%2==0) bottom+=16;
|
||||
var choice_top = bottom-height+56;
|
||||
|
||||
var id=null, name=null, image=null, icon=null;
|
||||
var id=null, name=null, image=null, icon=null, iconHeight=32, animate=null;
|
||||
|
||||
var contents = null;
|
||||
var content_left = left + 15;
|
||||
@ -294,11 +552,21 @@ ui.prototype.drawChoices = function(content, choices) {
|
||||
id=ss[0];
|
||||
// monster
|
||||
if (id!='hero') {
|
||||
var enemys = core.material.enemys[id];
|
||||
if (core.isset(enemys)) {
|
||||
if (core.isset(core.material.enemys[id])) {
|
||||
name = core.material.enemys[id].name;
|
||||
image = core.material.images.enemys;
|
||||
icon = core.material.icons.enemys[id];
|
||||
|
||||
if (core.isset(core.material.icons.enemy48[id])) {
|
||||
image = core.material.images.enemy48;
|
||||
icon = core.material.icons.enemy48[id];
|
||||
iconHeight = 48;
|
||||
animate=4;
|
||||
}
|
||||
else {
|
||||
image = core.material.images.enemys;
|
||||
icon = core.material.icons.enemys[id];
|
||||
iconHeight = 32;
|
||||
animate=2;
|
||||
}
|
||||
}
|
||||
else {
|
||||
name=id;
|
||||
@ -311,8 +579,18 @@ ui.prototype.drawChoices = function(content, choices) {
|
||||
else {
|
||||
id='npc';
|
||||
name=ss[0];
|
||||
image=core.material.images.npcs;
|
||||
icon=core.material.icons.npcs[ss[1]];
|
||||
if (core.isset(core.material.icons.npc48[ss[1]])) {
|
||||
image = core.material.images.npc48;
|
||||
icon = core.material.icons.npc48[ss[1]];
|
||||
iconHeight = 48;
|
||||
animate=4;
|
||||
}
|
||||
else {
|
||||
image = core.material.images.npcs;
|
||||
icon = core.material.icons.npcs[ss[1]];
|
||||
iconHeight = 32;
|
||||
animate=2;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -361,11 +639,13 @@ ui.prototype.drawChoices = function(content, choices) {
|
||||
else {
|
||||
core.fillText('ui', name, title_offset, top + 27, '#FFD700', 'bold 19px Verdana');
|
||||
if (core.isset(icon)) {
|
||||
core.strokeRect('ui', left + 15 - 1, top + 30 - 1, 34, 34, '#DDDDDD', 2);
|
||||
core.strokeRect('ui', left + 15 - 1, top + 30 - 1, 34, iconHeight + 2, '#DDDDDD', 2);
|
||||
core.status.boxAnimateObjs = [];
|
||||
core.status.boxAnimateObjs.push({
|
||||
'bgx': left + 15, 'bgy': top + 30, 'bgsize': 32,
|
||||
'image': image, 'x': left + 15, 'y': top + 30, 'icon': icon
|
||||
'bgx': left + 15, 'bgy': top + 30, 'bgWidth': 32, 'bgHeight': iconHeight,
|
||||
'x': left+15, 'y': top+30, 'height': iconHeight, 'animate': animate,
|
||||
'image': image,
|
||||
'pos': icon*iconHeight
|
||||
});
|
||||
core.drawBoxAnimate();
|
||||
}
|
||||
@ -575,19 +855,28 @@ ui.prototype.drawBattleAnimate = function(monsterId, callback) {
|
||||
|
||||
var margin = 35;
|
||||
var boxWidth = 40;
|
||||
var monsterHeight = 32, animate=2;
|
||||
|
||||
var image = core.material.images.enemys, icon = core.material.icons.enemys;
|
||||
if (core.isset(core.material.icons.enemy48[monsterId])) {
|
||||
image = core.material.images.enemy48;
|
||||
icon = core.material.icons.enemy48;
|
||||
monsterHeight = 48;
|
||||
animate=4;
|
||||
}
|
||||
|
||||
// 方块
|
||||
var heroHeight = core.material.icons.hero.height;
|
||||
core.strokeRect('ui', left + margin - 1, top + margin - 1, boxWidth+2, heroHeight+boxWidth-32+2, '#FFD700', 2);
|
||||
core.strokeRect('ui', left + right - margin - boxWidth - 1 , top+margin-1, boxWidth+2, boxWidth+2);
|
||||
core.strokeRect('ui', left + right - margin - boxWidth - 1 , top+margin-1, boxWidth+2, monsterHeight+boxWidth-32+2);
|
||||
|
||||
// 名称
|
||||
core.canvas.ui.textAlign='center';
|
||||
core.fillText('ui', core.status.hero.name, left+margin+boxWidth/2, top+margin+heroHeight+40, '#FFD700', 'bold 22px Verdana');
|
||||
core.fillText('ui', "怪物", left+right-margin-boxWidth/2, top+margin+32+40);
|
||||
core.fillText('ui', "怪物", left+right-margin-boxWidth/2, top+margin+monsterHeight+40);
|
||||
for (var i=0, j=0; i<specialTexts.length;i++) {
|
||||
if (specialTexts[i]!='') {
|
||||
core.fillText('ui', specialTexts[i], left+right-margin-boxWidth/2, top+margin+32+44+20*(++j), '#FF6A6A', '15px Verdana');
|
||||
core.fillText('ui', specialTexts[i], left+right-margin-boxWidth/2, top+margin+monsterHeight+44+20*(++j), '#FF6A6A', '15px Verdana');
|
||||
}
|
||||
}
|
||||
|
||||
@ -599,11 +888,11 @@ ui.prototype.drawBattleAnimate = function(monsterId, callback) {
|
||||
// 怪物的
|
||||
core.status.boxAnimateObjs = [];
|
||||
core.status.boxAnimateObjs.push({
|
||||
'bgx': left + right - margin - 40, 'bgy': top+margin, 'bgsize': boxWidth,
|
||||
'image': core.material.images.enemys, 'x': left + right - margin - 40 + (boxWidth-32)/2, 'y': top + margin + (boxWidth-32)/2, 'icon': core.material.icons.enemys[monsterId]
|
||||
});
|
||||
'bgx': left+right-margin-40, 'bgy': top+margin, 'bgWidth': boxWidth, 'bgHeight': monsterHeight+boxWidth-32,
|
||||
'x': left + right - margin - 40 + (boxWidth-32)/2, 'y': top + margin + (boxWidth-32)/2, 'height': monsterHeight,
|
||||
'image': image, 'pos': monsterHeight*icon[monsterId], 'animate': animate
|
||||
})
|
||||
core.drawBoxAnimate();
|
||||
|
||||
var lineWidth = 80;
|
||||
|
||||
var left_start = left + margin + boxWidth + 10;
|
||||
@ -694,11 +983,11 @@ ui.prototype.drawBattleAnimate = function(monsterId, callback) {
|
||||
|
||||
if (turn==0) {
|
||||
// 勇士攻击
|
||||
core.drawLine('data', left + right - margin - boxWidth + 6, top+margin+boxWidth-6,
|
||||
core.drawLine('data', left + right - margin - boxWidth + 6, top+margin+monsterHeight+boxWidth-32-6,
|
||||
left+right-margin-6, top+margin+6, '#FF0000', 4);
|
||||
setTimeout(function() {
|
||||
core.clearMap('data', left + right - margin - boxWidth, top+margin,
|
||||
boxWidth, boxWidth);
|
||||
boxWidth, boxWidth+monsterHeight-32);
|
||||
}, 250);
|
||||
|
||||
if (hero_atk-mon_def>0)
|
||||
@ -832,6 +1121,14 @@ ui.prototype.drawLocalSaveSelect = function () {
|
||||
]);
|
||||
}
|
||||
|
||||
////// 绘制存档删除页面 //////
|
||||
ui.prototype.drawStorageRemove = function () {
|
||||
core.status.event.id = 'storageRemove';
|
||||
this.drawChoices(null, [
|
||||
"清空全部塔的存档", "只清空当前塔的存档", "返回上级菜单"
|
||||
]);
|
||||
}
|
||||
|
||||
////// 绘制分页 //////
|
||||
ui.prototype.drawPagination = function (page, totalPage) {
|
||||
|
||||
@ -924,11 +1221,18 @@ ui.prototype.drawBook = function (index) {
|
||||
var enemy = enemys[i];
|
||||
core.strokeRect('ui', 22, 62 * i + 22, 42, 42, '#DDDDDD', 2);
|
||||
|
||||
var cls = 'enemys';
|
||||
if (core.isset(core.material.icons.enemy48[enemy.id]))
|
||||
cls = 'enemy48';
|
||||
var height = cls=='enemy48'?48:32;
|
||||
var animate = cls=='enemy48'?4:2;
|
||||
|
||||
// 怪物
|
||||
core.status.boxAnimateObjs.push({
|
||||
'bgx': 22, 'bgy': 62 * i + 22, 'bgsize': 42,
|
||||
'image': core.material.images.enemys,
|
||||
'x': 27, 'y': 62 * i + 27, 'icon': core.material.icons.enemys[enemy.id]
|
||||
'bgx': 22, 'bgy': 62 * i + 22, 'bgWidth': 42, 'bgHeight': 42,
|
||||
'x': 27, 'y': 62 * i + 27, 'height': 32, 'animate': animate,
|
||||
'image': core.material.images[cls],
|
||||
'pos': core.material.icons[cls][enemy.id] * height
|
||||
});
|
||||
|
||||
// 数据
|
||||
@ -949,24 +1253,41 @@ ui.prototype.drawBook = function (index) {
|
||||
core.fillText('ui', '防御', 335, 62 * i + 32, '#DDDDDD', '13px Verdana');
|
||||
core.fillText('ui', enemy.def, 365, 62 * i + 32, '#DDDDDD', 'bold 13px Verdana');
|
||||
|
||||
var expOffset = 165;
|
||||
var expOffset = 165, line_cnt=0;
|
||||
if (core.flags.enableMoney) {
|
||||
core.fillText('ui', '金币', 165, 62 * i + 50, '#DDDDDD', '13px Verdana');
|
||||
core.fillText('ui', enemy.money, 195, 62 * i + 50, '#DDDDDD', 'bold 13px Verdana');
|
||||
expOffset = 255;
|
||||
line_cnt++;
|
||||
}
|
||||
|
||||
if (core.flags.enableExperience) {
|
||||
// 加点
|
||||
if (core.flags.enableAddPoint) {
|
||||
core.canvas.ui.textAlign = "left";
|
||||
core.fillText('ui', '加点', expOffset, 62 * i + 50, '#DDDDDD', '13px Verdana');
|
||||
core.fillText('ui', enemy.point, expOffset + 30, 62 * i + 50, '#DDDDDD', 'bold 13px Verdana');
|
||||
expOffset = 255;
|
||||
line_cnt++;
|
||||
}
|
||||
|
||||
if (core.flags.enableExperience && line_cnt<2) {
|
||||
core.canvas.ui.textAlign = "left";
|
||||
core.fillText('ui', '经验', expOffset, 62 * i + 50, '#DDDDDD', '13px Verdana');
|
||||
core.fillText('ui', enemy.experience, expOffset + 30, 62 * i + 50, '#DDDDDD', 'bold 13px Verdana');
|
||||
line_cnt++;
|
||||
}
|
||||
|
||||
var damageOffset = 281;
|
||||
if (line_cnt==1) damageOffset=326;
|
||||
if (line_cnt==2) damageOffset=361;
|
||||
|
||||
/*
|
||||
var damageOffet = 281;
|
||||
if (core.flags.enableMoney && core.flags.enableExperience)
|
||||
damageOffet = 361;
|
||||
else if (core.flags.enableMoney || core.flags.enableExperience)
|
||||
damageOffet = 326;
|
||||
*/
|
||||
|
||||
|
||||
core.canvas.ui.textAlign = "center";
|
||||
@ -975,7 +1296,7 @@ ui.prototype.drawBook = function (index) {
|
||||
if (damage >= core.status.hero.hp) color = '#FF0000';
|
||||
if (damage <= 0) color = '#00FF00';
|
||||
if (damage >= 999999999) damage = '无法战斗';
|
||||
core.fillText('ui', damage, damageOffet, 62 * i + 50, color, 'bold 13px Verdana');
|
||||
core.fillText('ui', damage, damageOffset, 62 * i + 50, color, 'bold 13px Verdana');
|
||||
|
||||
core.canvas.ui.textAlign = "left";
|
||||
|
||||
@ -1297,35 +1618,24 @@ ui.prototype.drawThumbnail = function(floorId, canvas, blocks, x, y, size, heroL
|
||||
}
|
||||
}
|
||||
|
||||
if (core.isset(core.floors[floorId].png)) {
|
||||
var png = core.floors[floorId].png;
|
||||
/*
|
||||
if (core.isset(core.material.images.pngs[png])) {
|
||||
core.canvas.ui.drawImage(core.material.images.pngs[png], x, y, size, size);
|
||||
var images = [];
|
||||
if (core.isset(core.floors[floorId].images)) {
|
||||
images = core.floors[floorId].images;
|
||||
if (typeof images == 'string') {
|
||||
images = [[0, 0, images]];
|
||||
}
|
||||
*/
|
||||
|
||||
var ratio = size/416;
|
||||
|
||||
if (typeof png == 'string') {
|
||||
if (core.isset(core.material.images.pngs[png])) {
|
||||
core.canvas.ui.drawImage(core.material.images.pngs[png], x, y, size, size);
|
||||
}
|
||||
}
|
||||
else if (png instanceof Array) {
|
||||
png.forEach(function (t) {
|
||||
if (t.length!=3) return;
|
||||
var dx=parseInt(t[0]), dy=parseInt(t[1]), p=t[2];
|
||||
if (core.isset(dx) && core.isset(dy) && core.isset(core.material.images.pngs[p])) {
|
||||
dx*=32; dy*=32;
|
||||
var image = core.material.images.pngs[p];
|
||||
core.canvas.ui.drawImage(image, x+dx*ratio, y+dy*ratio, Math.min(size-dx*ratio, ratio*image.width), Math.min(size-dy*ratio, ratio*image.height));
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
images.forEach(function (t) {
|
||||
var ratio = size/416;
|
||||
var dx=parseInt(t[0]), dy=parseInt(t[1]), p=t[2];
|
||||
if (core.isset(dx) && core.isset(dy) && !t[3] && core.isset(core.material.images.images[p])) {
|
||||
dx*=32; dy*=32;
|
||||
var image = core.material.images.images[p];
|
||||
core.canvas.ui.drawImage(image, x+dx*ratio, y+dy*ratio, Math.min(size-dx*ratio, ratio*image.width), Math.min(size-dy*ratio, ratio*image.height));
|
||||
}
|
||||
})
|
||||
|
||||
var mapArray = core.maps.getMapArray(blocks);
|
||||
for (var b in blocks) {
|
||||
var block = blocks[b];
|
||||
@ -1337,7 +1647,8 @@ ui.prototype.drawThumbnail = function(floorId, canvas, blocks, x, y, size, heroL
|
||||
if (block.event.id!='none') {
|
||||
var blockIcon = core.material.icons[block.event.cls][block.event.id];
|
||||
var blockImage = core.material.images[block.event.cls];
|
||||
core.canvas[canvas].drawImage(blockImage, 0, blockIcon * 32, 32, 32, x + block.x * persize, y + block.y * persize, persize, persize);
|
||||
var height = block.event.height || 32;
|
||||
core.canvas[canvas].drawImage(blockImage, 0, blockIcon * height, 32, height, x + block.x * persize, y + block.y * persize + (persize-persize*height/32), persize, persize * height/32);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1349,6 +1660,17 @@ ui.prototype.drawThumbnail = function(floorId, canvas, blocks, x, y, size, heroL
|
||||
var realHeight = persize*height/32;
|
||||
core.canvas[canvas].drawImage(core.material.images.hero, heroIcon.stop * 32, heroIcon.loc * height, 32, height, x+persize*heroLoc.x, y+persize*heroLoc.y+persize-realHeight, persize, realHeight);
|
||||
}
|
||||
|
||||
images.forEach(function (t) {
|
||||
var ratio = size/416;
|
||||
var dx=parseInt(t[0]), dy=parseInt(t[1]), p=t[2];
|
||||
if (core.isset(dx) && core.isset(dy) && t[3] && core.isset(core.material.images.images[p])) {
|
||||
dx*=32; dy*=32;
|
||||
var image = core.material.images.images[p];
|
||||
core.canvas.ui.drawImage(image, x+dx*ratio, y+dy*ratio, Math.min(size-dx*ratio, ratio*image.width), Math.min(size-dy*ratio, ratio*image.height));
|
||||
}
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
ui.prototype.drawKeyBoard = function () {
|
||||
@ -1390,32 +1712,8 @@ ui.prototype.drawKeyBoard = function () {
|
||||
}
|
||||
|
||||
////// 绘制“关于”界面 //////
|
||||
ui.prototype.drawAbout = function() {
|
||||
|
||||
if (!core.isPlaying()) {
|
||||
core.status.event = {'id': null, 'data': null};
|
||||
core.dom.startPanel.style.display = 'none';
|
||||
}
|
||||
core.lockControl();
|
||||
core.status.event.id = 'about';
|
||||
|
||||
core.clearMap('ui', 0, 0, 416, 416);
|
||||
var left = 48, top = 36, right = 416 - 2 * left, bottom = 416 - 2 * top;
|
||||
|
||||
core.setAlpha('ui', 0.85);
|
||||
core.fillRect('ui', left, top, right, bottom, '#000000');
|
||||
core.setAlpha('ui', 1);
|
||||
core.strokeRect('ui', left - 1, top - 1, right + 1, bottom + 1, '#FFFFFF', 2);
|
||||
|
||||
var text_start = left + 24;
|
||||
|
||||
// 名称
|
||||
core.canvas.ui.textAlign = "left";
|
||||
core.fillText('ui', "HTML5 魔塔样板", text_start, top+35, "#FFD700", "bold 22px Verdana");
|
||||
core.fillText('ui', "版本: "+core.firstData.version, text_start, top + 80, "#FFFFFF", "bold 17px Verdana");
|
||||
core.fillText('ui', "作者: 艾之葵", text_start, top + 112);
|
||||
core.fillText('ui', 'HTML5魔塔交流群:539113091', text_start, top+112+32);
|
||||
// TODO: 写自己的“关于”页面,每次增加32像素即可
|
||||
ui.prototype.drawAbout = function () {
|
||||
return this.uidata.drawAbout();
|
||||
}
|
||||
|
||||
////// 绘制帮助页面 //////
|
||||
@ -1445,4 +1743,5 @@ ui.prototype.drawHelp = function () {
|
||||
"双击勇士: 轻按(仅在轻按开关打开时有效)\n"+
|
||||
"长按任意位置:跳过剧情对话或打开虚拟键盘\n"
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
468
libs/utils.js
Normal file
@ -0,0 +1,468 @@
|
||||
/*
|
||||
utils.js 工具类
|
||||
|
||||
*/
|
||||
|
||||
function utils() {
|
||||
|
||||
}
|
||||
|
||||
utils.prototype.init = function () {
|
||||
|
||||
}
|
||||
|
||||
////// 将文字中的${和}(表达式)进行替换 //////
|
||||
utils.prototype.replaceText = function (text) {
|
||||
return text.replace(/\${([^}]+)}/g, function (word, value) {
|
||||
return core.calValue(value);
|
||||
});
|
||||
}
|
||||
|
||||
////// 计算表达式的值 //////
|
||||
utils.prototype.calValue = function (value) {
|
||||
value=value.replace(/status:([\w\d_]+)/g, "core.getStatus('$1')");
|
||||
value=value.replace(/item:([\w\d_]+)/g, "core.itemCount('$1')");
|
||||
value=value.replace(/flag:([\w\d_]+)/g, "core.getFlag('$1', false)");
|
||||
return eval(value);
|
||||
}
|
||||
|
||||
////// 字符串自动换行的分割 //////
|
||||
utils.prototype.splitLines = function(canvas, text, maxLength, font) {
|
||||
if (core.isset(font)) core.setFont(canvas, font);
|
||||
|
||||
var contents = [];
|
||||
var last = 0;
|
||||
for (var i=0;i<text.length;i++) {
|
||||
|
||||
if (text.charAt(i)=='\n') {
|
||||
contents.push(text.substring(last, i));
|
||||
last=i+1;
|
||||
}
|
||||
else if (text.charAt(i)=='\\' && text.charAt(i+1)=='n') {
|
||||
contents.push(text.substring(last, i));
|
||||
last=i+2;
|
||||
}
|
||||
else {
|
||||
var toAdd = text.substring(last, i+1);
|
||||
var width = core.canvas[canvas].measureText(toAdd).width;
|
||||
if (width>maxLength) {
|
||||
contents.push(text.substring(last, i));
|
||||
last=i;
|
||||
}
|
||||
}
|
||||
}
|
||||
contents.push(text.substring(last));
|
||||
return contents;
|
||||
}
|
||||
|
||||
////// 向某个数组前插入另一个数组或元素 //////
|
||||
utils.prototype.unshift = function (a,b) {
|
||||
if (!(a instanceof Array) || !core.isset(b)) return;
|
||||
if (b instanceof Array) {
|
||||
core.clone(b).reverse().forEach(function (e) {
|
||||
a.unshift(e);
|
||||
});
|
||||
}
|
||||
else a.unshift(b);
|
||||
return a;
|
||||
}
|
||||
|
||||
////// 设置本地存储 //////
|
||||
utils.prototype.setLocalStorage = function(key, value) {
|
||||
try {
|
||||
localStorage.setItem(core.firstData.name + "_" + key, JSON.stringify(value));
|
||||
return true;
|
||||
}
|
||||
catch (e) {
|
||||
console.log(e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
////// 获得本地存储 //////
|
||||
utils.prototype.getLocalStorage = function(key, defaultValue) {
|
||||
var value = localStorage.getItem(core.firstData.name+"_"+key);
|
||||
if (core.isset(value)) return JSON.parse(value);
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
////// 移除本地存储 //////
|
||||
utils.prototype.removeLocalStorage = function (key) {
|
||||
localStorage.removeItem(core.firstData.name+"_"+key);
|
||||
}
|
||||
|
||||
////// 深拷贝一个对象 //////
|
||||
utils.prototype.clone = function (data) {
|
||||
if (!core.isset(data)) return data;
|
||||
// date
|
||||
if (data instanceof Date) {
|
||||
var copy=new Date();
|
||||
copy.setTime(data.getTime());
|
||||
return copy;
|
||||
}
|
||||
// array
|
||||
if (data instanceof Array) {
|
||||
var copy=[];
|
||||
// for (var i=0;i<data.length;i++) {
|
||||
for (var i in data) {
|
||||
// copy.push(core.clone(data[i]));
|
||||
copy[i] = core.clone(data[i]);
|
||||
}
|
||||
return copy;
|
||||
}
|
||||
// 函数
|
||||
if (data instanceof Function) {
|
||||
return data;
|
||||
}
|
||||
// object
|
||||
if (data instanceof Object) {
|
||||
var copy={};
|
||||
for (var i in data) {
|
||||
if (data.hasOwnProperty(i))
|
||||
copy[i]=core.clone(data[i]);
|
||||
}
|
||||
return copy;
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
////// 格式化时间为字符串 //////
|
||||
utils.prototype.formatDate = function(date) {
|
||||
if (!core.isset(date)) return "";
|
||||
return date.getFullYear()+"-"+core.setTwoDigits(date.getMonth()+1)+"-"+core.setTwoDigits(date.getDate())+" "
|
||||
+core.setTwoDigits(date.getHours())+":"+core.setTwoDigits(date.getMinutes())+":"+core.setTwoDigits(date.getSeconds());
|
||||
}
|
||||
|
||||
////// 格式化时间为最简字符串 //////
|
||||
utils.prototype.formatDate2 = function (date) {
|
||||
if (!core.isset(date)) return "";
|
||||
return date.getFullYear()+core.setTwoDigits(date.getMonth()+1)+core.setTwoDigits(date.getDate())
|
||||
+core.setTwoDigits(date.getHours())+core.setTwoDigits(date.getMinutes())+core.setTwoDigits(date.getSeconds());
|
||||
}
|
||||
|
||||
////// 两位数显示 //////
|
||||
utils.prototype.setTwoDigits = function (x) {
|
||||
return parseInt(x)<10?"0"+x:x;
|
||||
}
|
||||
|
||||
////// 数组转RGB //////
|
||||
utils.prototype.arrayToRGB = function (color) {
|
||||
var nowR = parseInt(color[0])||0, nowG = parseInt(color[1])||0, nowB = parseInt(color[2])||0;
|
||||
if (nowR<0) nowR=0; if (nowB<0) nowB=0;if (nowG<0) nowG=0;
|
||||
if (nowR>255) nowR=255; if (nowB>255) nowB=255; if (nowG>255) nowG=255;
|
||||
return "#"+((1<<24)+(nowR<<16)+(nowG<<8)+nowB).toString(16).slice(1);
|
||||
}
|
||||
|
||||
////// 加密路线 //////
|
||||
utils.prototype.encodeRoute = function (route) {
|
||||
var ans="";
|
||||
var lastMove = "", cnt=0;
|
||||
|
||||
route.forEach(function (t) {
|
||||
if (t=='up' || t=='down' || t=='left' || t=='right') {
|
||||
if (t!=lastMove && cnt>0) {
|
||||
ans+=lastMove.substring(0,1).toUpperCase();
|
||||
if (cnt>1) ans+=cnt;
|
||||
cnt=0;
|
||||
}
|
||||
lastMove=t;
|
||||
cnt++;
|
||||
}
|
||||
else {
|
||||
if (cnt>0) {
|
||||
ans+=lastMove.substring(0,1).toUpperCase();
|
||||
if (cnt>1) ans+=cnt;
|
||||
cnt=0;
|
||||
}
|
||||
if (t.indexOf('item:')==0)
|
||||
ans+="I"+t.substring(5)+":";
|
||||
else if (t.indexOf('fly:')==0)
|
||||
ans+="F"+t.substring(4)+":";
|
||||
else if (t.indexOf('choices:')==0)
|
||||
ans+="C"+t.substring(8);
|
||||
else if (t.indexOf('shop:')==0)
|
||||
ans+="S"+t.substring(5);
|
||||
else if (t=='turn')
|
||||
ans+='T';
|
||||
else if (t=='getNext')
|
||||
ans+='G';
|
||||
else if (t.indexOf('input:')==0)
|
||||
ans+="P"+t.substring(6);
|
||||
else if (t=='no')
|
||||
ans+='N';
|
||||
else if (t.indexOf('move:')==0)
|
||||
ans+="M"+t.substring(5);
|
||||
else if (t=='key:')
|
||||
ans+='K'+t.substring(4);
|
||||
}
|
||||
});
|
||||
if (cnt>0) {
|
||||
ans+=lastMove.substring(0,1).toUpperCase();
|
||||
if (cnt>1) ans+=cnt;
|
||||
}
|
||||
return ans;
|
||||
}
|
||||
|
||||
////// 解密路线 //////
|
||||
utils.prototype.decodeRoute = function (route) {
|
||||
|
||||
if (!core.isset(route)) return route;
|
||||
|
||||
var ans=[], index=0;
|
||||
|
||||
var getNumber = function (noparse) {
|
||||
var num="";
|
||||
while (index<route.length && !isNaN(route.charAt(index))) {
|
||||
num+=route.charAt(index++);
|
||||
}
|
||||
if (num.length==0) num="1";
|
||||
return core.isset(noparse)?num:parseInt(num);
|
||||
}
|
||||
var getString = function () {
|
||||
var str="";
|
||||
while (index<route.length && /\w/.test(route.charAt(index))) {
|
||||
str+=route.charAt(index++);
|
||||
}
|
||||
index++;
|
||||
return str;
|
||||
}
|
||||
|
||||
while (index<route.length) {
|
||||
var c=route.charAt(index++);
|
||||
var nxt=(c=='I'||c=='F'||c=='S')?getString():getNumber();
|
||||
|
||||
switch (c) {
|
||||
case "U": for (var i=0;i<nxt;i++) ans.push("up"); break;
|
||||
case "D": for (var i=0;i<nxt;i++) ans.push("down"); break;
|
||||
case "L": for (var i=0;i<nxt;i++) ans.push("left"); break;
|
||||
case "R": for (var i=0;i<nxt;i++) ans.push("right"); break;
|
||||
case "I": ans.push("item:"+nxt); break;
|
||||
case "F": ans.push("fly:"+nxt); break;
|
||||
case "C": ans.push("choices:"+nxt); break;
|
||||
case "S": ans.push("shop:"+nxt+":"+getNumber(true)); break;
|
||||
case "T": ans.push("turn"); break;
|
||||
case "G": ans.push("getNext"); break;
|
||||
case "P": ans.push("input:"+nxt); break;
|
||||
case "N": ans.push("no"); break;
|
||||
case "M": ++index; ans.push("move:"+nxt+":"+getNumber()); break;
|
||||
case "K": ans.push("key:"+nxt); break;
|
||||
}
|
||||
}
|
||||
return ans;
|
||||
}
|
||||
|
||||
////// 判断某对象是否不为undefined也不会null //////
|
||||
utils.prototype.isset = function (val) {
|
||||
if (val == undefined || val == null || (typeof val=='number' && isNaN(val))) {
|
||||
return false;
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
////// 读取一个本地文件内容 //////
|
||||
utils.prototype.readFile = function (success, error, readType) {
|
||||
|
||||
// step 0: 不为http/https,直接不支持
|
||||
if (!core.platform.isOnline) {
|
||||
alert("离线状态下不支持文件读取!");
|
||||
if (core.isset(error)) error();
|
||||
return;
|
||||
}
|
||||
|
||||
// Step 1: 如果不支持FileReader,直接不支持
|
||||
if (core.platform.fileReader==null) {
|
||||
alert("当前浏览器不支持FileReader!");
|
||||
if (core.isset(error)) error();
|
||||
return;
|
||||
}
|
||||
|
||||
if (core.platform.fileInput==null) {
|
||||
core.platform.fileInput = document.createElement("input");
|
||||
core.platform.fileInput.style.display = 'none';
|
||||
core.platform.fileInput.type = 'file';
|
||||
core.platform.fileInput.onchange = function () {
|
||||
var files = core.platform.fileInput.files;
|
||||
if (files.length==0) {
|
||||
if (core.isset(core.platform.errorCallback))
|
||||
core.platform.errorCallback();
|
||||
return;
|
||||
}
|
||||
if(!readType)core.platform.fileReader.readAsText(core.platform.fileInput.files[0]);
|
||||
else core.platform.fileReader.readAsDataURL(core.platform.fileInput.files[0]);
|
||||
core.platform.fileInput.value = '';
|
||||
}
|
||||
}
|
||||
|
||||
core.platform.successCallback = success;
|
||||
core.platform.errorCallback = error;
|
||||
core.platform.fileInput.click();
|
||||
}
|
||||
|
||||
////// 下载文件到本地 //////
|
||||
utils.prototype.download = function (filename, content) {
|
||||
|
||||
// Step 0: 不为http/https,直接不支持
|
||||
if (!core.platform.isOnline) {
|
||||
alert("离线状态下不支持下载操作!");
|
||||
return;
|
||||
}
|
||||
|
||||
// Step 1: 如果是iOS平台,直接不支持
|
||||
if (core.platform.isIOS) {
|
||||
alert("iOS平台下不支持下载操作!");
|
||||
return;
|
||||
}
|
||||
|
||||
// Step 2: 如果不是PC平台(Android),则只支持chrome
|
||||
if (!core.platform.isPC) {
|
||||
if (!core.platform.isChrome || core.platform.isQQ || core.platform.isWeChat) { // 检测chrome
|
||||
if (core.copy(content)) {
|
||||
alert("移动端只有Chrome浏览器支持直接下载文件!\n所有应下载内容已经复制到您的剪切板,请自行创建空白文件并粘贴。");
|
||||
}
|
||||
else {
|
||||
alert("该平台或浏览器暂不支持下载操作!");
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Step 3: 如果是Safari浏览器,则提示并打开新窗口
|
||||
if (core.platform.isSafari) {
|
||||
alert("你当前使用的是Safari浏览器,不支持直接下载文件。\n即将打开一个新窗口为应下载内容,请自行全选复制然后创建空白文件并粘贴。");
|
||||
var blob = new Blob([content], {type: 'text/plain;charset=utf-8'});
|
||||
var href = window.URL.createObjectURL(blob);
|
||||
var opened=window.open(href, "_blank");
|
||||
// if (!opened) window.location.href=href;
|
||||
window.URL.revokeObjectURL(href);
|
||||
return;
|
||||
}
|
||||
|
||||
// Step 4: 下载
|
||||
var blob = new Blob([content], {type: 'text/plain;charset=utf-8'});
|
||||
if(window.navigator.msSaveOrOpenBlob) {
|
||||
window.navigator.msSaveBlob(blob, filename);
|
||||
}
|
||||
else {
|
||||
var href = window.URL.createObjectURL(blob);
|
||||
var elem = window.document.createElement('a');
|
||||
elem.href = href;
|
||||
elem.download = filename;
|
||||
document.body.appendChild(elem);
|
||||
elem.click();
|
||||
document.body.removeChild(elem);
|
||||
window.URL.revokeObjectURL(href);
|
||||
}
|
||||
}
|
||||
|
||||
////// 复制一段内容到剪切板 //////
|
||||
utils.prototype.copy = function (data) {
|
||||
if (!core.platform.supportCopy) return false;
|
||||
|
||||
var textArea = document.createElement("textarea");
|
||||
textArea.style.position = 'fixed';
|
||||
textArea.style.top = 0;
|
||||
textArea.style.left = 0;
|
||||
textArea.style.width = '2em';
|
||||
textArea.style.height = '2em';
|
||||
textArea.style.padding = 0;
|
||||
textArea.style.border = 'none';
|
||||
textArea.style.outline = 'none';
|
||||
textArea.style.boxShadow = 'none';
|
||||
textArea.style.background = 'transparent';
|
||||
textArea.value = data;
|
||||
document.body.appendChild(textArea);
|
||||
textArea.select();
|
||||
var successful = false;
|
||||
try {
|
||||
successful = document.execCommand('copy');
|
||||
} catch (err) {
|
||||
successful = false;
|
||||
}
|
||||
|
||||
document.body.removeChild(textArea);
|
||||
return successful;
|
||||
}
|
||||
|
||||
////// 动画显示某对象 //////
|
||||
utils.prototype.show = function (obj, speed, callback) {
|
||||
if (!core.isset(speed)) {
|
||||
obj.style.display = 'block';
|
||||
return;
|
||||
}
|
||||
obj.style.display = 'block';
|
||||
if (main.mode!='play'){
|
||||
obj.style.opacity = 1;
|
||||
if (core.isset(callback)) {callback();}
|
||||
return;
|
||||
}
|
||||
obj.style.opacity = 0;
|
||||
var opacityVal = 0;
|
||||
var showAnimate = window.setInterval(function () {
|
||||
opacityVal += 0.03;
|
||||
obj.style.opacity = opacityVal;
|
||||
if (opacityVal > 1) {
|
||||
clearInterval(showAnimate);
|
||||
if (core.isset(callback)) {
|
||||
callback();
|
||||
}
|
||||
}
|
||||
}, speed);
|
||||
}
|
||||
|
||||
////// 动画使某对象消失 //////
|
||||
utils.prototype.hide = function (obj, speed, callback) {
|
||||
if (!core.isset(speed)) {
|
||||
obj.style.display = 'none';
|
||||
return;
|
||||
}
|
||||
if (main.mode!='play'){
|
||||
obj.style.display = 'none';
|
||||
if (core.isset(callback)) {callback();}
|
||||
return;
|
||||
}
|
||||
var opacityVal = 1;
|
||||
var hideAnimate = window.setInterval(function () {
|
||||
opacityVal -= 0.03;
|
||||
obj.style.opacity = opacityVal;
|
||||
if (opacityVal < 0) {
|
||||
obj.style.display = 'none';
|
||||
clearInterval(hideAnimate);
|
||||
if (core.isset(callback)) {
|
||||
callback();
|
||||
}
|
||||
}
|
||||
}, speed);
|
||||
}
|
||||
|
||||
utils.prototype.http = function (type, url, formData, success, error, mimeType) {
|
||||
var xhr = new XMLHttpRequest();
|
||||
xhr.open(type, url, true);
|
||||
if (core.isset(mimeType))
|
||||
xhr.overrideMimeType(mimeType);
|
||||
xhr.onload = function(e) {
|
||||
if (xhr.status==200) {
|
||||
if (core.isset(success)) {
|
||||
success(xhr.response);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (core.isset(error))
|
||||
error("HTTP "+xhr.status);
|
||||
}
|
||||
};
|
||||
xhr.onabort = function () {
|
||||
if (core.isset(error))
|
||||
error("Abort");
|
||||
}
|
||||
xhr.ontimeout = function() {
|
||||
if (core.isset(error))
|
||||
error("Timeout");
|
||||
}
|
||||
xhr.onerror = function() {
|
||||
if (core.isset(error))
|
||||
error("Error on Connection");
|
||||
}
|
||||
if (core.isset(formData))
|
||||
xhr.send(formData);
|
||||
else xhr.send();
|
||||
}
|
||||
167
main.js
@ -9,29 +9,6 @@ function main() {
|
||||
// 请注意,只有useCompress是false时才会读取floors目录下的文件,为true时会直接读取libs目录下的floors.min.js文件。
|
||||
// 如果要进行剧本的修改请务必将其改成false。
|
||||
|
||||
this.floorIds = [ // 在这里按顺序放所有的楼层;其顺序直接影响到楼层传送器的顺序和上楼器/下楼器的顺序
|
||||
"sample0", "sample1", "sample2"
|
||||
];
|
||||
this.pngs = [ // 在此存放所有可能使用的图片,只能是png格式,可以不写后缀名
|
||||
// 图片可以被作为背景图(的一部分),也可以直接用自定义事件进行显示。
|
||||
// 图片名不能使用中文,不能带空格或特殊字符;可以直接改名拼音就好
|
||||
// 建议对于较大的图片,在网上使用在线的“图片压缩工具(http://compresspng.com/zh/)”来进行压缩,以节省流量
|
||||
"bg", // 依次向后添加
|
||||
];
|
||||
this.animates = [ // 在此存放所有可能使用的动画,必须是animate格式,在这里不写后缀名
|
||||
// 动画必须放在animates目录下;文件名不能使用中文,不能带空格或特殊字符
|
||||
"hand", "sword", "zone", "yongchang", // "jianji", "thunder" // 根据需求自行添加
|
||||
];
|
||||
this.bgms = [ // 在此存放所有的bgm,和文件名一致。第一项为默认播放项
|
||||
// 音频名不能使用中文,不能带空格或特殊字符;可以直接改名拼音就好
|
||||
'bgm.mp3', 'qianjin.mid', 'star.mid',
|
||||
];
|
||||
this.sounds = [ // 在此存放所有的SE,和文件名一致
|
||||
// 音频名不能使用中文,不能带空格或特殊字符;可以直接改名拼音就好
|
||||
'floor.mp3', 'attack.ogg', 'door.ogg', 'item.ogg', 'zone.ogg'
|
||||
];
|
||||
this.bgmRemote = false; // 是否使用远程的背景音乐;此项一般不要开启
|
||||
|
||||
//------------------------ 用户修改内容 END ------------------------//
|
||||
|
||||
this.dom = {
|
||||
@ -45,6 +22,7 @@ function main() {
|
||||
'startTopProgress': document.getElementById('startTopProgress'),
|
||||
'startTopLoadTips': document.getElementById('startTopLoadTips'),
|
||||
'startBackground': document.getElementById('startBackground'),
|
||||
'startLogo': document.getElementById('startLogo'),
|
||||
'startButtonGroup': document.getElementById('startButtonGroup'),
|
||||
'floorMsgGroup': document.getElementById('floorMsgGroup'),
|
||||
'logoLabel': document.getElementById('logoLabel'),
|
||||
@ -61,13 +39,11 @@ function main() {
|
||||
'loadGame': document.getElementById('loadGame'),
|
||||
'replayGame': document.getElementById('replayGame'),
|
||||
'levelChooseButtons': document.getElementById('levelChooseButtons'),
|
||||
'easyLevel': document.getElementById('easyLevel'),
|
||||
'normalLevel': document.getElementById('normalLevel'),
|
||||
'hardLevel': document.getElementById('hardLevel'),
|
||||
'data': document.getElementById('data'),
|
||||
'statusLabels': document.getElementsByClassName('statusLabel'),
|
||||
'floorCol': document.getElementById('floorCol'),
|
||||
'lvCol': document.getElementById('lvCol'),
|
||||
'hpmaxCol': document.getElementById('hpmaxCol'),
|
||||
'mdefCol': document.getElementById('mdefCol'),
|
||||
'moneyCol': document.getElementById('moneyCol'),
|
||||
'expCol': document.getElementById('expCol'),
|
||||
@ -75,17 +51,22 @@ function main() {
|
||||
'debuffCol': document.getElementById('debuffCol'),
|
||||
'hard': document.getElementById('hard'),
|
||||
};
|
||||
this.mode = 'play';
|
||||
this.loadList = [
|
||||
'items', 'icons', 'maps', 'enemys', 'events', 'data', 'ui', 'core'
|
||||
'loader', 'control', 'utils', 'items', 'icons', 'maps', 'enemys', 'events', 'actions', 'data', 'ui', 'core'
|
||||
];
|
||||
this.images = [
|
||||
'animates', 'enemys', 'hero', 'items', 'npcs', 'terrains'
|
||||
this.pureData = [
|
||||
"data","enemys","icons","maps","items","functions"
|
||||
];
|
||||
this.materials = [
|
||||
'animates', 'enemys', 'hero', 'items', 'npcs', 'terrains', 'enemy48', 'npc48'
|
||||
];
|
||||
|
||||
this.statusBar = {
|
||||
'image': {
|
||||
'floor': document.getElementById('img-floor'),
|
||||
'lv': document.getElementById('img-lv'),
|
||||
'hpmax': document.getElementById('img-hpmax'),
|
||||
'hp': document.getElementById("img-hp"),
|
||||
'atk': document.getElementById("img-atk"),
|
||||
'def': document.getElementById("img-def"),
|
||||
@ -116,6 +97,7 @@ function main() {
|
||||
},
|
||||
'floor': document.getElementById('floor'),
|
||||
'lv': document.getElementById('lv'),
|
||||
'hpmax': document.getElementById('hpmax'),
|
||||
'hp': document.getElementById('hp'),
|
||||
'atk': document.getElementById('atk'),
|
||||
'def': document.getElementById("def"),
|
||||
@ -132,60 +114,89 @@ function main() {
|
||||
'hard': document.getElementById("hard")
|
||||
}
|
||||
this.floors = {}
|
||||
this.instance = {};
|
||||
this.canvas = {};
|
||||
}
|
||||
|
||||
////// 初始化 //////
|
||||
main.prototype.init = function () {
|
||||
main.prototype.init = function (mode, callback) {
|
||||
for (var i = 0; i < main.dom.gameCanvas.length; i++) {
|
||||
main.canvas[main.dom.gameCanvas[i].id] = main.dom.gameCanvas[i].getContext('2d');
|
||||
}
|
||||
if (({"editor":0}).hasOwnProperty(mode)) {
|
||||
main.mode = mode;
|
||||
if (mode === 'editor')main.editor = {'disableGlobalAnimate':true};
|
||||
}
|
||||
Object.keys(this.statusBar.icons).forEach(function (t) {
|
||||
var image=new Image();
|
||||
image.src="images/"+t+".png";
|
||||
image.src="project/images/"+t+".png";
|
||||
main.statusBar.icons[t] = image;
|
||||
})
|
||||
main.loaderJs(function () {
|
||||
var coreData = {};
|
||||
for (i = 0; i < main.loadList.length; i++) {
|
||||
var name = main.loadList[i];
|
||||
if (name === 'core') continue;
|
||||
main[name].init(main.dom);
|
||||
coreData[name] = main[name];
|
||||
}
|
||||
main.loaderFloors(function() {
|
||||
["dom", "statusBar", "canvas", "images", "pngs",
|
||||
main.loaderJs('project', main.pureData, function(){
|
||||
var mainData = data_a1e2fb4a_e986_4524_b0da_9b7ba7c0874d.main;
|
||||
for(var ii in mainData)main[ii]=mainData[ii];
|
||||
|
||||
main.dom.startBackground.src="project/images/"+main.startBackground;
|
||||
main.dom.startLogo.style=main.startLogoStyle;
|
||||
main.levelChoose.forEach(function(value){
|
||||
var span = document.createElement('span');
|
||||
span.setAttribute('class','startButton');
|
||||
span.innerText=value[0];
|
||||
(function(span,str_){
|
||||
span.onclick = function () {
|
||||
core.events.startGame(str_);
|
||||
}
|
||||
})(span,value[1]);
|
||||
main.dom.levelChooseButtons.appendChild(span);
|
||||
});
|
||||
|
||||
main.loaderJs('libs', main.loadList, function () {
|
||||
main.core = core;
|
||||
|
||||
for (i = 0; i < main.loadList.length; i++) {
|
||||
var name = main.loadList[i];
|
||||
if (name === 'core') continue;
|
||||
main.core[name] = new (eval(name))();
|
||||
}
|
||||
|
||||
main.loaderFloors(function() {
|
||||
var coreData = {};
|
||||
["dom", "statusBar", "canvas", "images", "materials",
|
||||
"animates", "bgms", "sounds", "floorIds", "floors"].forEach(function (t) {
|
||||
coreData[t] = main[t];
|
||||
})
|
||||
main.core.init(coreData);
|
||||
main.core.resize(main.dom.body.clientWidth, main.dom.body.clientHeight);
|
||||
})
|
||||
})
|
||||
main.core.init(coreData, callback);
|
||||
main.core.resize(main.dom.body.clientWidth, main.dom.body.clientHeight);
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
////// 动态加载所有核心JS文件 //////
|
||||
main.prototype.loaderJs = function (callback) {
|
||||
main.prototype.loaderJs = function (dir, loadList, callback) {
|
||||
var instanceNum = 0;
|
||||
// 加载js
|
||||
main.setMainTipsText('正在加载核心js文件...')
|
||||
for (var i = 0; i < main.loadList.length; i++) {
|
||||
main.loadMod(main.loadList[i], function (modName) {
|
||||
instanceNum = 0;
|
||||
for (var i = 0; i < loadList.length; i++) {
|
||||
main.loadMod(dir, loadList[i], function (modName) {
|
||||
main.setMainTipsText(modName + '.js 加载完毕');
|
||||
for (var key in main.instance) {
|
||||
instanceNum++;
|
||||
}
|
||||
if (instanceNum === main.loadList.length) {
|
||||
delete main.instance;
|
||||
// main.dom.mainTips.style.display = 'none';
|
||||
instanceNum++;
|
||||
if (instanceNum === loadList.length) {
|
||||
callback();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
////// 加载某一个JS文件 //////
|
||||
main.prototype.loadMod = function (dir, modName, callback) {
|
||||
var script = document.createElement('script');
|
||||
var name = modName;
|
||||
script.src = dir + '/' + modName + (this.useCompress?".min":"") + '.js?v=' + this.version;
|
||||
main.dom.body.appendChild(script);
|
||||
script.onload = function () {
|
||||
callback(name);
|
||||
}
|
||||
}
|
||||
|
||||
////// 动态加载所有楼层(剧本) //////
|
||||
main.prototype.loaderFloors = function (callback) {
|
||||
|
||||
@ -193,7 +204,7 @@ main.prototype.loaderFloors = function (callback) {
|
||||
main.setMainTipsText('正在加载楼层文件...')
|
||||
if (this.useCompress) { // 读取压缩文件
|
||||
var script = document.createElement('script');
|
||||
script.src = 'libs/floors.min.js?v=' + this.version;
|
||||
script.src = 'project/floors.min.js?v=' + this.version;
|
||||
main.dom.body.appendChild(script);
|
||||
script.onload = function () {
|
||||
main.dom.mainTips.style.display = 'none';
|
||||
@ -213,22 +224,10 @@ main.prototype.loaderFloors = function (callback) {
|
||||
}
|
||||
}
|
||||
|
||||
////// 加载某一个JS文件 //////
|
||||
main.prototype.loadMod = function (modName, callback) {
|
||||
var script = document.createElement('script');
|
||||
var name = modName;
|
||||
script.src = 'libs/' + modName + (this.useCompress?".min":"") + '.js?v=' + this.version;
|
||||
main.dom.body.appendChild(script);
|
||||
script.onload = function () {
|
||||
main[name] = main.instance[name];
|
||||
callback(name);
|
||||
}
|
||||
}
|
||||
|
||||
////// 加载某一个楼层 //////
|
||||
main.prototype.loadFloor = function(floorId, callback) {
|
||||
var script = document.createElement('script');
|
||||
script.src = 'libs/floors/' + floorId +'.js?v=' + this.version;
|
||||
script.src = 'project/floors/' + floorId +'.js?v=' + this.version;
|
||||
main.dom.body.appendChild(script);
|
||||
script.onload = function () {
|
||||
callback(floorId);
|
||||
@ -240,8 +239,8 @@ main.prototype.setMainTipsText = function (text) {
|
||||
main.dom.mainTips.innerHTML = text;
|
||||
}
|
||||
|
||||
var main = new main();
|
||||
main.init();
|
||||
|
||||
main.prototype.listen = function () {
|
||||
|
||||
////// 窗口大小变化时 //////
|
||||
window.onresize = function () {
|
||||
@ -436,8 +435,9 @@ main.dom.replayGame.onclick = function () {
|
||||
return;
|
||||
}
|
||||
if (core.isset(obj.version) && obj.version!=core.firstData.version) {
|
||||
alert("游戏版本不一致!");
|
||||
return;
|
||||
// alert("游戏版本不一致!");
|
||||
if (!confirm("游戏版本不一致!\n你仍然想播放录像吗?"))
|
||||
return;
|
||||
}
|
||||
if (!core.isset(obj.route) || !core.isset(obj.hard)) {
|
||||
alert("无效的录像!");
|
||||
@ -448,25 +448,14 @@ main.dom.replayGame.onclick = function () {
|
||||
core.resetStatus(core.firstData.hero, obj.hard, core.firstData.floorId, null, core.initStatus.maps);
|
||||
core.events.setInitData(obj.hard);
|
||||
core.changeFloor(core.status.floorId, null, core.firstData.hero.loc, null, function() {
|
||||
//core.setHeroMoveTriggerInterval();
|
||||
core.startReplay(core.decodeRoute(obj.route));
|
||||
});
|
||||
}, true);
|
||||
}, function () {
|
||||
|
||||
})
|
||||
}
|
||||
|
||||
////// 点击“简单难度”时 //////
|
||||
main.dom.easyLevel.onclick = function() {
|
||||
core.events.startGame('Easy');
|
||||
}
|
||||
|
||||
////// 点击“普通难度”时 //////
|
||||
main.dom.normalLevel.onclick = function () {
|
||||
core.events.startGame('Normal');
|
||||
}
|
||||
}//listen end
|
||||
|
||||
////// 点击“困难难度”时 //////
|
||||
main.dom.hardLevel.onclick = function () {
|
||||
core.events.startGame('Hard');
|
||||
}
|
||||
var main = new main();
|
||||
89
project/comment.js
Normal file
@ -0,0 +1,89 @@
|
||||
comment_c456ea59_6018_45ef_8bcc_211a24c627dc =
|
||||
{
|
||||
"items" : {
|
||||
'items':{
|
||||
'cls': "只能取keys(钥匙) items(宝石、血瓶) constants(物品) tools(道具)\n$select({\"values\":[\"keys\",\"items\",\"constants\",\"tools\"]})$end",
|
||||
'name': '名称',
|
||||
'text': '道具在道具栏中显示的描述',
|
||||
'isEquipment': '物品是否属于装备(仅在core.flags.equipment时有效)\n$select({\"values\":[true,false]})$end'
|
||||
},
|
||||
'itemEffect':'cls为items的即捡即用类物品的效果,执行时会对这里的字符串执行eval()',
|
||||
'itemEffectTip':'cls为items的即捡即用类物品,在获得时左上角额外显示的文字,执行时会对这里的字符串执行eval()得到字符串'
|
||||
},
|
||||
"items_template" : {'cls': 'items', 'name': '新物品'},
|
||||
"enemys" : {
|
||||
'name': '名称',
|
||||
'hp': '生命值',
|
||||
'atk': '攻击力',
|
||||
'def': '防御力',
|
||||
'money': '金币',
|
||||
'experience': '经验',
|
||||
'point': '加点',
|
||||
'special': '特殊属性\n\n0:无,1:先攻,2:魔攻,3:坚固,4:2连击,\n5:3连击,6:n连击,7:破甲,8:反击,9:净化,\n10:模仿,11:吸血,12:中毒,13:衰弱,14:诅咒,\n15:领域,16:夹击,17:仇恨,18:阻击,19:自爆,\n20:无敌,21:退化,22:固伤,23:重生\n\n多个属性例如用[1,4,11]表示先攻2连击吸血\n模仿怪的攻防设为0就好\n$leaf(true)$end',
|
||||
'value': '特殊属性的数值\n领域怪需要加value表示领域伤害的数值\n吸血怪需要在后面添加value代表吸血比例',
|
||||
'zoneSquare': '领域怪zoneSquare代表是否九宫格伤害',
|
||||
'range': 'range可选,代表领域伤害的范围;不加默认为1\n$range((thiseval==~~thiseval && thiseval>0)||thiseval==null)$end',
|
||||
'bomb':' 加入 "bomb": false 代表该怪物不可被炸弹或圣锤炸掉\n$select({\"values\":[true,false]})$end',
|
||||
'n': '多连击需要在后面指定n代表是几连击\n$range((thiseval==~~thiseval && thiseval>0)||thiseval==null)$end',
|
||||
'add': '代表吸血后是否加到自身\n$select({\"values\":[true,false]})$end',
|
||||
'atkValue':'退化时勇士下降的攻击力点数\n$range(thiseval==~~thiseval||thiseval==null)$end',
|
||||
'defValue':'退化时勇士下降的防御力点数\n$range(thiseval==~~thiseval||thiseval==null)$end',
|
||||
'damage':'战前扣血的点数\n$range(thiseval==~~thiseval||thiseval==null)$end'
|
||||
},
|
||||
"enemys_template" : {'name': '新敌人', 'hp': 0, 'atk': 0, 'def': 0, 'money': 0, 'experience': 0, 'point': 0, 'special': 0},
|
||||
"floors" : {
|
||||
'floor' : {
|
||||
"floorId": "文件名和floorId需要保持完全一致 \n楼层唯一标识符仅能由字母、数字、下划线组成,且不能由数字开头 \n推荐用法:第20层就用MT20,第38层就用MT38,地下6层就用MT_6(用下划线代替负号),隐藏3层用MT3h(h表示隐藏),等等 \n楼层唯一标识符,需要和名字完全一致 \n这里不能更改floorId,请通过另存为来实现\n$range(false)$end",
|
||||
"title": "楼层中文名 ",
|
||||
"name": "显示在状态栏中的层数 ",
|
||||
"canFlyTo": "该楼能否被楼传器飞到(不能的话在该楼也不允许使用楼传器) \n$select({\"values\":[true,false]})$end",
|
||||
"canUseQuickShop": "该层是否允许使用快捷商店 \n$select({\"values\":[true,false]})$end",
|
||||
"defaultGround": "默认地面的图块ID(terrains中) \n$select({\"values\":Object.keys(editor.core.icons.icons.terrains)})$end",
|
||||
"images": "背景/前景图;你可以选择一张图片来作为背景/前景素材。详细用法请参见文档“自定义素材”中的说明。 \n$leaf(true)$end",
|
||||
"color": "该层的默认画面色调。本项可不写(代表无色调),如果写需要是一个RGBA数组。 \n$leaf(true)$end",
|
||||
"weather": "该层的默认天气。本项可忽略表示晴天,如果写则第一项为\"rain\"或\"snow\"代表雨雪,第二项为1-10之间的数代表强度。 \n$leaf(true)$end",
|
||||
"bgm": "到达该层后默认播放的BGM。本项可忽略。 ",
|
||||
//"map": "地图数据,需要是13x13,建议使用地图生成器来生成 ",
|
||||
"item_ratio": "每一层的宝石/血瓶效果,即获得宝石和血瓶时框内\"ratio\"的值。$range((thiseval==~~thiseval && thiseval>0)||thiseval==null)$end",
|
||||
"firstArrive": "第一次到该楼层触发的事件 \n$leaf(true)$end",
|
||||
},
|
||||
'loc' : {
|
||||
"events": "该楼的所有可能事件列表 \n$leaf(true)$end",
|
||||
"changeFloor": "楼层转换事件;该事件不能和上面的events有冲突(同位置点),否则会被覆盖 \n$leaf(true)$end",
|
||||
"afterBattle": "战斗后可能触发的事件列表 \n$leaf(true)$end",
|
||||
"afterGetItem": "获得道具后可能触发的事件列表 \n$leaf(true)$end",
|
||||
"afterOpenDoor": "开完门后可能触发的事件列表 \n$leaf(true)$end",
|
||||
"cannotMove": "每个图块不可通行的方向 \n 可以在这里定义每个点不能前往哪个方向,例如悬崖边不能跳下去 \n'x,y': ['up', 'left'], // (x,y)点不能往上和左走\n$leaf(true)$end",
|
||||
}
|
||||
},
|
||||
/*
|
||||
'floors_template' : {
|
||||
"floorId": "tempfloor",
|
||||
"title": "主塔 0 层",
|
||||
"name": "0",
|
||||
"canFlyTo": true,
|
||||
"canUseQuickShop": true,
|
||||
"defaultGround": "ground",
|
||||
"map": [
|
||||
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
||||
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
||||
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
||||
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
||||
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
||||
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
||||
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
||||
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
||||
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
||||
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
||||
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
||||
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
||||
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
|
||||
],
|
||||
"firstArrive": [],
|
||||
"events": {},
|
||||
"changeFloor": {},
|
||||
"afterBattle": {},
|
||||
"afterGetItem": {},
|
||||
"afterOpenDoor": {}
|
||||
}, */
|
||||
}
|
||||
179
project/data.comment.js
Normal file
@ -0,0 +1,179 @@
|
||||
data_comment_c456ea59_6018_45ef_8bcc_211a24c627dc =
|
||||
{
|
||||
"main": {
|
||||
"floorIds": " 在这里按顺序放所有的楼层;其顺序直接影响到楼层传送器的顺序和上楼器/下楼器的顺序 \n$leaf(true)$end",
|
||||
"images": " 在此存放所有可能使用的图片 \n 图片可以被作为背景图(的一部分),也可以直接用自定义事件进行显示。 \n 图片名不能使用中文,不能带空格或特殊字符;可以直接改名拼音就好 \n 建议对于较大的图片,在网上使用在线的“图片压缩工具(http://compresspng.com/zh/)”来进行压缩,以节省流量 \n 依次向后添加 \n$leaf(true)$end",
|
||||
"animates": " 在此存放所有可能使用的动画,必须是animate格式,在这里不写后缀名 \n 动画必须放在animates目录下;文件名不能使用中文,不能带空格或特殊字符 \n \"jianji\", \"thunder\" \n 根据需求自行添加 \n$leaf(true)$end",
|
||||
"bgms": " 在此存放所有的bgm,和文件名一致。第一项为默认播放项 \n 音频名不能使用中文,不能带空格或特殊字符;可以直接改名拼音就好 \n$leaf(true)$end",
|
||||
"sounds": " 在此存放所有的SE,和文件名一致 \n 音频名不能使用中文,不能带空格或特殊字符;可以直接改名拼音就好 \n$leaf(true)$end",
|
||||
"bgmRemote" : " 是否使用远程的背景音乐;此项一般不要开启 \n$select({\"values\":[false]})$end",
|
||||
"startBackground" : "标题界面的背景,建议使用jpg格式以压缩背景图空间",
|
||||
"startLogoStyle" : "标题样式:可以改变颜色,也可以隐藏标题(如果背景图自带)",
|
||||
"levelChoose" : " 难度选择:每个数组的第一个是其在标题界面显示的难度,第二个是在游戏内部传输的字符串,会显示在状态栏,修改此处后需要在project/functions中作相应更改 \n$leaf(true)$end"
|
||||
},
|
||||
"firstData": {
|
||||
"title": " 游戏名,将显示在标题页面以及切换楼层的界面中 ",
|
||||
"name": " 游戏的唯一英文标识符。由英文、数字、下划线组成,不能超过20个字符。 ",
|
||||
"version": " 当前游戏版本;版本不一致的存档不能通用。 ",
|
||||
"floorId": " 初始楼层ID ",
|
||||
"hero": {
|
||||
"name": " 勇士初始数据 \n 勇士名;可以改成喜欢的 ",
|
||||
"lv": " 初始等级,该项必须为正整数 \n$range(thiseval==~~thiseval &&thiseval>0)$end",
|
||||
"hpmax": " 初始生命上限,只有在enableHPMax开启时才有效",
|
||||
"hp": " 初始生命值 ",
|
||||
"atk": " 初始攻击 ",
|
||||
"def": " 初始防御 ",
|
||||
"mdef": " 初始魔防 ",
|
||||
"money": " 初始金币 ",
|
||||
"experience": " 初始经验 ",
|
||||
"items": {
|
||||
"keys": " 初始道具个数 \n$leaf(true)$end"/* {
|
||||
"yellowKey": " 初始道具个数 ",
|
||||
"blueKey": "",
|
||||
"redKey": ""
|
||||
} */,
|
||||
"constants": "\n$leaf(true)$end",
|
||||
"tools": "\n$leaf(true)$end"
|
||||
},
|
||||
"flyRange": " 初始可飞的楼层;一般留空数组即可 \n$leaf(true)$end",
|
||||
"loc": {
|
||||
"direction": " 勇士初始位置 ",
|
||||
"x": "",
|
||||
"y": ""
|
||||
},
|
||||
"flags": " 游戏过程中的变量或flags \n$leaf(true)$end"/* {
|
||||
"poison": " 游戏过程中的变量或flags \n 毒 ",
|
||||
"weak": " 衰 ",
|
||||
"curse": " 咒 "
|
||||
} */,
|
||||
"steps": " 行走步数统计 ",
|
||||
},
|
||||
"startText": " 游戏开始前剧情。如果无剧情直接留一个空数组即可。 \n$leaf(true)$end",
|
||||
"shops": "全局商店\n$leaf(true)$end",/*{
|
||||
"moneyShop1": {
|
||||
"name": " 定义全局商店(即快捷商店) \n 商店唯一ID \n 商店名称(标题) ",
|
||||
"icon": " 商店图标,blueShop为蓝色商店,pinkShop为粉色商店 ",
|
||||
"textInList": " 在快捷商店栏中显示的名称 ",
|
||||
"use": " 商店所要使用的。只能是\"money\"或\"experience\"。 ",
|
||||
"need": " 商店需要的金币/经验数值;可以是一个表达式,以times作为参数计算。 \n 这里用到的times为该商店的已经的访问次数。首次访问该商店时times的值为0。 \n 上面的例子是50层商店的计算公式。你也可以写任意其他的计算公式,只要以times作为参数即可。 \n 例如: \"need\": \"25\" 就是恒定需要25金币的商店; \"need\": \"20+2*times\" 就是第一次访问要20金币,以后每次递增2金币的商店。 \n 如果是对于每个选项有不同的计算公式,写 \"need\": \"-1\" 即可。可参见下面的经验商店。 ",
|
||||
"text": " 显示的文字,需手动加换行符。可以使用${need}表示上面的need值。 ",
|
||||
"choices": [
|
||||
{
|
||||
"text": "",
|
||||
"effect": " 商店的选项 \n 如果有多个effect以分号分开,参见下面的经验商店 "
|
||||
},
|
||||
{
|
||||
"text": "",
|
||||
"effect": ""
|
||||
},
|
||||
{
|
||||
"text": "",
|
||||
"effect": ""
|
||||
},
|
||||
{
|
||||
"text": "",
|
||||
"effect": " effect只能对status和item进行操作,不能修改flag值。 \n 必须是X+=Y的形式,其中Y可以是一个表达式,以status:xxx或item:xxx为参数 \n 其他effect样例: \n \"item:yellowKey+=1\" 黄钥匙+1 \n \"item:pickaxe+=3\" 破墙镐+3 \n \"status:hp+=2*(status:atk+status:def)\" 将生命提升攻防和的数值的两倍 "
|
||||
}
|
||||
]
|
||||
},
|
||||
"expShop1": {
|
||||
"name": " 商店唯一ID ",
|
||||
"icon": "",
|
||||
"textInList": "",
|
||||
"use": " 该商店使用的是经验进行计算 ",
|
||||
"need": " 如果是对于每个选项所需要的数值不同,这里直接写-1,然后下面选项里给定具体数值 ",
|
||||
"text": "",
|
||||
"choices": [
|
||||
{
|
||||
"text": "",
|
||||
"need": "",
|
||||
"effect": " 在choices中写need,可以针对每个选项都有不同的需求。 \n 这里的need同样可以以times作为参数,比如 \"need\": \"100+20*times\" 多个effect直接以分号分开即可。如上面的意思是生命+1000,攻击+7,防御+7。 "
|
||||
},
|
||||
{
|
||||
"text": "",
|
||||
"need": "",
|
||||
"effect": ""
|
||||
},
|
||||
{
|
||||
"text": "",
|
||||
"need": "",
|
||||
"effect": ""
|
||||
}
|
||||
]
|
||||
}
|
||||
},*/
|
||||
"levelUp": " 经验升级所需要的数值,是一个数组 \n 第一项为初始等级,可以简单留空,也可以写name \n 每一个里面可以含有三个参数 need, name, effect \n need为所需要的经验数值,是一个正整数。请确保need所需的依次递增 \n name为该等级的名称,也可以省略代表使用系统默认值;本项将显示在状态栏中 \n effect为本次升级所执行的操作,可由若干项组成,由分号分开 \n 其中每一项写法和上面的商店完全相同,同样必须是X+=Y的形式,Y是一个表达式,同样可以使用status:xxx或item:xxx代表勇士的某项数值/道具个数 \n$leaf(true)$end"/* [
|
||||
" 经验升级所需要的数值,是一个数组 \n 第一项为初始等级,可以简单留空,也可以写name \n 每一个里面可以含有三个参数 need, name, effect \n need为所需要的经验数值,是一个正整数。请确保need所需的依次递增 \n name为该等级的名称,也可以省略代表使用系统默认值;本项将显示在状态栏中 \n effect为本次升级所执行的操作,可由若干项组成,由分号分开 \n 其中每一项写法和上面的商店完全相同,同样必须是X+=Y的形式,Y是一个表达式,同样可以使用status:xxx或item:xxx代表勇士的某项数值/道具个数 \n$leaf(true)$end",
|
||||
{
|
||||
"need": "",
|
||||
"name": "",
|
||||
"effect": " 先将生命提升攻防和的2倍;再将攻击+10,防御+10 "
|
||||
},
|
||||
{
|
||||
"need": "",
|
||||
"effect": " effect也允许写一个function,代表本次升级将会执行的操作 \n 依次往下写需要的数值即可 "
|
||||
}
|
||||
] */
|
||||
},
|
||||
"values": {
|
||||
"lavaDamage": " 各种数值;一些数值可以在这里设置\n /****** 角色相关 ******/ \n 经过血网受到的伤害 ",
|
||||
"poisonDamage": " 中毒后每步受到的伤害 ",
|
||||
"weakValue": " 衰弱状态下攻防减少的数值 ",
|
||||
"redJewel": " /****** 道具相关 ******/ \n 红宝石加攻击的数值 ",
|
||||
"blueJewel": " 蓝宝石加防御的数值 ",
|
||||
"greenJewel": " 绿宝石加魔防的数值 ",
|
||||
"redPotion": " 红血瓶加血数值 ",
|
||||
"bluePotion": " 蓝血瓶加血数值 ",
|
||||
"yellowPotion": " 黄血瓶加血数值 ",
|
||||
"greenPotion": " 绿血瓶加血数值 ",
|
||||
"sword0": " 默认装备折断的剑的攻击力 ",
|
||||
"shield0": " 默认装备残破的盾的防御力 ",
|
||||
"sword1": " 铁剑加攻数值 ",
|
||||
"shield1": " 铁盾加防数值 ",
|
||||
"sword2": " 银剑加攻数值 ",
|
||||
"shield2": " 银盾加防数值 ",
|
||||
"sword3": " 骑士剑加攻数值 ",
|
||||
"shield3": " 骑士盾加防数值 ",
|
||||
"sword4": " 圣剑加攻数值 ",
|
||||
"shield4": " 圣盾加防数值 ",
|
||||
"sword5": " 神圣剑加攻数值 ",
|
||||
"shield5": " 神圣盾加防数值 ",
|
||||
"moneyPocket": " 金钱袋加金币的数值 ",
|
||||
"breakArmor": " /****** 怪物相关 ******/ \n 破甲的比例(战斗前,怪物附加角色防御的x%作为伤害) ",
|
||||
"counterAttack": " 反击的比例(战斗时,怪物每回合附加角色攻击的x%作为伤害,无视角色防御) ",
|
||||
"purify": " 净化的比例(战斗前,怪物附加勇士魔防的x倍作为伤害) ",
|
||||
"hatred": " 仇恨属性中,每杀死一个怪物获得的仇恨值 ",
|
||||
"animateSpeed": " /****** 系统相关 ******/ \n 动画时间 "
|
||||
},
|
||||
"flags": {
|
||||
"enableFloor": " 系统FLAG,在游戏运行中中请不要修改它。 /****** 状态栏相关 ******/ \n 是否在状态栏显示当前楼层 \n$select({\"values\":[true,false]})$end",
|
||||
"enableLv": " 是否在状态栏显示当前等级 \n$select({\"values\":[true,false]})$end",
|
||||
"enableHPMax": " 是否是否启用生命上限 \n$select({\"values\":[true,false]})$end",
|
||||
"enableMDef": " 是否在状态栏及战斗界面显示魔防(护盾) \n$select({\"values\":[true,false]})$end",
|
||||
"enableMoney": " 是否在状态栏、怪物手册及战斗界面显示金币 \n$select({\"values\":[true,false]})$end",
|
||||
"enableExperience": " 是否在状态栏、怪物手册及战斗界面显示经验 \n$select({\"values\":[true,false]})$end",
|
||||
"enableLevelUp": " 是否允许等级提升(进阶);如果上面enableExperience为false,则此项恒视为false \n$select({\"values\":[true,false]})$end",
|
||||
"enableDebuff": " 是否涉及毒衰咒;如果此项为false则不会在状态栏中显示毒衰咒的debuff ////// 上述的几个开关将直接影响状态栏的显示效果 ////// \n$select({\"values\":[true,false]})$end",
|
||||
"flyNearStair": " /****** 道具相关 ******/ \n 是否需要在楼梯边使用传送器 \n$select({\"values\":[true,false]})$end",
|
||||
"pickaxeFourDirections": " 使用破墙镐是否四个方向都破坏;如果false则只破坏面前的墙壁 \n$select({\"values\":[true,false]})$end",
|
||||
"bombFourDirections": " 使用炸弹是否四个方向都会炸;如果false则只炸面前的怪物(即和圣锤等价) \n$select({\"values\":[true,false]})$end",
|
||||
"bigKeyIsBox": " 如果此项为true,则视为钥匙盒,红黄蓝钥匙+1;若为false,则视为大黄门钥匙 \n$select({\"values\":[true,false]})$end",
|
||||
"equipment": " 剑和盾是否直接作为装备。如果此项为true,则作为装备,需要在道具栏使用,否则将直接加属性。 \n$select({\"values\":[true,false]})$end",
|
||||
"enableDeleteItem": " 是否允许删除(丢弃)道具 \n$select({\"values\":[true,false]})$end",
|
||||
"enableAddPoint": " /****** 怪物相关 ******/ \n 是否支持加点 \n$select({\"values\":[true,false]})$end",
|
||||
"enableNegativeDamage": "是否支持负伤害(回血) \n$select({\"values\":[true,false]})$end",
|
||||
"hatredDecrease": " 是否在和仇恨怪战斗后减一半的仇恨值,此项为false则和仇恨怪不会扣减仇恨值。 \n$select({\"values\":[true,false]})$end",
|
||||
"betweenAttackCeil": " 夹击方式是向上取整还是向下取整。如果此项为true则为向上取整,为false则为向下取整 \n$select({\"values\":[true,false]})$end",
|
||||
"startDirectly": " /****** 系统相关 ******/ \n 点击“开始游戏”后是否立刻开始游戏而不显示难度选择界面 \n$select({\"values\":[true,false]})$end",
|
||||
"canOpenBattleAnimate": " 是否允许用户开启战斗过程;如果此项为false,则下面两项均强制视为false \n$select({\"values\":[true,false]})$end",
|
||||
"showBattleAnimateConfirm": " 是否在游戏开始时提供“是否开启战斗动画”的选项 \n$select({\"values\":[true,false]})$end",
|
||||
"battleAnimate": " 是否默认显示战斗动画;用户可以手动在菜单栏中开关 \n$select({\"values\":[true,false]})$end",
|
||||
"displayEnemyDamage": " 是否地图怪物显伤;用户可以手动在菜单栏中开关 \n$select({\"values\":[true,false]})$end",
|
||||
"displayExtraDamage": " 是否地图高级显伤(领域、夹击等);用户可以手动在菜单栏中开关 \n$select({\"values\":[true,false]})$end",
|
||||
"enableGentleClick": " 是否允许轻触(获得面前物品) \n$select({\"values\":[true,false]})$end",
|
||||
"potionWhileRouting": " 寻路算法是否经过血瓶;如果该项为false,则寻路算法会自动尽量绕过血瓶 \n$select({\"values\":[true,false]})$end",
|
||||
"enableViewMaps": " 是否支持在菜单栏中查看所有楼层的地图 \n$select({\"values\":[true,false]})$end",
|
||||
"portalWithoutTrigger": " 经过楼梯、传送门时是否能“穿透”。穿透的意思是,自动寻路得到的的路径中间经过了楼梯,行走时是否触发楼层转换事件 \n$select({\"values\":[true,false]})$end",
|
||||
"enableMoveDirectly": " 是否允许瞬间移动 \n$select({\"values\":[true,false]})$end"
|
||||
}
|
||||
}
|
||||
168
project/data.js
Normal file
@ -0,0 +1,168 @@
|
||||
data_a1e2fb4a_e986_4524_b0da_9b7ba7c0874d =
|
||||
{
|
||||
"main" : {
|
||||
"floorIds" : [
|
||||
"sample0", "sample1", "sample2"
|
||||
],
|
||||
"images" : [
|
||||
"bg.jpg",
|
||||
],
|
||||
"animates" : [
|
||||
"hand", "sword", "zone", "yongchang",
|
||||
],
|
||||
"bgms" : [
|
||||
'bgm.mp3', 'qianjin.mid', 'star.mid',
|
||||
],
|
||||
"sounds" : [
|
||||
'floor.mp3', 'attack.ogg', 'door.ogg', 'item.ogg', 'zone.ogg'
|
||||
],
|
||||
"bgmRemote" : false,
|
||||
"startBackground" : "bg.jpg",
|
||||
"startLogoStyle" : "color: black",
|
||||
"levelChoose" : [["简单","Easy"],["普通","Normal"],["困难","Hard"],["噩梦","Hell"]],
|
||||
},
|
||||
"firstData" : {
|
||||
"title": "魔塔样板",
|
||||
"name": "template",
|
||||
"version": "Ver 1.4.1",
|
||||
"floorId": "sample0",
|
||||
"hero": {
|
||||
"name": "阳光",
|
||||
'lv': 1,
|
||||
"hpmax": 9999,
|
||||
"hp": 1000,
|
||||
"atk": 100,
|
||||
"def": 100,
|
||||
"mdef": 100,
|
||||
"money": 100,
|
||||
"experience": 0,
|
||||
"items": {
|
||||
"keys": {
|
||||
"yellowKey": 0,
|
||||
"blueKey": 0,
|
||||
"redKey": 0
|
||||
},
|
||||
"constants": {},
|
||||
"tools": {}
|
||||
},
|
||||
"flyRange": [],
|
||||
"loc": {"direction": "up", "x": 6, "y": 10},
|
||||
"flags": {
|
||||
"poison": false,
|
||||
"weak": false,
|
||||
"curse": false,
|
||||
},
|
||||
"steps": 0,
|
||||
},
|
||||
"startText": [
|
||||
"Hi,欢迎来到 HTML5 魔塔样板!\n\n本样板由艾之葵制作,可以让你在不会写任何代码\n的情况下也能做出属于自己的H5魔塔!",
|
||||
"这里游戏开始时的剧情。\n定义在data.js的startText处。\n\n你可以在这里写上自己的内容。",
|
||||
"赶快来试一试吧!"
|
||||
],
|
||||
"shops": [
|
||||
{
|
||||
"id": "moneyShop1",
|
||||
"name": "贪婪之神",
|
||||
"icon": "blueShop",
|
||||
"textInList": "1F金币商店",
|
||||
"use": "money",
|
||||
"need": "20+10*times*(times+1)",
|
||||
"text": "勇敢的武士啊,给我${need}金币就可以:",
|
||||
"choices": [
|
||||
{"text": "生命+800", "effect": "status:hp+=800"},
|
||||
{"text": "攻击+4", "effect": "status:atk+=4"},
|
||||
{"text": "防御+4", "effect": "status:def+=4"},
|
||||
{"text": "魔防+10", "effect": "status:mdef+=10"}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "expShop1",
|
||||
"name": "经验之神",
|
||||
"icon": "pinkShop",
|
||||
"textInList": "1F经验商店",
|
||||
"use": "experience",
|
||||
"need": "-1",
|
||||
"text": "勇敢的武士啊,给我若干经验就可以:",
|
||||
"choices": [
|
||||
{"text": "等级+1", "need": "100", "effect": "status:lv+=1;status:hp+=1000;status:atk+=7;status:def+=7"},
|
||||
{"text": "攻击+5", "need": "30", "effect": "status:atk+=5"},
|
||||
{"text": "防御+5", "need": "30", "effect": "status:def+=5"},
|
||||
]
|
||||
}
|
||||
],
|
||||
"levelUp": [
|
||||
{},
|
||||
{"need": 20, "name": "第二级", "effect": "status:hp+=2*(status:atk+status:def);status:atk+=10;status:def+=10"},
|
||||
{"need": 40, "effect": function () {
|
||||
core.insertAction("恭喜升级!");
|
||||
core.status.hero.hp *= 2;
|
||||
core.status.hero.atk += 100;
|
||||
core.status.hero.def += 100;
|
||||
}},
|
||||
]
|
||||
},
|
||||
|
||||
"values" : {
|
||||
"lavaDamage": 100,
|
||||
"poisonDamage": 10,
|
||||
"weakValue": 20,
|
||||
"redJewel": 3,
|
||||
"blueJewel": 3,
|
||||
"greenJewel": 5,
|
||||
"redPotion": 100,
|
||||
"bluePotion": 250,
|
||||
"yellowPotion": 500,
|
||||
"greenPotion": 800,
|
||||
"sword0": 0,
|
||||
"shield0": 0,
|
||||
"sword1": 10,
|
||||
"shield1": 10,
|
||||
"sword2": 20,
|
||||
"shield2": 20,
|
||||
"sword3": 40,
|
||||
"shield3": 40,
|
||||
"sword4": 80,
|
||||
"shield4": 80,
|
||||
"sword5": 160,
|
||||
"shield5": 160,
|
||||
"moneyPocket": 500,
|
||||
/****** 怪物相关 ******/
|
||||
'breakArmor': 0.9,
|
||||
'counterAttack': 0.1,
|
||||
'purify': 3,
|
||||
'hatred': 2,
|
||||
'animateSpeed': 300,
|
||||
},
|
||||
|
||||
"flags" : {
|
||||
"enableFloor": true,
|
||||
"enableLv": false,
|
||||
"enableHPMax": false,
|
||||
"enableMDef": true,
|
||||
"enableMoney": true,
|
||||
"enableExperience": false,
|
||||
"enableLevelUp": false,
|
||||
"enableDebuff": false,
|
||||
"flyNearStair": true,
|
||||
"pickaxeFourDirections": true,
|
||||
"bombFourDirections": true,
|
||||
"bigKeyIsBox": false,
|
||||
"equipment": false,
|
||||
"enableDeleteItem": true,
|
||||
"enableAddPoint": false,
|
||||
"enableNegativeDamage": true,
|
||||
"hatredDecrease": true,
|
||||
"betweenAttackCeil": false,
|
||||
"startDirectly": false,
|
||||
"canOpenBattleAnimate": true,
|
||||
"showBattleAnimateConfirm": true,
|
||||
"battleAnimate": true,
|
||||
"displayEnemyDamage": true,
|
||||
"displayExtraDamage": true,
|
||||
"enableGentleClick": true,
|
||||
"potionWhileRouting": false,
|
||||
"enableViewMaps": true,
|
||||
"portalWithoutTrigger": true,
|
||||
"enableMoveDirectly": true,
|
||||
}
|
||||
}
|
||||
67
project/enemys.js
Normal file
@ -0,0 +1,67 @@
|
||||
enemys_fcae963b_31c9_42b4_b48c_bb48d09f3f80 =
|
||||
{
|
||||
'greenSlime': {'name': '绿头怪', 'hp': 100, 'atk': 120, 'def': 0, 'money': 1, 'experience': 1, 'point': 0, 'special': [1,5,7,8]},
|
||||
'redSlime': {'name': '红头怪', 'hp': 0, 'atk': 0, 'def': 0, 'money': 0, 'experience': 0, 'point': 0, 'special': 0},
|
||||
'blackSlime': {'name': '青头怪', 'hp': 0, 'atk': 0, 'def': 0, 'money': 0, 'experience': 0, 'point': 0, 'special': 0},
|
||||
'slimelord': {'name': '怪王', 'hp': 100, 'atk': 120, 'def': 0, 'money': 10, 'experience': 0, 'point': 0, 'special': [1,9]},
|
||||
'bat': {'name': '小蝙蝠', 'hp': 100, 'atk': 120, 'def': 0, 'money': 2, 'experience': 0, 'point': 0, 'special': 1},
|
||||
'bigBat': {'name': '大蝙蝠', 'hp': 0, 'atk': 0, 'def': 0, 'money': 0, 'experience': 0, 'point': 0, 'special': 0},
|
||||
'redBat': {'name': '红蝙蝠', 'hp': 100, 'atk': 120, 'def': 0, 'money': 5, 'experience': 0, 'point': 0, 'special': 4},
|
||||
'vampire': {'name': '冥灵魔王', 'hp': 0, 'atk': 0, 'def': 0, 'money': 0, 'experience': 0, 'point': 0, 'special': 0},
|
||||
'skeleton': {'name': '骷髅人', 'hp': 0, 'atk': 0, 'def': 0, 'money': 0, 'experience': 0, 'point': 0, 'special': 0},
|
||||
'skeletonSoilder': {'name': '骷髅士兵', 'hp': 0, 'atk': 0, 'def': 0, 'money': 0, 'experience': 0, 'point': 0, 'special': 0},
|
||||
'skeletonCaptain': {'name': '骷髅队长', 'hp': 0, 'atk': 0, 'def': 0, 'money': 0, 'experience': 0, 'point': 0, 'special': 0},
|
||||
'ghostSkeleton': {'name': '冥队长', 'hp': 100, 'atk': 120, 'def': 0, 'money': 8, 'experience': 0, 'point': 0, 'special': 7},
|
||||
'zombie': {'name': '兽人', 'hp': 0, 'atk': 0, 'def': 0, 'money': 0, 'experience': 0, 'point': 0, 'special': 0},
|
||||
'zombieKnight': {'name': '兽人武士', 'hp': 0, 'atk': 0, 'def': 0, 'money': 0, 'experience': 0, 'point': 0, 'special': 0},
|
||||
'rock': {'name': '石头人', 'hp': 100, 'atk': 120, 'def': 0, 'money': 4, 'experience': 0, 'point': 0, 'special': 3},
|
||||
'slimeMan': {'name': '影子战士', 'hp': 100, 'atk': 0, 'def': 0, 'money': 11, 'experience': 0, 'point': 0, 'special': [10,21], 'atkValue': 2, 'defValue': 3}, // 退化怪可以在后面写atkValue和defValue表示退化的数值
|
||||
'bluePriest': {'name': '初级法师', 'hp': 100, 'atk': 120, 'def': 0, 'money': 3, 'experience': 0, 'point': 1, 'special': 2},
|
||||
'redPriest': {'name': '高级法师', 'hp': 0, 'atk': 0, 'def': 0, 'money': 0, 'experience': 0, 'point': 0, 'special': 0},
|
||||
'brownWizard': {'name': '初级巫师', 'hp': 100, 'atk': 120, 'def': 0, 'money': 16, 'experience': 0, 'point': 0, 'special': 15, 'value': 100, 'range': 2}, // 领域怪需要加value表示领域伤害的数值;range可选,代表领域伤害的范围;不加默认为1
|
||||
'redWizard': {'name': '高级巫师', 'hp': 1000, 'atk': 1200, 'def': 0, 'money': 160, 'experience': 0, 'point': 0, 'special': 15, 'value': 200, 'zoneSquare': true}, // zoneSquare可选,代表是否九宫格伤害,true为是九宫格伤害,false或不设置为十字伤害
|
||||
'yellowGuard': {'name': '初级卫兵', 'hp': 100, 'atk': 120, 'def': 0, 'money': 10, 'experience': 0, 'point': 0, 'special': 0},
|
||||
'blueGuard': {'name': '中级卫兵', 'hp': 0, 'atk': 0, 'def': 0, 'money': 0, 'experience': 0, 'point': 0, 'special': 0},
|
||||
'redGuard': {'name': '高级卫兵', 'hp': 0, 'atk': 0, 'def': 0, 'money': 0, 'experience': 0, 'point': 0, 'special': 0},
|
||||
'swordsman': {'name': '双手剑士', 'hp': 100, 'atk': 120, 'def': 0, 'money': 6, 'experience': 0, 'point': 0, 'special': [5,23]},
|
||||
'soldier': {'name': '冥战士', 'hp': 0, 'atk': 0, 'def': 0, 'money': 0, 'experience': 0, 'point': 0, 'special': 0},
|
||||
'yellowKnight': {'name': '金骑士', 'hp': 0, 'atk': 0, 'def': 0, 'money': 0, 'experience': 0, 'point': 0, 'special': 0},
|
||||
'redKnight': {'name': '红骑士', 'hp': 0, 'atk': 0, 'def': 0, 'money': 0, 'experience': 0, 'point': 0, 'special': 0},
|
||||
'darkKnight': {'name': '黑骑士', 'hp': 0, 'atk': 0, 'def': 0, 'money': 0, 'experience': 0, 'point': 0, 'special': 0},
|
||||
'blackKing': {'name': '黑衣魔王', 'hp': 1000, 'atk': 500, 'def': 0, 'money': 1000, 'experience': 1000, 'point': 0, 'special': 0, 'bomb': false}, // 加入 'bomb': false 代表该怪物不可被炸弹或圣锤炸掉
|
||||
'yellowKing': {'name': '黄衣魔王', 'hp': 0, 'atk': 0, 'def': 0, 'money': 0, 'experience': 0, 'point': 0, 'special': 0},
|
||||
'greenKing': {'name': '青衣武士', 'hp': 0, 'atk': 0, 'def': 0, 'money': 0, 'experience': 0, 'point': 0, 'special': 0},
|
||||
'blueKnight': {'name': '蓝骑士', 'hp': 100, 'atk': 120, 'def': 0, 'money': 9, 'experience': 0, 'point': 0, 'special': 8},
|
||||
'goldSlime': {'name': '黄头怪', 'hp': 0, 'atk': 0, 'def': 0, 'money': 0, 'experience': 0, 'point': 0, 'special': 0},
|
||||
'poisonSkeleton': {'name': '紫骷髅', 'hp': 0, 'atk': 0, 'def': 0, 'money': 0, 'experience': 0, 'point': 0, 'special': 0},
|
||||
'poisonBat': {'name': '紫蝙蝠', 'hp': 100, 'atk': 120, 'def': 0, 'money': 14, 'experience': 0, 'point': 0, 'special': 13},
|
||||
'steelRock': {'name': '铁面人', 'hp': 0, 'atk': 0, 'def': 0, 'money': 0, 'experience': 0, 'point': 0, 'special': 0},
|
||||
'skeletonPriest': {'name': '骷髅法师', 'hp': 100, 'atk': 100, 'def': 0, 'money': 0, 'experience': 0, 'point': 0, 'special': 18, 'value': 20},
|
||||
'skeletonKing': {'name': '骷髅王', 'hp': 0, 'atk': 0, 'def': 0, 'money': 0, 'experience': 0, 'point': 0, 'special': 0},
|
||||
'skeletonWizard': {'name': '骷髅巫师', 'hp': 0, 'atk': 0, 'def': 0, 'money': 0, 'experience': 0, 'point': 0, 'special': 0},
|
||||
'redSkeletonCaption': {'name': '骷髅武士', 'hp': 0, 'atk': 0, 'def': 0, 'money': 0, 'experience': 0, 'point': 0, 'special': 0},
|
||||
'badHero': {'name': '迷失勇者', 'hp': 0, 'atk': 0, 'def': 0, 'money': 0, 'experience': 0, 'point': 0, 'special': 0},
|
||||
'demon': {'name': '魔神武士', 'hp': 0, 'atk': 0, 'def': 0, 'money': 0, 'experience': 0, 'point': 0, 'special': 0},
|
||||
'demonPriest': {'name': '魔神法师', 'hp': 0, 'atk': 0, 'def': 0, 'money': 0, 'experience': 0, 'point': 0, 'special': 0},
|
||||
'goldHornSlime': {'name': '金角怪', 'hp': 0, 'atk': 0, 'def': 0, 'money': 0, 'experience': 0, 'point': 0, 'special': 0},
|
||||
'redKing': {'name': '红衣魔王', 'hp': 0, 'atk': 0, 'def': 0, 'money': 0, 'experience': 0, 'point': 0, 'special': 0},
|
||||
'whiteKing': {'name': '白衣武士', 'hp': 100, 'atk': 120, 'def': 0, 'money': 17, 'experience': 0, 'point': 0, 'special': 16},
|
||||
'blackMagician': {'name': '黑暗大法师', 'hp': 100, 'atk': 120, 'def': 0, 'money': 12, 'experience': 0, 'point': 0, 'special': 11, 'value': 1/3, 'add': true, 'bomb': false}, // 吸血怪需要在后面添加value代表吸血比例;添加add: true可以将吸血的伤害加到自身
|
||||
'silverSlime': {'name': '银头怪', 'hp': 100, 'atk': 120, 'def': 0, 'money': 15, 'experience': 0, 'point': 0, 'special': 14},
|
||||
'swordEmperor': {'name': '剑圣', 'hp': 0, 'atk': 0, 'def': 0, 'money': 0, 'experience': 0, 'point': 0, 'special': 0},
|
||||
'whiteHornSlime': {'name': '尖角怪', 'hp': 0, 'atk': 0, 'def': 0, 'money': 0, 'experience': 0, 'point': 0, 'special': 0},
|
||||
'badPrincess': {'name': '痛苦魔女', 'hp': 0, 'atk': 0, 'def': 0, 'money': 0, 'experience': 0, 'point': 0, 'special': 0},
|
||||
'badFairy': {'name': '黑暗仙子', 'hp': 0, 'atk': 0, 'def': 0, 'money': 0, 'experience': 0, 'point': 0, 'special': 0},
|
||||
'grayPriest': {'name': '中级法师', 'hp': 0, 'atk': 0, 'def': 0, 'money': 0, 'experience': 0, 'point': 0, 'special': 0},
|
||||
'redSwordsman': {'name': '剑王', 'hp': 100, 'atk': 120, 'def': 0, 'money': 7, 'experience': 0, 'point': 0, 'special': 6, 'n': 8}, // 多连击需要在后面指定n代表是几连击
|
||||
'whiteGhost': {'name': '水银战士', 'hp': 0, 'atk': 0, 'def': 0, 'money': 0, 'experience': 0, 'point': 0, 'special': 0},
|
||||
'poisonZombie': {'name': '绿兽人', 'hp': 100, 'atk': 120, 'def': 0, 'money': 13, 'experience': 0, 'point': 0, 'special': 12},
|
||||
'magicDragon': {'name': '魔龙', 'hp': 0, 'atk': 0, 'def': 0, 'money': 0, 'experience': 0, 'point': 0, 'special': 0},
|
||||
'octopus': {'name': '血影', 'hp': 0, 'atk': 0, 'def': 0, 'money': 0, 'experience': 0, 'point': 0, 'special': 0},
|
||||
'darkFairy': {'name': '仙子', 'hp': 0, 'atk': 0, 'def': 0, 'money': 0, 'experience': 0, 'point': 0, 'special': 0},
|
||||
'greenKnight': {'name': '强盾骑士', 'hp': 0, 'atk': 0, 'def': 0, 'money': 0, 'experience': 0, 'point': 0, 'special': 0},
|
||||
'angel': {'name': '天使', 'hp': 0, 'atk': 0, 'def': 0, 'money': 0, 'experience': 0, 'point': 0, 'special': 0},
|
||||
'elemental': {'name': '元素生物', 'hp': 0, 'atk': 0, 'def': 0, 'money': 0, 'experience': 0, 'point': 0, 'special': 0},
|
||||
'steelGuard': {'name': '铁守卫', 'hp': 0, 'atk': 0, 'def': 0, 'money': 0, 'experience': 0, 'point': 0, 'special': 18, 'value': 20},
|
||||
'evilBat': {'name': '邪恶蝙蝠', 'hp': 1000, 'atk': 1, 'def': 0, 'money': 0, 'experience': 0, 'point': 0, 'special': [2,3]},
|
||||
}
|
||||
@ -1,17 +1,19 @@
|
||||
// 这里需要改楼层名,请和文件名及下面的floorId保持完全一致
|
||||
// 楼层唯一标识符仅能由字母、数字、下划线组成,且不能由数字开头
|
||||
// 推荐用法:第20层就用MT20,第38层就用MT38,地下6层就用MT_6(用下划线代替负号),隐藏3层用MT3h(h表示隐藏),等等
|
||||
main.floors.MT0 = {
|
||||
"floorId": "MT0", // 楼层唯一标识符,需要和名字完全一致
|
||||
main.floors.MT0 =
|
||||
{
|
||||
"floorId": "MT0", // 这里需要改楼层名,请和文件名及下面的floorId保持完全一致
|
||||
// 楼层唯一标识符仅能由字母、数字、下划线组成,且不能由数字开头
|
||||
// 推荐用法:第20层就用MT20,第38层就用MT38,地下6层就用MT_6(用下划线代替负号),隐藏3层用MT3h(h表示隐藏),等等
|
||||
// 楼层唯一标识符,需要和名字完全一致
|
||||
"title": "主塔 0 层", // 楼层中文名
|
||||
"name": "0", // 显示在状态栏中的层数
|
||||
"canFlyTo": true, // 该楼能否被楼传器飞到(不能的话在该楼也不允许使用楼传器)
|
||||
"canUseQuickShop": true, // 该层是否允许使用快捷商店
|
||||
"defaultGround": "ground", // 默认地面的图块ID(terrains中)
|
||||
"png": [], // 该层默认显示的所有图片;详细用法请查看文档“自定义素材”中的说明。
|
||||
"images": [], // 该层默认显示的所有图片;详细用法请查看文档“自定义素材”中的说明。
|
||||
// "color": [0,0,0,0.3], // 该层的默认画面色调。本项可不写(代表无色调),如果写需要是一个RGBA数组。
|
||||
// "weather": ["snow",5], // 该层的默认天气。本项可忽略表示晴天,如果写则第一项为"rain"或"snow"代表雨雪,第二项为1-10之间的数代表强度。
|
||||
// "bgm": "bgm.mp3", // 到达该层后默认播放的BGM。本项可忽略。
|
||||
"item_ratio": 1, // 该层的宝石/血瓶倍率
|
||||
"map": [ // 地图数据,需要是13x13,建议使用地图生成器来生成
|
||||
|
||||
],
|
||||
@ -1,29 +1,31 @@
|
||||
// 这里需要改楼层名,请和文件名及下面的floorId保持完全一致
|
||||
// 楼层唯一标识符仅能由字母、数字、下划线组成,且不能由数字开头
|
||||
// 推荐用法:第20层就用MT20,第38层就用MT38,地下6层就用MT_6(用下划线代替负号),隐藏3层用MT3h(h表示隐藏),等等
|
||||
main.floors.sample0 = {
|
||||
"floorId": "sample0", // 楼层唯一标识符,需要和名字完全一致
|
||||
main.floors.sample0 =
|
||||
{
|
||||
"floorId": "sample0", // 这里需要改楼层名,请和文件名及下面的floorId保持完全一致
|
||||
// 楼层唯一标识符仅能由字母、数字、下划线组成,且不能由数字开头
|
||||
// 推荐用法:第20层就用MT20,第38层就用MT38,地下6层就用MT_6(用下划线代替负号),隐藏3层用MT3h(h表示隐藏),等等
|
||||
// 楼层唯一标识符,需要和名字完全一致
|
||||
"title": "样板 0 层", // 楼层中文名
|
||||
"name": "0", // 显示在状态栏中的层数
|
||||
"canFlyTo": true, // 该楼能否被楼传器飞到(不能的话在该楼也不允许使用楼传器)
|
||||
"canUseQuickShop": true, // 该层是否允许使用快捷商店
|
||||
"defaultGround": "ground", // 默认地面的图块ID(terrains中)
|
||||
"png": [], // 该层默认显示的所有图片;详细用法请查看文档“自定义素材”中的说明。
|
||||
"images": [], // 该层默认显示的所有图片;详细用法请查看文档“自定义素材”中的说明。
|
||||
// "color": [0,0,0,0.3] // 该层的默认画面色调。本项可不写(代表无色调),如果写需要是一个RGBA数组。
|
||||
// "weather": ["snow",5], // 该层的默认天气。本项可忽略表示晴天,如果写则第一项为"rain"或"snow"代表雨雪,第二项为1-10之间的数代表强度。
|
||||
"bgm": "bgm.mp3", // 到达该层后默认播放的BGM。本项可忽略。
|
||||
"item_ratio": 2, // 该层的宝石/血瓶倍率
|
||||
"map": [ // 地图数据,需要是13x13,建议使用地图生成器来生成
|
||||
[0, 0, 220, 0, 0, 20, 87, 3, 65, 64, 44, 43, 42],
|
||||
[0, 246, 0, 246, 0, 20, 0, 3, 58, 59, 60, 61, 41],
|
||||
[219, 0, 0, 0, 219, 20, 0, 3, 57, 26, 62, 63, 40],
|
||||
[20, 20, 125, 20, 20, 20, 0, 3, 53, 54, 55, 56, 39],
|
||||
[216, 247, 256, 235, 248, 6, 0, 3, 49, 50, 51, 52, 38],
|
||||
[216, 247, 263, 235, 248, 6, 0, 3, 49, 50, 51, 52, 38],
|
||||
[6, 6, 125, 6, 6, 6, 0, 1, 45, 46, 47, 48, 37],
|
||||
[224, 254, 212, 232, 204, 5, 0, 1, 31, 32, 34, 33, 36],
|
||||
[201, 205, 217, 215, 207, 5, 0, 1, 27, 28, 29, 30, 35],
|
||||
[224, 254, 212, 262, 204, 5, 0, 1, 31, 32, 34, 33, 36],
|
||||
[201, 261, 217, 264, 207, 5, 0, 1, 27, 28, 29, 30, 35],
|
||||
[5, 5, 125, 5, 5, 5, 0, 1, 21, 22, 23, 24, 25],
|
||||
[0, 0, 237, 0, 0, 0, 45, 1, 1, 1, 121, 1, 1],
|
||||
[4, 4, 126, 4, 4, 4, 0, 0, 0, 0, 0, 85, 124],
|
||||
[4, 4, 133, 4, 4, 4, 0, 0, 0, 0, 0, 85, 124],
|
||||
[87, 11, 12, 13, 14, 4, 4, 2, 2, 2, 122, 2, 2],
|
||||
[88, 89, 90, 91, 92, 93, 94, 2, 81, 82, 83, 84, 86],
|
||||
],
|
||||
@ -44,12 +46,12 @@ main.floors.sample0 = {
|
||||
"10,11": [ // 守着门的老人
|
||||
"\t[老人,woman]这些是门,需要对应的钥匙打开。\n机关门必须使用特殊的开法。",
|
||||
"\t[老人,woman]开门后可触发 afterOpenDoor 事件。\n\n有关事件的各种信息在下一层会有更为详细的说明。",
|
||||
{'type': 'hide', "time": 500}
|
||||
{"type": "hide", "time": 500}
|
||||
],
|
||||
"2,10": [ // 守着楼梯、传送门、路障的老人
|
||||
"\t[老人,womanMagician]这些是路障、楼梯、传送门。",
|
||||
"\t[老人,womanMagician]血网的伤害数值、中毒后每步伤害数值、衰弱时攻防下降的数值,都在 data.js 内定义。\n\n路障同样会尽量被自动寻路绕过。",
|
||||
"\t[老人,womanMagician]楼梯和传送门需要在changeFloor中定义目标楼层和位置,可参见样板里已有的的写法。",
|
||||
"\t[少女,npc0]这些是路障、楼梯、传送门。",
|
||||
"\t[少女,npc0]血网的伤害数值、中毒后每步伤害数值、衰弱时攻防下降的数值,都在 data.js 内定义。\n\n路障同样会尽量被自动寻路绕过。",
|
||||
"\t[少女,npc0]楼梯和传送门需要在changeFloor中定义目标楼层和位置,可参见样板里已有的的写法。",
|
||||
{"type": "hide", "time": 500}
|
||||
],
|
||||
"2,8": [ // 守着第一批怪物的老人
|
||||
@ -64,7 +66,7 @@ main.floors.sample0 = {
|
||||
],
|
||||
"2,3": [ // 守着第三批怪物的老人
|
||||
"\t[老人,magician]领域、夹击。\n请注意领域怪需要设置value为伤害数值,可参见样板中初级巫师的写法。",
|
||||
"\t[老人,magician]夹击和领域同时发生时先计算领域,再夹击。\n自动寻路同样会尽量绕过你设置的这些点。\n\n另:本塔不支持阻击怪。",
|
||||
"\t[老人,magician]夹击和领域同时发生时先计算领域,再夹击。\n自动寻路同样会尽量绕过你设置的这些点。",
|
||||
{"type": "hide", "time": 500}
|
||||
],
|
||||
"12,10": { // 隐藏的仙子
|
||||
@ -76,7 +78,6 @@ main.floors.sample0 = {
|
||||
},
|
||||
},
|
||||
"changeFloor": { // 楼层转换事件;该事件不能和上面的events有冲突(同位置点),否则会被覆盖
|
||||
"7,9": {"floorId": "sample1", "stair": "downFloor"},
|
||||
"6,0": {"floorId": "sample1", "stair": "downFloor"}, // 目标点:sample1层的下楼梯位置
|
||||
"0,11": {"floorId": "sample0", "loc": [0,12]}, // 目标点:sample0层的x=0,y=12位置
|
||||
"0,12": {"floorId": "sample0", "stair": "upFloor"}, // 注意,目标层有多个楼梯的话,写stair可能会导致到达位置不确定。这时候推荐写loc指明目标点位置。
|
||||
@ -1,17 +1,19 @@
|
||||
// 这里需要改楼层名,请和文件名及下面的floorId保持完全一致
|
||||
// 楼层唯一标识符仅能由字母、数字、下划线组成,且不能由数字开头
|
||||
// 推荐用法:第20层就用MT20,第38层就用MT38,地下6层就用MT_6(用下划线代替负号),隐藏3层用MT3h(h表示隐藏),等等
|
||||
main.floors.sample1 = {
|
||||
"floorId": "sample1", // 楼层唯一标识符,需要和名字完全一致
|
||||
main.floors.sample1 =
|
||||
{
|
||||
"floorId": "sample1", // 这里需要改楼层名,请和文件名及下面的floorId保持完全一致
|
||||
// 楼层唯一标识符仅能由字母、数字、下划线组成,且不能由数字开头
|
||||
// 推荐用法:第20层就用MT20,第38层就用MT38,地下6层就用MT_6(用下划线代替负号),隐藏3层用MT3h(h表示隐藏),等等
|
||||
// 楼层唯一标识符,需要和名字完全一致
|
||||
"title": "样板 1 层", // 楼层中文名
|
||||
"name": "1", // 显示在状态栏中的层数
|
||||
"canFlyTo": true, // 该楼能否被楼传器飞到(不能的话在该楼也不允许使用楼传器)
|
||||
"canUseQuickShop": true, // 该层是否允许使用快捷商店
|
||||
"defaultGround": "grass", // 默认地面的图块ID(terrains中)
|
||||
"png": [[0,0,"bg"]], // // 该层默认显示的所有图片;详细用法请查看文档“自定义素材”中的说明。
|
||||
"images": [[0,0,"bg.jpg",false]], // 该层默认显示的所有图片;详细用法请查看文档“自定义素材”中的说明。
|
||||
// "color": [0,0,0,0.3] // 该层的默认画面色调。本项可不写(代表无色调),如果写需要是一个RGBA数组。
|
||||
"weather": ["snow",6], // 该层的默认天气。本项可忽略表示晴天,如果写则第一项为"rain"或"snow"代表雨雪,第二项为1-10之间的数代表强度。
|
||||
// "bgm": "bgm.mp3", // 到达该层后默认播放的BGM。本项可忽略。
|
||||
"item_ratio": 1, // 该层的宝石/血瓶倍率
|
||||
"map": [ // 地图数据,需要是13x13,建议使用地图生成器来生成
|
||||
[7, 131, 8, 152, 9, 130, 10, 152, 166, 165, 132, 165, 166],
|
||||
[0, 0, 0, 0, 0, 0, 0, 152, 165, 164, 0, 162, 165],
|
||||
@ -60,9 +62,9 @@ main.floors.sample1 = {
|
||||
{"type": "hide", "loc": [[1,6],[0,7],[2,7],[1,8]]}, // 直接隐藏四个白衣武士,没有动画效果
|
||||
{"type": "hide", "loc": [1,5], "time": 500}, // 隐藏红衣魔王,动画500ms
|
||||
{"type": "hide"}, // 隐藏本事件
|
||||
{"type": "setFg", "color": [0,0,0], 'time': 1250}, // 渐变为白色
|
||||
{"type": "setFg", "color": [0,0,0], "time": 1250}, // 渐变为白色
|
||||
{"type": "sleep", "time": 700},
|
||||
{"type": "changeFloor", "floorId": "sample1", "loc": [1,11], 'direction': 'right', 'time': 1000}, // 楼层切换。changeFloor必须指定floorId和loc。
|
||||
{"type": "changeFloor", "floorId": "sample1", "loc": [1,11], "direction": "right", "time": 1000}, // 楼层切换。changeFloor必须指定floorId和loc。
|
||||
// 备注:这里也可以下面的这种写法:
|
||||
// {"type": "changePos", "loc": [1,11]}
|
||||
// 使用这种写法将不会有“楼层切换动画”,而是直接让勇士到达本层的loc位置。
|
||||
@ -1,17 +1,19 @@
|
||||
// 这里需要改楼层名,请和文件名及下面的floorId保持完全一致
|
||||
// 楼层唯一标识符仅能由字母、数字、下划线组成,且不能由数字开头
|
||||
// 推荐用法:第20层就用MT20,第38层就用MT38,地下6层就用MT_6(用下划线代替负号),隐藏3层用MT3h(h表示隐藏),等等
|
||||
main.floors.sample2 = {
|
||||
"floorId": "sample2", // 楼层唯一标识符,需要和名字完全一致
|
||||
main.floors.sample2 =
|
||||
{
|
||||
"floorId": "sample2", // 这里需要改楼层名,请和文件名及下面的floorId保持完全一致
|
||||
// 楼层唯一标识符仅能由字母、数字、下划线组成,且不能由数字开头
|
||||
// 推荐用法:第20层就用MT20,第38层就用MT38,地下6层就用MT_6(用下划线代替负号),隐藏3层用MT3h(h表示隐藏),等等
|
||||
// 楼层唯一标识符,需要和名字完全一致
|
||||
"title": "主塔 40 层", // 楼层中文名
|
||||
"name": "40", // 显示在状态栏中的层数
|
||||
"canFlyTo": false, // 该楼能否被楼传器飞到(不能的话在该楼也不允许使用楼传器)
|
||||
"canUseQuickShop": true, // 该层是否允许使用快捷商店
|
||||
"defaultGround": "snowGround", // 默认地面的图块ID(terrains中)
|
||||
"png": [], // // 该层默认显示的所有图片;详细用法请查看文档“自定义素材”中的说明。
|
||||
"images": [], // // 该层默认显示的所有图片;详细用法请查看文档“自定义素材”中的说明。
|
||||
"color": [255,0,0,0.3], // 该层的默认画面色调。本项可不写(代表无色调),如果写需要是一个RGBA数组。
|
||||
"weather": ["rain",10], // 该层的默认天气。本项可忽略表示晴天,如果写则第一项为"rain"或"snow"代表雨雪,第二项为1-10之间的数代表强度。
|
||||
"bgm": "qianjin.mid", // 到达该层后默认播放的BGM。本项可忽略。
|
||||
"item_ratio": 1, // 该层的宝石/血瓶倍率
|
||||
"map": [ // 地图数据,需要是13x13,建议使用地图生成器来生成
|
||||
[5, 5, 5, 5, 5, 5, 87, 5, 5, 5, 5, 5, 5],
|
||||
[5, 4, 4, 4, 4, 1, 0, 1, 4, 4, 4, 4, 5],
|
||||
21
project/functions.comment.js
Normal file
@ -0,0 +1,21 @@
|
||||
functions_comment_c456ea59_6018_45ef_8bcc_211a24c627dc =
|
||||
{
|
||||
"events" : {
|
||||
"setInitData" : "不同难度分别设置初始属性",
|
||||
"win" : "游戏获胜事件",
|
||||
"lose" : "游戏失败事件",
|
||||
"afterChangeFloor":"转换楼层结束的事件",
|
||||
"addPoint":"加点事件",
|
||||
"afterBattle" : "战斗结束后触发的事件",
|
||||
"afterOpenDoor" : "开一个门后触发的事件",
|
||||
"afterChangeLight" : "改变亮灯之后,可以触发的事件",
|
||||
"afterPushBox" : "推箱子后的事件",
|
||||
"afterUseBomb" : "使用炸弹/圣锤后的事件",
|
||||
"beforeSaveData" : "即将存档前可以执行的操作",
|
||||
"afterLoadData" : "读档事件后,载入事件前,可以执行的操作"
|
||||
|
||||
},
|
||||
"ui" : {
|
||||
"drawAbout" : "绘制“关于”界面"
|
||||
}
|
||||
}
|
||||
301
project/functions.js
Normal file
@ -0,0 +1,301 @@
|
||||
functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a =
|
||||
{
|
||||
"events":{
|
||||
////// 不同难度分别设置初始属性 //////
|
||||
"setInitData":function (hard) {
|
||||
// 不同难度分别设置初始属性
|
||||
if (hard=='Easy') { // 简单难度
|
||||
core.setFlag('hard', 1); // 可以用flag:hard来获得当前难度
|
||||
// 可以在此设置一些初始福利,比如设置初始生命值可以调用:
|
||||
// core.setStatus("hp", 10000);
|
||||
// 赠送一把黄钥匙可以调用
|
||||
// core.setItem("yellowKey", 1);
|
||||
}
|
||||
if (hard=='Normal') { // 普通难度
|
||||
core.setFlag('hard', 2); // 可以用flag:hard来获得当前难度
|
||||
}
|
||||
if (hard=='Hard') { // 困难难度
|
||||
core.setFlag('hard', 3); // 可以用flag:hard来获得当前难度
|
||||
}
|
||||
if (hard=='Hell') { // 噩梦难度
|
||||
core.setFlag('hard', 4); // 可以用flag:hard来获得当前难度
|
||||
}
|
||||
core.events.afterLoadData();
|
||||
},
|
||||
////// 游戏获胜事件 //////
|
||||
"win" : function(reason) {
|
||||
// 游戏获胜事件
|
||||
core.ui.closePanel();
|
||||
var replaying = core.status.replay.replaying;
|
||||
core.stopReplay();
|
||||
core.waitHeroToStop(function() {
|
||||
core.removeGlobalAnimate(0,0,true);
|
||||
core.clearMap('all'); // 清空全地图
|
||||
core.drawText([
|
||||
"\t[恭喜通关]你的分数是${status:hp}。"
|
||||
], function () {
|
||||
core.events.gameOver(reason||'', replaying);
|
||||
})
|
||||
});
|
||||
},
|
||||
////// 游戏失败事件 //////
|
||||
"lose" : function(reason) {
|
||||
// 游戏失败事件
|
||||
core.ui.closePanel();
|
||||
var replaying = core.status.replay.replaying;
|
||||
core.stopReplay();
|
||||
core.waitHeroToStop(function() {
|
||||
core.drawText([
|
||||
"\t[结局1]你死了。\n如题。"
|
||||
], function () {
|
||||
core.events.gameOver(null, replaying);
|
||||
});
|
||||
})
|
||||
},
|
||||
////// 转换楼层结束的事件 //////
|
||||
"afterChangeFloor" : function (floorId) {
|
||||
// 转换楼层结束的事件
|
||||
if (!core.hasFlag("visited_"+floorId)) {
|
||||
core.insertAction(core.floors[floorId].firstArrive);
|
||||
core.setFlag("visited_"+floorId, true);
|
||||
}
|
||||
},
|
||||
////// 加点事件 //////
|
||||
"addPoint" : function (enemy) {
|
||||
// 加点事件
|
||||
var point = enemy.point;
|
||||
if (!core.flags.enableAddPoint || !core.isset(point) || point<=0) return [];
|
||||
|
||||
// 加点,返回一个choices事件
|
||||
return [
|
||||
{"type": "choices",
|
||||
"choices": [
|
||||
{"text": "攻击+"+(1*point), "action": [
|
||||
{"type": "setValue", "name": "status:atk", "value": "status:atk+"+(1*point)}
|
||||
]},
|
||||
{"text": "防御+"+(2*point), "action": [
|
||||
{"type": "setValue", "name": "status:def", "value": "status:def+"+(2*point)}
|
||||
]},
|
||||
{"text": "生命+"+(200*point), "action": [
|
||||
{"type": "setValue", "name": "status:hp", "value": "status:hp+"+(200*point)}
|
||||
]},
|
||||
]
|
||||
}
|
||||
];
|
||||
},
|
||||
////// 战斗结束后触发的事件 //////
|
||||
"afterBattle" : function(enemyId,x,y,callback) {
|
||||
// 战斗结束后触发的事件
|
||||
|
||||
var enemy = core.material.enemys[enemyId];
|
||||
|
||||
// 扣减体力值
|
||||
core.status.hero.hp -= core.enemys.getDamage(enemyId);
|
||||
if (core.status.hero.hp<=0) {
|
||||
core.status.hero.hp=0;
|
||||
core.updateStatusBar();
|
||||
core.events.lose('battle');
|
||||
return;
|
||||
}
|
||||
// 获得金币和经验
|
||||
var money = enemy.money;
|
||||
if (core.hasItem('coin')) money *= 2;
|
||||
if (core.hasFlag('curse')) money=0;
|
||||
core.status.hero.money += money;
|
||||
var experience =enemy.experience;
|
||||
if (core.hasFlag('curse')) experience=0;
|
||||
core.status.hero.experience += experience;
|
||||
var hint = "打败 " + enemy.name;
|
||||
if (core.flags.enableMoney)
|
||||
hint += ",金币+" + money;
|
||||
if (core.flags.enableExperience)
|
||||
hint += ",经验+" + experience;
|
||||
core.drawTip(hint);
|
||||
|
||||
// 删除该块
|
||||
if (core.isset(x) && core.isset(y)) {
|
||||
core.removeBlock(x, y);
|
||||
core.canvas.event.clearRect(32 * x, 32 * y, 32, 32);
|
||||
}
|
||||
|
||||
// 毒衰咒的处理
|
||||
var special = enemy.special;
|
||||
// 中毒
|
||||
if (core.enemys.hasSpecial(special, 12) && !core.hasFlag('poison')) {
|
||||
core.setFlag('poison', true);
|
||||
}
|
||||
// 衰弱
|
||||
if (core.enemys.hasSpecial(special, 13) && !core.hasFlag('weak')) {
|
||||
core.setFlag('weak', true);
|
||||
core.status.hero.atk-=core.values.weakValue;
|
||||
core.status.hero.def-=core.values.weakValue;
|
||||
}
|
||||
// 诅咒
|
||||
if (core.enemys.hasSpecial(special, 14) && !core.hasFlag('curse')) {
|
||||
core.setFlag('curse', true);
|
||||
}
|
||||
// 仇恨属性:减半
|
||||
if (core.flags.hatredDecrease && core.enemys.hasSpecial(special, 17)) {
|
||||
core.setFlag('hatred', parseInt(core.getFlag('hatred', 0)/2));
|
||||
}
|
||||
// 自爆
|
||||
if (core.enemys.hasSpecial(special, 19)) {
|
||||
core.status.hero.hp = 1;
|
||||
}
|
||||
// 退化
|
||||
if (core.enemys.hasSpecial(special, 21)) {
|
||||
core.status.hero.atk -= (enemy.atkValue||0);
|
||||
core.status.hero.def -= (enemy.defValue||0);
|
||||
if (core.status.hero.atk<0) core.status.hero.atk=0;
|
||||
if (core.status.hero.def<0) core.status.hero.def=0;
|
||||
}
|
||||
// 增加仇恨值
|
||||
core.setFlag('hatred', core.getFlag('hatred',0)+core.values.hatred);
|
||||
core.updateStatusBar();
|
||||
|
||||
|
||||
// 事件的处理
|
||||
var todo = [];
|
||||
// 如果不为阻击,且该点存在,且有事件
|
||||
if (!core.enemys.hasSpecial(special, 18) && core.isset(x) && core.isset(y)) {
|
||||
var event = core.floors[core.status.floorId].afterBattle[x+","+y];
|
||||
if (core.isset(event)) {
|
||||
// 插入事件
|
||||
core.unshift(todo, event);
|
||||
}
|
||||
}
|
||||
// 如果有加点
|
||||
var point = core.material.enemys[enemyId].point;
|
||||
if (core.isset(point) && point>0) {
|
||||
core.unshift(todo, core.events.addPoint(core.material.enemys[enemyId]));
|
||||
}
|
||||
|
||||
// 如果事件不为空,将其插入
|
||||
if (todo.length>0) {
|
||||
core.events.insertAction(todo,x,y);
|
||||
}
|
||||
|
||||
// 如果已有事件正在处理中
|
||||
if (core.status.event.id == null) {
|
||||
core.continueAutomaticRoute();
|
||||
}
|
||||
else {
|
||||
core.clearContinueAutomaticRoute();
|
||||
}
|
||||
if (core.isset(callback)) callback();
|
||||
|
||||
},
|
||||
////// 开一个门后触发的事件 //////
|
||||
"afterOpenDoor" : function(doorId,x,y,callback) {
|
||||
// 开一个门后触发的事件
|
||||
|
||||
var todo = [];
|
||||
if (core.isset(x) && core.isset(y)) {
|
||||
var event = core.floors[core.status.floorId].afterOpenDoor[x+","+y];
|
||||
if (core.isset(event)) {
|
||||
core.unshift(todo, event);
|
||||
}
|
||||
}
|
||||
|
||||
if (todo.length>0) {
|
||||
core.events.insertAction(todo,x,y);
|
||||
}
|
||||
|
||||
if (core.status.event.id == null) {
|
||||
core.continueAutomaticRoute();
|
||||
}
|
||||
else {
|
||||
core.clearContinueAutomaticRoute();
|
||||
}
|
||||
if (core.isset(callback)) callback();
|
||||
},
|
||||
////// 改变亮灯之后,可以触发的事件 //////
|
||||
"afterChangeLight" : function(x,y) {
|
||||
// 改变亮灯之后,可以触发的事件
|
||||
|
||||
},
|
||||
////// 推箱子后的事件 //////
|
||||
"afterPushBox" : function () {
|
||||
// 推箱子后的事件
|
||||
|
||||
var noBoxLeft = function () {
|
||||
// 地图上是否还存在未推到的箱子,如果不存在则返回true,存在则返回false
|
||||
for (var i=0;i<core.status.thisMap.blocks.length;i++) {
|
||||
var block=core.status.thisMap.blocks[i];
|
||||
if (core.isset(block.event) && block.event.id=='box') return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
if (noBoxLeft()) {
|
||||
// 可以通过if语句来进行开门操作
|
||||
/*
|
||||
if (core.status.floorId=='xxx') { // 在某个楼层
|
||||
core.insertAction([ // 插入一条事件
|
||||
{"type": "openDoor", "loc": [x,y]} // 开门
|
||||
])
|
||||
}
|
||||
*/
|
||||
}
|
||||
},
|
||||
////// 使用炸弹/圣锤后的事件 //////
|
||||
"afterUseBomb" : function () {
|
||||
// 使用炸弹/圣锤后的事件
|
||||
|
||||
// 这是一个使用炸弹也能开门的例子
|
||||
/*
|
||||
if (core.status.floorId=='xxx' && core.terrainExists(x0,y0,'specialDoor') // 某个楼层,该机关门存在
|
||||
&& !core.enemyExists(x1,y1) && !core.enemyExists(x2,y2)) // 且守门的怪物都不存在
|
||||
{
|
||||
core.insertAction([ // 插入事件
|
||||
{"type": "openDoor", "loc": [x0,y0]} // 开门
|
||||
])
|
||||
}
|
||||
*/
|
||||
|
||||
},
|
||||
////// 即将存档前可以执行的操作 //////
|
||||
"beforeSaveData" : function(data) {
|
||||
// 即将存档前可以执行的操作
|
||||
|
||||
},
|
||||
////// 读档事件后,载入事件前,可以执行的操作 //////
|
||||
"afterLoadData" : function(data) {
|
||||
// 读档事件后,载入事件前,可以执行的操作
|
||||
|
||||
}
|
||||
|
||||
|
||||
},
|
||||
"ui":{
|
||||
////// 绘制“关于”界面 //////
|
||||
"drawAbout" : function() {
|
||||
// 绘制“关于”界面
|
||||
|
||||
if (!core.isPlaying()) {
|
||||
core.status.event = {'id': null, 'data': null};
|
||||
core.dom.startPanel.style.display = 'none';
|
||||
}
|
||||
core.lockControl();
|
||||
core.status.event.id = 'about';
|
||||
|
||||
core.clearMap('ui', 0, 0, 416, 416);
|
||||
var left = 48, top = 36, right = 416 - 2 * left, bottom = 416 - 2 * top;
|
||||
|
||||
core.setAlpha('ui', 0.85);
|
||||
core.fillRect('ui', left, top, right, bottom, '#000000');
|
||||
core.setAlpha('ui', 1);
|
||||
core.strokeRect('ui', left - 1, top - 1, right + 1, bottom + 1, '#FFFFFF', 2);
|
||||
|
||||
var text_start = left + 24;
|
||||
|
||||
// 名称
|
||||
core.canvas.ui.textAlign = "left";
|
||||
core.fillText('ui', "HTML5 魔塔样板", text_start, top+35, "#FFD700", "bold 22px Verdana");
|
||||
core.fillText('ui', "版本: "+core.firstData.version, text_start, top + 80, "#FFFFFF", "bold 17px Verdana");
|
||||
core.fillText('ui', "作者: 艾之葵", text_start, top + 112);
|
||||
core.fillText('ui', 'HTML5魔塔交流群:539113091', text_start, top+112+32);
|
||||
// TODO: 写自己的“关于”页面,每次增加32像素即可
|
||||
}
|
||||
}
|
||||
}
|
||||
234
project/icons.js
Normal file
@ -0,0 +1,234 @@
|
||||
icons_4665ee12_3a1f_44a4_bea3_0fccba634dc1 =
|
||||
{
|
||||
'hero': {
|
||||
'down': {'loc': 0, 'stop': 0, 'leftFoot': 1, 'rightFoot': 3},
|
||||
'left': {'loc': 1, 'stop': 0, 'leftFoot': 1, 'rightFoot': 3},
|
||||
'right': {'loc': 2, 'stop': 0, 'leftFoot': 1, 'rightFoot': 3},
|
||||
'up': {'loc': 3, 'stop': 0, 'leftFoot': 1, 'rightFoot': 3}
|
||||
},
|
||||
'terrains': {
|
||||
'ground': 0,
|
||||
'grass': 1,
|
||||
'grass2': 2,
|
||||
'yellowWall': 3,
|
||||
'whiteWall': 4,
|
||||
'blueWall': 5,
|
||||
'snowGround': 6,
|
||||
'ground2': 7,
|
||||
'ground3': 8,
|
||||
'ground4': 9,
|
||||
'sand': 10,
|
||||
'ground5': 11,
|
||||
'yellowWall2': 12,
|
||||
'whiteWall2': 13,
|
||||
'blueWall2': 14,
|
||||
'blockWall': 15,
|
||||
'grayWall': 16,
|
||||
'white': 17,
|
||||
'ground6': 18,
|
||||
'soil': 19,
|
||||
'star': 20,
|
||||
'lava': 21,
|
||||
'ice': 22,
|
||||
'downFloor': 23,
|
||||
'upFloor': 24,
|
||||
'yellowDoor': 25,
|
||||
'blueDoor': 26,
|
||||
'redDoor': 27,
|
||||
'greenDoor': 28,
|
||||
'specialDoor': 29,
|
||||
'steelDoor': 30,
|
||||
'blueShop-left': 31,
|
||||
'blueShop-right': 32,
|
||||
'pinkShop-left': 33,
|
||||
'pinkShop-right': 34,
|
||||
'arrowUp': 35,
|
||||
'arrowDown': 36,
|
||||
'arrowLeft': 37,
|
||||
'arrowRight': 38,
|
||||
'light': 39,
|
||||
'darkLight': 40,
|
||||
'ski': 41,
|
||||
'flower': 42,
|
||||
'box': 43,
|
||||
'boxed': 44
|
||||
},
|
||||
'animates': {
|
||||
'star': 0,
|
||||
'lava': 1,
|
||||
'waterWall': 2,
|
||||
'yellowDoor': 3,
|
||||
'blueDoor': 4,
|
||||
'redDoor': 5,
|
||||
'greenDoor': 6,
|
||||
'specialDoor': 7,
|
||||
'blueWallDoor': 8,
|
||||
'yellowWallDoor': 9,
|
||||
'whiteWallDoor': 10,
|
||||
'steelDoor': 11,
|
||||
'lavaDoor': 12,
|
||||
'grayLavaDoor': 13,
|
||||
'starDoor': 14,
|
||||
'mockBlueWallDoor': 15,
|
||||
'mockYellowWallDoor': 16,
|
||||
'mockWhiteWallDoor': 17,
|
||||
'iceYellowWallDoor': 18,
|
||||
'starPortal': 19,
|
||||
'exclamation': 20,
|
||||
'portal': 21,
|
||||
'switch': 22,
|
||||
'lavaNet': 23,
|
||||
'poisonNet': 24,
|
||||
'weakNet': 25,
|
||||
'curseNet': 26,
|
||||
'downPortal': 27,
|
||||
'leftPortal': 28,
|
||||
'rightPortal': 29,
|
||||
'upPortal': 30,
|
||||
'water': 31,
|
||||
},
|
||||
'npcs': {
|
||||
'man': 0,
|
||||
'woman': 1,
|
||||
'thief': 2,
|
||||
'fairy': 3,
|
||||
'magician': 4,
|
||||
'womanMagician': 5,
|
||||
'oldMan': 6,
|
||||
'child': 7,
|
||||
'wood': 8,
|
||||
'pinkShop': 9,
|
||||
'blueShop': 10,
|
||||
'princess': 11
|
||||
},
|
||||
'npc48': {
|
||||
'npc0': 0,
|
||||
'npc1': 1,
|
||||
'npc2': 2,
|
||||
'npc3': 3,
|
||||
'npc4': 4,
|
||||
},
|
||||
'enemys': {
|
||||
'greenSlime': 0,
|
||||
'redSlime': 1,
|
||||
'blackSlime': 2,
|
||||
'slimelord': 3,
|
||||
'bat': 4,
|
||||
'bigBat': 5,
|
||||
'redBat': 6,
|
||||
'vampire': 7,
|
||||
'skeleton': 8,
|
||||
'skeletonSoilder': 9,
|
||||
'skeletonCaptain': 10,
|
||||
'ghostSkeleton': 11,
|
||||
'zombie': 12,
|
||||
'zombieKnight': 13,
|
||||
'rock': 14,
|
||||
'slimeMan': 15,
|
||||
'bluePriest': 16,
|
||||
'redPriest': 17,
|
||||
'brownWizard': 18,
|
||||
'redWizard': 19,
|
||||
'yellowGuard': 20,
|
||||
'blueGuard': 21,
|
||||
'redGuard': 22,
|
||||
'swordsman': 23,
|
||||
'soldier': 24,
|
||||
'yellowKnight': 25,
|
||||
'redKnight': 26,
|
||||
'darkKnight': 27,
|
||||
'blackKing': 28,
|
||||
'yellowKing': 29,
|
||||
'greenKing': 30,
|
||||
'blueKnight': 31,
|
||||
'goldSlime': 32,
|
||||
'poisonSkeleton': 33,
|
||||
'poisonBat': 34,
|
||||
'steelRock': 35,
|
||||
'skeletonPriest': 36,
|
||||
'skeletonKing': 37,
|
||||
'skeletonWizard': 38,
|
||||
'redSkeletonCaption': 39,
|
||||
'badHero': 40,
|
||||
'demon': 41,
|
||||
'demonPriest': 42,
|
||||
'goldHornSlime': 43,
|
||||
'redKing': 44,
|
||||
'whiteKing': 45,
|
||||
'blackMagician': 46,
|
||||
'silverSlime': 47,
|
||||
'swordEmperor': 48,
|
||||
'whiteHornSlime': 49,
|
||||
'badPrincess': 50,
|
||||
'badFairy': 51,
|
||||
'grayPriest': 52,
|
||||
'redSwordsman': 53,
|
||||
'whiteGhost': 54,
|
||||
'poisonZombie': 55,
|
||||
'magicDragon': 56,
|
||||
'octopus': 57,
|
||||
'darkFairy': 58,
|
||||
'greenKnight': 59,
|
||||
},
|
||||
'enemy48': {
|
||||
'angel': 0,
|
||||
'elemental': 1,
|
||||
'steelGuard': 2,
|
||||
'evilBat': 3,
|
||||
},
|
||||
'items': {
|
||||
'yellowKey': 0,
|
||||
'blueKey': 1,
|
||||
'redKey': 2,
|
||||
'greenKey': 3,
|
||||
'steelKey': 4,
|
||||
'bigKey': 6,
|
||||
'redJewel': 16,
|
||||
'blueJewel': 17,
|
||||
'greenJewel': 18,
|
||||
'yellowJewel': 19,
|
||||
'redPotion': 20,
|
||||
'bluePotion': 21,
|
||||
'greenPotion': 22,
|
||||
'yellowPotion': 23,
|
||||
'sword0': 60,
|
||||
'sword1': 50,
|
||||
'sword2': 51,
|
||||
'sword3': 52,
|
||||
'sword4': 53,
|
||||
'sword5': 54,
|
||||
'shield0': 61,
|
||||
'shield1': 55,
|
||||
'shield2': 56,
|
||||
'shield3': 57,
|
||||
'shield4': 58,
|
||||
'shield5': 59,
|
||||
'book': 9,
|
||||
'fly': 12,
|
||||
'pickaxe': 45,
|
||||
'icePickaxe': 44,
|
||||
'bomb': 43,
|
||||
'centerFly': 13,
|
||||
'upFly': 15,
|
||||
'downFly': 14,
|
||||
'coin': 11,
|
||||
'snow': 41,
|
||||
'cross': 40,
|
||||
'superPotion': 29,
|
||||
'earthquake': 8,
|
||||
'poisonWine': 24,
|
||||
'weakWine': 25,
|
||||
'curseWine': 27,
|
||||
'superWine': 28,
|
||||
'knife': 42,
|
||||
'moneyPocket': 46,
|
||||
'shoes': 47,
|
||||
'hammer': 48
|
||||
},
|
||||
'autotile': { // 所有的Autotile列表;后面的index简单取0即可
|
||||
'autotile': 0,
|
||||
'autotile1': 0,
|
||||
'autotile2': 0,
|
||||
'autotile3': 0,
|
||||
}
|
||||
}
|
||||
BIN
project/images/animates.png
Normal file
|
After Width: | Height: | Size: 29 KiB |
|
Before Width: | Height: | Size: 207 B After Width: | Height: | Size: 207 B |
|
Before Width: | Height: | Size: 3.4 KiB After Width: | Height: | Size: 3.4 KiB |
|
Before Width: | Height: | Size: 2.8 KiB After Width: | Height: | Size: 2.8 KiB |
|
Before Width: | Height: | Size: 7.3 KiB After Width: | Height: | Size: 7.3 KiB |
|
Before Width: | Height: | Size: 3.7 KiB After Width: | Height: | Size: 3.7 KiB |
BIN
project/images/bg.jpg
Normal file
|
After Width: | Height: | Size: 38 KiB |
|
Before Width: | Height: | Size: 464 B After Width: | Height: | Size: 464 B |
|
Before Width: | Height: | Size: 276 B After Width: | Height: | Size: 276 B |
BIN
project/images/enemy48.png
Normal file
|
After Width: | Height: | Size: 9.6 KiB |
|
Before Width: | Height: | Size: 37 KiB After Width: | Height: | Size: 37 KiB |
|
Before Width: | Height: | Size: 508 B After Width: | Height: | Size: 508 B |
|
Before Width: | Height: | Size: 995 B After Width: | Height: | Size: 995 B |
|
Before Width: | Height: | Size: 854 B After Width: | Height: | Size: 854 B |