From 5e78501f8425e5be7a1ba469a14339920a3ed824 Mon Sep 17 00:00:00 2001 From: ckcz123 Date: Sat, 7 Aug 2021 22:12:17 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AF=B9=E8=AF=9D=E6=A1=86=E9=A2=84=E8=A7=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- _docs/api.md | 6 ++ _server/CodeMirror/defs.js | 8 ++ _server/MotaAction.g4 | 10 +-- _server/editor_blockly.js | 21 ++++- _server/editor_ui.js | 22 ++++- libs/control.js | 7 ++ libs/events.js | 40 +++++---- libs/maps.js | 9 +- libs/ui.js | 175 +++++++++++++++++++++---------------- project/floors/sample1.js | 11 +-- runtime.d.ts | 6 ++ 11 files changed, 200 insertions(+), 115 deletions(-) diff --git a/_docs/api.md b/_docs/api.md index 36381d5a..3af3e7f7 100644 --- a/_docs/api.md +++ b/_docs/api.md @@ -1142,6 +1142,12 @@ setHeroIcon: fn(name: string, noDraw?: bool) name: 新的行走图文件名,可以是全塔属性中映射前的中文名。映射后会被存入core.status.hero.image noDraw: true表示不立即刷新(刷新会导致大地图下视野重置到以主角为中心) +setNameMap: fn(name: string, value?: string) +设置文件别名 + +setTextAttribute: fn(data: ?) +设置剧情文本的属性 + setValue: fn(name: string, operator: string, value: ?, prefix?: string) 数值操作 diff --git a/_server/CodeMirror/defs.js b/_server/CodeMirror/defs.js index 982c1510..91cc4fc1 100644 --- a/_server/CodeMirror/defs.js +++ b/_server/CodeMirror/defs.js @@ -3876,6 +3876,14 @@ var terndefs_f6783a0a_522d_417e_8407_94c67b692e50 = [ "!doc": "设置全塔属性", "!type": "fn(name: string, value: string)" }, + "setNameMap": { + "!doc": "设置文件别名", + "!type": "fn(name: string, value?: string)" + }, + "setTextAttribute": { + "!doc": "设置剧情文本的属性", + "!type": "fn(data: ?)" + }, "openToolbox": { "!doc": "点击工具栏时的打开操作", "!type": "fn(fromUserAction?: bool)" diff --git a/_server/MotaAction.g4 b/_server/MotaAction.g4 index 90fd905f..10468310 100644 --- a/_server/MotaAction.g4 +++ b/_server/MotaAction.g4 @@ -914,7 +914,7 @@ text_0_s /* text_0_s tooltip : text:显示一段文字(剧情) helpUrl : /_docs/#/instruction -doubleclicktext : EvalString_Multi_0 +previewBlock : true default : ["欢迎使用事件编辑器(回车直接多行编辑)"] var code = '"'+EvalString_Multi_0+'"'; if (block.isCollapsed() || !block.isEnabled()) { @@ -933,7 +933,7 @@ text_1_s /* text_1_s tooltip : text:显示一段文字(剧情),选项较多请右键点击帮助 helpUrl : /_docs/#/instruction -doubleclicktext : EvalString_Multi_0 +previewBlock : true allIds : ['EvalString_1'] default : ["小妖精","fairy","","","","","欢迎使用事件编辑器(回车直接多行编辑)"] var title=''; @@ -973,9 +973,8 @@ text_2_s /* text_2_s tooltip : text:显示一段文字(剧情),选项较多请右键点击帮助 helpUrl : /_docs/#/instruction -doubleclicktext : EvalString_Multi_0 +previewBlock : true allIds : ['EvalString_1'] -menu : [['预览所有立绘','editor_blockly.previewBlock(block)']] default : ["小妖精","fairy","","","","","欢迎使用事件编辑器(回车直接多行编辑)",null] var title=''; if (EvalString_0==''){ @@ -1121,6 +1120,7 @@ setText_s /* setText_s tooltip : setText:设置剧情文本的属性,颜色为RGB三元组或RGBA四元组,打字间隔为剧情文字添加的时间间隔,为整数或不填,字符间距为字符之间的距离,为整数或不填。 helpUrl : /_docs/#/instruction +previewBlock : true default : [null,"",null,null,"",'rgba(255,255,255,1)',"",'rgba(255,255,255,1)',"",'rgba(255,255,255,1)',"","","","","",""] SetTextPosition_List_0 =SetTextPosition_List_0==='null'?'': ', "position": "'+SetTextPosition_List_0+'"'; TextAlign_List_0 = TextAlign_List_0==='null'?'': ', "align": "'+TextAlign_List_0+'"'; @@ -2689,7 +2689,7 @@ choices_s /* choices_s tooltip : choices: 给用户提供选项 helpUrl : /_docs/#/instruction -doubleclicktext : EvalString_Multi_0 +previewBlock : true default : ["","流浪者","trader",0] allIds : ['IdString_0'] var title=''; diff --git a/_server/editor_blockly.js b/_server/editor_blockly.js index cc0b53b2..7d189e55 100644 --- a/_server/editor_blockly.js +++ b/_server/editor_blockly.js @@ -241,6 +241,8 @@ editor_blockly = function () { return hasAsync; } + var _isTextAttributeSet = false; + editor_blockly.previewBlock = function (b,args) { var previewTextDrawing = function (content) { @@ -283,7 +285,7 @@ editor_blockly = function () { try { // 特殊处理立绘 - if (b.type == 'textDrawing' || b.type == 'text_2_s') { + if (b.type == 'textDrawing') { previewTextDrawing(Blockly.JavaScript.blockToCode(b)); return true; } @@ -293,6 +295,23 @@ editor_blockly = function () { if (obj.length == 0) return true; obj = obj[0]; switch (b.type) { + case 'text_0_s': + case 'text_1_s': + case 'text_2_s': + case 'choices_s': + if (!_isTextAttributeSet) { + alert('警告!你尚未设置用于预览的剧情文本的属性,将采用默认属性进行预览。\n你可以双击“设置剧情文本的属性”事件来设置用于预览的属性。'); + core.status.textAttribute = core.clone(core.initStatus.textAttribute); + _isTextAttributeSet = true; + } + editor.uievent.previewUI([obj]); + break; + case 'setText_s': // 设置剧情文本的属性 + _isTextAttributeSet = true; + core.status.textAttribute = core.clone(core.initStatus.textAttribute); + core.setTextAttribute(obj); + alert('已成功设置此属性为显示文章的预览属性!') + break; case 'waitContext_2': // 等待用户操作坐标预览 editor.uievent.previewUI([{"type": "fillRect", "x": obj.px[0], "y": obj.py[0], "width": "(" + obj.px[1] + ")-(" + obj.px[0] + ")", "height": "(" + obj.py[1] + ")-(" + obj.py[0] + ")", diff --git a/_server/editor_ui.js b/_server/editor_ui.js index e4db4ae3..580a627d 100644 --- a/_server/editor_ui.js +++ b/_server/editor_ui.js @@ -392,9 +392,27 @@ editor_ui_wrapper = function (editor) { if (uievent.values.list instanceof Array) { uievent.values.list.forEach(function (data) { + if (typeof data == 'string') data = { "type": "text", "text": data }; var type = data.type; - if (!type || !core.ui["_uievent_" + type]) return; - core.ui["_uievent_" + type](data); + if (type == "text") { + data.ctx = 'uievent'; + core.saveCanvas('uievent'); + core.drawTextBox(data.text, data); + core.loadCanvas('uievent'); + return; + } + else if (type == "choices") { + for (var i = 0; i < data.choices.length; i++) { + if (typeof data.choices[i] === 'string') + data.choices[i] = {"text": data.choices[i]}; + data.choices[i].text = core.replaceText(data.choices[i].text); + } + core.saveCanvas('uievent'); + core.drawChoices(core.replaceText(data.text), data.choices, 'uievent'); + core.loadCanvas('uievent'); + return; + } else if (core.ui["_uievent_" + type]) + core.ui["_uievent_" + type](data); }) } } diff --git a/libs/control.js b/libs/control.js index 52b1b630..8b9154cd 100644 --- a/libs/control.js +++ b/libs/control.js @@ -2305,6 +2305,9 @@ control.prototype.getStatus = function (name) { if (!core.status.hero) return null; if (name == 'x' || name == 'y' || name == 'direction') return this.getHeroLoc(name); + if (main.mode == 'editor') { + return data_a1e2fb4a_e986_4524_b0da_9b7ba7c0874d.firstData.hero[name]; + } return core.status.hero[name]; } @@ -2389,6 +2392,10 @@ control.prototype.setHeroLoc = function (name, value, noGather) { ////// 获得勇士的位置 ////// control.prototype.getHeroLoc = function (name) { if (!core.status.hero) return; + if (main.mode == 'editor') { + if (name == null) return data_a1e2fb4a_e986_4524_b0da_9b7ba7c0874d.firstData.hero.loc; + return data_a1e2fb4a_e986_4524_b0da_9b7ba7c0874d.firstData.hero.loc[name]; + } if (name == null) return core.status.hero.loc; return core.status.hero.loc[name]; } diff --git a/libs/events.js b/libs/events.js index f25b4c25..b8790319 100644 --- a/libs/events.js +++ b/libs/events.js @@ -1380,23 +1380,7 @@ events.prototype._action__label = function (data, x, y, prefix) { } events.prototype._action_setText = function (data, x, y, prefix) { - ["position", "offset", "align", "bold", "titlefont", "textfont", "lineHeight", "time", "letterSpacing", "animateTime"].forEach(function (t) { - if (data[t] != null) core.status.textAttribute[t] = data[t]; - }); - ["background", "title", "text"].forEach(function (t) { - if ((data[t] instanceof Array) && data[t].length >= 3) { - if (data[t].length == 3) data[t].push(1); - core.status.textAttribute[t] = data[t]; - } - if (t == 'background') { - var name = core.getMappedName(data[t]); - var img = core.material.images.images[name]; - if (img && img.width == 192 && img.height == 128) { - core.status.textAttribute[t] = name; - } - } - }); - core.setFlag('textAttribute', core.status.textAttribute); + this.setTextAttribute(data); core.doAction(); } @@ -3051,6 +3035,28 @@ events.prototype.setNameMap = function (name, value) { flags.__nameMap__[name] = value; } +////// 设置剧情文本的属性 ////// +events.prototype.setTextAttribute = function (data) { + if (!core.isPlaying()) return; + ["position", "offset", "align", "bold", "titlefont", "textfont", "lineHeight", "time", "letterSpacing", "animateTime"].forEach(function (t) { + if (data[t] != null) core.status.textAttribute[t] = data[t]; + }); + ["background", "title", "text"].forEach(function (t) { + if ((data[t] instanceof Array) && data[t].length >= 3) { + if (data[t].length == 3) data[t].push(1); + core.status.textAttribute[t] = data[t]; + } + if (t == 'background') { + var name = core.getMappedName(data[t]); + var img = core.material.images.images[name]; + if (img && img.width == 192 && img.height == 128) { + core.status.textAttribute[t] = name; + } + } + }); + if (main.mode == 'play') core.setFlag('textAttribute', core.status.textAttribute); +} + events.prototype.closeDoor = function (x, y, id, callback) { id = id || ""; if ((core.material.icons.animates[id] == null && core.material.icons.npc48[id] == null) diff --git a/libs/maps.js b/libs/maps.js index e48462eb..7aa510fb 100644 --- a/libs/maps.js +++ b/libs/maps.js @@ -2751,12 +2751,15 @@ maps.prototype.removeGlobalAnimate = function (x, y, name) { ////// 绘制UI层的box动画 ////// maps.prototype.drawBoxAnimate = function () { + if (core.status.boxAnimateObjs.length == 0) return; core.status.boxAnimateObjs.forEach(function (obj) { - core.clearMap('ui', obj.bgx, obj.bgy, obj.bgWidth, obj.bgHeight); - core.fillRect('ui', obj.bgx, obj.bgy, obj.bgWidth, obj.bgHeight, core.material.groundPattern); - core.drawImage('ui', obj.image, core.status.globalAnimateStatus % obj.animate * 32, obj.pos, + var ctx = obj.ctx || 'ui'; + core.clearMap(ctx, obj.bgx, obj.bgy, obj.bgWidth, obj.bgHeight); + core.fillRect(ctx, obj.bgx, obj.bgy, obj.bgWidth, obj.bgHeight, core.material.groundPattern); + core.drawImage(ctx, obj.image, core.status.globalAnimateStatus % obj.animate * 32, obj.pos, 32, obj.height, obj.x, obj.y, obj.dw || 32, obj.dh || obj.height); }); + if (main.mode != 'play') core.status.boxAnimateObjs = []; } ////// 绘制动画 ////// diff --git a/libs/ui.js b/libs/ui.js index 18e88fb5..3ee3d1fd 100644 --- a/libs/ui.js +++ b/libs/ui.js @@ -814,12 +814,16 @@ ui.prototype._getPosition = function (content) { px = core.status.event.data.x; py = core.status.event.data.y; } + if (editor.mode != 'play') { + px = editor.pos.x; + py = editor.pos.y; + } content = content.replace("\b", "\\b") .replace(/\\b\[(up|center|down|hero|this)(,(hero|null|\d+,\d+|\d+))?]/g, function (s0, s1, s2, s3) { pos = s1; if (s3 == 'hero' || s1=='hero' && !s3) { - px = core.status.hero.loc.x; - py = core.status.hero.loc.y; + px = core.getHeroLoc('x'); + py = core.getHeroLoc('y'); } else if (s3 == 'null') { px = py = null; @@ -954,10 +958,10 @@ ui.prototype.drawBackground = function (left, top, right, bottom, posInfo) { var xoffset = posInfo.xoffset || 0, yoffset = posInfo.yoffset || 0; var background = core.status.textAttribute.background; - if (this._drawBackground_drawWindowSkin(background, left, top, right, bottom, posInfo.position, px, py)) + if (this._drawBackground_drawWindowSkin(background, left, top, right, bottom, posInfo.position, px, py, posInfo.ctx)) return true; if (typeof background == 'string') background = core.initStatus.textAttribute.background; - this._drawBackground_drawColor(background, left, top, right, bottom, posInfo.position, px, py, xoffset, yoffset); + this._drawBackground_drawColor(background, left, top, right, bottom, posInfo.position, px, py, xoffset, yoffset, posInfo.ctx); return false; } @@ -978,27 +982,29 @@ ui.prototype._drawWindowSkin_getOpacity = function () { return core.getFlag("__winskin_opacity__", 0.85); } -ui.prototype._drawBackground_drawWindowSkin = function (background, left, top, right, bottom, position, px, py) { +ui.prototype._drawBackground_drawWindowSkin = function (background, left, top, right, bottom, position, px, py, ctx) { + ctx = ctx || 'ui'; if (typeof background == 'string' && core.material.images.images[background]) { var image = core.material.images.images[background]; if (image.width==192 && image.height==128) { - core.setAlpha('ui', this._drawWindowSkin_getOpacity()); - this.drawWindowSkin(image, 'ui', left, top, right - left, bottom - top, position, px, py); - core.setAlpha('ui', 1); + core.setAlpha(ctx, this._drawWindowSkin_getOpacity()); + this.drawWindowSkin(image, ctx, left, top, right - left, bottom - top, position, px, py); + core.setAlpha(ctx, 1); return true; } } return false; } -ui.prototype._drawBackground_drawColor = function (background, left, top, right, bottom, position, px, py, xoffset, yoffset) { +ui.prototype._drawBackground_drawColor = function (background, left, top, right, bottom, position, px, py, xoffset, yoffset, ctx) { + ctx = ctx || 'ui'; var alpha = background[3]; - core.setAlpha('ui', alpha); - core.setStrokeStyle('ui', core.arrayToRGBA(core.status.globalAttribute.borderColor)); - core.setFillStyle('ui', core.arrayToRGB(background)); - core.setLineWidth('ui', 2); + core.setAlpha(ctx, alpha); + core.setStrokeStyle(ctx, core.arrayToRGBA(core.status.globalAttribute.borderColor)); + core.setFillStyle(ctx, core.arrayToRGB(background)); + core.setLineWidth(ctx, 2); // 绘制 - var ctx = core.canvas.ui; + ctx = core.getContextByName(ctx); ctx.beginPath(); ctx.moveTo(left, top); // 上边缘三角 @@ -1019,7 +1025,7 @@ ui.prototype._drawBackground_drawColor = function (background, left, top, right, ctx.closePath(); ctx.fill(); ctx.stroke(); - core.setAlpha('ui', 1); + core.setAlpha(ctx, 1); } ////// 计算有效文本框的宽度 @@ -1420,63 +1426,68 @@ ui.prototype.drawTextBox = function(content, config) { var posInfo = this._getPosition(titleInfo.content); if (posInfo.position != 'up' && posInfo.position != 'down') posInfo.px = posInfo.py = null; if (!posInfo.position) posInfo.position = textAttribute.position; - content = this._drawTextBox_drawImages(posInfo.content); + content = this._drawTextBox_drawImages(posInfo.content, config.ctx); if (config.pos) { delete posInfo.px; delete posInfo.py; posInfo.pos = config.pos; } + posInfo.ctx = config.ctx; // Step 2: 计算对话框的矩形位置 var hPos = this._drawTextBox_getHorizontalPosition(content, titleInfo, posInfo); var vPos = this._drawTextBox_getVerticalPosition(content, titleInfo, posInfo, hPos.validWidth); + posInfo.xoffset = hPos.xoffset; + posInfo.yoffset = vPos.yoffset - 4; // Step 3: 绘制背景图 - var pInfo = core.clone(posInfo); - pInfo.xoffset = hPos.xoffset; pInfo.yoffset = vPos.yoffset - 4; - var isWindowSkin = this.drawBackground(hPos.left, vPos.top, hPos.right, vPos.bottom, pInfo); + var isWindowSkin = this.drawBackground(hPos.left, vPos.top, hPos.right, vPos.bottom, posInfo); var alpha = isWindowSkin ? this._drawWindowSkin_getOpacity() : textAttribute.background[3]; // Step 4: 绘制标题、头像、动画 - var content_top = this._drawTextBox_drawTitleAndIcon(titleInfo, hPos, vPos, alpha); + var content_top = this._drawTextBox_drawTitleAndIcon(titleInfo, hPos, vPos, alpha, config.ctx); // Step 5: 绘制正文 - var config = this.drawTextContent('ui', content, { + var config = this.drawTextContent(config.ctx || 'ui', content, { left: hPos.content_left, top: content_top, maxWidth: hPos.validWidth, lineHeight: vPos.lineHeight, time: (config.showAll || textAttribute.time<=0 || core.status.event.id!='action')?0:textAttribute.time }); // Step 6: 绘制光标 - main.dom.next.style.display = 'block'; - main.dom.next.style.borderRightColor = main.dom.next.style.borderBottomColor = core.arrayToRGB(textAttribute.text); - main.dom.next.style.top = (vPos.bottom - 20) * core.domStyle.scale + "px"; - var left = (hPos.left + hPos.right) / 2; - if (pInfo.position == 'up' && !pInfo.noPeak && pInfo.px != null && Math.abs(pInfo.px * 32 + 16 - left) < 50) - left = hPos.right - 64; - main.dom.next.style.left = left * core.domStyle.scale + "px"; + if (main.mode == 'play') { + main.dom.next.style.display = 'block'; + main.dom.next.style.borderRightColor = main.dom.next.style.borderBottomColor = core.arrayToRGB(textAttribute.text); + main.dom.next.style.top = (vPos.bottom - 20) * core.domStyle.scale + "px"; + var left = (hPos.left + hPos.right) / 2; + if (posInfo.position == 'up' && !posInfo.noPeak && posInfo.px != null && Math.abs(posInfo.px * 32 + 16 - left) < 50) + left = hPos.right - 64; + main.dom.next.style.left = left * core.domStyle.scale + "px"; + } return config; } -ui.prototype._drawTextBox_drawImages = function (content) { +ui.prototype._drawTextBox_drawImages = function (content, ctx) { + ctx = ctx || 'ui'; return content.replace(/(\f|\\f)\[(.*?)]/g, function (text, sympol, str) { var ss = str.split(","); // 绘制 if (ss.length==3) - core.drawImage('ui', ss[0], parseFloat(ss[1]), parseFloat(ss[2])); + core.drawImage(ctx, ss[0], parseFloat(ss[1]), parseFloat(ss[2])); else if (ss.length==5) - core.drawImage('ui', ss[0], parseFloat(ss[1]), parseFloat(ss[2]), parseFloat(ss[3]), parseFloat(ss[4])); + core.drawImage(ctx, ss[0], parseFloat(ss[1]), parseFloat(ss[2]), parseFloat(ss[3]), parseFloat(ss[4])); else if (ss.length >= 9) { - if (ss.length >= 10) core.setAlpha('ui', parseFloat(ss[9])); + if (ss.length >= 10) core.setAlpha(ctx, parseFloat(ss[9])); var angle = (parseFloat(ss[10]) || 0) * Math.PI / 180; - core.drawImage('ui', ss[0], parseFloat(ss[1]), parseFloat(ss[2]), parseFloat(ss[3]), parseFloat(ss[4]), + core.drawImage(ctx, ss[0], parseFloat(ss[1]), parseFloat(ss[2]), parseFloat(ss[3]), parseFloat(ss[4]), parseFloat(ss[5]), parseFloat(ss[6]), parseFloat(ss[7]), parseFloat(ss[8]), angle); - core.setAlpha('ui', 1); + core.setAlpha(ctx, 1); } return ""; }); } ui.prototype._drawTextBox_getHorizontalPosition = function (content, titleInfo, posInfo) { + var ctx = posInfo.ctx || 'ui'; var realContent = this._getRealContent(content); var paddingLeft = 25, paddingRight = 12; if ((posInfo.px != null && posInfo.py != null) || posInfo.pos) paddingLeft = 20; @@ -1490,7 +1501,7 @@ ui.prototype._drawTextBox_getHorizontalPosition = function (content, titleInfo, // 无行走图或头像,则可以适当缩小min_width if (titleInfo.image == null) min_width = 160; if (titleInfo.title) { - min_width = core.clamp(core.calWidth('ui', titleInfo.title, this._buildFont(core.status.textAttribute.titlefont, true)), min_width, max_width); + min_width = core.clamp(core.calWidth(ctx, titleInfo.title, this._buildFont(core.status.textAttribute.titlefont, true)), min_width, max_width); } if (posInfo.pos) { left = core.calValue(posInfo.pos[0]) || 0; @@ -1548,8 +1559,9 @@ ui.prototype._drawTextBox_getVerticalPosition = function (content, titleInfo, po return { top: top, height: height, bottom: top + height, yoffset: yoffset, lineHeight: lineHeight }; } -ui.prototype._drawTextBox_drawTitleAndIcon = function (titleInfo, hPos, vPos, alpha) { - core.setTextAlign('ui', 'left'); +ui.prototype._drawTextBox_drawTitleAndIcon = function (titleInfo, hPos, vPos, alpha, ctx) { + ctx = ctx || 'ui'; + core.setTextAlign(ctx, 'left'); var textAttribute = core.status.textAttribute; var content_top = vPos.top + 15; var image_top = vPos.top + 15; @@ -1557,23 +1569,23 @@ ui.prototype._drawTextBox_drawTitleAndIcon = function (titleInfo, hPos, vPos, al var titlefont = textAttribute.titlefont; content_top += titlefont + 5; image_top = vPos.top + 40; - core.setFillStyle('ui', core.arrayToRGB(textAttribute.title)); - core.setStrokeStyle('ui', core.arrayToRGB(textAttribute.title)); + core.setFillStyle(ctx, core.arrayToRGB(textAttribute.title)); + core.setStrokeStyle(ctx, core.arrayToRGB(textAttribute.title)); // --- title也要居中或者右对齐? - var title_width = core.calWidth('ui', titleInfo.title, this._buildFont(titlefont, true)); + var title_width = core.calWidth(ctx, titleInfo.title, this._buildFont(titlefont, true)); var title_left = hPos.content_left; if (textAttribute.align == 'center') title_left = hPos.left + (hPos.width - title_width) / 2; else if (textAttribute.align == 'right') title_left = hPos.right - title_width - 12; - core.fillText('ui', titleInfo.title, title_left, vPos.top + 8 + titlefont); + core.fillText(ctx, titleInfo.title, title_left, vPos.top + 8 + titlefont); } if (titleInfo.icon != null) { - core.setAlpha('ui', alpha); - core.strokeRect('ui', hPos.left + 15 - 1, image_top-1, 34, titleInfo.height + 2, null, 2); - core.setAlpha('ui', 1); + core.setAlpha(ctx, alpha); + core.strokeRect(ctx, hPos.left + 15 - 1, image_top-1, 34, titleInfo.height + 2, null, 2); + core.setAlpha(ctx, 1); core.status.boxAnimateObjs = []; // --- 勇士 if (titleInfo.image == core.material.images.hero) { @@ -1583,12 +1595,12 @@ ui.prototype._drawTextBox_drawTitleAndIcon = function (titleInfo, hPos, vPos, al core.status.boxAnimateObjs.push({ 'bgx': hPos.left + 15, 'bgy': image_top, 'bgWidth': 32, 'bgHeight': titleInfo.height, 'x': hPos.left + 15, 'y': image_top, 'height': titleInfo.height, 'animate': 4, - 'image': titleInfo.image, 'pos': core.material.icons.hero[direction].loc * titleInfo.height + 'image': titleInfo.image, 'pos': core.material.icons.hero[direction].loc * titleInfo.height, ctx: ctx, }) } else { - core.clearMap('ui', hPos.left + 15, image_top, 32, titleInfo.height); - core.fillRect('ui', hPos.left + 15, image_top, 32, titleInfo.height, core.material.groundPattern); - core.drawImage('ui', titleInfo.image, 0, 0, core.material.icons.hero.width || 32, core.material.icons.hero.height, + core.clearMap(ctx, hPos.left + 15, image_top, 32, titleInfo.height); + core.fillRect(ctx, hPos.left + 15, image_top, 32, titleInfo.height, core.material.groundPattern); + core.drawImage(ctx, titleInfo.image, 0, 0, core.material.icons.hero.width || 32, core.material.icons.hero.height, hPos.left + 15, image_top, 32, titleInfo.height); } } @@ -1596,13 +1608,13 @@ ui.prototype._drawTextBox_drawTitleAndIcon = function (titleInfo, hPos, vPos, al core.status.boxAnimateObjs.push({ 'bgx': hPos.left + 15, 'bgy': image_top, 'bgWidth': 32, 'bgHeight': titleInfo.height, 'x': hPos.left + 15, 'y': image_top, 'height': titleInfo.height, 'animate': titleInfo.animate, - 'image': titleInfo.image, 'pos': titleInfo.icon * titleInfo.height + 'image': titleInfo.image, 'pos': titleInfo.icon * titleInfo.height, ctx: ctx, }); } core.drawBoxAnimate(); } if (titleInfo.image != null && titleInfo.icon == null) { // 头像图 - core.drawImage('ui', titleInfo.image, 0, 0, titleInfo.image.width, titleInfo.image.height, + core.drawImage(ctx, titleInfo.image, 0, 0, titleInfo.image.width, titleInfo.image.height, hPos.left+10, vPos.top+10, 70, 70); } return content_top; @@ -1665,7 +1677,7 @@ ui.prototype.textImage = function (content, lineHeight) { } ////// 绘制一个选项界面 ////// -ui.prototype.drawChoices = function(content, choices) { +ui.prototype.drawChoices = function(content, choices, ctx) { choices = core.clone(choices || []); core.status.event.ui = {"text": content, "choices": choices}; @@ -1673,25 +1685,26 @@ ui.prototype.drawChoices = function(content, choices) { content = core.replaceText(content || ""); var titleInfo = this._getTitleAndIcon(content); - titleInfo.content = this._drawTextBox_drawImages(titleInfo.content); - var hPos = this._drawChoices_getHorizontalPosition(titleInfo, choices); + titleInfo.content = this._drawTextBox_drawImages(titleInfo.content, ctx); + var hPos = this._drawChoices_getHorizontalPosition(titleInfo, choices, ctx); var vPos = this._drawChoices_getVerticalPosition(titleInfo, choices, hPos); core.status.event.ui.offset = vPos.offset; - var isWindowSkin = this.drawBackground(hPos.left, vPos.top, hPos.right, vPos.bottom); - this._drawChoices_drawTitle(titleInfo, hPos, vPos); - this._drawChoices_drawChoices(choices, isWindowSkin, hPos, vPos); + var isWindowSkin = this.drawBackground(hPos.left, vPos.top, hPos.right, vPos.bottom, {ctx: ctx}); + this._drawChoices_drawTitle(titleInfo, hPos, vPos, ctx); + this._drawChoices_drawChoices(choices, isWindowSkin, hPos, vPos, ctx); } -ui.prototype._drawChoices_getHorizontalPosition = function (titleInfo, choices) { +ui.prototype._drawChoices_getHorizontalPosition = function (titleInfo, choices, ctx) { + ctx = ctx || 'ui'; // 宽度计算:考虑提示文字和选项的长度 - core.setFont('ui', this._buildFont(17, true)); - var width = this._calTextBoxWidth('ui', titleInfo.content || "", 246, this.PIXEL - 20); + core.setFont(ctx, this._buildFont(17, true)); + var width = this._calTextBoxWidth(ctx, titleInfo.content || "", 246, this.PIXEL - 20); for (var i = 0; i < choices.length; i++) { if (typeof choices[i] === 'string') choices[i] = {"text": choices[i]}; choices[i].text = core.replaceText(choices[i].text); - choices[i].width = core.calWidth('ui', core.replaceText(choices[i].text)); + choices[i].width = core.calWidth(ctx, core.replaceText(choices[i].text)); if (choices[i].icon != null) choices[i].width += 28; width = Math.max(width, choices[i].width+30); } @@ -1723,11 +1736,12 @@ ui.prototype._drawChoices_getVerticalPosition = function (titleInfo, choices, hP return {top: bottom - height, height: height, bottom: bottom, choice_top: choice_top, offset: offset }; } -ui.prototype._drawChoices_drawTitle = function (titleInfo, hPos, vPos) { +ui.prototype._drawChoices_drawTitle = function (titleInfo, hPos, vPos, ctx) { if (!titleInfo.content) return; + ctx = ctx || 'ui'; var content_top = vPos.top + 21; if (titleInfo.title != null) { - core.setTextAlign('ui', 'center'); + core.setTextAlign(ctx, 'center'); content_top = vPos.top + 41; var title_offset = hPos.left+hPos.width/2; @@ -1735,45 +1749,46 @@ ui.prototype._drawChoices_drawTitle = function (titleInfo, hPos, vPos) { if (titleInfo.icon != null) { title_offset += 12; - core.strokeRect('ui', hPos.left + 15 - 1, vPos.top + 30 - 1, 34, titleInfo.height + 2, '#DDDDDD', 2); + core.strokeRect(ctx, hPos.left + 15 - 1, vPos.top + 30 - 1, 34, titleInfo.height + 2, '#DDDDDD', 2); core.status.boxAnimateObjs = []; core.status.boxAnimateObjs.push({ 'bgx': hPos.left + 15, 'bgy': vPos.top + 30, 'bgWidth': 32, 'bgHeight': titleInfo.height, 'x': hPos.left + 15, 'y': vPos.top + 30, 'height': titleInfo.height, 'animate': titleInfo.animate, - 'image': titleInfo.image, 'pos': titleInfo.icon * titleInfo.height + 'image': titleInfo.image, 'pos': titleInfo.icon * titleInfo.height, ctx: ctx }); core.drawBoxAnimate(); }; - core.fillText('ui', titleInfo.title, title_offset, vPos.top + 27, + core.fillText(ctx, titleInfo.title, title_offset, vPos.top + 27, core.arrayToRGBA(core.status.textAttribute.title), this._buildFont(19, true)); } - core.setTextAlign('ui', 'left'); - this.drawTextContent('ui', titleInfo.content, { + core.setTextAlign(ctx, 'left'); + this.drawTextContent(ctx, titleInfo.content, { left: hPos.content_left, top: content_top, maxWidth: hPos.validWidth, fontSize: 15, lineHeight: 20, bold: true }); } -ui.prototype._drawChoices_drawChoices = function (choices, isWindowSkin, hPos, vPos) { +ui.prototype._drawChoices_drawChoices = function (choices, isWindowSkin, hPos, vPos, ctx) { + ctx = ctx || 'ui'; // 选项 - core.setTextAlign('ui', 'center'); - core.setFont('ui', this._buildFont(17, true)); + core.setTextAlign(ctx, 'center'); + core.setFont(ctx, this._buildFont(17, true)); for (var i = 0; i < choices.length; i++) { var color = core.arrayToRGBA(choices[i].color || core.status.textAttribute.text); if (choices[i].need != null && choices[i].need != '' && !core.calValue(choices[i].need)) color = '#999999'; - core.setFillStyle('ui', color); + core.setFillStyle(ctx, color); var offset = this.HPIXEL; if (choices[i].icon) { var iconInfo = this._getDrawableIconInfo(choices[i].icon), image = iconInfo[0], icon = iconInfo[1]; if (image != null) { - core.drawImage('ui', image, 0, 32 * icon, 32, 32, + core.drawImage(ctx, image, 0, 32 * icon, 32, 32, this.HPIXEL - choices[i].width/2, vPos.choice_top + 32*i - 17, 22, 22); offset += 14; } } - core.fillText('ui', choices[i].text, offset, vPos.choice_top + 32 * i, color); + core.fillText(ctx, choices[i].text, offset, vPos.choice_top + 32 * i, color); } if (choices.length>0 && core.status.event.selection != 'none') { @@ -1781,11 +1796,17 @@ ui.prototype._drawChoices_drawChoices = function (choices, isWindowSkin, hPos, v while (core.status.event.selection < 0) core.status.event.selection += choices.length; while (core.status.event.selection >= choices.length) core.status.event.selection -= choices.length; var len = choices[core.status.event.selection].width; - if (isWindowSkin) - this._drawWindowSelector(core.status.textAttribute.background, - this.HPIXEL - len/2 - 5, vPos.choice_top + 32 * core.status.event.selection - 20, len + 10, 28); + if (isWindowSkin) { + if (ctx) { + this._drawSelector(ctx, core.status.textAttribute.background, + len + 10, 28, this.HPIXEL - len/2 - 5, vPos.choice_top + 32 * core.status.event.selection - 20); + } else { + this._drawWindowSelector(core.status.textAttribute.background, + this.HPIXEL - len/2 - 5, vPos.choice_top + 32 * core.status.event.selection - 20, len + 10, 28); + } + } else - core.strokeRoundRect('ui', this.HPIXEL - len/2 - 5, vPos.choice_top + 32 * core.status.event.selection - 20, + core.strokeRoundRect(ctx, this.HPIXEL - len/2 - 5, vPos.choice_top + 32 * core.status.event.selection - 20, len+10, 28, 6, core.status.globalAttribute.selectColor, 2); } } diff --git a/project/floors/sample1.js b/project/floors/sample1.js index 7abedced..46324ac2 100644 --- a/project/floors/sample1.js +++ b/project/floors/sample1.js @@ -7,16 +7,7 @@ main.floors.sample1= "canFlyFrom": true, "canUseQuickShop": true, "defaultGround": "grass", - "images": [ - { - "name": "bg.jpg", - "canvas": "bg", - "x": 0, - "y": 0, - "w": 416, - "h": 416 - } - ], + "images": null, "weather": [ "snow", 6 diff --git a/runtime.d.ts b/runtime.d.ts index 1aa0bfcc..b43fe891 100644 --- a/runtime.d.ts +++ b/runtime.d.ts @@ -1245,6 +1245,12 @@ declare class events { /** 设置全塔属性 */ setGlobalAttribute(name: string, value: any): void + /** 设置剧情文本的属性 */ + setTextAttribute(data: any): void + + /** 设置文件别名 */ + setNameMap(name: string, value?: string): void + /** 检查升级事件 */ checkLvUp(): void }