Merge pull request #377 from zhaouv/refactoring-editor

Refactoring editor
This commit is contained in:
Zhang Chen 2019-06-04 13:36:42 +08:00 committed by GitHub
commit c3217fa9dd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
30 changed files with 2453 additions and 511 deletions

View File

@ -952,10 +952,11 @@ core.startEvents(list, x, y, callback)
此函数将调用core.setEvents然后停止勇士再执行core.doAction()。
core.doAction()
core.doAction(keepUI)
执行下一个自定义事件。
此函数将检测事件列表是否全部执行完毕,如果是则执行回调函数。
否则将从事件列表中弹出下一个事件并调用core.doEvent进行执行。
如果keepUI为true则不会清掉UI层和selector适合于自己用脚本的绘制。
core.insertAction(action, x, y, callback, addToLast)
@ -1615,9 +1616,10 @@ core.clearMap(name)
该函数的name也可以是'all',若为'all'则为清空所有系统画布。
core.fillText(name, text, x, y, style, font)
core.fillText(name, text, x, y, style, font, maxWidth)
在某个画布上绘制一段文字。
text为要绘制的文本x,y为要绘制的坐标style可选为绘制的样式font可选为绘制的字体。下同
如果maxWidth不为null则视为文字最大宽度如果超过此宽度则会自动放缩文字直到自适应为止。
请注意textAlign和textBaseline将决定绘制的左右对齐和上下对齐方式。
具体可详见core.setTextAlign()和core.setTextBaseline()函数。
@ -1693,6 +1695,13 @@ core.drawImage(name, image, x, y, w, h, x1, y1, w1, h1)
http://www.w3school.com.cn/html5/canvas_drawimage.asp
这里的image允许传一个图片画布。也允许传递图片名将从你导入的图片中获取图片内容。
core.drawIcon(name, id, x, y, w, h)
在一张画布上绘制一个图标。
id为注册过的图标ID也可以使用状态栏的图标ID例如lv, hp, up, save, settings等。
x和y为绘制的左上角坐标w和h可选为绘制的宽高如果不填或null则使用该图标的默认宽高。
// ------ 具体的某个UI界面的绘制 ------ //
core.closePanel()
结束一切事件和UI绘制关闭UI窗口返回游戏。
@ -1746,7 +1755,7 @@ config为绘制的配置项目前可以包括如下几项
- bold是否粗体。如果不设置默认为false。
- align文字对齐方式仅在maxWidth设置时有效默认为'left'。
- fontSize字体大小如果不设置则使用剧情文本设置中的正文字体大小。
- lineHeight绘制的行距值如果不设置则使用fontSize*1.3即1.3行距)。
- lineHeight绘制的行距值如果不设置则使用fontSize*1.3即1.3行距)。
- time打字机效果。若不为0则会逐个字进行绘制并设置core.status.event.interval定时器。

View File

@ -1795,6 +1795,270 @@ yes和no均为必填项即用户点击确认或取消后执行的事件。
该事件会进行等待,直到所有可能的异步事件(异步动画除外)执行完毕。
### previewUIUI绘制并预览
此项可在地图编辑器中预览UI界面的绘制效果。
在编辑器中将会把此项包含的所有UI绘制事件进行绘制从而可以进行预览。
值得注意的是在游戏中UI绘制事件都是绘制在uievent层上的。
### clearMap清除画布
UI绘制事件。
`{"type": "clearMap"}`可以清除`uievent`画布的内容。
```js
[
{"type": "clearMap", "x": 0, "y": 0, "width": "flag:width", "height": 416}, // 清除画布的一部分
{"type": "clearMap"}, // 清空并删除画布
]
```
x, y, width, height均可选表示要清除的坐标和长宽。也可以使用`flag:xxx`。
如果存在某一项不填则会清空全部画布并删除。
### setAttribute设置画布属性
UI绘制事件。
此项可以设置`uievent`画布的各项属性。
```js
[
{"type": "setAttribute", "font": "17px Verdana", "fillStyle": [255,0,0,1]},
]
```
可以选择性的设置如下几项内容:
- `font`:字体,必须是`[italic] [bold] 14px Verdana`这种形式
- `fillStyle`填充样式必须是三元组RGB或四元组RGBA
- `strokeStyle`边框样式必须是三元组RGB或者四元组RGBA
- `lineWidth`:线宽度,必须是正整数
- `alpha`不透明度必须是0到1之间的浮点数
- `align`:对齐方式,只能是`left`, `center`, `right`,分别代表左对齐,居中和右对齐
- `baseline`:基准线,只能是`top`, `middle`, `alphabetic`, `bottom`,分别代表顶部,居中,标准值和底部。
- `z`画布的z值必须是正整数。初始创建时画布的z值是135。请注意闪烁光标所在画布的z值永远比该画布大1。
### fillText绘制文本
UI绘制事件。
此项可以绘制一行文本。
```js
[
{"type": "fillText", "text""要绘制的文本", "x": 10, "y": 20, "maxWidth": 50}
]
```
text必填为要绘制的文本支持`${}`的写法,不支持一切转义字符或换行符。
x和y必填为要绘制的左上角坐标。请使用`setAttribute`来设置绘制的对齐方式和基准线。
style可选如果设置需要是三元组RGB或四元组RBGA代表绘制样式。
font可选如果设置则是要绘制的字体。
maxWidth可选如果设置且不为0则代表要绘制的最大宽度超过此宽度会自动放缩。
### fillBoldText绘制描边文本
UI绘制事件。
此项可以绘制一行描边文本。
```js
[
{"type": "fillText", "text""要绘制的描边文本", "x": 10, "y": 20, "style": [255,0,0,1]}
]
```
text必填为要绘制的文本支持`${}`的写法,不支持一切转义字符或换行符。
x和y必填为要绘制的左上角坐标。请使用`setAttribute`来设置绘制的对齐方式和基准线。
style可选如果设置需要是三元组RGB或四元组RBGA代表绘制样式。
font可选如果设置则是要绘制的字体。
### drawTextContent绘制多行文本
UI绘制事件。
此项可以绘制多行文本。
```js
[
{"type": "drawTextContent", "text""要绘制的多行文本", "left": 10, "top": 20, "maxWidth": 100}
]
```
text必填为要绘制的文本支持所有的文字效果如\n${}\r\\i等但不支持支持\t和\b的语法。
left和top必填为要绘制的起始像素坐标。实际绘制时会将textBaseline设置为'top',因此只需要考虑第一个字的左上角位置。
maxWidth可选为单行最大宽度超过此宽度将自动换行不设置不会自动换行。
color可选表示绘制时的颜色为三元组RGB或四元组RGBA。如果不设置则使用剧情文本设置中的正文颜色。
bold可选是否粗体。如果不设置默认为false。
align可选文字对齐方式仅在maxWidth设置时有效默认为'left'。
fontSize可选为字体大小如果不设置则使用剧情文本设置中的正文字体大小。
lineHeight可选绘制的行距值如果不设置则使用fontSize*1.3即1.3倍行距)。
此项不支持字体样式的设置,使用的是全塔属性中的全局字体;如有需要请使用“设置全局属性”事件来设置字体样式。
### fillRect绘制矩形
UI绘制事件。此项可以绘制一个矩形。
```js
[
{"type": "fillRect", "x": 100, "y": 100, "width": 120, "height": 120, "style": [255,0,0,1]}
]
```
x, y, width, height必填为要绘制的起点坐标和宽高也可以用`flag:xxx`。
color可选表示绘制时的颜色为三元组RGB或四元组RGBA。
### strokeRect绘制矩形边框
UI绘制事件。此项可以绘制一个矩形边框。
```js
[
{"type": "strokeRect", "x": 100, "y": 100, "width": 120, "height": 120, "style": [255,0,0,1], "lineWidth": 4}
]
```
x, y, width, height必填为要绘制的起点坐标和宽高也可以用`flag:xxx`。
style可选表示绘制时的颜色为三元组RGB或四元组RGBA。
lineWidth可选表示边框的线宽。
### drawLine绘制线段
UI绘制事件。此事件可以绘制一个函数。
```js
[
{"type": "drawLine", "x1": 0, "y1": 0, "x2": "flag:x", "y2": 200, "style": [255,0,0,1]}
]
```
x1, y1, x2, x2必填为要绘制的起点和终点坐标也可以用`flag:xxx`的写法。
style可选表示绘制时的颜色为三元组RGB或四元组RGBA。
lineWidth可选表示边框的线宽。
### drawArrow绘制箭头
UI绘制事件。此事件可以绘制一个箭头。
参数和写法与`drawLine`完全一致,只不过是会多画一个箭头标记。
### fillPolygon绘制多边形
UI绘制事件。此事件可以绘制一个多边形。
```js
[
{"type": "fillPolygon", "nodes": [[0,0],[0,100],[100,0]], "style": [255,0,0,1]}
]
```
nodes必填为一个二维数组其中每一项都是多边形一个顶点坐标。与显示/隐藏事件写法相同)
style可选表示绘制时的颜色为三元组RGB或四元组RGBA。
### strokePolygon绘制多边形边框
UI绘制事件。此事件可以绘制一个多边形边框。
参数列表和`fillPolygon`基本相同,不过多了一个`lineWidth`表示的绘制线宽。
### drawImage绘制图片
UI绘制事件。此事件可以绘制一个图片。
```js
[
{"type": "drawImage", "image": "bg.jpg", "x": 0, "y": 0}, // 在(0,0)绘制bg.jpg
{"type": "drawImage", "image": "bg.jpg", "x": 0, "y": 0, "w": 100, "h": 100}, // 在(0,0)绘制bg.jpg且放缩到100x100
// 裁剪并放缩图片
{"type": "drawImage", "image": "bg.jpg", "x": 0, "y": 0, "w": 100, "h": 100, "x1": 0, "y1": 0, "w1": 100, "h1": 100}
]
```
image必填为图片名。图片必须在全塔属性中被注册过。
此函数有三种写法:
- 只写x和y表示要绘制到的位置。
- 写x, y, w, h表示要绘制到的位置且将图片放缩到指定宽高。
- 写x, y, w, h, x1, y1, w1, h1从原始图片上裁剪[x,y,w,h]的图片,并绘制画布上的[x1,y1,w1,h1]
可以查看下面的文档以了解各项参数的信息:
http://www.w3school.com.cn/html5/canvas_drawimage.asp
### drawIcon绘制图标
UI绘制事件。此事件可以绘制一个图标。
```js
[
{"type": "drawIcon", "id": "yellowKey", "x": 100, "y": 100}, // 在(100,100)绘制黄钥匙
]
```
id必填为要绘制的图标ID。可以是一个注册过的图标ID也可以使用状态栏的图标ID例如lv, hp, up, save, settings等。
x, y必填为要绘制的左上角坐标。width和height可选如果设置则会将图标放缩成对应的宽高。
### drawBackground绘制背景图
UI绘制事件。此事件可以绘制一个背景图。
```js
[
{"type": "drawBackground", "background": "winskin.png", "x": 0, "y": 0, "width": 100, "height": 100},
]
```
background必填为要绘制的背景图内容。其可以是一个三元组RGB或四元组RGBA纯色绘制或一个WindowSkin的图片名。
x, y, width, height必填分别为要绘制的起点坐标和长宽。
可以使用“设置画布属性”来设置不透明度和纯色绘制时的边框颜色。
### drawSelector绘制闪烁光标
UI绘制事件。此事件可以绘制闪烁光标。
```js
[
{"type": "drawSelector", "image": "winskin.png", "x": 0, "y": 0, "width": 100, "height": 100},
{"type": "drawSelector"} // 清除闪烁光标
]
```
image为要绘制的WindowSkin图片名如果不填则视为“清除闪烁光标”。
x, y, width, height分别为要绘制的起点坐标和长宽。
请注意,同时只会有一个闪烁光标存在,如果创建多个则后者会替换前者。
闪烁光标将会一直存在即使事件流结束;请使用本事件并不填`image`来清除闪烁光标。
### function: 自定义JS脚本
上述给出了这么多事件,但有时候往往不能满足需求,这时候就需要执行自定义脚本了。

View File

@ -22,6 +22,7 @@ HTML5魔塔是使用画布canvas来绘制存在若干个图层它们
- paint**[D]**绘图层主要用来进行绘图模式。z-index: 95)
- curtain色调层用来控制当前楼层的画面色调 (z-index: 125)
- image1\~50**[D]**图片层用来绘制图片等操作。z-index: 100+code, 101~150
- uievent**[D]**自定义UI绘制层用来进行自定义UI绘制等操作。z-index135可以通过事件设置该值
- uiUI层用来绘制一切UI窗口如剧情文本、怪物手册、楼传器、系统菜单等等 (z-index: 140)
- data数据层用来绘制一些顶层的或更新比较快的数据如左上角的提示战斗界面中数据的变化等等。 (z-index: 170)
@ -29,6 +30,8 @@ HTML5魔塔是使用画布canvas来绘制存在若干个图层它们
色调层的z-index是25ui层的z-index是140因此图片编号在1~24的将被色调层遮挡25~40的将被ui层遮挡41~50的将遮挡UI层。
uievent层为自定义UI绘制所在的层其z值初始是135可以通过事件设置自定义绘制的闪烁光标所在层的z值永远比该值大1。
### 动态创建canvas
从V2.5.3开始可以在H5样板中任意动态创建canvas并进行使用。

File diff suppressed because it is too large Load Diff

View File

@ -314,7 +314,11 @@ Blockly.FieldColour.prototype.createWidget_ = function() {
var getValue=function(){
// return self.getValue() // css颜色
return pb.getFieldValue(targetf);
var f = pb.getFieldValue(targetf);
if (/^(25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d),(25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d),(25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)(,0(\.\d+)?|,1)?$/.test(f)) {
return f;
}
return "";
// 也可以用 pb.getFieldValue(targetf) 获得颜色块左边的域的内容
}

View File

@ -262,10 +262,6 @@ body {
position: absolute;
}
.egameCanvas {
position: absolute;
}
.gameCanvas {
position: absolute;
}
@ -287,6 +283,13 @@ body {
0 0 0 3px #000;
}
#iconExpandBtn {
position: absolute;
left: 10px;
bottom: 30px;
display: none;
}
.warnText {
color: #D50000;
font-weight: 700;
@ -458,4 +461,88 @@ table.row td {
left: 6px;
top: 6px;
background-image:url('data:image/svg+xml;base64,PHN2ZyB2ZXJzaW9uPSIxLjEiIGJhc2VQcm9maWxlPSJmdWxsIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB4bWxuczpldj0iaHR0cDovL3d3dy53My5vcmcvMjAwMS94bWwtZXZlbnRzIj4KPGc%2BCgk8cG9seWdvbiBmaWxsPSIjNjY2IiBwb2ludHM9IjkuMjA3LDYuMTI2IDcuNzkzLDcuNTQxIDExLjc5MywxMS41NDEgMTMuMjA3LDEwLjEyNiIgLz4KCTxwYXRoIGZpbGw9IiM2NjYiIGQ9Ik01LjkxNywyYzEuNjA4LDAsMi45MTcsMS4zMDgsMi45MTcsMi45MTdTNy41MjUsNy44MzMsNS45MTcsNy44MzNTMyw2LjUyNSwzLDQuOTE3UzQuMzA4LDIsNS45MTcsMgoJCSBNNS45MTcsMEMzLjIwMSwwLDEsMi4yMDEsMSw0LjkxN3MyLjIwMSw0LjkxNyw0LjkxNyw0LjkxN3M0LjkxNy0yLjIwMSw0LjkxNy00LjkxN0MxMC44MzMsMi4yMDEsOC42MzIsMCw1LjkxNywwTDUuOTE3LDB6IiAvPgo8L2c%2BCjwvc3ZnPgo%3D');
}
#uieventDiv {
display: none;
width: 100%;
height: 100%;
position: fixed;
top: 0;
left: 0;
background: rgba(127,127,127,0.6);
z-index: 2000
}
#uieventDialog {
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -60%);
background: white;
width: 436px;
}
#uieventHead {
margin: 10px 20px;
}
#uieventTitle {
font-weight: bold;
}
#uieventNo {
float: right;
}
#uieventYes {
display: none;
float: right;
margin-right: 15px;
}
#uieventBody {
width: 416px;
height: 416px;
position: relative;
margin-left: 10px;
margin-bottom: 5px;
overflow: hidden;
}
#uievent {
position: absolute;
width: 100%;
height: 100%;
left: 0;
top: 0;
}
#selectPoint {
display: none;
margin-left: 10px;
margin-bottom: 10px;
}
#selectPointFloor {
margin-right: 10px;
}
#selectPointButtons {
display: inline;
}
#selectPointBox {
position: absolute;
z-index: 75;
width: 26px;
height: 26px;
margin: 3px 0 0 3px;
padding: 0;
/* display: none; */
box-sizing: border-box;
background-color: rgba(255, 255, 255, 0.0);
border: 1px solid #000;
box-shadow: 0 0 0 2px #fff,
0 0 0 3px #000;
}

View File

@ -247,10 +247,6 @@ body {
position: absolute;
}
.egameCanvas {
position: absolute;
}
.gameCanvas {
position: absolute;
}
@ -272,6 +268,13 @@ body {
0 0 0 3px #000;
}
#iconExpandBtn {
position: absolute;
left: 10px;
bottom: 30px;
display: none;
}
.warnText {
color: #D50000;
font-weight: 700;
@ -433,7 +436,7 @@ div.row .rowtd .rowtext{
font: normal 2.5vw Arial, sans-serif;
list-style: none;
margin: 0;
padding: 4px 7em 4px 28px;
padding: 4px 7em 4px 4px;
white-space: nowrap;
/* padding-left: 12px; */
@ -482,4 +485,88 @@ div.row .rowtd .rowtext{
margin: 2px 0;
border-radius: 3px;
width: 90px;
}
#uieventDiv {
display: none;
width: 100%;
height: 100%;
position: fixed;
top: 0;
left: 0;
background: rgba(127,127,127,0.6);
z-index: 2000
}
#uieventDialog {
position: fixed;
top: 50%;
left: 0;
transform: translateY(-50%);
background: white;
width: 100vw;
}
#uieventHead {
margin: 10px 20px;
}
#uieventTitle {
font-weight: bold;
}
#uieventNo {
float: right;
}
#uieventYes {
display: none;
float: right;
margin-right: 15px;
}
#uieventBody {
width: 100vw;
height: 100vw;
position: relative;
margin-left: 0;
margin-bottom: 5px;
overflow: hidden;
}
#uievent {
position: absolute;
width: 100%;
height: 100%;
left: 0;
top: 0;
}
#selectPoint {
display: none;
margin-left: 10px;
margin-bottom: 10px;
}
#selectPointFloor {
margin-right: 10px;
}
#selectPointButtons {
display: inline;
}
#selectPointBox {
position: absolute;
z-index: 75;
width: 26px;
height: 26px;
margin: 3px 0 0 3px;
padding: 0;
/* display: none; */
box-sizing: border-box;
background-color: rgba(255, 255, 255, 0.0);
border: 1px solid #000;
box-shadow: 0 0 0 2px #fff,
0 0 0 3px #000;
}

View File

@ -144,14 +144,15 @@ editor.prototype.changeFloor = function (floorId, callback) {
}
editor.preMapData = null;
core.changeFloor(floorId, null, {"x": 0, "y": 0, "direction": "up"}, null, function () {
core.bigmap.offsetX=0;
core.bigmap.offsetY=0;
editor.moveViewport(0,0);
editor.game.fetchMapFromCore();
editor.updateMap();
editor_mode.floor();
editor.drawEventBlock();
editor.viewportLoc = editor.viewportLoc || {};
var loc = editor.viewportLoc[floorId] || [], x = loc[0] || 0, y = loc[1] || 0;
editor.setViewport(x, y);
if (callback) callback();
});
}
@ -256,14 +257,19 @@ editor.prototype.updateMap = function () {
}
editor.prototype.moveViewport=function(x,y){
core.bigmap.offsetX = core.clamp(core.bigmap.offsetX+32*x, 0, 32*core.bigmap.width-core.__PIXELS__);
core.bigmap.offsetY = core.clamp(core.bigmap.offsetY+32*y, 0, 32*core.bigmap.height-core.__PIXELS__);
editor.prototype.setViewport=function (x, y) {
core.bigmap.offsetX = core.clamp(x, 0, 32*core.bigmap.width-core.__PIXELS__);
core.bigmap.offsetY = core.clamp(y, 0, 32*core.bigmap.height-core.__PIXELS__);
editor.viewportLoc[editor.currentFloorId] = [core.bigmap.offsetX, core.bigmap.offsetY];
core.control.updateViewport();
editor.buildMark();
editor.drawPosSelection();
}
editor.prototype.moveViewport=function(x,y){
editor.setViewport(core.bigmap.offsetX+32*x, core.bigmap.offsetY+32*y);
}
/////////// 界面交互相关 ///////////
editor.prototype.drawInitData = function (icons) {
@ -272,6 +278,9 @@ editor.prototype.drawInitData = function (icons) {
var maxHeight = 700;
var sumWidth = 0;
editor.widthsX = {};
editor.folded = core.getLocalStorage('folded', false);
// editor.folded = true;
editor.foldPerCol = 50;
// var imgNames = Object.keys(images); //还是固定顺序吧;
var imgNames = ["terrains", "animates", "enemys", "enemy48", "items", "npcs", "npc48", "autotile"];
@ -282,20 +291,21 @@ editor.prototype.drawInitData = function (icons) {
for (var im in autotiles) {
tempy += autotiles[im].height;
}
editor.widthsX[img] = [img, sumWidth / 32, (sumWidth + 3 * 32) / 32, tempy];
sumWidth += 3 * 32;
var tempx = editor.folded ? 32 : 3 * 32;
editor.widthsX[img] = [img, sumWidth / 32, (sumWidth + tempx) / 32, tempy];
sumWidth += tempx;
maxHeight = Math.max(maxHeight, tempy);
continue;
}
if (img == 'terrains') {
editor.widthsX[img] = [img, sumWidth / 32, (sumWidth + images[img].width) / 32, images[img].height + 32*2]
sumWidth += images[img].width;
maxHeight = Math.max(maxHeight, images[img].height + 32*2);
continue;
var width = images[img].width, height = images[img].height, mh = height;
if (editor.folded) {
var per_height = (img == 'enemy48' || img == 'npc48' ? 48 : 32);
width = Math.ceil(height / per_height / editor.foldPerCol) * 32;
if (width > 32) mh = per_height * editor.foldPerCol;
}
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);
editor.widthsX[img] = [img, sumWidth / 32, (sumWidth + width) / 32, height];
sumWidth += width;
maxHeight = Math.max(maxHeight, mh + 64);
}
var tilesets = images.tilesets;
for (var ii in core.tilesets) {
@ -312,82 +322,75 @@ editor.prototype.drawInitData = function (icons) {
if (fullWidth > edata.width) edata.style.width = (edata.width = fullWidth) / ratio + 'px';
edata.style.height = (edata.height = fullHeight) / ratio + 'px';
*/
var iconImages = document.getElementById('iconImages');
iconImages.style.width = (iconImages.width = fullWidth) / ratio + 'px';
iconImages.style.height = (iconImages.height = fullHeight) / ratio + 'px';
var dc = {drawImage:function(){
var image, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight;
var a=Array.prototype.slice.call(arguments)
if(arguments.length==3){
// [image, dx, dy]=arguments
// [sx, sy, sWidth, sHeight, dWidth, dHeight]=[0,0,image.width,image.height,image.width,image.height]
image=a[0]
a=[a[0],0,0,image.width,image.height,a[1],a[2],image.width,image.height]
}
if(arguments.length==5){
// [image, dx, dy, dWidth, dHeight]=arguments
// [sx, sy, sWidth, sHeight]=[0,0,image.width,image.height]
image=a[0]
a=[a[0],0,0,image.width,image.height,a[1],a[2],a[3],a[4]]
}
if(arguments.length==9){
// [image, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight]=arguments
}
image=a[0];
sx=a[1];
sy=a[2];
sWidth=a[3];
sHeight=a[4];
dx=a[5];
dy=a[6];
dWidth=a[7];
dHeight=a[8];
//放弃对 dWidth, dHeight 的支持, 始终画一样大的
var dimg=new Image()
dimg.src = image.src;
dimg.style.clip=['rect(',sy,'px,',sx+sWidth,'px,',sy+sHeight,'px,',sx,'px)'].join('')
dimg.style.top=dy-sy+'px'
dimg.style.left=dx-sx+'px'
dimg.width=image.width/ratio
dimg.height=image.height/ratio
iconImages.appendChild(dimg)
}}
// var dc = edata.getContext('2d');
var nowx = 0;
var nowy = 0;
var drawImage = function (image, x, y) {
image.style.left = x + 'px';
image.style.top = y + 'px';
iconImages.appendChild(image);
}
var nowx = 0, nowy = 0;
for (var ii = 0; ii < imgNames.length; ii++) {
var img = imgNames[ii];
if (img == 'terrains') {
(function(image,dc,nowx){
(function(image,nowx){
if (image.complete) {
dc.drawImage(image, nowx, 32);
drawImage(image, nowx, 32);
core.material.images.airwall = image;
delete(editor.airwallImg);
} else image.onload = function () {
dc.drawImage(image, nowx, 32);
drawImage(image, nowx, 32);
core.material.images.airwall = image;
delete(editor.airwallImg);
editor.updateMap();
}
})(editor.airwallImg,dc,nowx);
dc.drawImage(images[img], nowx, 32*2);
nowx += images[img].width;
})(editor.airwallImg,nowx);
if (editor.folded) {
// --- 单列 & 折行
var subimgs = core.splitImage(images[img], 32, editor.foldPerCol * 32);
var frames = images[img].width / 32;
for (var i = 0; i < subimgs.length; i+=frames) {
drawImage(subimgs[i], nowx, i==0?2*32:0);
nowx += 32;
}
}
else {
drawImage(images[img], nowx, 32*2);
nowx += images[img].width;
}
continue;
}
if (img == 'autotile') {
var autotiles = images[img];
var tempx = editor.folded ? 32 : 96;
for (var im in autotiles) {
dc.drawImage(autotiles[im], 0, 0, 96, 128, nowx, nowy, 96, 128);
var subimgs = core.splitImage(autotiles[im], tempx, autotiles[im].height);
drawImage(subimgs[0], nowx, nowy);
nowy += autotiles[im].height;
}
nowx += 3 * 32;
nowx += tempx;
continue;
}
dc.drawImage(images[img], nowx, 0)
nowx += images[img].width;
if (editor.folded) {
// --- 单列 & 折行
var per_height = img.endsWith('48') ? 48 : 32;
var subimgs = core.splitImage(images[img], 32, editor.foldPerCol * per_height);
var frames = images[img].width / 32;
for (var i = 0; i < subimgs.length; i+=frames) {
drawImage(subimgs[i], nowx, 0);
nowx += 32;
}
}
else {
drawImage(images[img], nowx, 0);
nowx += images[img].width;
}
}
for (var ii in core.tilesets) {
var img = core.tilesets[ii];
dc.drawImage(tilesets[img], nowx, 0)
drawImage(tilesets[img], nowx, 0);
nowx += tilesets[img].width;
}
//editor.mapInit();
@ -461,8 +464,12 @@ editor.prototype.setSelectBoxFromInfo=function(thisevent){
pos.x=editor.widthsX[thisevent.images][1];
pos.y=thisevent.y;
if(thisevent.x)pos.x+=thisevent.x;
if(thisevent.images=='terrains')pos.y+=2;
ysize = thisevent.images.endsWith('48') ? 48 : 32;
if (editor.folded && core.tilesets.indexOf(thisevent.images)==-1) {
pos.x += Math.floor(pos.y / editor.foldPerCol);
pos.y %= editor.foldPerCol;
}
if(pos.x == 0) pos.y+=2;
}
var dataSelection = document.getElementById('dataSelection');
dataSelection.style.left = pos.x * 32 + 'px';
@ -484,4 +491,69 @@ editor.prototype.mobile_listen=function(){
// 移动至 editor_unsorted_1.js
}
editor.prototype.copyFromPos = function (pos) {
var fields = Object.keys(editor.file.comment._data.floors._data.loc._data);
pos = pos || editor.pos;
var map = core.clone(editor.map[pos.y][pos.x]);
var events = {};
fields.forEach(function(v){
events[v] = core.clone(editor.currentFloorData[v][pos.x+','+pos.y]);
})
return {map: map, events: events};
}
editor.prototype.pasteToPos = function (info, pos) {
if (info == null) return;
var fields = Object.keys(editor.file.comment._data.floors._data.loc._data);
pos = pos || editor.pos;
editor.map[pos.y][pos.x] = core.clone(info.map);
fields.forEach(function(v){
if (info.events[v] == null) delete editor.currentFloorData[v][pos.x+","+pos.y];
else editor.currentFloorData[v][pos.x+","+pos.y] = core.clone(info.events[v]);
});
}
editor.prototype.movePos = function (startPos, endPos, callback) {
if (!startPos || !endPos) return;
if (startPos.x == endPos.x && startPos.y == endPos.y) return;
var copyed = editor.copyFromPos(startPos);
editor.pasteToPos({map:0, events: {}}, startPos);
editor.pasteToPos(copyed, endPos);
editor.updateMap();
editor.file.saveFloorFile(function (err) {
if (err) {
printe(err);
throw(err)
}
;printf('移动事件成功');
editor.drawPosSelection();
if (callback) callback();
});
}
editor.prototype.clearPos = function (clearPos, pos, callback) {
var fields = Object.keys(editor.file.comment._data.floors._data.loc._data);
pos = pos || editor.pos;
editor.hideMidMenu();
editor.preMapData = null;
editor.info = 0;
editor_mode.onmode('');
if (clearPos)
editor.map[pos.y][pos.x]=editor.info;
editor.updateMap();
fields.forEach(function(v){
delete editor.currentFloorData[v][pos.x+','+pos.y];
})
editor.file.saveFloorFile(function (err) {
if (err) {
printe(err);
throw(err)
}
;printf(clearPos?'清空该点和事件成功':'只清空该点事件成功');
editor.drawPosSelection();
if (callback) callback();
});
}
editor = new editor();

View File

@ -169,6 +169,27 @@ editor_blockly = function () {
MotaActionBlocks['autoSave_s'].xmlText(),
MotaActionBlocks['callLoad_s'].xmlText(),
],
'UI绘制':[
MotaActionBlocks['previewUI_s'].xmlText(),
MotaActionBlocks['clearMap_s'].xmlText(),
MotaActionBlocks['clearMap_1_s'].xmlText(),
MotaActionBlocks['setAttribute_s'].xmlText(),
MotaActionBlocks['fillText_s'].xmlText(),
MotaActionBlocks['fillBoldText_s'].xmlText(),
MotaActionBlocks['drawTextContent_s'].xmlText(),
MotaActionBlocks['fillRect_s'].xmlText(),
MotaActionBlocks['strokeRect_s'].xmlText(),
MotaActionBlocks['drawLine_s'].xmlText(),
MotaActionBlocks['drawArrow_s'].xmlText(),
MotaActionBlocks['fillPolygon_s'].xmlText(),
MotaActionBlocks['strokePolygon_s'].xmlText(),
MotaActionBlocks['drawImage_s'].xmlText(),
MotaActionBlocks['drawImage_1_s'].xmlText(),
MotaActionBlocks['drawIcon_s'].xmlText(),
MotaActionBlocks['drawBackground_s'].xmlText(),
MotaActionBlocks['drawSelector_s'].xmlText(),
MotaActionBlocks['drawSelector_1_s'].xmlText(),
],
'原生脚本':[
MotaActionBlocks['function_s'].xmlText(),
MotaActionBlocks['unknown_s'].xmlText(),
@ -591,7 +612,23 @@ function omitedcheckUpdateFunction(event) {
editor_blockly.doubleClickBlock = function (blockId) {
var b = editor_blockly.workspace.getBlockById(blockId);
//console.log(b);
// console.log(Blockly.JavaScript.blockToCode(b));
if (b && b.type == 'previewUI_s') { // previewUI
try {
var code = "[" + Blockly.JavaScript.blockToCode(b).replace(/\\i/g, '\\\\i') + "]";
eval("var obj="+code);
// console.log(obj);
if (obj.length > 0 && obj[0].type == 'previewUI') {
uievent.previewUI(obj[0].action);
}
} catch (e) {main.log(e);}
return;
}
if (b && b.type in selectPointBlocks) { // selectPoint
this.selectPoint();
return;
}
var textStringDict = {
'text_0_s': 'EvalString_0',
'text_1_s': 'EvalString_2',
@ -603,6 +640,7 @@ function omitedcheckUpdateFunction(event) {
'function_s': 'RawEvalString_0',
'shopsub': 'EvalString_3',
'confirm_s': 'EvalString_0',
'drawTextContent_s': 'EvalString_0',
}
var f = b ? textStringDict[b.type] : null;
if (f) {
@ -650,40 +688,26 @@ function omitedcheckUpdateFunction(event) {
// Index from 1 - 9
editor_blockly.openToolbox = function(index) {
// var element = document.getElementById(':'+index);
// if (element == null || element.getAttribute("aria-selected")=="true") return;
// element.click();
editor_blockly.workspace.toolbox_.tree_.setSelectedItem(editor_blockly.workspace.toolbox_.tree_.children_[index-1]);
if (index < 0) index += editor_blockly.workspace.toolbox_.tree_.children_.length;
editor_blockly.workspace.toolbox_.tree_.setSelectedItem(editor_blockly.workspace.toolbox_.tree_.children_[index]);
}
editor_blockly.reopenToolbox = function(index) {
// var element = document.getElementById(':'+index);
// if (element == null) return;
// if (element.getAttribute("aria-selected")=="true") element.click();
// element.click();
editor_blockly.workspace.toolbox_.tree_.setSelectedItem(editor_blockly.workspace.toolbox_.tree_.children_[index-1]);
editor_blockly.workspace.getFlyout_().show(editor_blockly.workspace.toolbox_.tree_.children_[index-1].blocks);
if (index < 0) index += editor_blockly.workspace.toolbox_.tree_.children_.length;
editor_blockly.workspace.toolbox_.tree_.setSelectedItem(editor_blockly.workspace.toolbox_.tree_.children_[index]);
editor_blockly.workspace.getFlyout_().show(editor_blockly.workspace.toolbox_.tree_.children_[index].blocks);
}
editor_blockly.closeToolbox = function() {
/*
for (var i=1; i<=10; i++) {
var element = document.getElementById(':'+i);
if (element && element.getAttribute("aria-selected")=="true") {
element.click();
return;
}
}
*/
editor_blockly.workspace.toolbox_.clearSelection();
}
var searchInput = document.getElementById("searchBlock");
searchInput.onfocus = function () {
editor_blockly.reopenToolbox(10);
editor_blockly.reopenToolbox(-1);
}
searchInput.oninput = function () {
editor_blockly.reopenToolbox(10);
editor_blockly.reopenToolbox(-1);
}
editor_blockly.searchBlock = function (value) {
@ -708,6 +732,56 @@ function omitedcheckUpdateFunction(event) {
return results.length == 0 ? editor_blockly.lastUsedType : results;
}
// ------ select point ------
// id: [x, y, floorId, forceFloor]
var selectPointBlocks = {
"changeFloor_m": ["Number_0", "Number_1", "IdString_0", true],
"jumpHero_s": ["PosString_0", "PosString_1"],
"changeFloor_s": ["PosString_0", "PosString_1", "IdString_0", true],
"changePos_0_s": ["PosString_0", "PosString_1"],
"battle_1_s": ["PosString_0", "PosString_1"],
"openDoor_s": ["PosString_0", "PosString_1", "IdString_0"],
"closeDoor_s": ["PosString_0", "PosString_1"],
"show_s": ["EvalString_0", "EvalString_1", "IdString_0"],
"hide_s": ["EvalString_0", "EvalString_1", "IdString_0"],
"setBlock_s": ["PosString_0", "PosString_1", "IdString_0"],
"move_s": ["PosString_0", "PosString_1"],
"jump_s": ["PosString_2", "PosString_3"], // 跳跃暂时只考虑终点
"showBgFgMap_s": ["EvalString_0", "EvalString_1", "IdString_0"],
"hideBgFgMap_s": ["EvalString_0", "EvalString_1", "IdString_0"],
"setBgFgBlock_s": ["PosString_0", "PosString_1", "IdString_0"],
"showFloorImg_s": ["EvalString_0", "EvalString_1", "IdString_0"],
"hideFloorImg_s": ["EvalString_0", "EvalString_1", "IdString_0"],
"trigger_s": ["PosString_0", "PosString_1"],
"insert_2_s": ["PosString_0", "PosString_1", "IdString_0"]
}
editor_blockly.selectPoint = function () {
var block = Blockly.selected, arr = null;
var floorId = editor.currentFloorId, pos = editor.pos, x = pos.x, y = pos.y;
if (block != null && block.type in selectPointBlocks) {
arr = selectPointBlocks[block.type];
var xv = parseInt(block.getFieldValue(arr[0])), yv = parseInt(block.getFieldValue(arr[1]));
if (!isNaN(xv)) x = xv;
if (!isNaN(yv)) y = yv;
if (arr[2] != null) floorId = block.getFieldValue(arr[2]) || floorId;
}
uievent.selectPoint(floorId, x, y, arr && arr[2] == null, function (fv, xv, yv) {
if (!arr) return;
if (arr[2] != null) {
if (fv != editor.currentFloorId) block.setFieldValue(fv, arr[2]);
else block.setFieldValue(arr[3] ? fv : "", arr[2]);
}
block.setFieldValue(xv+"", arr[0]);
block.setFieldValue(yv+"", arr[1]);
if (block.type == 'changeFloor_m') {
block.setFieldValue("floorId", "Floor_List_0");
block.setFieldValue("loc", "Stair_List_0");
}
});
}
return editor_blockly;
}
//editor_blockly=editor_blockly();

View File

@ -8,13 +8,21 @@ editor_file = function (editor, callback) {
editor.file.saveFloorFile = function (callback) {
//callback(err:String)
checkCallback(callback);
for(var ii=0,name;name=['map','bgmap','fgmap'][ii];ii++){
var mapArray=editor[name].map(function (v) {
return v.map(function (v) {
return v.idnum || v || 0
})
});
editor.currentFloorData[name]=mapArray;
/* if (!isset(editor.currentFloorId) || !isset(editor.currentFloorData)) {
callback('未选中文件或无数据');
} */
var filename = 'project/floors/' + editor.currentFloorId + '.js';
var datastr = ['main.floors.', editor.currentFloorId, '=\n'];
if (core.floorIds.indexOf(editor.currentFloorId) >= 0) {
for(var ii=0,name;name=['map','bgmap','fgmap'][ii];ii++){
var mapArray=editor[name].map(function (v) {
return v.map(function (v) {
return v.idnum || v || 0
})
});
editor.currentFloorData[name]=mapArray;
}
}
editor.file.saveFloor(editor.currentFloorData)
}
@ -34,8 +42,8 @@ editor_file = function (editor, callback) {
title = "主塔 "+name+" 层";
}
var width = parseInt(document.getElementById('newMapsWidth').value);
var height = parseInt(document.getElementById('newMapsHeight').value);
var width = parseInt(document.getElementById('newMapWidth').value);
var height = parseInt(document.getElementById('newMapHeight').value);
var row = [], map = [];
for (var i=0;i<width;i++) row.push(0);
for (var i=0;i<height;i++) map.push(row);

View File

@ -57,7 +57,7 @@ editor_mode = function (editor) {
printe(objs_.slice(-1)[0]);
throw(objs_.slice(-1)[0])
}
;printf('修改成功');
;printf('修改成功' + (data_a1e2fb4a_e986_4524_b0da_9b7ba7c0874d.firstData.name == 'template' ? '\n\n请注意全塔属性的name尚未修改请及时予以设置' : ''));
}
switch (mode) {
case 'loc':
@ -114,8 +114,7 @@ editor_mode = function (editor) {
editor.drawEventBlock();
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())]);
if (!selectBox.isSelected()) tip.showHelp();
}
editor_mode.prototype.loc = function (callback) {

View File

@ -94,6 +94,8 @@ editor_multi = function () {
editor_multi.lintAutocomplete = false;
if (args.lint === true) editor_multi.lintAutocomplete = true;
if (field.indexOf('Effect') !== -1) editor_multi.lintAutocomplete = true;
if ((!input.value || input.value == 'null') && editor_mode.mode == 'plugins')
input.value = '"function () {\\n\\t// 在此增加新插件\\n\\t\\n}"';
if (input.value.slice(0, 1) === '"' || args.string) {
editor_multi.isString = true;
codeEditor.setValue(JSON.parse(input.value) || '');

View File

@ -104,6 +104,7 @@ editor.constructor.prototype.listen=function () {
holdingPath = 0;
stepPostfix = [];
uc.clearRect(0, 0, core.__PIXELS__, core.__PIXELS__);
startPos = endPos = null;
}//用于鼠标移出canvas时的自动清除状态
eui.oncontextmenu=function(e){e.preventDefault()}
@ -116,6 +117,7 @@ editor.constructor.prototype.listen=function () {
return;
}
var startPos=null, endPos=null;
eui.onmousedown = function (e) {
if (e.button==2){
var loc = eToLoc(e);
@ -130,6 +132,10 @@ editor.constructor.prototype.listen=function () {
editor_mode.onmode('loc');
//editor_mode.loc();
//tip.whichShow(1);
tip.showHelp(6);
startPos = pos;
uc.strokeStyle = '#FF0000';
uc.lineWidth = 3;
if(editor.isMobile)editor.showMidMenu(e.clientX,e.clientY);
return;
}
@ -149,7 +155,29 @@ editor.constructor.prototype.listen=function () {
eui.onmousemove = function (e) {
if (!selectBox.isSelected()) {
if (startPos == null) return;
//tip.whichShow(1);
var loc = eToLoc(e);
var pos = locToPos(loc,true);
if (endPos != null && endPos.x == pos.x && endPos.y == pos.y) return;
if (endPos != null) {
uc.clearRect(Math.min(32 * startPos.x - core.bigmap.offsetX, 32 * endPos.x - core.bigmap.offsetX),
Math.min(32 * startPos.y - core.bigmap.offsetY, 32 * endPos.y - core.bigmap.offsetY),
(Math.abs(startPos.x - endPos.x) + 1) * 32, (Math.abs(startPos.y - endPos.y) + 1) * 32)
}
endPos = pos;
if (startPos != null) {
if (startPos.x != endPos.x || startPos.y != endPos.y) {
core.drawArrow('eui',
32 * startPos.x + 16 - core.bigmap.offsetX, 32 * startPos.y + 16 - core.bigmap.offsetY,
32 * endPos.x + 16 - core.bigmap.offsetX, 32 * endPos.y + 16 - core.bigmap.offsetY);
}
}
// editor_mode.onmode('nextChange');
// editor_mode.onmode('loc');
//editor_mode.loc();
//tip.whichShow(1);
// tip.showHelp(6);
return;
}
@ -181,6 +209,9 @@ editor.constructor.prototype.listen=function () {
eui.onmouseup = function (e) {
if (!selectBox.isSelected()) {
//tip.whichShow(1);
editor.movePos(startPos, endPos);
startPos = endPos = null;
uc.clearRect(0, 0, core.__PIXELS__, core.__PIXELS__);
return;
}
holdingPath = 0;
@ -283,8 +314,21 @@ editor.constructor.prototype.listen=function () {
};
var reDo = null;
var shortcut = core.getLocalStorage('shortcut',{48: 0, 49: 0, 50: 0, 51: 0, 52: 0, 53: 0, 54: 0, 55: 0, 56: 0, 57: 0});
var copyedInfo = null;
document.body.onkeydown = function (e) {
// UI预览 & 地图选点
if (uievent && uievent.isOpen) {
e.preventDefault();
if (e.keyCode == 27) uievent.close();
else if (e.keyCode == 13) uievent.confirm();
else if (e.keyCode==87) uievent.move(0,-1)
else if (e.keyCode==65) uievent.move(-1,0)
else if (e.keyCode==83) uievent.move(0,1);
else if (e.keyCode==68) uievent.move(1,0);
return;
}
// 监听Ctrl+S保存
if (e.ctrlKey && e.keyCode == 83) {
e.preventDefault();
@ -331,31 +375,23 @@ editor.constructor.prototype.listen=function () {
}
// PGUP和PGDOWN切换楼层
if (e.keyCode==33) {
if (e.keyCode==33 || e.keyCode==34) {
e.preventDefault();
var index=editor.core.floorIds.indexOf(editor.currentFloorId);
if (index<editor.core.floorIds.length-1) {
var toId = editor.core.floorIds[index+1];
editor_mode.onmode('nextChange');
editor_mode.onmode('floor');
document.getElementById('selectFloor').value = toId;
editor.changeFloor(toId);
}
}
if (e.keyCode==34) {
e.preventDefault();
var index=editor.core.floorIds.indexOf(editor.currentFloorId);
if (index>0) {
var toId = editor.core.floorIds[index-1];
var nextIndex = index + (e.keyCode==33?1:-1);
if (nextIndex>=0 && nextIndex<editor.core.floorIds.length) {
var toId = editor.core.floorIds[nextIndex];
editor_mode.onmode('nextChange');
editor_mode.onmode('floor');
document.getElementById('selectFloor').value = toId;
editor.changeFloor(toId);
}
return;
}
//ctrl + 0~9 切换到快捷图块
if (e.ctrlKey && [48, 49, 50, 51, 52, 53, 54, 55, 56, 57].indexOf(e.keyCode) !== -1){
editor.setSelectBoxFromInfo(JSON.parse(JSON.stringify(shortcut[e.keyCode]||0)));
return;
}
//alt + 0~9 改变快捷图块
if (e.altKey && [48, 49, 50, 51, 52, 53, 54, 55, 56, 57].indexOf(e.keyCode) !== -1){
@ -364,21 +400,104 @@ editor.constructor.prototype.listen=function () {
shortcut[e.keyCode]=JSON.parse(infoToSave);
printf('已保存该快捷图块, ctrl + '+(e.keyCode-48)+' 使用.')
core.setLocalStorage('shortcut',shortcut);
return;
}
var focusElement = document.activeElement;
if (!focusElement || focusElement.tagName.toLowerCase()=='body') {
// wasd平移大地图
if (e.keyCode==87)
editor.moveViewport(0,-1)
else if (e.keyCode==65)
editor.moveViewport(-1,0)
else if (e.keyCode==83)
editor.moveViewport(0,1);
else if (e.keyCode==68)
editor.moveViewport(1,0);
// Ctrl+C, Ctrl+X, Ctrl+V
if (e.ctrlKey && e.keyCode == 67 && !selectBox.isSelected()) {
e.preventDefault();
copyedInfo = editor.copyFromPos();
printf('该点事件已复制');
return;
}
if (e.ctrlKey && e.keyCode == 88 && !selectBox.isSelected()) {
e.preventDefault();
copyedInfo = editor.copyFromPos();
editor.clearPos(true, null, function () {
printf('该点事件已剪切');
})
return;
}
if (e.ctrlKey && e.keyCode == 86 && !selectBox.isSelected()) {
e.preventDefault();
if (!copyedInfo) {
printe("没有复制的事件");
return;
}
editor.pasteToPos(copyedInfo);
editor.updateMap();
editor.file.saveFloorFile(function (err) {
if (err) {
printe(err);
throw(err)
}
;printf('粘贴事件成功');
editor.drawPosSelection();
});
return;
}
// DELETE
if (e.keyCode == 46 && !selectBox.isSelected()) {
editor.clearPos(true);
return;
}
// ESC
if (e.keyCode == 27) {
if (selectBox.isSelected()) {
editor_mode.onmode('');
editor.file.saveFloorFile(function (err) {
if (err) {
printe(err);
throw(err)
}
;printf('地图保存成功');
});
}
selectBox.isSelected(false);
editor.info = {};
return;
}
switch (e.keyCode) {
// WASD
case 87: editor.moveViewport(0,-1); break;
case 65: editor.moveViewport(-1,0); break;
case 83: editor.moveViewport(0,1); break;
case 68: editor.moveViewport(1,0); break;
// Z~.
case 90: editor_mode.change('map'); break; // Z
case 88: editor_mode.change('loc'); break; // X
case 67: editor_mode.change('enemyitem'); break; // C
case 86: editor_mode.change('floor'); break; // V
case 66: editor_mode.change('tower'); break; // B
case 78: editor_mode.change('functions'); break; // N
case 77: editor_mode.change('appendpic'); break; // M
case 188: editor_mode.change('commonevent'); break; // ,
case 190: editor_mode.change('plugins'); break; // .
// H
case 72: editor.showHelp(); break;
}
return;
}
}
editor.showHelp = function () {
alert(
"快捷操作帮助:\n" +
"ESC / 点击空白处:自动保存当前修改" +
"WASD / 长按箭头:平移大地图\n" +
"PgUp, PgDn / 鼠标滚轮:上下切换楼层\n" +
"Z~.(键盘的第三排):快捷切换标签\n" +
"双击地图:选中对应点的素材\n" +
"右键地图:弹出菜单栏\n" +
"Alt+0~9保存当前使用的图块\n" +
"Ctrl+0~9选中保存的图块\n" +
"Ctrl+Z / Ctrl+Y撤销/重做上次绘制\n" +
"Ctrl+S事件与脚本编辑器的保存并退出\n" +
"双击事件编辑器:长文本编辑/脚本编辑/地图选点/UI绘制预览"
);
}
var getScrollBarHeight = function () {
var outer = document.createElement("div");
outer.style.visibility = "hidden";
@ -405,11 +524,22 @@ editor.constructor.prototype.listen=function () {
}
var scrollBarHeight = getScrollBarHeight();
var iconExpandBtn = document.getElementById('iconExpandBtn');
iconExpandBtn.style.display = 'block';
iconExpandBtn.innerText = editor.folded ? "展开" : "折叠";
iconExpandBtn.onclick = function () {
if (confirm(editor.folded ? "你想要展开素材吗?\n展开模式下将显示全素材内容。"
: ("你想要折叠素材吗?\n折叠模式下每个素材将仅显示单列并且每"+editor.foldPerCol+"个自动换列。"))) {
core.setLocalStorage('folded', !editor.folded);
window.location.reload();
}
}
var dataSelection = document.getElementById('dataSelection');
var iconLib=document.getElementById('iconLib');
iconLib.onmousedown = function (e) {
e.stopPropagation();
if (!editor.isMobile && e.clientY>=((core.__SIZE__==13?630:655) - scrollBarHeight)) return;
if (!editor.isMobile && e.clientY>=iconLib.offsetHeight - scrollBarHeight) return;
var scrollLeft = document.documentElement.scrollLeft || document.body.scrollLeft;
var scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
var loc = {
@ -421,11 +551,11 @@ editor.constructor.prototype.listen=function () {
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;
var ysize = spriter.endsWith('48') ? 48 : 32;
loc.ysize = ysize;
pos.images = editor.widthsX[spriter][0];
pos.y = ~~(loc.y / loc.ysize);
if(core.tilesets.indexOf(pos.images)==-1)pos.x = editor.widthsX[spriter][1];
if(!editor.folded && core.tilesets.indexOf(pos.images)==-1) pos.x = editor.widthsX[spriter][1];
var autotiles = core.material.images['autotile'];
if (pos.images == 'autotile') {
var imNames = Object.keys(autotiles);
@ -439,8 +569,15 @@ editor.constructor.prototype.listen=function () {
}
}
}
} else if ((pos.y + 1) * ysize > editor.widthsX[spriter][3])
pos.y = ~~(editor.widthsX[spriter][3] / ysize) - 1;
}
else {
var height = editor.widthsX[spriter][3], col = height / ysize;
if (editor.folded && core.tilesets.indexOf(pos.images)==-1) {
col = (pos.x == editor.widthsX[spriter][2] - 1) ? ((col - 1) % editor.foldPerCol + 1) : editor.foldPerCol;
}
if (spriter == 'terrains' && pos.x == editor.widthsX[spriter][1]) col += 2;
pos.y = Math.min(pos.y, col - 1);
}
selectBox.isSelected(true);
// console.log(pos,core.material.images[pos.images].height)
@ -454,10 +591,16 @@ editor.constructor.prototype.listen=function () {
} else if(pos.x == 0 && pos.y == 1){
editor.info = editor.ids[editor.indexs[17]];
} else {
if (Object.prototype.hasOwnProperty.call(autotiles, pos.images)) editor.info = {'images': pos.images, 'y': 0};
else if (pos.images == 'terrains') editor.info = {'images': pos.images, 'y': pos.y - 2};
if (autotiles[pos.images]) editor.info = {'images': pos.images, 'y': 0};
else if (core.tilesets.indexOf(pos.images)!=-1) editor.info = {'images': pos.images, 'y': pos.y, 'x': pos.x-editor.widthsX[spriter][1]};
else editor.info = {'images': pos.images, 'y': pos.y};
else {
var y = pos.y;
if (editor.folded) {
y += editor.foldPerCol * (pos.x-editor.widthsX[spriter][1]);
}
if (pos.images == 'terrains' && pos.x == 0) y -= 2;
editor.info = {'images': pos.images, 'y': y}
}
for (var ii = 0; ii < editor.ids.length; ii++) {
if ((core.tilesets.indexOf(pos.images)!=-1 && editor.info.images == editor.ids[ii].images
@ -484,10 +627,13 @@ editor.constructor.prototype.listen=function () {
var midMenu=document.getElementById('midMenu');
midMenu.oncontextmenu=function(e){e.preventDefault()}
editor.lastRightButtonPos=[{x:0,y:0},{x:0,y:0}];
editor.lastCopyedInfo = [null, null];
editor.showMidMenu=function(x,y){
editor.lastRightButtonPos=JSON.parse(JSON.stringify(
[editor.pos,editor.lastRightButtonPos[0]]
));
// --- copy
editor.lastCopyedInfo = [editor.copyFromPos(), editor.lastCopyedInfo[0]];
var locStr='('+editor.lastRightButtonPos[1].x+','+editor.lastRightButtonPos[1].y+')';
var scrollLeft = document.documentElement.scrollLeft || document.body.scrollLeft;
var scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
@ -502,6 +648,10 @@ editor.constructor.prototype.listen=function () {
addFloorEvent.style.display='block';
addFloorEvent.children[0].innerHTML='绑定下楼事件';
}
else if (['leftPortal','rightPortal','downPortal','upPortal'].indexOf(thisevent.id)>=0) {
addFloorEvent.style.display='block';
addFloorEvent.children[0].innerHTML='绑定楼传事件';
}
else addFloorEvent.style.display='none';
chooseThis.children[0].innerHTML='选中此点'+'('+editor.pos.x+','+editor.pos.y+')'
@ -524,20 +674,27 @@ editor.constructor.prototype.listen=function () {
editor.hideMidMenu();
e.stopPropagation();
var thisevent = editor.map[editor.pos.y][editor.pos.x];
var loc = editor.pos.x+","+editor.pos.y;
if (thisevent.id=='upFloor') {
editor.currentFloorData.changeFloor[editor.pos.x+","+editor.pos.y] = {"floorId": ":next", "stair": "downFloor"};
editor.currentFloorData.changeFloor[loc] = {"floorId": ":next", "stair": "downFloor"};
}
else if (thisevent.id=='downFloor') {
editor.currentFloorData.changeFloor[editor.pos.x+","+editor.pos.y] = {"floorId": ":before", "stair": "upFloor"};
editor.currentFloorData.changeFloor[loc] = {"floorId": ":before", "stair": "upFloor"};
}
else if (thisevent.id=='leftPortal' || thisevent.id=='rightPortal') {
editor.currentFloorData.changeFloor[loc] = {"floorId": ":next", "stair": ":symmetry_x"}
}
else if (thisevent.id=='upPortal' || thisevent.id=='downPortal') {
editor.currentFloorData.changeFloor[loc] = {"floorId": ":next", "stair": ":symmetry_y"}
}
editor.file.saveFloorFile(function (err) {
if (err) {
printe(err);
throw(err)
}
;printf('添加楼梯事件成功');
editor.drawPosSelection();
editor_mode.showMode('loc');
printf('添加楼梯事件成功');
});
}
@ -562,8 +719,6 @@ editor.constructor.prototype.listen=function () {
editor.setSelectBoxFromInfo(thisevent);
}
var fields = Object.keys(editor.file.comment._data.floors._data.loc._data);
var copyLoc = document.getElementById('copyLoc');
copyLoc.onmousedown = function(e){
editor.hideMidMenu();
@ -571,22 +726,10 @@ editor.constructor.prototype.listen=function () {
editor.preMapData = null;
reDo = null;
editor_mode.onmode('');
var now = editor.pos;
var last = editor.lastRightButtonPos[1];
var lastevent = editor.map[last.y][last.x];
var lastinfo = 0;
if(lastevent==0){
lastinfo = 0;
} else {
var ids=editor.indexs[lastevent.idnum];
ids=ids[0]?ids[0]:ids;
lastinfo=editor.ids[ids];
}
editor.map[now.y][now.x]=lastinfo;
var now = editor.pos, last = editor.lastRightButtonPos[1];
if (now.x == last.x && now.y == last.y) return;
editor.pasteToPos(editor.lastCopyedInfo[1]);
editor.updateMap();
fields.forEach(function(v){
editor.currentFloorData[v][now.x+','+now.y]=editor.currentFloorData[v][last.x+','+last.y]
})
editor.file.saveFloorFile(function (err) {
if (err) {
printe(err);
@ -603,36 +746,12 @@ editor.constructor.prototype.listen=function () {
e.stopPropagation();
editor.preMapData = null;
reDo = null;
var thisevent = editor.map[editor.pos.y][editor.pos.x];
if(thisevent==0){
editor.info = 0;
} else {
var ids=editor.indexs[thisevent.idnum];
ids=ids[0]?ids[0]:ids;
editor.info=editor.ids[ids];
}
editor_mode.onmode('');
var now = editor.pos;
var last = editor.lastRightButtonPos[1];
var lastevent = editor.map[last.y][last.x];
var lastinfo = 0;
if(lastevent==0){
lastinfo = 0;
} else {
var ids=editor.indexs[lastevent.idnum];
ids=ids[0]?ids[0]:ids;
lastinfo=editor.ids[ids];
}
editor.map[last.y][last.x]=editor.info;
editor.map[now.y][now.x]=lastinfo;
var now = editor.pos, last = editor.lastRightButtonPos[1];
if (now.x == last.x && now.y == last.y) return;
editor.pasteToPos(editor.lastCopyedInfo[1], now);
editor.pasteToPos(editor.lastCopyedInfo[0], last);
editor.updateMap();
fields.forEach(function(v){
var temp_atsfcytaf=editor.currentFloorData[v][now.x+','+now.y];
editor.currentFloorData[v][now.x+','+now.y]=editor.currentFloorData[v][last.x+','+last.y];
editor.currentFloorData[v][last.x+','+last.y]=temp_atsfcytaf;
})
editor.file.saveFloorFile(function (err) {
if (err) {
printe(err);
@ -643,39 +762,18 @@ editor.constructor.prototype.listen=function () {
});
}
var _clearPoint = function (clearPoint) {
editor.hideMidMenu();
editor.preMapData = null;
reDo = null;
editor.info = 0;
editor_mode.onmode('');
var now = editor.pos;
if (clearPoint)
editor.map[now.y][now.x]=editor.info;
editor.updateMap();
fields.forEach(function(v){
delete editor.currentFloorData[v][now.x+','+now.y];
})
editor.file.saveFloorFile(function (err) {
if (err) {
printe(err);
throw(err)
}
;printf(clearPoint?'清空该点和事件成功':'只清空该点事件成功');
editor.drawPosSelection();
});
}
var clearEvent = document.getElementById('clearEvent');
clearEvent.onmousedown = function (e) {
e.stopPropagation();
_clearPoint(false);
reDo = null;
editor.clearPos(false);
}
var clearLoc = document.getElementById('clearLoc');
clearLoc.onmousedown = function(e){
e.stopPropagation();
_clearPoint(true);
reDo = null;
editor.clearPos(true);
}
var brushMod=document.getElementById('brushMod');
@ -689,8 +787,11 @@ editor.constructor.prototype.listen=function () {
}
var brushMod3=document.getElementById('brushMod3');
if(brushMod3)brushMod3.onchange=function(){
editor.brushMod=brushMod3.value;
if(brushMod3) {
brushMod3.onchange=function(){
tip.showHelp(5)
editor.brushMod=brushMod3.value;
}
}
var bgc = document.getElementById('bg'), fgc = document.getElementById('fg'),
@ -737,10 +838,31 @@ editor.constructor.prototype.listen=function () {
}
var viewportButtons=document.getElementById('viewportButtons');
var pressTimer = null;
for(var ii=0,node;node=viewportButtons.children[ii];ii++){
(function(x,y){
node.onclick=function(){
editor.moveViewport(x,y);
var move = function () {
editor.moveViewport(x, y);
}
node.onmousedown = function () {
clearTimeout(pressTimer);
pressTimer = setTimeout(function () {
pressTimer = -1;
var f = function () {
if (pressTimer != null) {
move();
setTimeout(f, 150);
}
}
f();
}, 500);
};
node.onmouseup = function () {
if (pressTimer > 0) {
clearTimeout(pressTimer);
move();
}
pressTimer = null;
}
})([-1,0,0,1][ii],[0,-1,1,0][ii]);
}

View File

@ -568,11 +568,14 @@ editor_unsorted_2_wrapper=function(editor_mode){
});
}
editor_mode.change = function (value) {
editor_mode.onmode('nextChange');
editor_mode.onmode(value);
if(editor.isMobile)editor.showdataarea(false);
}
var editModeSelect = document.getElementById('editModeSelect');
editModeSelect.onchange = function () {
editor_mode.onmode('nextChange');
editor_mode.onmode(editModeSelect.value);
if(editor.isMobile)editor.showdataarea(false);
editor_mode.change(editModeSelect.value);
}
editor_mode.checkUnique = function (thiseval) {

View File

@ -206,13 +206,20 @@ printf = function (str_, type) {
printe = function (str_) {
printf(str_, 'error')
}
tip_in_showMode = [
'涉及图片的更改需要F5刷新浏览器来生效',
'文本域可以通过双击,在文本编辑器或事件编辑器中编辑',
'事件编辑器中的显示文本和自定义脚本的方块也可以双击',
"画出的地图要点击\"保存地图\"才会写入到文件中",
];
tip=document.getElementById('tip')
tip.showHelp = function(value) {
var tips = [
'表格的文本域可以双击进行编辑',
'双击地图可以选中素材,右键可以弹出菜单',
'双击事件编辑器的图块可以进行长文本编辑/脚本编辑/地图选点/UI绘制预览等操作',
'ESC或点击空白处可以自动保存当前修改',
'H键可以打开操作帮助哦',
'tileset贴图模式下可以按选中tileset素材并在地图上拖动来一次绘制一个区域',
'可以拖动地图上的图块和事件或按Ctrl+C, Ctrl+X和Ctrl+V进行复制剪切和粘贴Delete删除'
];
if (value == null) value = Math.floor(Math.random() * tips.length);
printf('tips: ' + tips[value])
}
tip._infos= {}
tip.infos=function(value){
if(value!=null){
@ -367,3 +374,195 @@ selectBox.isSelected=function(value){
return selectBox._isSelected
}
// ------ UI预览 & 地图选点相关 ------ //
uievent = {
elements: {},
values: {},
isOpen: false,
mode: ""
};
uievent.elements.div = document.getElementById('uieventDiv');
uievent.elements.title = document.getElementById('uieventTitle');
uievent.elements.yes = document.getElementById('uieventYes');
uievent.elements.no = document.getElementById('uieventNo');
uievent.elements.selectBackground = document.getElementById('uieventBackground');
uievent.elements.selectPoint = document.getElementById('selectPoint');
uievent.elements.selectFloor = document.getElementById('selectPointFloor');
uievent.elements.selectPointBox = document.getElementById('selectPointBox');
uievent.elements.body = document.getElementById('uieventBody');
uievent.elements.selectPointButtons = document.getElementById('selectPointButtons');
uievent.confirm = function () {
var callback = uievent.values.callback, floorId = uievent.values.floorId,
x = uievent.values.x, y = uievent.values.y;
uievent.close();
if (callback) {
callback(floorId, x, y);
}
}
uievent.elements.yes.onclick = uievent.confirm;
uievent.close = function () {
uievent.isOpen = false;
uievent.elements.div.style.display = 'none';
uievent.values = {};
}
uievent.elements.no.onclick = uievent.close;
uievent.elements.selectBackground.onchange = function () {
uievent.drawPreviewUI();
}
uievent.drawPreviewUI = function () {
core.setAlpha('uievent', 1);
core.clearMap('uievent');
// 绘制UI
var background = uievent.elements.selectBackground.value;
if (background == 'thumbnail') {
core.drawThumbnail(editor.currentFloorId, null, {}, 'uievent');
}
else {
core.fillRect('uievent', 0, 0, core.__PIXELS__, core.__PIXELS__, background);
}
if (uievent.values.list instanceof Array) {
uievent.values.list.forEach(function (data) {
var type = data.type;
if (!type || !core.ui["_uievent_"+type]) return;
core.ui["_uievent_"+type](data);
})
}
}
uievent.previewUI = function (list) {
uievent.isOpen = true;
uievent.elements.div.style.display = 'block';
uievent.mode = 'previewUI';
uievent.elements.selectPoint.style.display = 'none';
uievent.elements.yes.style.display = 'none';
uievent.elements.title.innerText = 'UI绘制预览';
uievent.elements.selectBackground.style.display = 'inline';
uievent.elements.selectBackground.value = 'thumbnail';
uievent.elements.selectPointBox.style.display = 'none';
uievent.values.list = list;
uievent.drawPreviewUI();
}
uievent.selectPoint = function (floorId, x, y, hideFloor, callback) {
uievent.values.hideFloor = hideFloor;
uievent.values.callback = callback;
uievent.values.size = editor.isMobile ? window.innerWidth / core.__SIZE__ : 32;
uievent.elements.selectPointBox.style.width = (uievent.values.size - 6) + "px";
uievent.elements.selectPointBox.style.height = (uievent.values.size - 6) + "px";
uievent.isOpen = true;
uievent.elements.div.style.display = 'block';
uievent.mode = 'selectPoint';
uievent.elements.selectPoint.style.display = 'block';
uievent.elements.yes.style.display = 'inline';
uievent.elements.selectBackground.style.display = 'none';
uievent.elements.selectFloor.style.display = hideFloor ? 'none': 'inline';
uievent.elements.selectPointBox.style.display = 'block';
// Append children
var floors = "";
core.floorIds.forEach(function (f) {
floors += "<option value="+f+">"+f+"</option>";
})
uievent.elements.selectFloor.innerHTML = floors;
this.setPoint(floorId || editor.currentFloorId, core.calValue(x) || 0, core.calValue(y) || 0);
}
uievent.updateSelectPoint = function (redraw) {
uievent.elements.title.innerText = '地图选点 ('+uievent.values.x+","+uievent.values.y+')';
if (redraw) {
core.drawThumbnail(uievent.values.floorId, null, null,
{ctx: 'uievent', centerX: uievent.values.left + core.__HALF_SIZE__,
centerY: uievent.values.top + core.__HALF_SIZE__});
}
uievent.elements.selectPointBox.style.left = uievent.values.size * (uievent.values.x - uievent.values.left) + "px";
uievent.elements.selectPointBox.style.top = uievent.values.size * (uievent.values.y - uievent.values.top) + "px";
}
uievent.setPoint = function (floorId, x, y) {
if (core.floorIds.indexOf(floorId) == -1) floorId = editor.currentFloorId;
uievent.values.floorId = floorId;
uievent.elements.selectFloor.value = floorId;
uievent.values.x = x != null ? x : ( uievent.values.x || 0);
uievent.values.y = y != null ? y : ( uievent.values.x || 0);
uievent.values.width = core.floors[uievent.values.floorId].width || core.__SIZE__;
uievent.values.height = core.floors[uievent.values.floorId].height || core.__SIZE__;
uievent.values.left = core.clamp(uievent.values.x - core.__HALF_SIZE__, 0, uievent.values.width - core.__SIZE__);
uievent.values.top = core.clamp(uievent.values.y - core.__HALF_SIZE__, 0, uievent.values.height - core.__SIZE__);
uievent.updateSelectPoint(true);
}
uievent.elements.selectFloor.onchange = function () {
uievent.setPoint(uievent.elements.selectFloor.value);
}
uievent.elements.body.onclick = function (e) {
if (uievent.mode != 'selectPoint') return;
uievent.values.x = uievent.values.left + Math.floor(e.offsetX / uievent.values.size);
uievent.values.y = uievent.values.top + Math.floor(e.offsetY / uievent.values.size);
uievent.updateSelectPoint(false);
}
uievent.move = function (dx, dy) {
if (uievent.mode != 'selectPoint') return;
uievent.values.left = core.clamp(uievent.values.left + dx, 0, uievent.values.width - core.__SIZE__);
uievent.values.top = core.clamp(uievent.values.top + dy, 0, uievent.values.height - core.__SIZE__);
this.updateSelectPoint(true);
};
(function() {
var viewportButtons = uievent.elements.selectPointButtons;
var pressTimer = null;
for(var ii=0,node;node=viewportButtons.children[ii];ii++){
(function(x,y){
var move = function () {
uievent.move(x, y);
}
node.onmousedown = function () {
clearTimeout(pressTimer);
pressTimer = setTimeout(function () {
pressTimer = -1;
var f = function () {
if (pressTimer != null) {
move();
setTimeout(f, 150);
}
}
f();
}, 500);
};
node.onmouseup = function () {
if (pressTimer > 0) {
clearTimeout(pressTimer);
move();
}
pressTimer = null;
}
})([-1,0,0,1][ii],[0,-1,1,0][ii]);
}
})();
uievent.elements.div.onmousewheel = function (e) {
if (uievent.mode != 'selectPoint' || uievent.values.hideFloor) return;
var index = core.floorIds.indexOf(uievent.values.floorId);
try {
if (e.wheelDelta)
index+=Math.sign(e.wheelDelta);
else if (e.detail)
index+=Math.sign(e.detail);
} catch (ee) { main.log(ee); }
index = core.clamp(index, 0, core.floorIds.length - 1);
uievent.setPoint(core.floorIds[index]);
}

View File

@ -16,12 +16,19 @@ editor_file之后是更改editor.map的储存方式, 现有的存对象的模式
## 文件结构
(全部小写,必要时用下划线分割)
+ [ ] editor_blockly 图块化事件编辑器
+ [ ] editor_multi 多行文本编辑器
+ [x] editor_table 处理表格的生成, 及其响应的事件, 从原editor\_mode中分离
+ [ ] editor_file 调用fs.js编辑文件, 把原editor\_file模块化, 并且只负责文件写入
+ [ ] editor_game 处理游戏数据, 导入为editor的数据, 编辑数据, 从原editor和editor_file中抽离. **只有此文件允许`\s(main|core)`形式的调用**(以及其初始化`editor_game_wrapper(editor, main, core);`)
+ [x] editor_util 生成guid/处理颜色 等函数, 从editor分离
+ [ ] editor_action 处理界面上的按钮/下拉框点击等用户的操作与功能函数的绑定, 维护editor.dom, unsorted_1/2中的绑定挪到此处, 其中的函数内容, 分类放在其他文件
+ [ ] editor_mappanel 与地图面板相关的功能, <-unsorted_1/2/3
+ [ ] editor_datapanel 与数据面板相关的功能, <-unsorted_1/2/3
+ [ ] editor_materialpanel 与素材面板相关的功能, <-unsorted_1/2/3
+ [ ] editor_ui 维护printe/printf/tip, 以及之后可能的窗口化
+ [ ] editor 执行初始化流程加组合各组件
+ [ ] 原editor_mode 移除
+ [x] 原vm 移除
@ -72,9 +79,11 @@ editor: {
+ editor.widthX特别不直观
+ ? 编辑器使用可拖拽和调大小的窗口做容器
## 功能改进
+ [ ] 大地图
+ [x] 大地图
在切换时, 每次都回到最左上->每个楼层记录一个位置
四个箭头支持长按
? 滚动条
@ -87,12 +96,12 @@ editor: {
+ [ ] ? 简洁的事件方块注册
`editor.registerEvent('log',[['test','Int','测试',0],['floorId','Idstring','楼层','MT0']])`
+ [ ] 一个显示所有快捷键的文本
+ [x] 一个显示所有快捷键的文本
+ [ ] 更多快捷键
+ [x] 更多快捷键
【全塔属性】、【楼层属性】等常用的编辑栏切换
+ [ ] ? 地图编辑优化
+ [x] ? 地图编辑优化
常用的地图编辑快捷键/命令复制ctrl+c、粘贴ctrl+v、复制可绑定为现在的“选中xx位置事件” 粘贴为复制xx事件到此处撤回ctrl+z、取消撤回ctrl+y
可以按住拖动图块与事件。
@ -103,18 +112,20 @@ editor: {
+ [x] 修改系统的触发器(下拉菜单增加新项)
在编辑器修改`comment.js`现场发readFile请求读文件然后开脚本编辑器进行编辑
+ [ ] ? 删除注册项/修改图块ID
+ [x] ? 删除注册项/修改图块ID
+ [ ] ? 怪物和道具也能像其他类型那样查看“图块信息”(而不只是具体的怪物属性)
+ [ ] 素材区自动换列
+ [x] 素材区自动换列
怪物或道具太多时, 按照每100个进行拆分新开列来显示
+ [ ] 多帧素材只显示第一帧
+ [x] 多帧素材只显示第一帧
+ [ ] `显示文章`以及`选项`等方块, 把`标题`和`图像`从字符串提取出填回相应的空
+ [x] `显示文章`以及`选项`等方块, 把`标题`和`图像`从字符串提取出填回相应的空
+ [ ] blockly中某些需要选点的填空, 增加按钮, 点击后从缩略图中点击位置
+ [x] blockly中某些需要选点的填空, 增加按钮, 点击后从缩略图中点击位置
+ [ ] 插件编写增加判定,如果保存时框内不是以 "function\s*()" 开头(也就是用户直接写的脚本),则自动添加一个 function() { } 将代码包装起来。
## 左侧页面模式

View File

@ -216,6 +216,7 @@
<input class="color" id="colorPicker" value="255,215,0,1"/>
<button onclick="confirmColor()">确定</button>
</div>
<button class="cpPanel" onclick="editor_blockly.selectPoint()">选点</button>
<xml id="toolbox" style="display:none">
</xml>
</h3>
@ -296,7 +297,7 @@
<canvas class='gameCanvas' id='event2' width='416' height='416'></canvas>
<canvas class='gameCanvas' id='fg' width='416' height='416'></canvas>
<canvas class='gameCanvas' id='efg' width='416' height='416'></canvas>
<canvas class='egameCanvas' id='eui' width='416' height='416' style='z-index:100'></canvas>
<canvas class='gameCanvas' id='eui' width='416' height='416' style='z-index:100'></canvas>
</div>
</div>
@ -307,6 +308,7 @@
<div id='dataSelection' style="display:none"></div>
</div>
</div>
<button id="iconExpandBtn"></button>
</div>
<div id="down">
<div style="margin:0.5rem">
@ -514,7 +516,7 @@
<canvas class='gameCanvas' id='data' width='416' height='416'>此浏览器不支持HTML5</canvas>
</div>
</div>
<div id='inputBackground' style='display: none'>
<div id='inputDiv' style='display: none'>
<div id='inputDialog'>
<p id="inputMessage">请输入文字...</p>
<input id='inputBox' type="text"/>
@ -522,6 +524,35 @@
<button id='inputNo'>取消</button>
</div>
</div>
<!-- UI预览 & 地图选点 -->
<div id='uieventDiv' style='display: none'>
<div id='uieventDialog'>
<div id="uieventHead">
<span id="uieventTitle"></span>
<select id="uieventBackground" style="margin-left: 20px">
<option value="thumbnail" selected>缩略图</option>
<option value="#000000">黑色</option>
<option value="#FFFFFF">白色</option>
</select>
<button id="uieventNo">关闭</button>
<button id="uieventYes">确定</button>
</div>
<hr style="clear: both; margin-top: 0"/>
<div id='uieventBody'>
<canvas class='gameCanvas' id='uievent' width='416' height='416'></canvas>
<div id="selectPointBox"></div>
</div>
<div id="selectPoint">
<select id="selectPointFloor"></select>
<div id="selectPointButtons">
<input type="button" value="←"/>
<input type="button" value="↑"/>
<input type="button" value="↓"/>
<input type="button" value="→"/>
</div>
</div>
</div>
</div>
<!-- */</script> -->
<!-- =========================================================== -->

View File

@ -211,6 +211,7 @@
<input class="color" id="colorPicker" value="255,215,0,1"/>
<button onclick="confirmColor()">确定</button>
</div>
<button class="cpPanel" onclick="editor_blockly.selectPoint()" style="margin-left:5px">地图选点</button>
</div>
<xml id="toolbox" style="display:none">
</xml>
@ -292,7 +293,7 @@
<canvas class='gameCanvas' id='event2' width='416' height='416'></canvas>
<canvas class='gameCanvas' id='fg' width='416' height='416'></canvas>
<canvas class='gameCanvas' id='efg' width='416' height='416'></canvas>
<canvas class='egameCanvas' id='eui' width='416' height='416' style='z-index:100'></canvas>
<canvas class='gameCanvas' id='eui' width='416' height='416' style='z-index:100'></canvas>
</div>
<div class="tools">
<div id="tip">
@ -351,6 +352,7 @@
<div id='dataSelection' style="display:none"></div>
</div>
</div>
<button id="iconExpandBtn"></button>
</div>
<div id="menuDiv">
<div id="midMenu" style="display:none">
@ -497,7 +499,7 @@
<canvas class='gameCanvas' id='data' width='416' height='416'>此浏览器不支持HTML5</canvas>
</div>
</div>
<div id='inputBackground' style='display: none'>
<div id='inputDiv' style='display: none'>
<div id='inputDialog'>
<p id="inputMessage">请输入文字...</p>
<input id='inputBox' type="text"/>
@ -505,6 +507,37 @@
<button id='inputNo'>取消</button>
</div>
</div>
<!-- UI预览 & 地图选点 -->
<div id='uieventDiv' style='display: none'>
<div id='uieventDialog'>
<div id="uieventHead">
<span id="uieventTitle"></span>
<select id="uieventBackground" style="margin-left: 20px">
<option value="thumbnail" selected>缩略图</option>
<option value="#000000">黑色</option>
<option value="#FFFFFF">白色</option>
</select>
<button id="uieventNo">关闭</button>
<button id="uieventYes">确定</button>
</div>
<hr style="clear: both; margin-top: 0"/>
<div id='uieventBody'>
<canvas class='gameCanvas' id='uievent' width='416' height='416'></canvas>
<div id="selectPointBox"></div>
</div>
<div id="selectPoint">
<select id="selectPointFloor"></select>
<div id="selectPointButtons">
<input type="button" value="←"/>
<input type="button" value="↑"/>
<input type="button" value="↓"/>
<input type="button" value="→"/>
</div>
</div>
</div>
</div>
<!-- */</script> -->
<!-- =========================================================== -->

View File

@ -113,7 +113,8 @@ actions.prototype.doRegisteredAction = function (action) {
actions.prototype._checkReplaying = function () {
if (core.isReplaying() && core.status.event.id != 'save'
&& (core.status.event.id || "").indexOf('book') != 0 && core.status.event.id != 'viewMaps')
&& (core.status.event.id || "").indexOf('book') != 0 && core.status.event.id != 'viewMaps'
&& core.status.event.id != 'toolbox' && core.status.event.id != 'equipbox')
return true;
return false;
}
@ -170,6 +171,10 @@ actions.prototype._sys_onkeyUp_replay = function (e) {
core.viewMapReplay();
else if (e.keyCode == 78) // N
core.stepReplay();
else if (e.keyCode == 84) // T
core.toolboxReplay();
else if (e.keyCode == 81) // Q
core.equipboxReplay();
else if (e.keyCode >= 49 && e.keyCode <= 51) // 1-3
core.setReplaySpeed(e.keyCode - 48);
else if (e.keyCode == 52) // 4
@ -1317,7 +1322,10 @@ actions.prototype._clickToolbox = function (x, y) {
// 装备栏
if (x >= this.LAST - 2 && y == 0) {
core.ui.closePanel();
core.openEquipbox();
if (core.isReplaying())
core.equipboxReplay();
else
core.openEquipbox();
return;
}
if (x >= this.LAST - 2 && y == this.LAST) {
@ -1376,6 +1384,7 @@ actions.prototype._clickToolboxIndex = function (index) {
if (select >= items.length) return;
var itemId = items[select];
if (itemId == core.status.event.data.selectId) {
if (core.isReplaying()) return;
core.events.tryUseItem(itemId);
}
else {
@ -1478,7 +1487,10 @@ actions.prototype._keyDownToolbox = function (keycode) {
actions.prototype._keyUpToolbox = function (keycode) {
if (keycode == 81) {
core.ui.closePanel();
core.openEquipbox();
if (core.isReplaying())
core.equipboxReplay();
else
core.openEquipbox();
return;
}
if (keycode == 84 || keycode == 27 || keycode == 88) {
@ -1498,7 +1510,10 @@ actions.prototype._clickEquipbox = function (x, y) {
// 道具栏
if (x >= this.LAST - 2 && y == 0) {
core.ui.closePanel();
core.openToolbox();
if (core.isReplaying())
core.toolboxReplay();
else
core.openToolbox();
return;
}
// 返回
@ -1547,6 +1562,7 @@ actions.prototype._clickEquipboxIndex = function (index) {
if (index < this.LAST) {
if (index >= core.status.globalAttribute.equipName.length) return;
if (index == core.status.event.selection && core.status.hero.equipment[index]) {
if (core.isReplaying()) return;
core.unloadEquip(index);
core.status.route.push("unEquip:" + index);
}
@ -1554,6 +1570,7 @@ actions.prototype._clickEquipboxIndex = function (index) {
else {
var equips = Object.keys(core.status.hero.items.equips || {}).sort();
if (index == core.status.event.selection) {
if (core.isReplaying()) return;
var equipId = equips[index - this.LAST + (core.status.event.data.page - 1) * this.LAST];
core.loadEquip(equipId);
core.status.route.push("equip:" + equipId);
@ -1645,7 +1662,10 @@ actions.prototype._keyUpEquipbox = function (keycode, altKey) {
}
if (keycode == 84) {
core.ui.closePanel();
core.openToolbox();
if (core.isReplaying())
core.toolboxReplay();
else
core.openToolbox();
return;
}
if (keycode == 81 || keycode == 27 || keycode == 88) {
@ -2078,13 +2098,7 @@ actions.prototype._clickSyncSave_readFile = function () {
}
actions.prototype._clickSyncSave_replay = function () {
if (core.hasFlag('debug')) {
core.drawText("\t[系统提示]调试模式下无法回放录像");
}
else {
core.status.event.selection = 0;
core.ui.drawReplay();
}
core.ui.drawReplay();
}
////// 同步存档界面时,放开某个键的操作 //////
@ -2311,7 +2325,7 @@ actions.prototype._clickReplay_replayRemain = function () {
}
actions.prototype._clickReplay_download = function () {
if (core.hasFlag('debug')) return core.drawText("\t[系统提示]调试模式下无法下载录像");
// if (core.hasFlag('debug')) return core.drawText("\t[系统提示]调试模式下无法下载录像");
core.download(core.firstData.name + "_" + core.formatDate2() + ".h5route", JSON.stringify({
'name': core.firstData.name,
'hard': core.status.hard,

View File

@ -152,8 +152,11 @@ control.prototype._animationFrame_globalAnimate = function (timestamp) {
}
control.prototype._animationFrame_selector = function (timestamp) {
if (timestamp - core.animateFrame.selectorTime <= 20 || !core.dymCanvas._selector) return;
var opacity = parseFloat(core.dymCanvas._selector.canvas.style.opacity);
if (timestamp - core.animateFrame.selectorTime <= 20) return;
var opacity = null;
if (core.dymCanvas._selector) opacity = parseFloat(core.dymCanvas._selector.canvas.style.opacity);
else if (core.dymCanvas._uievent_selector) opacity = parseFloat(core.dymCanvas._uievent_selector.canvas.style.opacity);
if (!core.isset(opacity)) return;
if (core.animateFrame.selectorUp)
opacity += 0.02;
else
@ -161,6 +164,7 @@ control.prototype._animationFrame_selector = function (timestamp) {
if (opacity > 0.95 || opacity < 0.55)
core.animateFrame.selectorUp = !core.animateFrame.selectorUp;
core.setOpacity("_selector", opacity);
core.setOpacity("_uievent_selector", opacity);
core.animateFrame.selectorTime = timestamp;
}
@ -919,7 +923,7 @@ control.prototype.checkBlock = function () {
if (damage) {
core.status.hero.hp -= damage;
core.drawTip("受到"+(core.status.checkBlock.type[loc]||"伤害")+damage+"点");
this._checkBlock_soundAndAnimate(x, y);
core.drawAnimate("zone", x, y);
this._checkBlock_disableQuickShop();
core.status.hero.statistics.extraDamage += damage;
if (core.status.hero.hp <= 0) {
@ -933,11 +937,6 @@ control.prototype.checkBlock = function () {
this._checkBlock_ambush(core.status.checkBlock.ambush[loc]);
}
control.prototype._checkBlock_soundAndAnimate = function (x,y) {
core.playSound('zone.mp3');
core.drawAnimate("zone", x, y);
}
control.prototype._checkBlock_disableQuickShop = function () {
// 禁用快捷商店
if (core.flags.disableShopOnDamage) {
@ -1219,6 +1218,28 @@ control.prototype.viewMapReplay = function () {
core.ui.drawMaps();
}
control.prototype.toolboxReplay = function () {
if (!core.isPlaying() || !core.isReplaying()) return;
if (!core.status.replay.pausing) return core.drawTip("请先暂停录像");
if (core.isMoving() || core.status.replay.animate || core.status.event.id)
return core.drawTip("请等待当前事件的处理结束");
core.lockControl();
core.status.event.id='toolbox';
core.ui.drawToolbox();
}
control.prototype.equipboxReplay = function () {
if (!core.isPlaying() || !core.isReplaying()) return;
if (!core.status.replay.pausing) return core.drawTip("请先暂停录像");
if (core.isMoving() || core.status.replay.animate || core.status.event.id)
return core.drawTip("请等待当前事件的处理结束");
core.lockControl();
core.status.event.id='equipbox';
core.ui.drawEquipbox();
}
////// 是否正在播放录像 //////
control.prototype.isReplaying = function () {
return (core.status.replay||{}).replaying;
@ -1982,7 +2003,7 @@ control.prototype.unLockControl = function () {
////// 开启debug模式 //////
control.prototype.debug = function() {
core.setFlag('debug', true);
core.drawText("\t[调试模式开启]此模式下按住Ctrl键或Ctrl+Shift键可以穿墙并忽略一切事件。\n同时,录像将失效,也无法上传成绩。");
core.drawText("\t[调试模式开启]此模式下按住Ctrl键或Ctrl+Shift键可以穿墙并忽略一切事件。\n此模式下将无法上传成绩。");
}
// ------ 天气色调BGM ------ //

View File

@ -548,8 +548,19 @@ events.prototype._changeFloor_getHeroLoc = function (floorId, stair, heroLoc) {
if (!heroLoc)
heroLoc = core.clone(core.status.hero.loc);
if (stair) {
// --- 对称
if (stair == ':now')
heroLoc = core.clone(core.status.hero.loc);
else if (stair == ':symmetry') {
heroLoc.x = core.bigmap.width - 1 - core.getHeroLoc('x');
heroLoc.y = core.bigmap.height - 1 - core.getHeroLoc('y');
}
else if (stair == ':symmetry_x')
heroLoc.x = core.bigmap.width - 1 - core.getHeroLoc('x');
else if (stair == ':symmetry_y')
heroLoc.y = core.bigmap.height - 1 - core.getHeroLoc('y');
// 检查该层地图的 upFloor & downFloor
if (core.status.maps[floorId][stair]) {
else if (core.status.maps[floorId][stair]) {
heroLoc.x = core.status.maps[floorId][stair][0];
heroLoc.y = core.status.maps[floorId][stair][1];
}
@ -788,11 +799,13 @@ events.prototype.startEvents = function (list, x, y, callback) {
}
////// 执行当前自定义事件列表中的下一个事件 //////
events.prototype.doAction = function () {
// 清空boxAnimate和UI层
core.clearUI();
clearInterval(core.status.event.interval);
core.status.event.interval = null;
events.prototype.doAction = function (keepUI) {
if (!keepUI) {
// 清空boxAnimate和UI层
core.clearUI();
clearInterval(core.status.event.interval);
core.status.event.interval = null;
}
// 判定是否执行完毕
if (this._doAction_finishEvents()) return;
// 当前点坐标和前缀
@ -1590,7 +1603,7 @@ events.prototype._action_callSave = function (data, x, y, prefix) {
events.prototype._action_autoSave = function (data, x, y, prefix) {
core.autosave();
core.drawTip("已自动存档");
if (!data.nohint) core.drawTip("已自动存档");
core.doAction();
}
@ -1607,6 +1620,86 @@ events.prototype._action_exit = function (data, x, y, prefix) {
core.doAction();
}
events.prototype._action_previewUI = function (data, x, y, prefix) {
this.insertAction(data.action);
core.doAction();
}
events.prototype._action_clearMap = function (data, x, y, prefix) {
core.ui._uievent_clearMap(data);
core.doAction();
}
events.prototype._action_fillText = function (data, x, y, prefix) {
core.ui._uievent_fillText(data);
core.doAction();
}
events.prototype._action_fillBoldText = function (data, x, y, prefix) {
core.ui._uievent_fillBoldText(data);
core.doAction();
}
events.prototype._action_fillRect = function (data, x, y, prefix) {
core.ui._uievent_fillRect(data);
core.doAction();
}
events.prototype._action_fillPolygon = function (data, x, y, prefix) {
core.ui._uievent_fillPolygon(data);
core.doAction();
}
events.prototype._action_strokeRect = function (data, x, y, prefix) {
core.ui._uievent_strokeRect(data);
core.doAction();
}
events.prototype._action_strokePolygon = function (data, x, y, prefix) {
core.ui._uievent_strokePolygon(data);
core.doAction();
}
events.prototype._action_drawLine = function (data, x, y, prefix) {
core.ui._uievent_drawLine(data);
core.doAction();
}
events.prototype._action_drawArrow = function (data, x, y, prefix) {
core.ui._uievent_drawArrow(data);
core.doAction();
}
events.prototype._action_setAttribute = function (data, x, y, prefix) {
core.ui._uievent_setAttribute(data);
core.doAction();
}
events.prototype._action_drawImage = function (data, x, y, prefix) {
core.ui._uievent_drawImage(data);
core.doAction();
}
events.prototype._action_drawIcon = function (data, x, y, prefix) {
core.ui._uievent_drawIcon(data);
core.doAction();
}
events.prototype._action_drawSelector = function (data, x, y, prefix) {
core.ui._uievent_drawSelector(data);
core.doAction();
}
events.prototype._action_drawBackground = function (data, x, y, prefix) {
core.ui._uievent_drawBackground(data);
core.doAction();
}
events.prototype._action_drawTextContent = function (data, x, y, prefix) {
core.ui._uievent_drawTextContent(data);
core.doAction();
}
// ------ 点击状态栏图标所进行的一些操作 ------ //
////// 判断当前能否进入某个事件 //////
@ -1842,7 +1935,7 @@ events.prototype.doEffect = function (effect, need, times) {
////// 设置楼层属性 //////
events.prototype.setFloorInfo = function (name, value, floorId, prefix) {
floorId = floorId || data.floorId;
floorId = floorId || core.status.floorId;
core.status.maps[floorId][name] = core.calValue(value, prefix);
core.updateStatusBar();
}
@ -1874,7 +1967,7 @@ events.prototype.setGlobalFlag = function (name, value) {
events.prototype.closeDoor = function (x, y, id, callback) {
id = id || "";
if (!(id.endsWith("Door") || id.endsWith("Wall"))
|| !core.material.icons.animates[id] || core.getBlock(x, y) != null) {
|| core.material.icons.animates[id] == null || core.getBlock(x, y) != null) {
if (callback) callback();
return;
}

View File

@ -372,7 +372,8 @@ items.prototype._realLoadEquip = function (type, loadId, unloadId, callback) {
}
items.prototype._realLoadEquip_playSound = function () {
core.stopSound(); // 先停止所有音效(为了避免快捷换装很乱)
if (core.hasFlag("__quickLoadEquip__")) return;
core.stopSound();
core.playSound('equip.mp3');
}
@ -398,20 +399,30 @@ items.prototype.quickLoadEquip = function (index) {
if (v && !this.canEquip(v, true))
return;
}
core.setFlag("__quickLoadEquip__", true);
// 快速换装
var toEquip = [];
for (var i = 0; i < equipSize; i++) {
var now = core.status.hero.equipment[i];
if (now) {
this.unloadEquip(i);
core.status.route.push("unEquip:" + i);
// --- 只考虑diff的装备
var to = current[i];
if (now != to) {
toEquip.push(to || null);
if (now) {
this.unloadEquip(i);
core.status.route.push("unEquip:" + i);
}
}
}
for (var i = 0; i < equipSize; i++) {
var to = current[i];
for (var i in toEquip) {
var to = toEquip[i];
if (to) {
this.loadEquip(to);
core.status.route.push("equip:" + to);
}
}
core.removeFlag("__quickLoadEquip__");
this._realLoadEquip_playSound();
core.drawTip("成功换上" + index + "号套装");
}

View File

@ -62,6 +62,12 @@ maps.prototype._mapIntoBlocks = function (map, floor, floorId) {
////// 从ID获得数字 //////
maps.prototype.getNumberById = function (id) {
core.status.id2number = core.status.id2number || {};
if (core.status.id2number[id] != null) return core.status.id2number[id];
return core.status.id2number[id] = this._getNumberById(id);
}
maps.prototype._getNumberById = function (id) {
for (var number in this.blocksInfo) {
if ((this.blocksInfo[number] || {}).id == id)
return parseInt(number) || 0;

View File

@ -37,6 +37,13 @@ ui.prototype.getContextByName = function (name) {
return null;
}
ui.prototype._createUIEvent = function () {
if (main.mode == 'editor') return;
if (!core.dymCanvas['uievent']) {
core.createCanvas('uievent', 0, 0, this.PIXEL, this.PIXEL, 135);
}
}
////// 清除地图 //////
ui.prototype.clearMap = function (name, x, y, width, height) {
if (name == 'all') {
@ -52,12 +59,45 @@ ui.prototype.clearMap = function (name, x, y, width, height) {
}
}
ui.prototype._uievent_clearMap = function (data) {
if (main.mode != 'editor' && (data.x == null || data.y == null || data.width == null || data.height == null)) {
this.deleteCanvas('uievent');
return;
}
this._createUIEvent();
this.clearMap('uievent', core.calValue(data.x), core.calValue(data.y), core.calValue(data.width), core.calValue(data.height));
}
////// 在某个canvas上绘制一段文字 //////
ui.prototype.fillText = function (name, text, x, y, style, font) {
ui.prototype.fillText = function (name, text, x, y, style, font, maxWidth) {
if (style) core.setFillStyle(name, style);
if (font) core.setFont(name, font);
var ctx = this.getContextByName(name);
if (ctx) ctx.fillText(text, x, y);
if (ctx) {
// 如果存在最大宽度
if (maxWidth != null)
this._fillTextWithMaxWidth(ctx, text, x, y, maxWidth);
else
ctx.fillText(text, x, y);
}
}
ui.prototype._uievent_fillText = function (data) {
this._createUIEvent();
this.fillText('uievent', core.replaceText(data.text), core.calValue(data.x), core.calValue(data.y), data.style, data.font, data.maxWidth);
}
////// 自适配字体大小
ui.prototype._fillTextWithMaxWidth = function (ctx, text, x, y, maxWidth) {
// 获得当前字体
var font = ctx.font, u = /(\d+)px/.exec(font);
if (u == null) return ctx.fillText(text, x, y);
for (var font_size = parseInt(u[1]); font_size >= 8; font_size--) {
ctx.font = font.replace(/(\d+)px/, font_size+"px");
if (ctx.measureText(text).width <= maxWidth) break;
}
ctx.fillText(text, x, y);
ctx.font = font;
}
////// 在某个canvas上绘制粗体 //////
@ -66,6 +106,7 @@ ui.prototype.fillBoldText = function (name, text, x, y, style, font) {
if (!ctx) return;
if (font) ctx.font = font;
if (!style) style = ctx.fillStyle;
if (style instanceof Array) style = core.arrayToRGBA(style);
ctx.fillStyle = '#000000';
ctx.fillText(text, x-1, y-1);
ctx.fillText(text, x-1, y+1);
@ -75,6 +116,11 @@ ui.prototype.fillBoldText = function (name, text, x, y, style, font) {
ctx.fillText(text, x, y);
}
ui.prototype._uievent_fillBoldText = function (data) {
this._createUIEvent();
this.fillBoldText('uievent', core.replaceText(data.text), core.calValue(data.x), core.calValue(data.y), data.style, data.font);
}
////// 在某个canvas上绘制一个矩形 //////
ui.prototype.fillRect = function (name, x, y, width, height, style) {
if (style) core.setFillStyle(name, style);
@ -82,6 +128,32 @@ ui.prototype.fillRect = function (name, x, y, width, height, style) {
if (ctx) ctx.fillRect(x, y, width, height);
}
ui.prototype._uievent_fillRect = function (data) {
this._createUIEvent();
this.fillRect('uievent', core.calValue(data.x), core.calValue(data.y), core.calValue(data.width), core.calValue(data.height), data.style);
}
////// 在某个canvas上绘制一个多边形 //////
ui.prototype.fillPolygon = function (name, nodes, style) {
if (style) core.setFillStyle(name, style);
var ctx = this.getContextByName(name);
if (!ctx) return;
if (!nodes || nodes.length<3) return;
ctx.beginPath();
for (var i = 0; i < nodes.length; ++i) {
var x = core.calValue(nodes[i][0]), y = core.calValue(nodes[i][1]);
if (i == 0) ctx.moveTo(x, y);
else ctx.lineTo(x, y);
}
ctx.closePath();
ctx.fill();
}
ui.prototype._uievent_fillPolygon = function (data) {
this._createUIEvent();
this.fillPolygon('uievent', data.nodes, data.style);
}
////// 在某个canvas上绘制一个矩形的边框 //////
ui.prototype.strokeRect = function (name, x, y, width, height, style, lineWidth) {
if (style) core.setStrokeStyle(name, style);
@ -90,6 +162,33 @@ ui.prototype.strokeRect = function (name, x, y, width, height, style, lineWidth)
if (ctx) ctx.strokeRect(x, y, width, height);
}
ui.prototype._uievent_strokeRect = function (data) {
this._createUIEvent();
this.strokeRect('uievent', core.calValue(data.x), core.calValue(data.y), core.calValue(data.width), core.calValue(data.height), data.style, data.lineWidth);
}
////// 在某个canvas上绘制一个多边形的边框 //////
ui.prototype.strokePolygon = function (name, nodes, style, lineWidth) {
if (style) core.setStrokeStyle(name, style);
if (lineWidth) core.setLineWidth(name, lineWidth);
var ctx = this.getContextByName(name);
if (!ctx) return;
if (!nodes || nodes.length<3) return;
ctx.beginPath();
for (var i = 0; i < nodes.length; ++i) {
var x = core.calValue(nodes[i][0]), y = core.calValue(nodes[i][1]);
if (i == 0) ctx.moveTo(x, y);
else ctx.lineTo(x, y);
}
ctx.closePath();
ctx.stroke();
}
ui.prototype._uievent_strokePolygon = function (data) {
this._createUIEvent();
this.strokePolygon('uievent', data.nodes, data.style, data.lineWidth);
}
////// 在某个canvas上绘制一条线 //////
ui.prototype.drawLine = function (name, x1, y1, x2, y2, style, lineWidth) {
if (style) core.setStrokeStyle(name, style);
@ -102,6 +201,11 @@ ui.prototype.drawLine = function (name, x1, y1, x2, y2, style, lineWidth) {
ctx.stroke();
}
ui.prototype._uievent_drawLine = function (data) {
this._createUIEvent();
this.drawLine('uievent', core.calValue(data.x1), core.calValue(data.y1), core.calValue(data.x2), core.calValue(data.y2), data.style, data.lineWidth);
}
////// 在某个canvas上绘制一个箭头 //////
ui.prototype.drawArrow = function (name, x1, y1, x2, y2, style, lineWidth) {
if (x1==x2 && y1==y2) return;
@ -121,6 +225,11 @@ ui.prototype.drawArrow = function (name, x1, y1, x2, y2, style, lineWidth) {
ctx.stroke();
}
ui.prototype._uievent_drawArrow = function (data) {
this._createUIEvent();
this.drawArrow('uievent', core.calValue(data.x1), core.calValue(data.y1), core.calValue(data.x2), core.calValue(data.y2), data.style, data.lineWidth);
}
////// 设置某个canvas的文字字体 //////
ui.prototype.setFont = function (name, font) {
var ctx = this.getContextByName(name);
@ -160,12 +269,14 @@ ui.prototype.setOpacity = function (name, opacity) {
////// 设置某个canvas的绘制属性如颜色等 //////
ui.prototype.setFillStyle = function (name, style) {
var ctx = this.getContextByName(name);
if (style instanceof Array) style = core.arrayToRGBA(style);
if (ctx) ctx.fillStyle = style;
}
////// 设置某个canvas边框属性 //////
ui.prototype.setStrokeStyle = function (name, style) {
var ctx = this.getContextByName(name);
if (style instanceof Array) style = core.arrayToRGBA(style);
if (ctx) ctx.strokeStyle = style;
}
@ -181,6 +292,23 @@ ui.prototype.setTextBaseline = function (name, baseline) {
if (ctx) ctx.textBaseline = baseline;
}
ui.prototype._uievent_setAttribute = function (data) {
this._createUIEvent();
if (data.font) this.setFont('uievent', data.font);
if (data.lineWidth) this.setLineWidth('uievent', data.lineWidth);
if (data.alpha != null) this.setAlpha('uievent', data.alpha);
if (data.fillStyle) this.setFillStyle('uievent', data.fillStyle);
if (data.strokeStyle) this.setStrokeStyle('uievent', data.strokeStyle);
if (data.align) this.setTextAlign('uievent', data.align);
if (data.baseline) this.setTextBaseline('uievent', data.baseline);
if (data.z != null && main.mode != 'editor') {
var z = parseInt(data.z) || 135;
core.dymCanvas.uievent.canvas.style.zIndex = z;
if (core.dymCanvas._uievent_selector)
core.dymCanvas._uievent_selector.canvas.style.zIndex = z + 1;
}
}
////// 计算某段文字的宽度 //////
ui.prototype.calWidth = function (name, text, font) {
var ctx = this.getContextByName(name);
@ -232,9 +360,9 @@ ui.prototype.drawImage = function (name, image, x, y, w, h, x1, y1, w1, h1) {
}
// 只能接受2, 4, 8个参数
if (core.isset(x) && core.isset(y)) {
if (core.isset(w) && core.isset(h)) {
if (core.isset(x1) && core.isset(y1) && core.isset(w1) && core.isset(h1)) {
if (x != null && y != null) {
if (w != null && h != null) {
if (x1 != null && y1 != null && w1 != null && h1 != null) {
ctx.drawImage(image, x, y, w, h, x1, y1, w1, h1);
return;
}
@ -246,6 +374,30 @@ ui.prototype.drawImage = function (name, image, x, y, w, h, x1, y1, w1, h1) {
}
}
ui.prototype._uievent_drawImage = function (data) {
this._createUIEvent();
this.drawImage('uievent', data.image, core.calValue(data.x), core.calValue(data.y), core.calValue(data.w), core.calValue(data.h),
core.calValue(data.x1), core.calValue(data.y1), core.calValue(data.w1), core.calValue(data.h1));
}
ui.prototype.drawIcon = function (name, id, x, y, w, h) {
var ctx = this.getContextByName(name);
if (!ctx) return;
var info = core.getBlockInfo(id);
if (!info) {
// 检查状态栏图标
if (core.statusBar.icons[id] instanceof Image)
info = {image: core.statusBar.icons[id], posX: 0, posY: 0, height: 32};
else return;
}
ctx.drawImage(info.image, 32 * info.posX, info.height * info.posY, 32, info.height, x, y, w || 32, h || info.height);
}
ui.prototype._uievent_drawIcon = function (data) {
this._createUIEvent();
this.drawIcon('uievent', data.id, core.calValue(data.x), core.calValue(data.y), core.calValue(data.width), core.calValue(data.height));
}
///////////////// UI绘制
////// 结束一切事件和绘制关闭UI窗口返回游戏进程 //////
@ -446,23 +598,54 @@ ui.prototype._getPosition = function (content) {
////// 绘制选择光标
ui.prototype.drawWindowSelector = function(background, x, y, w, h) {
w = Math.round(w), h = Math.round(h);
var ctx = core.ui.createCanvas("_selector", x, y, w, h, 165);
ctx.canvas.style.opacity = 0.8;
this._drawSelector(ctx, background, w, h);
}
ui.prototype._uievent_drawSelector = function (data) {
if (data.image == null) {
if (main.mode != 'editor')
core.deleteCanvas('_uievent_selector');
return;
}
var background = data.image || core.status.textAttribute.background;
if (typeof background != 'string') return;
var x = core.calValue(data.x), y = core.calValue(data.y), w = core.calValue(data.width), h = core.calValue(data.height);
w = Math.round(w); h = Math.round(h);
if (main.mode == 'editor') {
this._drawSelector('uievent', background, w, h, x, y);
return;
}
var z = 136;
if (core.dymCanvas.uievent) z = (parseInt(core.dymCanvas.uievent.canvas.style.zIndex) || 135) + 1;
var ctx = core.createCanvas('_uievent_selector', x, y, w, h, z);
ctx.canvas.style.opacity = 0.8;
this._drawSelector(ctx, background, w, h);
}
ui.prototype._drawSelector = function (ctx, background, w, h, left, top) {
left = left || 0;
top = top || 0;
ctx = this.getContextByName(ctx);
if (!ctx) return;
if (typeof background == 'string')
background = core.material.images.images[background];
w = Math.round(w), h = Math.round(h);
var dstImage = core.ui.createCanvas("_selector", x, y, w, h, 165);
core.setOpacity("_selector", 0.8);
if (!(background instanceof Image)) return;
// back
dstImage.drawImage(background, 130, 66, 28, 28, 2, 2,w-4,h-4);
ctx.drawImage(background, 130, 66, 28, 28, left+2, top+2, w-4, h-4);
// corner
dstImage.drawImage(background, 128, 64, 2, 2, 0, 0, 2, 2);
dstImage.drawImage(background, 158, 64, 2, 2,w-2, 0, 2, 2);
dstImage.drawImage(background, 128, 94, 2, 2, 0,h-2, 2, 2);
dstImage.drawImage(background, 158, 94, 2, 2,w-2,h-2, 2, 2);
ctx.drawImage(background, 128, 64, 2, 2, left, top, 2, 2);
ctx.drawImage(background, 158, 64, 2, 2, left+w-2, top, 2, 2);
ctx.drawImage(background, 128, 94, 2, 2, left, top+h-2, 2, 2);
ctx.drawImage(background, 158, 94, 2, 2, left+w-2, top+h-2, 2, 2);
// border
dstImage.drawImage(background, 130, 64, 28, 2, 2, 0,w-4, 2);
dstImage.drawImage(background, 130, 94, 28, 2, 2,h-2,w-4, 2);
dstImage.drawImage(background, 128, 66, 2, 28, 0, 2, 2,h-4);
dstImage.drawImage(background, 158, 66, 2, 28,w-2, 2, 2,h-4);
ctx.drawImage(background, 130, 64, 28, 2, left+2, top, w-4, 2);
ctx.drawImage(background, 130, 94, 28, 2, left+2, top+h-2, w-4, 2);
ctx.drawImage(background, 128, 66, 2, 28, left, top+2, 2,h-4);
ctx.drawImage(background, 158, 66, 2, 28, left+w-2, top+2, 2,h-4);
}
////// 绘制 WindowSkin
@ -524,6 +707,19 @@ ui.prototype.drawBackground = function (left, top, right, bottom, posInfo) {
return false;
}
ui.prototype._uievent_drawBackground = function (data) {
this._createUIEvent();
var background = data.background || core.status.textAttribute.background;
var x = core.calValue(data.x), y = core.calValue(data.y), w = core.calValue(data.width), h = core.calValue(data.height);
if (typeof background == 'string') {
this.drawWindowSkin(background, 'uievent', x, y, w, h);
}
else if (background instanceof Array) {
this.fillRect('uievent', x, y, w, h, core.arrayToRGBA(background));
this.strokeRect('uievent', x, y, w, h);
}
}
ui.prototype._drawWindowSkin_getOpacity = function () {
return core.getFlag("__winskin_opacity__", 0.85);
}
@ -633,7 +829,8 @@ ui.prototype.drawTextContent = function (ctx, content, config) {
config.left = config.left || 0;
config.right = config.left + (config.maxWidth == null ? ctx.canvas.width : config.maxWidth);
config.top = config.top || 0;
config.color = config.color || core.arrayToRGBA(textAttribute.text);
config.color = config.color || textAttribute.text;
if (config.color instanceof Array) config.color = core.arrayToRGBA(config.color);
if (config.bold == null) config.bold = textAttribute.bold;
config.align = config.align || textAttribute.align || "left";
config.fontSize = config.fontSize || textAttribute.textfont;
@ -659,6 +856,13 @@ ui.prototype.drawTextContent = function (ctx, content, config) {
tempCtx.textBaseline = _textBaseLine;
}
ui.prototype._uievent_drawTextContent = function (data) {
this._createUIEvent();
data.left = core.calValue(data.left);
data.top = core.calValue(data.top);
this.drawTextContent('uievent', core.replaceText(data.text), data);
}
// 绘制的基本逻辑:
// 1. 一个个字符绘制到对应画布上(靠左对齐);这个过程中,记下来每个字对应的方块 [x, y, w, h]
// 2. 每次换行时,计算当前行的宽度,然后如果是居中或者靠右对齐,则对当前行的每个小方块增加偏移量
@ -875,7 +1079,7 @@ ui.prototype._drawTextBox_getHorizontalPosition = function (content, titleInfo,
ui.prototype._drawTextBox_getVerticalPosition = function (content, titleInfo, posInfo, validWidth) {
var textAttribute = core.status.textAttribute || core.initStatus.textAttribute;
var lineHeight = textAttribute.textfont + 5;
var lineHeight = textAttribute.textfont + 6;
var realContent = this._getRealContent(content);
var height = 30 + lineHeight * core.splitLines("ui", realContent, validWidth, this._buildFont()).length;
if (titleInfo.title) height += textAttribute.titlefont + 5;
@ -1664,8 +1868,19 @@ ui.prototype.drawFly = function(page) {
core.setTextAlign('ui', 'center');
core.fillText('ui', '楼层跳跃', this.HPIXEL, 60, '#FFFFFF', this._buildFont(28, true));
core.fillText('ui', '返回游戏', this.HPIXEL, this.PIXEL - 13, null, this._buildFont(15, true))
core.fillText('ui', title, this.PIXEL - 60, this.HPIXEL + 39, null, this._buildFont(19, true));
var middle = this.HPIXEL + 39;
// 换行
var lines = core.splitLines('ui', title, 120, this._buildFont(19, true));
var start_y = middle - (lines.length - 1) * 11;
for (var i in lines) {
core.fillText('ui', lines[i], this.PIXEL - 60, start_y);
start_y += 22;
}
// core.fillText('ui', title, this.PIXEL - 60, this.HPIXEL + 39, null, this._buildFont(19, true));
if (core.actions._getNextFlyFloor(1) != page) {
core.fillText('ui', '▲', this.PIXEL - 60, middle - 64, null, this._buildFont(17, false));
core.fillText('ui', '▲', this.PIXEL - 60, middle - 96);
@ -1913,9 +2128,12 @@ ui.prototype._drawToolbox_drawDescription = function (info, max_height) {
// 检查能否eval
text = core.replaceText(text);
} catch (e) {}
var lines = core.splitLines('ui', text, this.PIXEL - 15, this._buildFont(17, false));
// --- 开始逐行绘制
var curr = 62, line_height = 25;
for (var font_size = 17; font_size >= 14; font_size -= 3) {
var lines = core.splitLines('ui', text, this.PIXEL - 15, this._buildFont(font_size, false));
var line_height = parseInt(font_size * 1.4), curr = 37 + line_height;
if (curr + lines.length * line_height < max_height) break;
}
core.setFillStyle('ui', '#FFFFFF');
for (var i=0;i<lines.length;++i) {
core.fillText('ui', lines[i], 10, curr);
@ -2019,8 +2237,12 @@ ui.prototype._drawEquipbox_description = function (info, max_height) {
try {
text = core.replaceText(text);
} catch (e) {}
var lines = core.splitLines('ui', text, this.PIXEL - 15, this._buildFont(17, false));
var curr = 62, line_height = 25;
for (var font_size = 17; font_size >= 11; font_size -= 3) {
var lines = core.splitLines('ui', text, this.PIXEL - 15, this._buildFont(font_size, false));
var line_height = parseInt(font_size * 1.4), curr = 37 + line_height;
if (curr + lines.length * line_height < max_height) break;
}
core.setFillStyle('ui', '#FFFFFF');
for (var i = 0; i < lines.length; ++i) {
core.fillText('ui', lines[i], 10, curr);
@ -2210,7 +2432,7 @@ ui.prototype._drawSLPanel_drawRecord = function(title, data, x, y, size, cho, hi
var v2 = "/"+core.formatBigNumber(data.hero.mdef,true);
if (core.calWidth('ui', v + v2, this._buildFont(10, false)) <= size) v += v2;
core.fillText('ui', v, x, y+30+size, '#FFD700');
core.fillText('ui', core.formatDate(new Date(data.time)), x, y+43+size, data.hero.flags.__consoleOpened__?'#FF6A6A':'#FFFFFF');
core.fillText('ui', core.formatDate(new Date(data.time)), x, y+43+size, data.hero.flags.__consoleOpened__||data.hero.flags.debug?'#FF6A6A':'#FFFFFF');
}
else {
core.fillRect('ui', x-size/2, y+15, size, size, '#333333', 2);

View File

@ -317,16 +317,15 @@ utils.prototype.splitImage = function (image, width, height) {
height = height || width;
var canvas = document.createElement("canvas");
var context = canvas.getContext("2d");
canvas.width = width;
canvas.height = height;
var ans = [];
for (var j = 0; j < image.height; j += height) {
for (var i = 0; i < image.width; i += width) {
context.drawImage(image, i, j, width, height, 0, 0, width, height);
var w = Math.min(width, image.width - i), h = Math.min(height, image.height - j);
canvas.width = w; canvas.height = h;
context.drawImage(image, i, j, w, h, 0, 0, w, h);
var img = new Image();
img.src = canvas.toDataURL("image/png");
ans.push(img);
context.clearRect(0, 0, width, height);
}
}
return ans;

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -513,64 +513,72 @@ var functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a =
mon_def = hero_atk - 1;
}
// 光环检查
// 从V2.5.4开始,对光环效果增加缓存,以解决多次重复计算的问题,从而大幅提升运行效率。
// 检查当前楼层所有光环怪物数字25
var hp_buff = 0,
atk_buff = 0,
def_buff = 0,
cnt = 0;
// ------ 支援 ------
var guards = [];
// 检查光环缓存
var index = x != null && y != null ? (x + "," + y) : "floor";
if (!core.status.checkBlock) core.status.checkBlock = {};
if (!core.status.checkBlock.cache) core.status.checkBlock.cache = {};
var cache = core.status.checkBlock.cache[index];
if (!cache) {
// 没有该点的缓存,则遍历每个图块
core.status.maps[floorId].blocks.forEach(function (block) {
if (!block.disable) {
// 获得该图块的ID
var id = block.event.id,
enemy = core.material.enemys[id];
// 检查是不是怪物,且是否拥有该特殊属性
if (enemy && core.hasSpecial(enemy.special, 25)) {
// 检查是否可叠加
if (enemy.add || cnt == 0) {
hp_buff += enemy.value || 0;
atk_buff += enemy.atkValue || 0;
def_buff += enemy.defValue || 0;
cnt++;
}
}
// 检查【支援】技能
if (enemy && core.hasSpecial(enemy.special, 26) &&
// 检查支援条件坐标存在距离为1且不能是自己
// 其他类型的支援怪,比如十字之类的话.... 看着做是一样的
x != null && y != null && Math.abs(block.x - x) <= 1 && Math.abs(block.y - y) <= 1 && !(x == block.x && y == block.y)) {
// 记录怪物的x,yID
guards.push([block.x, block.y, id]);
}
// TODO如果有其他类型光环怪物在这里仿照添加检查
}
});
core.status.checkBlock.cache[index] = { "hp_buff": hp_buff, "atk_buff": atk_buff, "def_buff": def_buff, "guards": guards };
} else {
// 直接使用缓存数据
hp_buff = cache.hp_buff;
atk_buff = cache.atk_buff;
def_buff = cache.def_buff;
guards = cache.guards;
// 光环检查
// 在这里判定是否需要遍历全图(由于光环需要遍历全图,应尽可能不需要以减少计算量,尤其是大地图)
var query = function () {
var floorIds = ["MTx"]; // 在这里给出所有需要遍历的楼层(即有光环或支援等)
return core.inArray(floorIds, floorId); // 也可以写其他的判定条件
}
// 增加比例;如果要增加数值可以直接在这里修改
mon_hp *= (1 + hp_buff / 100);
mon_atk *= (1 + atk_buff / 100);
mon_def *= (1 + def_buff / 100);
if (query()) {
// 从V2.5.4开始,对光环效果增加缓存,以解决多次重复计算的问题,从而大幅提升运行效率。
// 检查当前楼层所有光环怪物数字25
var hp_buff = 0,
atk_buff = 0,
def_buff = 0,
cnt = 0;
// 检查光环缓存
var index = x != null && y != null ? (x + "," + y) : "floor";
if (!core.status.checkBlock) core.status.checkBlock = {};
if (!core.status.checkBlock.cache) core.status.checkBlock.cache = {};
var cache = core.status.checkBlock.cache[index];
if (!cache) {
// 没有该点的缓存,则遍历每个图块
core.status.maps[floorId].blocks.forEach(function (block) {
if (!block.disable) {
// 获得该图块的ID
var id = block.event.id,
enemy = core.material.enemys[id];
// 检查是不是怪物,且是否拥有该特殊属性
if (enemy && core.hasSpecial(enemy.special, 25)) {
// 检查是否可叠加
if (enemy.add || cnt == 0) {
hp_buff += enemy.value || 0;
atk_buff += enemy.atkValue || 0;
def_buff += enemy.defValue || 0;
cnt++;
}
}
// 检查【支援】技能
if (enemy && core.hasSpecial(enemy.special, 26) &&
// 检查支援条件坐标存在距离为1且不能是自己
// 其他类型的支援怪,比如十字之类的话.... 看着做是一样的
x != null && y != null && Math.abs(block.x - x) <= 1 && Math.abs(block.y - y) <= 1 && !(x == block.x && y == block.y)) {
// 记录怪物的x,yID
guards.push([block.x, block.y, id]);
}
// TODO如果有其他类型光环怪物在这里仿照添加检查
}
});
core.status.checkBlock.cache[index] = { "hp_buff": hp_buff, "atk_buff": atk_buff, "def_buff": def_buff, "guards": guards };
} else {
// 直接使用缓存数据
hp_buff = cache.hp_buff;
atk_buff = cache.atk_buff;
def_buff = cache.def_buff;
guards = cache.guards;
}
// 增加比例;如果要增加数值可以直接在这里修改
mon_hp *= (1 + hp_buff / 100);
mon_atk *= (1 + atk_buff / 100);
mon_def *= (1 + def_buff / 100);
}
// TODO可以在这里新增其他的怪物数据变化
// 比如仿攻(怪物攻击不低于勇士攻击):
@ -913,9 +921,6 @@ var functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a =
"saveData": function () {
// 存档操作,此函数应该返回“具体要存档的内容”
// 勇士和hash值防改存档文件来作弊
var hero = core.clone(core.status.hero),
hashCode = core.utils.hashCode(hero);
// 差异化存储values
var values = {};
for (var key in core.values) {
@ -926,16 +931,18 @@ var functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a =
// 要存档的内容
var data = {
'floorId': core.status.floorId,
'hero': hero,
'hero': core.clone(core.status.hero),
'hard': core.status.hard,
'maps': core.maps.saveMap(),
'route': core.encodeRoute(core.status.route),
'values': values,
'shops': {},
'version': core.firstData.version,
"time": new Date().getTime(),
"hashCode": hashCode
"time": new Date().getTime()
};
if (core.flags.checkConsole) {
data.hashCode = core.utils.hashCode(data.hero);
}
// 设置商店次数
for (var shopId in core.status.shops) {
data.shops[shopId] = {

Binary file not shown.

Binary file not shown.