多对话框 & 移动对话框

This commit is contained in:
ckcz123 2021-08-08 12:29:48 +08:00
parent e3e8546d03
commit 115811447a
6 changed files with 173 additions and 48 deletions

View File

@ -771,6 +771,8 @@ action
: text_0_s
| text_1_s
| text_2_s
| moveTextBox_s
| clearTextBox_s
| comment_s
| autoText_s
| scrollText_s
@ -915,7 +917,7 @@ text_0_s
tooltip : text显示一段文字剧情
helpUrl : /_docs/#/instruction
previewBlock : true
default : ["欢迎使用事件编辑器(回车直接多行编辑)"]
default : ["欢迎使用事件编辑器(双击方块可直接预览)"]
var code = '"'+EvalString_Multi_0+'"';
if (block.isCollapsed() || !block.isEnabled()) {
code = '{"type": "text", "text": '+code;
@ -927,7 +929,7 @@ return code+',\n';
*/;
text_1_s
: '标题' EvalString? '图像' EvalString? '对话框效果' EvalString? '起点像素 px' PosString? 'py' PosString? '宽度' PosString? BGNL? Newline EvalString_Multi Newline
: '标题' EvalString? '图像' EvalString? '对话框效果' EvalString? '起点像素 px' PosString? 'py' PosString? '宽度' PosString? '对话框编号' Int BGNL? Newline EvalString_Multi Newline
/* text_1_s
@ -935,7 +937,7 @@ tooltip : text显示一段文字剧情,选项较多请右键点击帮
helpUrl : /_docs/#/instruction
previewBlock : true
allIds : ['EvalString_1']
default : ["小妖精","fairy","","","","","欢迎使用事件编辑器(回车直接多行编辑)"]
default : ["小妖精","fairy","","","","",0,"欢迎使用事件编辑器(双击方块可直接预览)"]
var title='';
if (EvalString_0==''){
if (EvalString_1=='' )title='';
@ -956,9 +958,10 @@ if(EvalString_2 && !(/^(up|center|down|hero|this)(,(hero|null|\d+,\d+|\d+))?$/.t
}
EvalString_2 = EvalString_2 && ('\\b['+EvalString_2+']');
var code = '"'+title+EvalString_2+EvalString_Multi_0+'"';
if (block.isCollapsed() || !block.isEnabled() || pos) {
if (block.isCollapsed() || !block.isEnabled() || pos || Int_0) {
code = '{"type": "text", "text": '+code;
if (pos) code += ', "pos": ' + pos;
if (Int_0) code += ', "code": ' + Int_0;
if (block.isCollapsed()) code += ', "_collapsed": true';
if (!block.isEnabled()) code += ', "_disabled": true';
code += '}';
@ -967,7 +970,7 @@ return code+',\n';
*/;
text_2_s
: '标题' EvalString? '图像' EvalString? '对话框效果' EvalString? '起点像素 px' PosString? 'py' PosString? '宽度' PosString? BGNL? Newline EvalString_Multi BGNL? Newline textDrawingList* Newline
: '标题' EvalString? '图像' EvalString? '对话框效果' EvalString? '起点像素 px' PosString? 'py' PosString? '宽度' PosString? '对话框编号' Int BGNL? Newline EvalString_Multi BGNL? Newline textDrawingList* Newline
/* text_2_s
@ -975,7 +978,7 @@ tooltip : text显示一段文字剧情,选项较多请右键点击帮
helpUrl : /_docs/#/instruction
previewBlock : true
allIds : ['EvalString_1']
default : ["小妖精","fairy","","","","","欢迎使用事件编辑器(回车直接多行编辑)",null]
default : ["小妖精","fairy","","","","",0,"欢迎使用事件编辑器(双击方块可直接预览)",null]
var title='';
if (EvalString_0==''){
if (EvalString_1=='' )title='';
@ -996,9 +999,10 @@ if(EvalString_2 && !(/^(up|center|down|hero|this)(,(hero|null|\d+,\d+|\d+))?$/.t
}
EvalString_2 = EvalString_2 && ('\\b['+EvalString_2+']');
var code = '"'+title+EvalString_2+textDrawingList_0.replace(/\s/g, '')+EvalString_Multi_0+'"';
if (block.isCollapsed() || !block.isEnabled() || pos) {
if (block.isCollapsed() || !block.isEnabled() || pos || Int_0) {
code = '{"type": "text", "text": '+code;
if (pos) code += ', "pos": ' + pos;
if (Int_0) code += ', "code": ' + Int_0;
if (block.isCollapsed()) code += ', "_collapsed": true';
if (!block.isEnabled()) code += ', "_disabled": true';
code += '}';
@ -1059,6 +1063,32 @@ var code = '';
return code;
*/;
moveTextBox_s
: '移动对话框' ':' Int 'px' PosString 'py' PosString '使用增量' Bool '移动方式' MoveMode_List '动画时间' Int '不等待执行完毕' Bool Newline
/* moveTextBox_s
tooltip : 移动对话框
helpUrl : /_docs/#/instruction
default : [1,"0","0",false,'',500,false]
MoveMode_List_0 = (MoveMode_List_0!=='') ? (', "moveMode": "'+MoveMode_List_0+'"'):'';
Bool_0 = Bool_0 ?', "relative": true':'';
Bool_1 = Bool_1 ?', "async": true':'';
var code = '{"type": "moveTextBox", "code": '+Int_0+', "loc": ['+PosString_0+','+PosString_1+']'+Bool_0+MoveMode_List_0+', "time": '+Int_1+Bool_1+'},\n';
return code;
*/;
clearTextBox_s
: '清除对话框' ':' Int Newline
/* clearTextBox_s
tooltip : 清除对话框
helpUrl : /_docs/#/instruction
default : [1]
var code = '{"type": "clearTextBox", "code": '+Int_0+'},\n';
return code;
*/;
comment_s
: '添加注释' ':' EvalString_Multi Newline

View File

@ -283,18 +283,26 @@ ActionParser.prototype.parseAction = function() {
}
data.pos = data.pos || [];
this.next = MotaActionFunctions.xmlText('text_2_s', [
info[0], info[1], info[2], data.pos[0], data.pos[1], data.pos[2], info[3], buildTextDrawing(textDrawing), this.next
info[0], info[1], info[2], data.pos[0], data.pos[1], data.pos[2], data.code||0, info[3], buildTextDrawing(textDrawing), this.next
], /* isShadow */false, /*comment*/ null, /*collapsed*/ data._collapsed, /*disabled*/ data._disabled);
} else if (info[0] || info[1] || info[2] || data.pos) {
} else if (info[0] || info[1] || info[2] || data.pos || data.code) {
data.pos = data.pos || [];
this.next = MotaActionFunctions.xmlText('text_1_s',[
info[0], info[1], info[2], data.pos[0], data.pos[1], data.pos[2], info[3], this.next], /* isShadow */false, /*comment*/ null, /*collapsed*/ data._collapsed, /*disabled*/ data._disabled);
info[0], info[1], info[2], data.pos[0], data.pos[1], data.pos[2], data.code||0, info[3], this.next], /* isShadow */false, /*comment*/ null, /*collapsed*/ data._collapsed, /*disabled*/ data._disabled);
}
else {
this.next = MotaActionFunctions.xmlText('text_0_s', [info[3],this.next],
/* isShadow */false, /*comment*/ null, /*collapsed*/ data._collapsed, /*disabled*/ data._disabled);
}
break;
case "moveTextBox": // 移动对话框
data.loc = data.loc || ['',''];
this.next = MotaActionBlocks['moveTextBox_s'].xmlText([
data.code, data.loc[0], data.loc[1], data.relative||false, data.moveMode, data.time, data.async, this.next]);
break;
case "clearTextBox": // 清除对话框
this.next = MotaActionBlocks['clearTextBox_s'].xmlText([data.code,this.next]);
break;
case "autoText": // 自动剧情文本
var info = this.getTitleAndPosition(data.text);
this.next = MotaActionBlocks['autoText_s'].xmlText([

View File

@ -95,7 +95,9 @@ editor_blocklyconfig=(function(){
'显示文字':[
MotaActionBlocks['text_0_s'].xmlText(),
MotaActionBlocks['text_1_s'].xmlText(),
MotaActionFunctions.actionParser.parseList("\t[小妖精,fairy]\f[fairy.png,0,0]欢迎使用事件编辑器(双击方块进入多行编辑)"),
MotaActionFunctions.actionParser.parseList("\t[小妖精,fairy]\f[fairy.png,0,0]欢迎使用事件编辑器(双击方块可直接预览)"),
MotaActionBlocks['moveTextBox_s'].xmlText(),
MotaActionBlocks['clearTextBox_s'].xmlText(),
MotaActionBlocks['comment_s'].xmlText(),
MotaActionBlocks['autoText_s'].xmlText(),
MotaActionBlocks['scrollText_s'].xmlText(),

View File

@ -1019,26 +1019,33 @@ actions.prototype._onMoveConfirmBox = function (x, y) {
}
}
actions.prototype._clickAction_text = function () {
// 正在淡入淡出的话不执行
if (core.status.event.animateUI) return;
var data = core.clone(core.status.event.data.current);
if (typeof data == 'string') data = { "type": "text", "text": data };
// 打字机效果显示全部文字
if (core.status.event.interval != null) {
data.showAll = true;
core.insertAction(data);
core.doAction();
return;
}
if (!data.code) {
core.ui._animateUI('hide', null, core.doAction);
} else {
// 不清除对话框
core.doAction();
}
}
////// 自定义事件时的点击操作 //////
actions.prototype._clickAction = function (x, y, px, py) {
if (core.status.event.data.type == 'text') {
// 正在淡入淡出的话不执行
if (core.status.event.animateUI) return;
var data = core.clone(core.status.event.data.current);
if (typeof data == 'string') data = { "type": "text", "text": data };
// 打字机效果显示全部文字
if (core.status.event.interval != null) {
data.showAll = true;
core.insertAction(data);
core.doAction();
return;
}
// 文字
core.ui._animateUI('hide', core.doAction);
return;
return this._clickAction_text();
}
if (core.status.event.data.type == 'wait') {
@ -1125,20 +1132,7 @@ actions.prototype._keyDownAction = function (keycode) {
////// 自定义事件时,放开某个键的操作 //////
actions.prototype._keyUpAction = function (keycode) {
if (core.status.event.data.type == 'text' && (keycode == 13 || keycode == 32 || keycode == 67)) {
// 正在淡入淡出的话不执行
if (core.status.event.animateUI) return;
var data = core.clone(core.status.event.data.current);
if (typeof data == 'string') data = { "type": "text", "text": data };
// 打字机效果显示全部文字
if (core.status.event.interval != null) {
data.showAll = true;
core.insertAction(data);
return;
}
core.ui._animateUI('hide', core.doAction);
return;
return this._clickAction_text();
}
if (core.status.event.data.type == 'wait') {
var timeout = Math.max(0, core.status.event.timeout - new Date().getTime()) || 0;

View File

@ -1354,8 +1354,28 @@ events.prototype.__action_doAsyncFunc = function (isAsync, func) {
events.prototype._action_text = function (data, x, y, prefix) {
if (this.__action_checkReplaying()) return;
data.text = core.replaceText(data.text, prefix);
var ctx = data.code ? '__text__' + data.code : null;;
data.ctx = ctx;
if (core.getContextByName(ctx) && !data.showAll) {
core.ui._animateUI('hide', ctx, function () {
core.ui.drawTextBox(data.text, data);
core.ui._animateUI('show', ctx);
});
return;
}
core.ui.drawTextBox(data.text, data);
if (!data.showAll) core.ui._animateUI('show');
if (!data.showAll) core.ui._animateUI('show', ctx);
}
events.prototype._action_moveTextBox = function (data, x, y, prefix) {
if (this.__action_checkReplaying()) return;
this.__action_doAsyncFunc(data.async, core.moveTextBox,
data.code, this.__action_getLoc(data.loc, x, y, prefix), data.relative, data.moveMode, data.time);
}
events.prototype._action_clearTextBox = function (data, x, y, prefix) {
if (this.__action_checkReplaying()) return;
core.clearTextBox(data.code, core.doAction);
}
events.prototype._action_autoText = function (data, x, y, prefix) {
@ -3057,6 +3077,67 @@ events.prototype.setTextAttribute = function (data) {
if (main.mode == 'play') core.setFlag('textAttribute', core.status.textAttribute);
}
events.prototype.moveTextBox = function (code, loc, relative, moveMode, time, callback) {
var ctx = core.getContextByName('__text__' + code);
if (!ctx) {
if (callback) callback();
return;
}
var sx = parseInt(ctx.canvas.getAttribute('_text_left')) || 0;
var sy = parseInt(ctx.canvas.getAttribute('_text_top')) || 0;
var dx = relative ? loc[0] : (loc[0] - sx);
var dy = relative ? loc[1] : (loc[1] - sy);
var ox = parseInt(ctx.canvas.getAttribute('_left')) || 0;
var oy = parseInt(ctx.canvas.getAttribute('_top')) || 0;
if (!time) {
core.relocateCanvas(ctx, ox + dx, oy + dy);
ctx.canvas.setAttribute('_text_left', loc[0]);
ctx.canvas.setAttribute('_text_top', loc[1]);
if (callback) callback();
return;
}
var moveInfo = {
sx: sx, sy: sy, dx: dx, dy: dy, ox: ox, oy: oy,
moveMode: moveMode, time: time / Math.max(core.status.replay.speed, 1)
};
this._moveTextBox_moving(ctx, moveInfo, callback);
}
events.prototype._moveTextBox_moving = function (ctx, moveInfo, callback) {
var step = 0, steps = moveInfo.time / 10;
if (steps <= 0) steps = 1;
var moveFunc = core.applyEasing(moveInfo.moveMode);
var animate = setInterval(function () {
step++;
var dx = moveInfo.dx * moveFunc(step / steps);
var dy = moveInfo.dy * moveFunc(step / steps);
core.relocateCanvas(ctx, parseInt(moveInfo.ox + dx), parseInt(moveInfo.oy + dy));
ctx.canvas.setAttribute('_text_left', moveInfo.sx + dx);
ctx.canvas.setAttribute('_text_top', moveInfo.sy + dy);
if (step == steps) {
delete core.animateFrame.asyncId[animate];
clearInterval(animate);
if (callback) callback();
}
}, 10);
core.animateFrame.asyncId[animate] = true;
}
////// 清除对话框 //////
events.prototype.clearTextBox = function (code, callback) {
var ctx = '__text__' + code;
if (!core.getContextByName(ctx)) {
if (callback) callback();
}
core.ui._animateUI('hide', ctx, function () {
core.deleteCanvas(ctx);
if (callback) callback();
});
}
////// 关门 //////
events.prototype.closeDoor = function (x, y, id, callback) {
id = id || "";
if ((core.material.icons.animates[id] == null && core.material.icons.npc48[id] == null)

View File

@ -1382,7 +1382,8 @@ ui.prototype._getRealContent = function (content) {
return content.replace(/(\r|\\(r|c|d|e|g|z))(\[.*?])?/g, "").replace(/(\\i)(\[.*?])?/g, "占1");
}
ui.prototype._animateUI = function (type, callback) {
ui.prototype._animateUI = function (type, ctx, callback) {
ctx = ctx || 'ui';
var time = core.status.textAttribute.animateTime || 0;
if (!core.status.event || !time || core.isReplaying() || (type != 'show' && type != 'hide')) {
if (callback) callback();
@ -1395,12 +1396,12 @@ ui.prototype._animateUI = function (type, callback) {
} else if (type == 'hide') {
opacity = 1;
}
core.setOpacity('ui', opacity);
core.setOpacity(ctx, opacity);
core.dom.next.style.opacity = opacity;
core.status.event.animateUI = setInterval(function () {
if (type == 'show') opacity += 0.05;
else opacity -= 0.05;
core.setOpacity('ui', opacity);
core.setOpacity(ctx, opacity);
core.dom.next.style.opacity = opacity;
if (opacity >= 1 || opacity <= 0) {
clearInterval(core.status.event.animateUI);
@ -1416,7 +1417,11 @@ ui.prototype.drawTextBox = function(content, config) {
this.clearUI();
content = core.replaceText(content);
var ctx = config.ctx || null;
if (ctx && main.mode == 'play') {
core.createCanvas(ctx, 0, 0, core.__PIXELS__, core.__PIXELS__, 141);
ctx = core.getContextByName(ctx);
}
// Step 1: 获得标题信息和位置信息
var textAttribute = core.status.textAttribute;
@ -1430,7 +1435,7 @@ ui.prototype.drawTextBox = function(content, config) {
delete posInfo.py;
posInfo.pos = config.pos;
}
posInfo.ctx = config.ctx;
posInfo.ctx = ctx;
// Step 2: 计算对话框的矩形位置
var hPos = this._drawTextBox_getHorizontalPosition(content, titleInfo, posInfo);
@ -1438,6 +1443,11 @@ ui.prototype.drawTextBox = function(content, config) {
posInfo.xoffset = hPos.xoffset;
posInfo.yoffset = vPos.yoffset - 4;
if (ctx && main.mode == 'play') {
ctx.canvas.setAttribute('_text_left', hPos.left);
ctx.canvas.setAttribute('_text_top', vPos.top);
}
// Step 3: 绘制背景图
var isWindowSkin = this.drawBackground(hPos.left, vPos.top, hPos.right, vPos.bottom, posInfo);
var alpha = isWindowSkin ? this._drawWindowSkin_getOpacity() : textAttribute.background[3];