Merge pull request #375 from ckcz123/v2.x

uievent
This commit is contained in:
Zhang Chen 2019-05-31 20:17:37 +08:00 committed by GitHub
commit c27335ea78
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
19 changed files with 1887 additions and 248 deletions

View File

@ -1695,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窗口返回游戏。
@ -1748,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,269 @@ 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`,分别代表顶部,居中,标准值和底部。
### 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脚本
上述给出了这么多事件,但有时候往往不能满足需求,这时候就需要执行自定义脚本了。

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

@ -458,4 +458,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

@ -482,4 +482,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

@ -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,52 @@ 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"],
"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]);
});
}
return editor_blockly;
}
//editor_blockly=editor_blockly();

View File

@ -15,13 +15,15 @@ editor_file = function (editor, callback) {
var filename = 'project/floors/' + editor.currentFloorId + '.js';
var datastr = ['main.floors.', editor.currentFloorId, '=\n'];
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 (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;
}
}
// format 更改实现方式以支持undefined删除

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':

View File

@ -285,6 +285,18 @@ editor.constructor.prototype.listen=function () {
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});
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();
@ -502,6 +514,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 +540,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('添加楼梯事件成功');
});
}

View File

@ -367,3 +367,178 @@ 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);
}
uievent.elements.selectPointButtons.children[0].onclick = function () {
uievent.move(-1, 0);
}
uievent.elements.selectPointButtons.children[1].onclick = function () {
uievent.move(0, -1);
}
uievent.elements.selectPointButtons.children[2].onclick = function () {
uievent.move(0, 1);
}
uievent.elements.selectPointButtons.children[3].onclick = function () {
uievent.move(1, 0);
}
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

@ -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>
@ -514,7 +515,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 +523,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>
@ -497,7 +498,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 +506,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) {

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;
}
@ -1219,6 +1223,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;

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];
}
@ -1592,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();
}
@ -1609,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();
}
// ------ 点击状态栏图标所进行的一些操作 ------ //
////// 判断当前能否进入某个事件 //////

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

@ -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,6 +59,15 @@ 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, maxWidth) {
if (style) core.setFillStyle(name, style);
@ -66,6 +82,11 @@ ui.prototype.fillText = function (name, text, x, y, style, font, maxWidth) {
}
}
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) {
// 获得当前字体
@ -85,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);
@ -94,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);
@ -101,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);
@ -109,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);
@ -121,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;
@ -140,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);
@ -179,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;
}
@ -200,6 +292,17 @@ 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);
}
////// 计算某段文字的宽度 //////
ui.prototype.calWidth = function (name, text, font) {
var ctx = this.getContextByName(name);
@ -251,9 +354,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;
}
@ -265,6 +368,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窗口返回游戏进程 //////
@ -465,23 +592,52 @@ 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 ctx = core.createCanvas('_uievent_selector', x, y, w, h, 136);
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
@ -543,6 +699,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);
}
@ -652,7 +821,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;
@ -678,6 +848,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. 每次换行时,计算当前行的宽度,然后如果是居中或者靠右对齐,则对当前行的每个小方块增加偏移量

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可以在这里新增其他的怪物数据变化
// 比如仿攻(怪物攻击不低于勇士攻击):
@ -930,8 +938,7 @@ var functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a =
'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);