From 018dbe83325abc25b8f37ec5e2c5c4117fe11a2c Mon Sep 17 00:00:00 2001 From: oc Date: Sun, 24 Mar 2019 16:05:46 +0800 Subject: [PATCH 01/33] rewrite drawTextBox & drawChoices --- libs/ui.js | 949 +++++++++++++++++++++-------------------------------- styles.css | 2 +- 2 files changed, 380 insertions(+), 571 deletions(-) diff --git a/libs/ui.js b/libs/ui.js index 4ab8359a..790ce132 100644 --- a/libs/ui.js +++ b/libs/ui.js @@ -13,7 +13,7 @@ function ui() { this.HSIZE = core.__HALF_SIZE__; this.LAST = this.SIZE - 1; this.PIXEL = core.__PIXELS__; - this.HPIXEL = this.PIX / 2; + this.HPIXEL = this.PIXEL / 2; } // 初始化UI @@ -341,10 +341,11 @@ ui.prototype._getTitleAndIcon = function (content) { if (blockInfo != null) { if (core.material.enemys[s4]) title = core.material.enemys[s4].name; image = blockInfo.image; - icon = blockInfo.posX; + icon = blockInfo.posY; height = blockInfo.height; animate = blockInfo.animate; } + else title = s4; } } if (s3) title = s3; @@ -360,65 +361,31 @@ ui.prototype._getTitleAndIcon = function (content) { }; } -ui.prototype.getTitleAndIcon = function (content) { - var id=null, name=null, image=null, icon=null, iconHeight=32, animate=null; - - var getInfo = function (v) { - var number = core.maps.getNumberById(v); - if (number>0) { - var block = core.maps.initBlock(0,0,number,true); - var cls = block.event.cls; - image = core.material.images[cls]; - icon = core.material.icons[cls][v]; - iconHeight = block.event.height; - animate = block.event.animate; - } - }; - - if (content.indexOf("\t[")==0 || content.indexOf("\\t[")==0) { - var index = content.indexOf("]"); - if (index>=0) { - var str=content.substring(2, index); - if (content.indexOf("\\t[")==0) str=content.substring(3, index); - content=content.substring(index+1); - var ss=str.split(","); - if (ss.length==1) { - if (/^[-\w.]+\.png$/.test(ss[0])) { - image = core.material.images.images[ss[0]]; - } - else { - id=ss[0]; - if (id=='hero') name = core.status.hero.name; - else if (core.isset(core.material.enemys[id])) { - name = core.material.enemys[id].name; - getInfo(id); - } - else { - name=id; - id='npc'; - } - } - } - else { - name=ss[0]; - id = 'npc'; - if (ss[1]=='hero') id = 'hero'; - else if (/^[-\w.]+\.png$/.test(ss[1])) { - image = core.material.images.images[ss[1]]; - } - else getInfo(ss[1]); - } - } +////// 正则处理 \b[up,xxx] 问题 +ui.prototype._getPosition = function (content) { + var pos = null, px = null, py = null; + if (core.status.event.id=='action') { + px = core.status.event.data.x; + py = core.status.event.data.y; } - return { - "content": content, - "id": id, - "name": name, - "image": image, - "icon": icon, - "iconHeight": iconHeight, - "animate": animate - }; + content = content.replace("\b", "\\b") + .replace(/\\b\[(up|center|down)(,(hero|null|\d+,\d+))?]/g, function (s0, s1, s2, s3) { + pos = s1; + if (s3 == 'hero') { + px = core.status.hero.loc.x; + py = core.status.hero.loc.y; + } + else if (s3 == 'null') { + px = py = null; + } + else if (s3) { + var str = s3.split(','); + px = parseInt(str[0]); + py = parseInt(str[1]); + } + return ""; + }); + return {content: content, position: pos, px: px, py: py}; } ////// 绘制选择光标 @@ -480,9 +447,9 @@ ui.prototype.drawWindowSkin = function(background, ctx, x, y, w, h, direction, p } ////// 计算有效文本框的宽度 -ui.prototype.calTextBoxWidth = function (ctx, content, min_width, max_width) { +ui.prototype.calTextBoxWidth = function (ctx, content, min_width, max_width, font) { // 无限长度自动换行 - var allLines = core.splitLines(ctx, content); + var allLines = core.splitLines(ctx, content, null, font); // 如果不存在手动换行,尽量调成半行形式 if (allLines.length == 1) { @@ -515,8 +482,10 @@ ui.prototype._getDrawableIconInfo = function (id) { return [image,icon]; } -ui.prototype._buildFont = function (fontSize) { - return (core.status.textAttribute.bold?"bold ":"") + fontSize + "px " +core.status.globalAttribute.font; +ui.prototype._buildFont = function (fontSize, bold) { + var textAttribute = core.status.textAttribute, globalAttribute = core.status.globalAttribute; + if (bold == null) bold = textAttribute.bold; + return (bold?"bold ":"") + (fontSize || textAttribute.textfont) + "px " + globalAttribute.font; } ////// 绘制一段文字到某个画布上面 @@ -524,7 +493,7 @@ ui.prototype._buildFont = function (fontSize) { // content:要绘制的内容;转义字符目前只允许留 \n, \r[...] 和 \i[...] // config:绘制配置项,目前暂时包含如下内容(均为可选) // left, top:起始点位置;maxWidth:单行最大宽度;color:默认颜色;align:左中右 -// fontSize:字体大小;font:字体样式;lineHeight:行高;time:打字机间隔 +// fontSize:字体大小;lineHeight:行高;time:打字机间隔 ui.prototype.drawTextContent = function (ctx, content, config) { ctx = core.getContextByName(ctx); if (!ctx) return; @@ -533,316 +502,215 @@ 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 || "#FFFFFF"; - config.align = config.align || "left"; + config.color = config.color || core.arrayToRGBA(core.status.textAttribute.text); + config.bold = config.bold || false; + config.align = config.align || core.status.textAttribute.align || "left"; config.fontSize = config.fontSize || core.status.textAttribute.textfont; - config.lineHeight = config.lineHeight || (config.fontSize * 1.2); + config.lineHeight = config.lineHeight || (config.fontSize * 1.3); config.time = config.time || 0; config.index = 0; - config.changed = true; config.currcolor = config.color; config.offsetX = 0; config.offsetY = 0; + config.line = 0; + config.blocks = []; // 创建一个新的临时画布 - var tempCtx = document.createElement('canvas').getContext('2d'); - tempCtx.canvas.height = config.lineHeight; + var tempCtx = core.bigmap.tempCanvas; + tempCtx.canvas.height = ctx.canvas.height; tempCtx.canvas.width = ctx.canvas.width; + var _textBaseLine = tempCtx.textBaseline; tempCtx.textBaseline = 'top'; - tempCtx.font = this._buildFont(config.fontSize); - + tempCtx.font = this._buildFont(config.fontSize, config.bold); + tempCtx.fillStyle = config.color; this._drawTextContent_draw(ctx, tempCtx, content, config); + tempCtx.textBaseline = _textBaseLine; } +// 绘制的基本逻辑: +// 1. 一个个字符绘制到对应画布上(靠左对齐);这个过程中,记下来每个字对应的方块 [x, y, w, h] +// 2. 每次换行时,计算当前行的宽度,然后如果是居中或者靠右对齐,则对当前行的每个小方块增加偏移量 +// 3. 实际绘制时,从临时画布直接将一个个小方块绘制到目标画布上,一次全部绘制,或者打字机效果一个个绘制 ui.prototype._drawTextContent_draw = function (ctx, tempCtx, content, config) { + // Step 1: 绘制到tempCtx上,并记录下图块信息 + while (this._drawTextContent_next(tempCtx, content, config)); + + // Step 2: 从tempCtx绘制到画布上 + config.index = 0; + var _drawNext = function () { + if (config.index >= config.blocks.length) return false; + var block = config.blocks[config.index++]; + ctx.drawImage(tempCtx.canvas, block.left, block.top, block.width, block.height, + config.left + block.left + block.marginLeft, config.top + block.top, block.width, block.height); + return true; + } if (config.time == 0) { - while (!core.ui._drawTextContent_next(ctx, tempCtx, content, config)); - core.ui._drawTextContent_drawLineToCtx(ctx, tempCtx, content, config); + while (_drawNext()); } else { core.status.event.interval = setInterval(function () { - config.changed = true; - if (!core.ui._drawTextContent_next(ctx, tempCtx, content, config)) { + if (!_drawNext()) { clearInterval(core.status.event.interval); core.status.event.interval = null; - core.ui._drawTextContent_drawLineToCtx(ctx, tempCtx, content, config); } - }, time); + }, config.time); } } -// 进行下一次绘制 -ui.prototype._drawTextContent_next = function (ctx, tempCtx, content, config) { - if (config.index >= content.length) return false; - // 是否需要改变颜色 - if (config.changed) { - core.setFillStyle(tempCtx, config.currcolor); - config.changed = false; +ui.prototype._drawTextContent_next = function (tempCtx, content, config) { + if (config.index >= content.length) { + this._drawTextContent_newLine(tempCtx, config); + return false; } // get next character var ch = content.charAt(config.index++); - return this._drawTextContent_drawChar(ctx, tempCtx, content, config, ch); + return this._drawTextContent_drawChar(tempCtx, content, config, ch); } // 绘制下一个字符 -ui.prototype._drawTextContent_drawChar = function (ctx, tempCtx, content, config, ch) { +ui.prototype._drawTextContent_drawChar = function (tempCtx, content, config, ch) { // \n, \\n if (ch == '\n' || (ch=='\\' && content.charAt(config.index)=='n')) { - this._drawTextContent_drawLineToCtx(ctx, tempCtx, content, config); + this._drawTextContent_newLine(tempCtx, config); if (ch=='\\') config.index++; - return this._drawTextContent_next(ctx, tempCtx, content, config); + return this._drawTextContent_next(tempCtx, content, config); } // \r, \\r if (ch == '\r' || (ch=='\\' && content.charAt(config.index)=='r')) { if (ch == '\\') config.index++; - return this._drawTextContent_changeColor(ctx, tempCtx, content, config); + return this._drawTextContent_changeColor(tempCtx, content, config); } // \\i 绘制图标 if (ch == '\\' && content.charAt(config.index)=='i') { - return this._drawTextContent_drawIcon(ctx, tempCtx, content, config); + return this._drawTextContent_drawIcon(tempCtx, content, config); } // 检查是不是自动换行 var charwidth = core.calWidth(tempCtx, ch); if (config.maxWidth != null && config.offsetX + charwidth > config.maxWidth) { - this._drawTextContent_drawLineToCtx(ctx, tempCtx, content, config); + this._drawTextContent_newLine(tempCtx, config); config.index--; - return this._drawTextContent_next(ctx, tempCtx, content, config); + return this._drawTextContent_next(tempCtx, content, config); } // 输出 - core.fillText(tempCtx, ch, config.offsetX, 0); + var left = config.offsetX, top = config.offsetY + (config.lineHeight - config.fontSize) / 2; + core.fillText(tempCtx, ch, left, top); + config.blocks.push({left: config.offsetX, top: config.offsetY, + width: charwidth, height: config.lineHeight, line: config.line, marginLeft: 0}); config.offsetX += charwidth; return true; } -// 从临时画布绘制到正式画布上面 -ui.prototype._drawTextContent_drawLineToCtx = function (ctx, tempCtx, content, config) { - // 计算坐标,宽高 - var left = config.left, top = config.top + config.offsetY; - var width = config.offsetX, height = config.lineHeight; - // 计算起点横坐标 +ui.prototype._drawTextContent_newLine = function (tempCtx, config) { + // 计算偏移量 + var width = config.offsetX, totalWidth = config.right - config.left; + var marginLeft = 0; if (config.align == 'center') - left = (config.left + config.right - width) / 2; + marginLeft = (totalWidth - width) / 2; else if (config.align == 'right') - left = config.right - width; + marginLeft = totalWidth - width; - core.drawImage(ctx, tempCtx.canvas, 0, 0, width, height, left, top, width, height); + config.blocks.forEach(function (b) { + if (b.line == config.line) + b.marginLeft = marginLeft; + }); config.offsetX = 0; config.offsetY += config.lineHeight; + config.line++; } -ui.prototype._drawTextContent_changeColor = function (ctx, tempCtx, content, config) { - config.changed = true; +ui.prototype._drawTextContent_changeColor = function (tempCtx, content, config) { // 检查是不是 [] var index = config.index, index2; if (content.charAt(index) == '[' && ((index2=content.indexOf(']', index))>=0)) { // 变色 var str = content.substring(index+1, index2); - if (str=="") config.currcolor = config.color; - else config.currcolor = str; + if (str=="") tempCtx.fillStyle = config.color; + else tempCtx.fillStyle = str; config.index = index2 + 1; } - else config.currcolor = color; - return this._drawTextContent_next(ctx, tempCtx,content, config); + else tempCtx.fillStyle = config.color; + return this._drawTextContent_next(tempCtx, content, config); } -ui.prototype._drawTextContent_drawIcon = function (ctx, tempCtx, content, config) { +ui.prototype._drawTextContent_drawIcon = function (tempCtx, content, config) { // 绘制一个 \i 效果 var index = config.index, index2; if (content.charAt(config.index+1) == '[' && ((index2=content.indexOf(']', index+1))>=0)) { var str = content.substring(index+2, index2); // --- 获得图标 var iconInfo = core.ui._getDrawableIconInfo(str), image = iconInfo[0], icon = iconInfo[1]; - if (image == null) return this._drawTextContent_next(ctx, tempCtx, content, config); + if (image == null) return this._drawTextContent_next(tempCtx, content, config); // 检查自动换行 - var width = config.fontSize + 2, left = config.offsetX + 2, top = (config.lineHeight - width) / 2; + var width = config.fontSize + 2, left = config.offsetX + 2, top = config.offsetY + (config.lineHeight - width) / 2 - 1; if (config.maxWidth != null && left + width > config.maxWidth) { - this._drawTextContent_drawLineToCtx(ctx, tempCtx, content, config); + this._drawTextContent_newLine(tempCtx, config); config.index--; - this._drawTextContent_next(ctx, tempCtx, content, config); + this._drawTextContent_next(tempCtx, content, config); } // 绘制到画布上 core.drawImage(tempCtx, image, 0, 32*icon, 32, 32, left, top, width, width); + + config.blocks.push({left: left, top: config.offsetY, + width: config.lineHeight, height: config.lineHeight, line: config.line, marginLeft: 0}); + config.offsetX += width + 6; config.index = index2 + 1; return true; } - return this._drawTextContent_next(ctx, tempCtx, content, config); + return this._drawTextContent_next(tempCtx, content, config); } -ui.prototype.__drawText = function (canvas, content, content_left, content_top, valid_width, - color, per_height, text_font, time) { - core.setTextAlign(canvas, 'left'); - - var offsetx = content_left, offsety = content_top; - core.setFillStyle(canvas, color); - var index = 0, currcolor = color, changed = false; - - var drawNext = function () { - if (index >= content.length) return false; - if (changed) { - core.setFillStyle(canvas, currcolor); - changed = false; - } - - // get next character - var ch = content.charAt(index++); - // \n, \\n - if (ch == '\n' || (ch=='\\' && content.charAt(index)=='n')) { - offsetx = content_left; - offsety += per_height; - if (ch=='\\') index++; - return drawNext(); - } - // \r, \\r - if (ch == '\r' || (ch=='\\' && content.charAt(index)=='r')) { - if (ch == '\\') index++; - changed = true; - // 检查是不是 [] - var index2; - if (content.charAt(index) == '[' && ((index2=content.indexOf(']', index))>=0)) { - // 变色 - var str = content.substring(index+1, index2); - if (str=="") currcolor = color; - else currcolor = str; - index = index2+1; - } - else currcolor = color; - return drawNext(); - } - // \\i 绘制图标 - if (ch == '\\' && content.charAt(index)=='i') { - // 绘制图标 - var index2; - if (content.charAt(index+1) == '[' && ((index2=content.indexOf(']', index+1))>=0)) { - var str = content.substring(index+2, index2); - // --- 获得图标 - var iconInfo = core.ui._getDrawableIconInfo(str), image = iconInfo[0], icon = iconInfo[1]; - if (image != null) { - if (core.isset(valid_width) && offsetx + text_font + 6 > content_left + valid_width) { - index --; - offsetx = content_left; - offsety += per_height; - return drawNext(); - } - // --- 绘制 - core.drawImage(canvas, image, 0, 32*icon, 32, 32, offsetx + 2, offsety - text_font + 1, text_font+2, text_font+2); - offsetx += text_font + 6; - index = index2+1; - return true; - } - } - } - // 检查是不是自动换行 - var charwidth = core.calWidth(canvas, ch); - if (core.isset(valid_width) && offsetx + charwidth > content_left + valid_width) { - index--; - offsetx = content_left; - offsety += per_height; - return drawNext(); - } - // 输出 - core.fillText(canvas, ch, offsetx, offsety); - offsetx += charwidth; - return true; - }; - - if (!core.isset(time) || time<=0) while (drawNext()); - else { - core.status.event.interval = setInterval(function () { - changed = true; - if (!drawNext()) { - clearInterval(core.status.event.interval); - core.status.event.interval = null; - } - }, time); - } +ui.prototype._getRealContent = function (content) { + return content.replace(/(\r|\\r)(\[.*?])?/g, "").replace(/(\\i)(\[.*?])?/g, "占1"); } ////// 绘制一个对话框 ////// ui.prototype.drawTextBox = function(content, showAll) { - - if (core.isset(core.status.event) && core.status.event.id=='action') { + if (core.status.event && core.status.event.id == 'action') core.status.event.ui = content; - } clearInterval(core.status.event.interval); core.status.event.interval = null; - - // 获得name, image, icon - var info = this.getTitleAndIcon(content); - content = info.content; - var id=info.id, name=info.name, image=info.image, icon=info.icon, iconHeight=info.iconHeight, animate=info.animate; - - // 获得颜色的盒子等信息 - var textAttribute = core.status.textAttribute || core.initStatus.textAttribute; - var titlefont = textAttribute.titlefont || 22; - var textfont = textAttribute.textfont || 16; - var offset = textAttribute.offset || 0; - var background = core.status.textAttribute.background; - var isWindowSkin = false; - if (typeof background == 'string') { - background = core.material.images.images[background]; - if (core.isset(background) && background.width==192 && background.height==128) isWindowSkin = true; - else background = core.initStatus.textAttribute.background; - } - - var titleColor = core.arrayToRGBA(textAttribute.title); - var textColor = core.arrayToRGBA(textAttribute.text); - var borderColor = core.status.globalAttribute.borderColor; - var alpha = isWindowSkin?0.85:background[3]; - - // 获得位置信息 - var position = textAttribute.position, px=null, py=null, ydelta=iconHeight-32; - if (content.indexOf("\b[")==0 || content.indexOf("\\b[")==0) { - var index = content.indexOf("]"); - if (index>=0) { - var str = content.substring(2, index); - if (content.indexOf("\\b[")==0) str = content.substring(3, index); - content = content.substring(index + 1); - - var ss=str.split(","); - - if (ss[0]=='up' || ss[0]=='center' || ss[0]=='down') { - position=ss[0]; - if (core.status.event.id=='action') { - px = core.status.event.data.x; - py = core.status.event.data.y; - } - else { - px = null; py=null; - } - - if (ss.length>=2) { - if (ss[1]=='hero') { - px=core.getHeroLoc('x'); - py=core.getHeroLoc('y'); - ydelta = core.material.icons.hero.height-32; - } - else if (ss[1] == 'null') { - px = py = null; - } - else if (ss.length>=3) { - px=parseInt(ss[1]); - py=parseInt(ss[2]); - } - } - } - } - } + core.status.boxAnimateObjs = []; + core.clearSelector(); + core.clearMap('ui'); content = core.replaceText(content); - core.status.boxAnimateObjs = []; - core.clearSelector(); + // Step 1: 获得标题信息和位置信息 + var textAttribute = core.status.textAttribute; + var titleInfo = this._getTitleAndIcon(content); + var posInfo = this._getPosition(titleInfo.content); + if (!posInfo.position) posInfo.position = textAttribute.position; + if (posInfo.position != 'up' && posInfo.position != 'down') posInfo.px = posInfo.py = null; + content = this._drawTextBox_drawImages(posInfo.content); - // drawImage - content = content.replace(/(\f|\\f)\[(.*?)]/g, function (text, sympol, str) { + // Step 2: 计算对话框的矩形位置 + var hPos = this._drawTextBox_getHorizontalPosition(content, titleInfo, posInfo); + var vPos = this._drawTextBox_getVerticalPosition(content, titleInfo, posInfo, hPos.validWidth); + + // Step 3: 绘制背景图 + var isWindowSkin = this._drawTextBox_drawBackground(titleInfo, posInfo, hPos, vPos); + var alpha = isWindowSkin ? 0.85 : (textAttribute.background[3] || core.initStatus.textAttribute.background[3]); + + // Step 4: 绘制标题、头像、 + var content_top = this._drawTextBox_drawTitleAndIcon(titleInfo, hPos, vPos, alpha); + + // Step 5: 绘制正文 + this.drawTextContent('ui', content, { + left: hPos.content_left, top: content_top, maxWidth: hPos.validWidth, + lineHeight: vPos.lineHeight, time: (showAll || textAttribute.time<=0 || core.status.event.id!='action')?0:textAttribute.time + }); +} + +ui.prototype._drawTextBox_drawImages = function (content) { + return content.replace(/(\f|\\f)\[(.*?)]/g, function (text, sympol, str) { var ss = str.split(","); if (ss.length!=3 && ss.length!=5 && ss.length!=9) return ""; var img = core.material.images.images[ss[0]]; - if (!core.isset(img)) return ""; + if (!img) return ""; // 绘制 if (ss.length==3) core.drawImage('ui', img, parseFloat(ss[1]), parseFloat(ss[2])); @@ -852,184 +720,183 @@ ui.prototype.drawTextBox = function(content, showAll) { core.drawImage('ui', img, parseFloat(ss[1]), parseFloat(ss[2]), parseFloat(ss[3]), parseFloat(ss[4]), parseFloat(ss[5]), parseFloat(ss[6]), parseFloat(ss[7]), parseFloat(ss[8])); return ""; }); +} - var globalFont = core.status.globalAttribute.font; - var font = textfont + 'px '+globalFont; - if (textAttribute.bold) font = "bold "+font; - var realContent = content.replace(/(\r|\\r)(\[.*?])?/g, "").replace(/(\\i)(\[.*?])?/g, "啊1"); - - var leftSpace = 25, rightSpace = 12; - if (core.isset(px) && core.isset(py)) leftSpace = 20; - if (id=='hero' || core.isset(icon)) leftSpace = 62; // 行走图:15+32+15 - else if (core.isset(image)) leftSpace = 90; // 大头像:10+70+10 - var left = 7, right = 416 - left, width = right - left, validWidth = width - leftSpace - rightSpace; - +ui.prototype._drawTextBox_getHorizontalPosition = function (content, titleInfo, posInfo) { + var realContent = this._getRealContent(content); + var paddingLeft = 25, paddingRight = 12; + if (posInfo.px != null && posInfo.py != null) paddingLeft = 20; + if (titleInfo.icon != null) paddingLeft = 62; // 15 + 32 + 15 + else if (titleInfo.image) paddingLeft = 90; // 10 + 70 + 10 + var left = 7 + 3 * (this.HSIZE - 6), right = this.PIXEL - left, + width = right - left, validWidth = width - paddingLeft - paddingRight; // 对话框效果:改为动态计算 - if (core.isset(px) && core.isset(py)) { - var min_width = 220 - leftSpace, max_width = validWidth; + if (posInfo.px != null && posInfo.py != null) { + var min_width = 220 - paddingLeft, max_width = validWidth; // 无行走图或头像,则可以适当缩小min_width - if (leftSpace == 20) min_width = 160; - core.setFont('ui', font); - validWidth = this.calTextBoxWidth('ui', realContent, min_width, max_width); - width = validWidth + leftSpace + rightSpace; - // left必须在7~416-7-width区间内,以保证left>=7,right<=416-7 - left = core.clamp(32*px+16-width/2-core.bigmap.offsetX, 7, 416-7-width); + if (titleInfo.image == null) min_width = 160; + validWidth = this.calTextBoxWidth('ui', realContent, min_width, max_width, this._buildFont()); + width = validWidth + paddingLeft + paddingRight; + left = core.clamp(32 * posInfo.px + 16 - width / 2 - core.bigmap.offsetX, left, right - width); right = left + width; } + return { left: left, right: right, width: width, validWidth: validWidth, xoffset: 11, content_left: left + paddingLeft }; +} - var content_left = left + leftSpace; - var height = 30 + (textfont+5)*core.splitLines("ui", realContent, validWidth, font).length; - if (core.isset(name)) height += titlefont + 5; - if (id == 'hero') - height = Math.max(height, core.material.icons.hero.height+50); - else if (core.isset(icon)) - height = Math.max(height, iconHeight+50); - else if (core.isset(image)) +ui.prototype._drawTextBox_getVerticalPosition = function (content, titleInfo, posInfo, validWidth) { + var textAttribute = core.status.textAttribute || core.initStatus.textAttribute; + var lineHeight = textAttribute.textfont + 5; + var realContent = this._getRealContent(content); + var height = 30 + lineHeight * core.splitLines("ui", realContent, validWidth, this._buildFont()).length; + if (titleInfo.title) height += textAttribute.titlefont + 5; + if (titleInfo.icon != null) + height = Math.max(height, titleInfo.height+50); + else if (titleInfo.image) height = Math.max(height, 90); - var xoffset = 11, yoffset = 16; - - var top; - if (position=='center') { - top = parseInt((416 - height) / 2); - } - else if (position=='up') { - if (px==null || py==null) - top = 5 + offset; - else { - top = 32 * py - height - ydelta - yoffset; - top -= core.bigmap.offsetY; - } - } - else if (position=='down') { - if (px==null || py==null) - top = 416 - height - 5 - offset; - else { - top = 32 * py + 32 + yoffset; - top -= core.bigmap.offsetY; - } - } - var bottom = top + height; - - if (isWindowSkin) { - core.setAlpha('ui', alpha); - this.drawWindowSkin(background,'ui',left,top,width,height,position,px==null?null:px*32-core.bigmap.offsetX,py==null?null:py*32-core.bigmap.offsetY); - core.setAlpha('ui', 1); - } - else { - yoffset -= 4; - core.setAlpha('ui', alpha); - core.setStrokeStyle('ui', borderColor); - core.setFillStyle('ui', core.arrayToRGB(background)); - core.setLineWidth('ui', 2); - // 绘制 - var canvas = core.canvas.ui; - canvas.beginPath(); - canvas.moveTo(left,top); - // 上边缘 - if (position=='down' && core.isset(px) && core.isset(py)) { - canvas.lineTo(32*px+xoffset - core.bigmap.offsetX, top); - canvas.lineTo(32*px+16 - core.bigmap.offsetX, top-yoffset); - canvas.lineTo(32*(px+1)-xoffset - core.bigmap.offsetX, top); - } - canvas.lineTo(right, top); - canvas.lineTo(right, bottom); - // 下边缘 - if (position=='up' && core.isset(px) && core.isset(py)) { - canvas.lineTo(32*(px+1)-xoffset - core.bigmap.offsetX, bottom); - canvas.lineTo(32*px+16 - core.bigmap.offsetX, bottom+yoffset); - canvas.lineTo(32*px+xoffset - core.bigmap.offsetX, bottom); - } - canvas.lineTo(left, bottom); - canvas.closePath(); - canvas.fill(); - canvas.stroke(); - core.setAlpha('ui', 1); - } - // 名称 - core.setTextAlign('ui', 'left'); - - var content_top = top + 15 + textfont; - if (core.isset(id)) { - - content_top += (titlefont + 5); - core.setFillStyle('ui', titleColor); - core.setStrokeStyle('ui', titleColor); - - if (id == 'hero') { - var heroHeight=core.material.icons.hero.height; - core.setAlpha('ui', alpha); - core.strokeRect('ui', left + 15 - 1, top + 40 - 1, 34, heroHeight+2, null, 2); - core.setAlpha('ui', 1); - core.fillText('ui', name, content_left, top + 8 + titlefont, null, 'bold '+titlefont+'px '+globalFont); - core.clearMap('ui', left + 15, top + 40, 32, heroHeight); - core.fillRect('ui', left + 15, top + 40, 32, heroHeight, core.material.groundPattern); - var heroIcon = core.material.icons.hero['down']; - core.drawImage('ui', core.material.images.hero, heroIcon.stop * 32, heroIcon.loc * heroHeight, 32, heroHeight, left+15, top+40, 32, heroHeight); - } - else { - core.fillText('ui', name, content_left, top + 8 + titlefont, null, 'bold '+titlefont+'px '+globalFont); - if (core.isset(icon)) { - core.setAlpha('ui', alpha); - core.strokeRect('ui', left + 15 - 1, top + 40-1, 34, iconHeight + 2, null, 2); - core.setAlpha('ui', 1); - core.status.boxAnimateObjs = []; - core.status.boxAnimateObjs.push({ - 'bgx': left + 15, 'bgy': top + 40, 'bgWidth': 32, 'bgHeight': iconHeight, - 'x': left+15, 'y': top+40, 'height': iconHeight, 'animate': animate, - 'image': image, - 'pos': icon*iconHeight - }); - core.drawBoxAnimate(); + var yoffset = 16; + var top = parseInt((this.PIXEL - height) / 2); + switch (posInfo.position) { + case 'center': top = parseInt((this.PIXEL - height) / 2); break; + case 'up': + if (posInfo.px==null || posInfo.py==null) + top = 5 + textAttribute.offset; + else + top = 32 * posInfo.py - height - (titleInfo.height - 32) - yoffset - core.bigmap.offsetY; + break; + case 'down': + if (posInfo.px==null || posInfo.py==null) + top = this.PIXEL - height - 5 - textAttribute.offset; + else { + top = 32 * posInfo.py + 32 + yoffset - core.bigmap.offsetY; } + } + + return { top: top, height: height, bottom: top + height, yoffset: yoffset, lineHeight: lineHeight }; +} + +ui.prototype._drawTextBox_drawBackground = function (titleInfo, posInfo, hPos, vPos) { + var background = core.status.textAttribute.background; + var px = posInfo.px == null ? null : posInfo.px * 32 - core.bigmap.offsetX; + var py = posInfo.py == null ? null : posInfo.py * 32 - core.bigmap.offsetY; + var xoffset = hPos.xoffset, yoffset = vPos.yoffset - 4; + var left = hPos.left, right = hPos.right, top = vPos.top, bottom = vPos.bottom; + + 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', 0.85); + this.drawWindowSkin(image, 'ui', left, top, right - left, bottom - top, posInfo.position, px, py); + core.setAlpha('ui', 1); + return true; + } + background = core.initStatus.textAttribute.background; + } + + var alpha = background[3]; + core.setAlpha('ui', alpha); + core.setStrokeStyle('ui', core.status.globalAttribute.borderColor); + core.setFillStyle('ui', core.arrayToRGB(background)); + core.setLineWidth('ui', 2); + + // 绘制 + var ctx = core.canvas.ui; + ctx.beginPath(); + ctx.moveTo(left, top); + // 上边缘三角 + if (posInfo.position == 'down' && px != null && py != null) { + ctx.lineTo(px + xoffset, top); + ctx.lineTo(px + 16, top - yoffset); + ctx.lineTo(px + 32 - xoffset, top); + } + ctx.lineTo(right, top); + ctx.lineTo(right, bottom); + // 下边缘三角 + if (posInfo.position == 'up' && px != null && py != null) { + ctx.lineTo(px + 32 - xoffset, bottom); + ctx.lineTo(px + 16, bottom + yoffset); + ctx.lineTo(px + xoffset, bottom); + } + ctx.lineTo(left, bottom); + ctx.closePath(); + ctx.fill(); + ctx.stroke(); + core.setAlpha('ui', 1); + return false; +} + +ui.prototype._drawTextBox_drawTitleAndIcon = function (titleInfo, hPos, vPos, alpha) { + core.setTextAlign('ui', 'left'); + var textAttribute = core.status.textAttribute; + var content_top = vPos.top + 15; + if (titleInfo.title != null) { + var titlefont = textAttribute.titlefont; + content_top += titlefont + 5; + core.setFillStyle('ui', core.arrayToRGB(textAttribute.title)); + core.setStrokeStyle('ui', core.arrayToRGB(textAttribute.title)); + + // --- title也要居中或者右对齐? + var title_width = core.calWidth('ui', titleInfo.title, 'bold '+titlefont+'px '+core.status.globalAttribute.font); + 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); + + if (titleInfo.icon != null) { + core.setAlpha('ui', alpha); + core.strokeRect('ui', hPos.left + 15 - 1, vPos.top + 40-1, 34, titleInfo.height + 2, null, 2); + core.setAlpha('ui', 1); + core.status.boxAnimateObjs = []; + core.status.boxAnimateObjs.push({ + 'bgx': hPos.left + 15, 'bgy': vPos.top + 40, 'bgWidth': 32, 'bgHeight': titleInfo.height, + 'x': hPos.left + 15, 'y': vPos.top + 40, 'height': titleInfo.height, 'animate': titleInfo.animate, + 'image': titleInfo.image, 'pos': titleInfo.icon * titleInfo.height + }); + core.drawBoxAnimate(); } } - if (core.isset(image) && !core.isset(icon)) { - core.drawImage('ui', image, 0, 0, image.width, image.height, left+10, top+10, 70, 70); + if (titleInfo.image != null && titleInfo.icon == null) { // 头像图 + core.drawImage('ui', titleInfo.image, 0, 0, titleInfo.image.width, titleInfo.image.height, + hPos.left+10, vPos.top+10, 70, 70); } + return content_top; +} - core.setFont('ui', font); - - this.__drawText('ui', content, content_left, content_top, validWidth, textColor, textfont + 5, textfont, - (showAll || textAttribute.time<=0 || core.status.event.id!='action')?0:textAttribute.time); - +ui.prototype._createTextCanvas = function (content, lineHeight) { + var realContent = this._getRealContent(content); + var lines = core.splitLines('ui', realContent, null, this._buildFont()); + var width = this.PIXEL, height = lines.length * lineHeight; + var ctx = document.createElement('canvas').getContext('2d'); + ctx.canvas.width = width; + ctx.canvas.height = height; + ctx.clearRect(0, 0, width, height); } ////// 绘制滚动字幕 ////// ui.prototype.drawScrollText = function (content, time, callback) { - - content = content || ""; + content = core.replaceText(content || ""); time = time || 5000; - clearInterval(core.status.event.interval); core.status.event.interval = null; + var offset = core.status.textAttribute.offset || 15; + var lineHeight = core.status.textAttribute.textfont * 1.4; + var ctx = this._createTextCanvas(content, lineHeight); + var obj = { align: core.status.textAttribute.align, lineHeight: lineHeight }; + if (obj.align == 'right') obj.left = this.PIXEL - offset; + else if (obj.align != 'center') obj.left = offset; + this.drawTextContent(ctx, content, obj); + this._drawScrollText_animate(ctx, height, time, callback); +} - // 获得颜色的盒子等信息 - var textAttribute = core.status.textAttribute || core.initStatus.textAttribute; - var textfont = textAttribute.textfont || 16; - var offset = textAttribute.offset || 15; - var textColor = core.arrayToRGBA(textAttribute.text); - - var font = textfont+"px "+core.status.globalAttribute.font; - if (textAttribute.bold) font = "bold "+font; - var realContent = content.replace(/(\r|\\r)(\[.*?])?/g, "").replace(/(\\i)(\[.*?])?/g, "啊1"); - var contents = core.splitLines('ui', realContent), lines = contents.length; - - // 计算总高度,按1.4倍行距计算 - var width = 416, height = textfont * 1.4 * lines; - var tempCanvas = core.bigmap.tempCanvas; - tempCanvas.canvas.width = width; - tempCanvas.canvas.height = height; - tempCanvas.clearRect(0, 0, width, height); - tempCanvas.font = font; - - this.__drawText(tempCanvas, content, offset, textfont, null, textColor, 1.4*textfont, textfont, 0); - +ui.prototype._drawScrollText_animate = function (ctx, height, time, callback) { // 开始绘制到UI上 core.clearMap('ui'); var per_pixel = 1, per_time = time * per_pixel / (416+height); var currH = 416; - core.drawImage('ui', tempCanvas.canvas, 0, currH); + core.drawImage('ui', ctx.canvas, 0, currH); var animate = setInterval(function () { core.clearMap('ui'); currH -= per_pixel; @@ -1039,197 +906,139 @@ ui.prototype.drawScrollText = function (content, time, callback) { if (core.isset(callback)) callback(); return; } - core.drawImage('ui', tempCanvas.canvas, 0, currH); + core.drawImage('ui', ctx.canvas, 0, currH); }, per_time); core.animateFrame.asyncId[animate] = true; } +////// 文本图片化 ////// +ui.prototype.textImage = function (content) { + content = core.replaceText(content || ""); + var lineHeight = core.status.textAttribute.textfont * 1.4; + var ctx = this._createTextCanvas(content, lineHeight); + this.drawTextContent(ctx, content, { align: core.status.textAttribute.align, lineHeight: lineHeight }); + return ctx.canvas; +} + ////// 绘制一个选项界面 ////// ui.prototype.drawChoices = function(content, choices) { choices = core.clone(choices || []); - var background = core.status.textAttribute.background; - var isWindowSkin = false; - if (typeof background == 'string') { - background = core.material.images.images[background]; - if (core.isset(background) && background.width==192 && background.height==128) isWindowSkin = true; - else background = core.initStatus.textAttribute.background; - } - if (!isWindowSkin) background = core.arrayToRGBA(background); - var borderColor = core.status.globalAttribute.borderColor; - var textColor = core.arrayToRGBA(core.status.textAttribute.text); - var titleColor = core.arrayToRGBA(core.status.textAttribute.title); - core.status.event.ui = {"text": content, "choices": choices}; + clearInterval(core.status.event.interval); + core.status.event.interval = null; + core.status.boxAnimateObjs = []; + core.clearSelector(); + core.clearMap('ui'); - // Step 1: 计算长宽高 - var length = choices.length; + content = core.replaceText(content || ""); + var titleInfo = this._getTitleAndIcon(content); + var hPos = this._drawChoices_getHorizontalPosition(titleInfo, choices); + var vPos = this._drawChoices_getVerticalPosition(titleInfo, choices, hPos); + var isWindowSkin = this._drawTextBox_drawBackground(titleInfo, {}, hPos, vPos); + this._drawChoices_drawTitle(titleInfo, hPos, vPos); + this._drawChoices_drawChoices(choices, isWindowSkin, hPos, vPos); +} + +ui.prototype._drawChoices_getHorizontalPosition = function (titleInfo, choices) { // 宽度计算:考虑选项的长度 - var width = 416 - 2*85; - var globalFont = core.status.globalAttribute.font; - core.setFont('ui', "bold 17px "+globalFont); + var width = this.PIXEL - 2 * 85; + core.setFont('ui', "bold 17px "+core.status.globalAttribute.font); 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)); - if (core.isset(choices[i].icon)) choices[i].width += 28; + if (choices[i].icon != null) choices[i].width += 28; width = Math.max(width, choices[i].width+30); } + var left = (this.PIXEL - width) / 2, right = left + width; + var content_left = left + (titleInfo.icon == null ? 15: 60), validWidth = right - content_left - 10; - var left=parseInt((416 - width) / 2); // 左边界 - // 高度 - var height = 32*(length+2), bottom = 208+height/2; - if (length%2==0) bottom+=16; - var choice_top = bottom-height+56; + return { left: left, right: right, width: width, content_left: content_left, validWidth: validWidth }; +} - var id=null, name=null, image=null, icon=null, iconHeight=32, animate=null; - - var contents = null; - var content_left = left + 15; - var validWidth = width-(content_left-left)-10; - - if (core.isset(content)) { - // 获得name, image, icon - var info = this.getTitleAndIcon(content); - content = core.replaceText(info.content); - var realContent = content.replace(/(\r|\\r)(\[.*?])?/g, "").replace(/(\\i)(\[.*?])?/g, "啊1"); - id=info.id; name=info.name; image=info.image; - icon=info.icon; iconHeight=info.iconHeight; animate=info.animate; - if (id=='hero' || core.isset(icon)) - content_left = left+60; - validWidth = width-(content_left-left)-10 - contents = core.splitLines('ui', realContent, validWidth, 'bold 15px '+globalFont); - - // content部分高度 - var cheight=0; - // 如果含有标题,标题高度 - if (name!=null) cheight+=25; - cheight += contents.length*20; - height+=cheight; +ui.prototype._drawChoices_getVerticalPosition = function (titleInfo, choices, hPos) { + var length = choices.length; + var height = 32 * (length + 2), bottom = this.HPIXEL + height / 2; + if (length % 2 == 0) bottom += 16; + var choice_top = bottom - height + 56; + if (titleInfo.content) { + var realContent = this._getRealContent(titleInfo.content); + var lines = core.splitLines('ui', realContent, hPos.validWidth, this._buildFont(15, true)); + if (titleInfo.title) height += 25; + height += lines.length * 20; } - var top = bottom-height; + return {top: bottom - height, height: height, bottom: bottom, choice_top: choice_top }; +} - core.clearMap('ui'); - if (isWindowSkin) { - core.setAlpha('ui', 0.85); - this.drawWindowSkin(background,'ui',left,top,width,height); - } - else { - core.fillRect('ui', left, top, width, height, background); - core.strokeRect('ui', left - 1, top - 1, width + 1, height + 1, borderColor, 2); - } - core.setAlpha('ui', 1); +ui.prototype._drawChoices_drawTitle = function (titleInfo, hPos, vPos) { + if (!titleInfo.content) return; + var content_top = vPos.top + 21; + if (titleInfo.title != null) { + core.setTextAlign('ui', 'center'); - // 如果有内容 - if (core.isset(contents)) { + content_top = vPos.top + 41; + var title_offset = hPos.left+hPos.width/2; + // 动画 - var content_top = top + 35; + 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.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 + }); + core.drawBoxAnimate(); + }; - if (core.isset(id)) { - core.setTextAlign('ui', 'center'); - - content_top = top+55; - var title_offset = left+width/2; - // 动画 - - if (id=='hero' || core.isset(icon)) - title_offset += 12; - - if (id == 'hero') { - var heroHeight = core.material.icons.hero.height; - core.strokeRect('ui', left + 15 - 1, top + 30 - 1, 34, heroHeight+2, '#DDDDDD', 2); - core.fillText('ui', name, title_offset, top + 27, titleColor, 'bold 19px '+globalFont); - core.clearMap('ui', left + 15, top + 30, 32, heroHeight); - core.fillRect('ui', left + 15, top + 30, 32, heroHeight, core.material.groundPattern); - var heroIcon = core.material.icons.hero['down']; - core.drawImage('ui', core.material.images.hero, heroIcon.stop * 32, heroIcon.loc *heroHeight, 32, heroHeight, left+15, top+30, 32, heroHeight); - } - else { - core.fillText('ui', name, title_offset, top + 27, titleColor, 'bold 19px '+globalFont); - if (core.isset(icon)) { - core.strokeRect('ui', left + 15 - 1, top + 30 - 1, 34, iconHeight + 2, '#DDDDDD', 2); - core.status.boxAnimateObjs = []; - core.status.boxAnimateObjs.push({ - 'bgx': left + 15, 'bgy': top + 30, 'bgWidth': 32, 'bgHeight': iconHeight, - 'x': left+15, 'y': top+30, 'height': iconHeight, 'animate': animate, - 'image': image, - 'pos': icon*iconHeight - }); - core.drawBoxAnimate(); - } - } - } - - core.setFont('ui', 'bold 15px '+globalFont); - this.__drawText('ui', content, content_left, content_top, validWidth, textColor, 20, 15, 0); + core.fillText('ui', titleInfo.title, title_offset, vPos.top + 27, + core.arrayToRGBA(core.status.textAttribute.title), 'bold 19px '+core.status.globalAttribute.font); } + core.setTextAlign('ui', 'left'); + this.drawTextContent('ui', 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) { // 选项 core.setTextAlign('ui', 'center'); + core.setFont('ui', "bold 17px " + core.status.globalAttribute.font); for (var i = 0; i < choices.length; i++) { - var color = choices[i].color || textColor; + var color = choices[i].color || core.status.textAttribute.text; if (color instanceof Array) color = core.arrayToRGBA(color); core.setFillStyle('ui', color); - var offset = 208; + var offset = this.HPIXEL; if (core.isset(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, - 208 - choices[i].width/2, choice_top + 32*i - 17, 22, 22); + core.drawImage('ui', 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, choice_top + 32 * i, null, "bold 17px "+globalFont); + core.fillText('ui', choices[i].text, offset, vPos.choice_top + 32 * i, color); } if (choices.length>0) { - if (!core.isset(core.status.event.selection)) core.status.event.selection=0; - 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; + core.status.event.selection = core.status.event.selection || 0; + 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(background, 208-len/2-5, choice_top + 32 * core.status.event.selection - 20, len+10, 28); + this.drawWindowSelector(core.material.images.images[core.status.textAttribute.background], + this.HPIXEL - len/2 - 5, vPos.choice_top + 32 * core.status.event.selection - 20, len + 10, 28); else - core.strokeRect('ui', 208-len/2-5, choice_top + 32 * core.status.event.selection - 20, len+10, 28, "#FFD700", 2); + core.strokeRect('ui', this.HPIXEL - len/2 - 5, vPos.choice_top + 32 * core.status.event.selection - 20, + len+10, 28, "#FFD700", 2); } - return; -} - -////// 文本图片化 ////// -ui.prototype.textImage = function (content) { - content = content || ""; - - // 获得颜色的盒子等信息 - var textAttribute = core.status.textAttribute || core.initStatus.textAttribute; - var textfont = textAttribute.textfont || 16; - var offset = textAttribute.offset || 15; - var textColor = core.arrayToRGBA(textAttribute.text); - - var font = textfont+"px "+core.status.globalAttribute.font; - if (textAttribute.bold) font = "bold "+font; - var contents = core.splitLines('ui', content), lines = contents.length; - - // 计算总高度,按1.4倍行距计算 - var width = 416, height = textfont * 1.4 * lines; - var tempCanvas = core.bigmap.tempCanvas; - tempCanvas.canvas.width = width; - tempCanvas.canvas.height = height; - tempCanvas.clearRect(0, 0, width, height); - tempCanvas.font = font; - tempCanvas.fillStyle = textColor; - - // 全部绘制 - var currH = textfont; - for (var i = 0; i < lines; ++i) { - var text = contents[i]; - tempCanvas.fillText(text, offset, currH); - currH += 1.4 * textfont; - } - - return tempCanvas.canvas; } ////// 绘制一个确认/取消的警告页面 ////// diff --git a/styles.css b/styles.css index 34bed2c4..a1d6649e 100644 --- a/styles.css +++ b/styles.css @@ -312,7 +312,7 @@ p#name { } #ui { - z-index: 160; + z-index: 140; } #data { From 38c8b81f480d737f75158a494c93bab178aea95f Mon Sep 17 00:00:00 2001 From: oc Date: Sun, 24 Mar 2019 16:45:48 +0800 Subject: [PATCH 02/33] actions choices HSIZE --- libs/actions.js | 246 ++++++++++++++++++++++++------------------------ libs/control.js | 2 + libs/ui.js | 2 +- 3 files changed, 128 insertions(+), 122 deletions(-) diff --git a/libs/actions.js b/libs/actions.js index 5bf8c43a..37f39db2 100644 --- a/libs/actions.js +++ b/libs/actions.js @@ -7,6 +7,11 @@ actions.js:用户交互的事件的处理 function actions() { this._init(); + this.SIZE = core.__SIZE__; + this.HSIZE = core.__HALF_SIZE__; + this.LAST = this.SIZE - 1; + this.CHOICES_LEFT = 5; // choices + this.CHOICES_RIGHT = this.LAST - this.CHOICES_LEFT; } actions.prototype._init = function () { @@ -109,7 +114,7 @@ actions.prototype.checkReplaying = function () { ////// 检查是否在录像播放中,如果是,则停止交互 actions.prototype._sys_checkReplay = function () { - if (core.actions.checkReplaying()) return true; + if (this.checkReplaying()) return true; } ////// 按下某个键时 ////// @@ -127,10 +132,10 @@ actions.prototype._sys_onkeyDown = function (e) { } } core.status.holdingKeys.push(e.keyCode); - core.actions.pressKey(e.keyCode); + this.pressKey(e.keyCode); } else { if (e.keyCode == 17) core.status.ctrlDown = true; - core.actions.keyDown(e.keyCode); + this.keyDown(e.keyCode); } } @@ -140,7 +145,7 @@ actions.prototype.onkeyUp = function (e) { } actions.prototype._sys_onkeyUp_replay = function (e) { - if (core.actions.checkReplaying()) { + if (this.checkReplaying()) { if (e.keyCode == 27) // ESCAPE core.stopReplay(); else if (e.keyCode == 90) // Z @@ -179,10 +184,10 @@ actions.prototype._sys_onkeyUp = function (e) { break; } } - core.actions.keyUp(e.keyCode, e.altKey); + this.keyUp(e.keyCode, e.altKey); } else { if (e.keyCode == 17) core.status.ctrlDown = false; - core.actions.keyUp(e.keyCode, e.altKey); + this.keyUp(e.keyCode, e.altKey); } } @@ -209,32 +214,32 @@ actions.prototype._sys_keyDown_lockControl = function (keyCode) { if (!core.status.lockControl) return false; // Ctrl跳过对话 if (keyCode == 17) { - core.actions.keyDownCtrl(); + this.keyDownCtrl(); return true; } switch (core.status.event.id) { case 'action': - core.actions._keyDownAction(keyCode); + this._keyDownAction(keyCode); break; case 'book': - core.actions._keyDownBook(keyCode); + this._keyDownBook(keyCode); break; case 'fly': - core.actions._keyDownFly(keyCode); + this._keyDownFly(keyCode); break; case 'viewMaps': - core.actions._keyDownViewMaps(keyCode); + this._keyDownViewMaps(keyCode); break; case 'equipbox': - core.actions._keyDownEquipbox(keyCode); + this._keyDownEquipbox(keyCode); break; case 'toolbox': - core.actions._keyDownToolbox(keyCode); + this._keyDownToolbox(keyCode); break; case 'save': case 'load': case 'replayLoad': - core.actions._keyDownSL(keyCode); + this._keyDownSL(keyCode); break; case 'shop': case 'selectShop': @@ -246,10 +251,10 @@ actions.prototype._sys_keyDown_lockControl = function (keyCode) { case 'storageRemove': case 'replay': case 'gameInfo': - core.actions._keyDownChoices(keyCode); + this._keyDownChoices(keyCode); break; case 'cursor': - core.actions._keyDownCursor(keyCode); + this._keyDownCursor(keyCode); break; } return true; @@ -271,7 +276,6 @@ actions.prototype._sys_keyDown = function (keyCode) { case 40: core.moveHero('down'); break; - break; } return true; } @@ -282,7 +286,7 @@ actions.prototype.keyUp = function (keyCode, altKey, fromReplay) { } actions.prototype._sys_keyUp_replay = function (keyCode, altKey, fromReplay) { - if (!fromReplay && core.actions.checkReplaying()) return true; + if (!fromReplay && this.checkReplaying()) return true; } actions.prototype._sys_keyUp_lockControl = function (keyCode, altKey) { @@ -298,81 +302,81 @@ actions.prototype._sys_keyUp_lockControl = function (keyCode, altKey) { ok() && core.drawText(); break; case 'confirmBox': - core.actions._keyUpConfirmBox(keyCode); + this._keyUpConfirmBox(keyCode); break; case 'action': - core.actions._keyUpAction(keyCode); + this._keyUpAction(keyCode); break; case 'about': - ok() && core.ui.closePanel(); + ok() && core.closePanel(); break; case 'help': - ok() && core.ui.closePanel(); + ok() && core.closePanel(); break; case 'book': - core.actions._keyUpBook(keyCode); + this._keyUpBook(keyCode); break; case 'book-detail': - ok() && core.actions._clickBookDetail(); + ok() && this._clickBookDetail(); break; case 'fly': this._keyUpFly(keyCode); break; case 'viewMaps': - core.actions._keyUpViewMaps(keyCode); + this._keyUpViewMaps(keyCode); break; case 'shop': - core.actions._keyUpShop(keyCode); + this._keyUpShop(keyCode); break; case 'selectShop': - core.actions._keyUpQuickShop(keyCode); + this._keyUpQuickShop(keyCode); break; case 'toolbox': - core.actions._keyUpToolbox(keyCode); + this._keyUpToolbox(keyCode); break; case 'equipbox': - core.actions._keyUpEquipbox(keyCode, altKey); + this._keyUpEquipbox(keyCode, altKey); break; case 'save': case 'load': case 'replayLoad': - core.actions._keyUpSL(keyCode); + this._keyUpSL(keyCode); break; case 'keyBoard': - ok() && core.ui.closePanel(); + ok() && core.closePanel(); break; case 'switchs': - core.actions._keyUpSwitchs(keyCode); + this._keyUpSwitchs(keyCode); break; case 'settings': - core.actions._keyUpSettings(keyCode); + this._keyUpSettings(keyCode); break; case 'syncSave': - core.actions._keyUpSyncSave(keyCode); + this._keyUpSyncSave(keyCode); break; case 'syncSelect': - core.actions._keyUpSyncSelect(keyCode); + this._keyUpSyncSelect(keyCode); break; case 'localSaveSelect': - core.actions._keyUpLocalSaveSelect(keyCode); + this._keyUpLocalSaveSelect(keyCode); break; case 'storageRemove': - core.actions._keyUpStorageRemove(keyCode); + this._keyUpStorageRemove(keyCode); break; case 'cursor': - core.actions._keyUpCursor(keyCode); + this._keyUpCursor(keyCode); break; case 'replay': - core.actions._keyUpReplay(keyCode); + this._keyUpReplay(keyCode); break; case 'gameInfo': - core.actions._keyUpGameInfo(keyCode); + this._keyUpGameInfo(keyCode); break; case 'centerFly': - core.actions._keyUpCenterFly(keyCode); + this._keyUpCenterFly(keyCode); break; case 'paint': - core.actions._keyUpPaint(keyCode); + this._keyUpPaint(keyCode); break; } return true; @@ -399,7 +403,7 @@ actions.prototype.ondown = function (loc) { actions.prototype._sys_ondown_paint = function (x, y, px, py) { // 画板 if (core.status.played && (core.status.event || {}).id == 'paint') { - core.actions._ondownPaint(px, py); + this._ondownPaint(px, py); return true; } } @@ -492,7 +496,7 @@ actions.prototype.onup = function () { actions.prototype._sys_onup_paint = function () { // 画板 if (core.status.played && (core.status.event || {}).id == 'paint') { - core.actions._onupPaint(); + this._onupPaint(); return true; } } @@ -567,75 +571,75 @@ actions.prototype._sys_onclick_lockControl = function (x, y) { if (!core.status.lockControl) return false; switch (core.status.event.id) { case 'centerFly': - core.actions._clickCenterFly(x, y); + this._clickCenterFly(x, y); break; case 'book': - core.actions._clickBook(x, y); + this._clickBook(x, y); break; case 'book-detail': - core.actions._clickBookDetail(x, y); + this._clickBookDetail(x, y); break; case 'fly': - core.actions._clickFly(x, y); + this._clickFly(x, y); break; case 'viewMaps': - core.actions._clickViewMaps(x, y); + this._clickViewMaps(x, y); break; case 'switchs': - core.actions._clickSwitchs(x, y); + this._clickSwitchs(x, y); break; case 'settings': - core.actions._clickSettings(x, y); + this._clickSettings(x, y); break; case 'shop': - core.actions._clickShop(x, y); + this._clickShop(x, y); break; case 'selectShop': - core.actions._clickQuickShop(x, y); + this._clickQuickShop(x, y); break; case 'equipbox': - core.actions._clickEquipbox(x, y); + this._clickEquipbox(x, y); break; case 'toolbox': - core.actions._clickToolbox(x, y); + this._clickToolbox(x, y); break; case 'save': case 'load': case 'replayLoad': - core.actions._clickSL(x, y); + this._clickSL(x, y); break; case 'confirmBox': - core.actions._clickConfirmBox(x, y); + this._clickConfirmBox(x, y); break; case 'keyBoard': - core.actions._clickKeyBoard(x, y); + this._clickKeyBoard(x, y); break; case 'action': - core.actions._clickAction(x, y); + this._clickAction(x, y); break; case 'text': core.drawText(); break; case 'syncSave': - core.actions._clickSyncSave(x, y); + this._clickSyncSave(x, y); break; case 'syncSelect': - core.actions._clickSyncSelect(x, y); + this._clickSyncSelect(x, y); break; case 'localSaveSelect': - core.actions._clickLocalSaveSelect(x, y); + this._clickLocalSaveSelect(x, y); break; case 'storageRemove': - core.actions._clickStorageRemove(x, y); + this._clickStorageRemove(x, y); break; case 'cursor': - core.actions._clickCursor(x, y); + this._clickCursor(x, y); break; case 'replay': - core.actions._clickReplay(x, y); + this._clickReplay(x, y); break; case 'gameInfo': - core.actions._clickGameInfo(x, y); + this._clickGameInfo(x, y); break; case 'about': case 'help': @@ -668,15 +672,15 @@ actions.prototype._sys_onmousewheel = function (direct) { // 楼层飞行器 if (core.status.lockControl && core.status.event.id == 'fly') { - if (direct == 1) core.ui.drawFly(core.actions._getNextFlyFloor(1)); - if (direct == -1) core.ui.drawFly(core.actions._getNextFlyFloor(-1)); + if (direct == 1) core.ui.drawFly(this._getNextFlyFloor(1)); + if (direct == -1) core.ui.drawFly(this._getNextFlyFloor(-1)); return; } // 怪物手册 if (core.status.lockControl && core.status.event.id == 'book') { - if (direct == 1) core.ui.drawBook(core.status.event.data - 6); - if (direct == -1) core.ui.drawBook(core.status.event.data + 6); + if (direct == 1) core.ui.drawBook(core.status.event.data - this.HSIZE); + if (direct == -1) core.ui.drawBook(core.status.event.data + this.HSIZE); return; } @@ -689,8 +693,8 @@ actions.prototype._sys_onmousewheel = function (direct) { // 浏览地图 if (core.status.lockControl && core.status.event.id == 'viewMaps') { - if (direct == 1) core.actions._clickViewMaps(6, 3); - if (direct == -1) core.actions._clickViewMaps(6, 9); + if (direct == 1) this._clickViewMaps(this.HSIZE, this.HSIZE - 3); + if (direct == -1) this._clickViewMaps(this.HSIZE, this.HSIZE + 3); return; } @@ -740,7 +744,7 @@ actions.prototype._sys_longClick_lockControl = function (x, y) { // 长按楼传器的箭头可以快速翻页 if (core.status.event.id == 'fly') { if ((x == 10 || x == 11) && (y == 5 || y == 9)) { - core.actions._clickFly(x, y); + this._clickFly(x, y); return true; } } @@ -772,14 +776,14 @@ actions.prototype._sys_longClick = function (x, y, fromEvent) { // 数字键快速选择选项 actions.prototype._selectChoices = function (length, keycode, callback) { - var topIndex = 6 - parseInt((length - 1) / 2); + var topIndex = this.HSIZE - parseInt((length - 1) / 2); if (keycode == 13 || keycode == 32 || keycode == 67) { - callback.apply(this, [6, topIndex + core.status.event.selection]); + callback.apply(this, [this.HSIZE, topIndex + core.status.event.selection]); } if (keycode >= 49 && keycode <= 57) { var index = keycode - 49; if (index < length) { - callback.apply(this, [6, topIndex + index]); + callback.apply(this, [this.HSIZE, topIndex + index]); } } } @@ -824,9 +828,9 @@ actions.prototype._keyUpCenterFly = function (keycode) { ////// 点击确认框时 ////// actions.prototype._clickConfirmBox = function (x, y) { - if ((x == 4 || x == 5) && y == 7 && core.status.event.data.yes) + if ((x == this.HSIZE-2 || x == this.HSIZE-1) && y == this.HSIZE+1 && core.status.event.data.yes) core.status.event.data.yes(); - if ((x == 7 || x == 8) && y == 7 && core.status.event.data.no) + if ((x == this.HSIZE+2 || x == this.HSIZE+1) && y == this.HSIZE+1 && core.status.event.data.no) core.status.event.data.no(); } @@ -877,8 +881,8 @@ actions.prototype._clickAction = function (x, y) { var data = core.status.event.data.current; var choices = data.choices; if (choices.length == 0) return; - if (x >= 5 && x <= 7) { - var topIndex = 6 - parseInt((choices.length - 1) / 2); + if (x >= this.CHOICES_LEFT && x <= this.CHOICES_RIGHT) { + var topIndex = this.HSIZE - parseInt((choices.length - 1) / 2); if (y >= topIndex && y < topIndex + choices.length) { // 选择 core.status.route.push("choices:" + (y - topIndex)); @@ -925,17 +929,17 @@ actions.prototype._keyUpAction = function (keycode) { ////// 怪物手册界面的点击操作 ////// actions.prototype._clickBook = function (x, y) { // 上一页 - if ((x == 3 || x == 4) && y == 12) { - core.ui.drawBook(core.status.event.data - 6); + if ((x == this.HSIZE-2 || x == this.HSIZE-3) && y == this.LAST) { + core.ui.drawBook(core.status.event.data - this.HSIZE); return; } // 下一页 - if ((x == 8 || x == 9) && y == 12) { - core.ui.drawBook(core.status.event.data + 6); + if ((x == this.HSIZE+2 || x == this.HSIZE+3) && y == this.LAST) { + core.ui.drawBook(core.status.event.data + this.HSIZE); return; } // 返回 - if (x >= 10 && x <= 12 && y == 12) { + if (x >= this.LAST-2 && y == this.LAST) { if (core.events.recoverEvents(core.status.event.interval)) { return; } @@ -948,9 +952,9 @@ actions.prototype._clickBook = function (x, y) { } // 怪物信息 var data = core.status.event.data; - if (data != null && y < 12) { - var page = parseInt(data / 6); - var index = 6 * page + parseInt(y / 2); + if (data != null && y < this.LAST) { + var page = parseInt(data / this.HSIZE); + var index = this.HSIZE * page + parseInt(y / 2); core.ui.drawBook(index); core.ui.drawBookDetail(index); } @@ -959,12 +963,12 @@ actions.prototype._clickBook = function (x, y) { ////// 怪物手册界面时,按下某个键的操作 ////// actions.prototype._keyDownBook = function (keycode) { - if (keycode == 37) core.ui.drawBook(core.status.event.data - 6); + if (keycode == 37) core.ui.drawBook(core.status.event.data - this.HSIZE); if (keycode == 38) core.ui.drawBook(core.status.event.data - 1); - if (keycode == 39) core.ui.drawBook(core.status.event.data + 6); + if (keycode == 39) core.ui.drawBook(core.status.event.data + this.HSIZE); if (keycode == 40) core.ui.drawBook(core.status.event.data + 1); - if (keycode == 33) core.ui.drawBook(core.status.event.data - 6); - if (keycode == 34) core.ui.drawBook(core.status.event.data + 6); + if (keycode == 33) core.ui.drawBook(core.status.event.data - this.HSIZE); + if (keycode == 34) core.ui.drawBook(core.status.event.data + this.HSIZE); return; } @@ -984,7 +988,7 @@ actions.prototype._keyUpBook = function (keycode) { if (keycode == 13 || keycode == 32 || keycode == 67) { var data = core.status.event.data; if (data != null) { - this._clickBook(6, 2 * (data % 6)); + this._clickBook(this.HSIZE, 2 * (data % this.HSIZE)); } return; } @@ -998,12 +1002,12 @@ actions.prototype._clickBookDetail = function () { ////// 楼层传送器界面时的点击操作 ////// actions.prototype._clickFly = function (x, y) { - if ((x == 10 || x == 11) && y == 9) core.ui.drawFly(this._getNextFlyFloor(-1)); - if ((x == 10 || x == 11) && y == 5) core.ui.drawFly(this._getNextFlyFloor(1)); - if ((x == 10 || x == 11) && y == 10) core.ui.drawFly(this._getNextFlyFloor(-10)); - if ((x == 10 || x == 11) && y == 4) core.ui.drawFly(this._getNextFlyFloor(10)); - if (x >= 5 && x <= 7 && y == 12) core.ui.closePanel(); - if (x >= 0 && x <= 9 && y >= 3 && y <= 11) + if ((x == this.SIZE-2 || x == this.SIZE-3) && y == this.HSIZE+3) core.ui.drawFly(this._getNextFlyFloor(-1)); + if ((x == this.SIZE-2 || x == this.SIZE-3) && y == this.HSIZE-1) core.ui.drawFly(this._getNextFlyFloor(1)); + if ((x == this.SIZE-2 || x == this.SIZE-3) && y == this.HSIZE+4) core.ui.drawFly(this._getNextFlyFloor(-10)); + if ((x == this.SIZE-2 || x == this.SIZE-3) && y == this.HSIZE-2) core.ui.drawFly(this._getNextFlyFloor(10)); + if (x >= this.HSIZE-1 && x <= this.HSIZE+1 && y == this.LAST) core.ui.closePanel(); + if (x >= 0 && x <= this.HSIZE+3 && y >= 3 && y <= this.LAST - 1) core.flyTo(core.floorIds[core.status.event.data]); return; } @@ -1041,7 +1045,7 @@ actions.prototype._keyUpFly = function (keycode) { if (keycode == 71 || keycode == 27 || keycode == 88) core.ui.closePanel(); if (keycode == 13 || keycode == 32 || keycode == 67) - this._clickFly(5, 5); + this._clickFly(this.HSIZE-1, this.HSIZE-1); return; } @@ -1167,8 +1171,8 @@ actions.prototype._keyUpViewMaps = function (keycode) { actions.prototype._clickShop = function (x, y) { var shop = core.status.event.data.shop; var choices = shop.choices; - if (x >= 5 && x <= 7) { - var topIndex = 6 - parseInt(choices.length / 2); + if (x >= this.CHOICES_LEFT && x <= this.CHOICES_RIGHT) { + var topIndex = this.HSIZE - parseInt(choices.length / 2); if (y >= topIndex && y < topIndex + choices.length) { return core.events._useShop(shop, y - topIndex); } @@ -1196,8 +1200,8 @@ actions.prototype._clickQuickShop = function (x, y) { var shopList = core.status.shops, keys = Object.keys(shopList).filter(function (shopId) { return shopList[shopId].visited || !shopList[shopId].mustEnable }); - if (x >= 5 && x <= 7) { - var topIndex = 6 - parseInt(keys.length / 2); + if (x >= this.CHOICES_LEFT && x <= this.CHOICES_RIGHT) { + var topIndex = this.HSIZE - parseInt(keys.length / 2); if (y >= topIndex && y < topIndex + keys.length) { var reason = core.events.canUseQuickShop(keys[y - topIndex]); if (!core.flags.enableDisabledShop && reason) { @@ -1749,9 +1753,9 @@ actions.prototype._keyUpSL = function (keycode) { ////// 系统设置界面时的点击操作 ////// actions.prototype._clickSwitchs = function (x, y) { - if (x < 5 || x > 7) return; + if (x < this.CHOICES_LEFT || x > this.CHOICES_RIGHT) return; var choices = core.status.event.ui.choices; - var topIndex = 6 - parseInt((choices.length - 1) / 2); + var topIndex = this.HSIZE - parseInt((choices.length - 1) / 2); if (y >= topIndex && y < topIndex + choices.length) { var selection = y - topIndex; core.status.event.selection = selection; @@ -1844,11 +1848,11 @@ actions.prototype._keyUpSwitchs = function (keycode) { this._selectChoices(core.status.event.ui.choices.length, keycode, this._clickSwitchs); } -////// 系统菜单栏界面时的点击事件 ////// +////// 系统菜单栏界面时的点击操作 ////// actions.prototype._clickSettings = function (x, y) { - if (x < 5 || x > 7) return; + if (x < this.CHOICES_LEFT || x > this.CHOICES_RIGHT) return; var choices = core.status.event.ui.choices; - var topIndex = 6 - parseInt((choices.length - 1) / 2); + var topIndex = this.HSIZE - parseInt((choices.length - 1) / 2); if (y >= topIndex && y < topIndex + choices.length) { var selection = y - topIndex; core.status.event.selection = selection; @@ -1897,9 +1901,9 @@ actions.prototype._keyUpSettings = function (keycode) { ////// 同步存档界面时的点击操作 ////// actions.prototype._clickSyncSave = function (x, y) { - if (x < 5 || x > 7) return; + if (x < this.CHOICES_LEFT || x > this.CHOICES_RIGHT) return; var choices = core.status.event.ui.choices; - var topIndex = 6 - parseInt((choices.length - 1) / 2); + var topIndex = this.HSIZE - parseInt((choices.length - 1) / 2); if (y >= topIndex && y < topIndex + choices.length) { var selection = y - topIndex; core.status.event.selection = selection; @@ -1979,10 +1983,10 @@ actions.prototype._keyUpSyncSave = function (keycode) { ////// 同步存档选择界面时的点击操作 ////// actions.prototype._clickSyncSelect = function (x, y) { - if (x < 5 || x > 7) return; + if (x < this.CHOICES_LEFT || x > this.CHOICES_RIGHT) return; var choices = core.status.event.ui.choices; - var topIndex = 6 - parseInt((choices.length - 1) / 2); + var topIndex = this.HSIZE - parseInt((choices.length - 1) / 2); if (y >= topIndex && y < topIndex + choices.length) { var selection = y - topIndex; core.status.event.selection = selection; @@ -2013,10 +2017,10 @@ actions.prototype._keyUpSyncSelect = function (keycode) { ////// 存档下载界面时的点击操作 ////// actions.prototype._clickLocalSaveSelect = function (x, y) { - if (x < 5 || x > 7) return; + if (x < this.CHOICES_LEFT || x > this.CHOICES_RIGHT) return; var choices = core.status.event.ui.choices; - var topIndex = 6 - parseInt((choices.length - 1) / 2); + var topIndex = this.HSIZE - parseInt((choices.length - 1) / 2); if (y >= topIndex && y < topIndex + choices.length) { var selection = y - topIndex; @@ -2051,10 +2055,10 @@ actions.prototype._keyUpLocalSaveSelect = function (keycode) { ////// 存档删除界面时的点击操作 ////// actions.prototype._clickStorageRemove = function (x, y) { - if (x < 5 || x > 7) return; + if (x < this.CHOICES_LEFT || x > this.CHOICES_RIGHT) return; var choices = core.status.event.ui.choices; - var topIndex = 6 - parseInt((choices.length - 1) / 2); + var topIndex = this.HSIZE - parseInt((choices.length - 1) / 2); if (y >= topIndex && y < topIndex + choices.length) { var selection = y - topIndex; @@ -2132,10 +2136,10 @@ actions.prototype._keyUpStorageRemove = function (keycode) { ////// 回放选择界面时的点击操作 ////// actions.prototype._clickReplay = function (x, y) { - if (x < 5 || x > 7) return; + if (x < this.CHOICES_LEFT || x > this.CHOICES_RIGHT) return; var choices = core.status.event.ui.choices; - var topIndex = 6 - parseInt((choices.length - 1) / 2); + var topIndex = this.HSIZE - parseInt((choices.length - 1) / 2); if (y >= topIndex && y < topIndex + choices.length) { var selection = y - topIndex; @@ -2186,10 +2190,10 @@ actions.prototype._keyUpReplay = function (keycode) { ////// 游戏信息界面时的点击操作 ////// actions.prototype._clickGameInfo = function (x, y) { - if (x < 5 || x > 7) return; + if (x < this.CHOICES_LEFT || x > this.CHOICES_RIGHT) return; var choices = core.status.event.ui.choices; - var topIndex = 6 - parseInt((choices.length - 1) / 2); + var topIndex = this.HSIZE - parseInt((choices.length - 1) / 2); if (y >= topIndex && y < topIndex + choices.length) { var selection = y - topIndex; diff --git a/libs/control.js b/libs/control.js index 3b4ddc2b..70f6ac48 100644 --- a/libs/control.js +++ b/libs/control.js @@ -625,6 +625,7 @@ control.prototype.moveAction = function (callback) { } control.prototype._moveAction_noPass = function (canMove, callback) { + core.status.route.push(core.getHeroLoc('direction')); core.status.automaticRoute.moveStepBeforeStop = []; core.status.automaticRoute.lastDirection = core.getHeroLoc('direction'); if (canMove) core.events._trigger(core.nextX(), core.nextY()); @@ -641,6 +642,7 @@ control.prototype._moveAction_moving = function (callback) { core.setHeroMoveInterval(function () { var direction = core.getHeroLoc('direction'); core.control._moveAction_popAutomaticRoute(); + core.status.route.push(direction); // 无事件的道具(如血瓶)需要优先于阻激夹域判定 var nowx = core.getHeroLoc('x'), nowy = core.getHeroLoc('y'); diff --git a/libs/ui.js b/libs/ui.js index 790ce132..72adee7c 100644 --- a/libs/ui.js +++ b/libs/ui.js @@ -944,7 +944,7 @@ ui.prototype.drawChoices = function(content, choices) { ui.prototype._drawChoices_getHorizontalPosition = function (titleInfo, choices) { // 宽度计算:考虑选项的长度 - var width = this.PIXEL - 2 * 85; + var width = 246; core.setFont('ui', "bold 17px "+core.status.globalAttribute.font); for (var i = 0; i < choices.length; i++) { if (typeof choices[i] === 'string') From 9813dc3115f49c87e89aa1794bdcc3efdfd1764e Mon Sep 17 00:00:00 2001 From: oc Date: Mon, 25 Mar 2019 00:29:18 +0800 Subject: [PATCH 03/33] lineHeight, showImage, splitImage --- _docs/event.md | 17 ++++++---- _server/MotaAction.g4 | 70 +++++++++++++++++++++++++++++---------- _server/editor_blockly.js | 1 + libs/events.js | 27 +++++++++------ libs/loader.js | 2 +- libs/ui.js | 19 ++++++----- libs/utils.js | 26 +++++++++------ 7 files changed, 108 insertions(+), 54 deletions(-) diff --git a/_docs/event.md b/_docs/event.md index 73961975..3beb965a 100644 --- a/_docs/event.md +++ b/_docs/event.md @@ -338,7 +338,7 @@ time为可选项,代表该自动文本的时间。可以不指定,不指定 ``` js "x,y": [ // 实际执行的事件列表 - {"type": "scrollText", "text": "第一排\n第二牌\n\n空行后的一排", "time": 5000, "async": true}, + {"type": "scrollText", "text": "第一排\n第二牌\n\n空行后的一排", "time": 5000, "lineHeight": 1.4, "async": true}, ] ``` @@ -346,6 +346,8 @@ text为正文文本内容。可以使用`${ }`来计算表达式的值,且使 time为可选项,代表总的滚动时间。默认为5000毫秒。 +lineHeight为可选项,代表行距。默认为1.4。 + async可选,如果为true则会异步执行(即不等待当前事件执行完毕,立刻执行下一个事件)。 可以使用下面的[设置剧情文本的属性](event#setText:设置剧情文本的属性)来对文字颜色、文字大小、粗体、距离左边的偏移量进行设置。 @@ -1059,9 +1061,10 @@ loc可忽略,如果忽略则显示为事件当前点。 ``` js "x,y": [ // 实际执行的事件列表 - {"type": "showImage", "code": 1, "image": "bg.jpg", "loc": [231,297], "dw": 100, "dy" : 100, "opacity": 1, "time" : 0}, // 在(231,297)显示bg.jpg - {"type": "showImage", "code": 12, "image": "1.png", "loc": [209,267], "dw": 100, "dy" : 100, "opacity": 0.5, "time" : 1000}, // 在(209,267)渐变显示1.png,渐变时间为1000毫秒,完成时不透明度为0.5,这张图片将遮盖上一张 - {"type": "showImage", "code": 8, "image": "hero.png", "loc": [349,367], "dw": 50, "dy" : 50, "opacity": 1, "time" : 500, "async": true}, // 在(209,267)渐变显示hero.png,大小为原图片的一半,渐变时间为500毫秒,异步执行;这张图片将被上一张遮盖 + {"type": "showImage", "code": 1, "image": "bg.jpg", "loc": [231,297], "opacity": 1, "time" : 0}, // 在(231,297)显示bg.jpg + {"type": "showImage", "code": 12, "image": "1.png", "loc": [209,267], "opacity": 0.5, "time" : 1000}, // 在(209,267)渐变显示1.png,渐变时间为1000毫秒,完成时不透明度为0.5,这张图片将遮盖上一张 + {"type": "showImage", "code": 8, "image": "hero.png", "loc": [349,367], "opacity": 1, "time" : 500, "async": true}, // 在(209,267)渐变显示hero.png,渐变时间为500毫秒,异步执行;这张图片将被上一张遮盖 + {"type": "showImage", "code": 10, "image": "hero.png", "sloc": [100,100,100,100], "loc": [0,0,100,100], "opacity": 1, "time": 0} // 截取原图的一部分绘制到画布上的一部分。 ] ``` @@ -1069,9 +1072,9 @@ code为图片编号,如果两张图片重叠,编号较大会覆盖编号较 image为图片名。**请确保图片在全塔属性中的images中被定义过。** -loc为图片左上角坐标,以像素为单位进行计算。 +sloc为可选项;如果设置了则是个2或4元组,代表裁剪原始图片的左上角像素位置和宽高。 -dw和dh为图片的横向、纵向放大率,默认值为100,即不进行缩放。 +loc为2或4元组,代表要绘制的画布上的左上角像素位置和宽高。 opacity为图片不透明度,在0~1之间,默认值为1,即不透明。 @@ -1097,6 +1100,8 @@ loc为图片左上角坐标,以像素为单位进行计算。 opacity为图片不透明度,在0~1之间,默认值为1,即不透明。 +lineHeight为可选项,代表行距。默认为1.4。 + time为渐变时间,默认值为0,即不渐变直接显示。 async可选,如果为true则会异步执行(即不等待当前事件执行完毕,立刻执行下一个事件)。 diff --git a/_server/MotaAction.g4 b/_server/MotaAction.g4 index 6cf3b5d3..1aa58715 100644 --- a/_server/MotaAction.g4 +++ b/_server/MotaAction.g4 @@ -268,6 +268,7 @@ action | animate_s | vibrate_s | showImage_s + | showImage_1_s | hideImage_s | showTextImage_s | moveImage_s @@ -380,27 +381,28 @@ return code; */; scrollText_s - : '滚动剧情文本:' '时间' Int '不等待执行完毕' Bool? BGNL? EvalString Newline + : '滚动剧情文本:' '时间' Int '行距' Number '不等待执行完毕' Bool? BGNL? EvalString Newline /* scrollText_s tooltip : scrollText:滚动剧情文本,将从下到上进行滚动显示。 helpUrl : https://h5mota.com/games/template/docs/#/event?id=scrollText%ef%bc%9a%e6%bb%9a%e5%8a%a8%e5%89%a7%e6%83%85%e6%96%87%e6%9c%ac -default : [5000,false,"时间是总时间,可以使用setText事件来控制字体、颜色、大小、偏移量等"] +default : [5000,1.4,false,"时间是总时间,可以使用setText事件来控制字体、颜色、大小、偏移量等"] Bool_0 = Bool_0?', "async": true':''; -var code = '{"type": "scrollText", "text": "'+EvalString_0+'"'+Bool_0+', "time" :'+Int_0+'},\n'; +var code = '{"type": "scrollText", "text": "'+EvalString_0+'"'+Bool_0+', "time" :'+Int_0+', "lineHeight": '+Number_0+'},\n'; return code; */; setText_s - : '设置剧情文本的属性' '位置' SetTextPosition_List '偏移像素' EvalString? BGNL? '标题颜色' EvalString? Colour '正文颜色' EvalString? Colour '背景色' EvalString? Colour BGNL? '粗体' B_1_List '标题字体大小' EvalString? '正文字体大小' EvalString? '打字间隔' EvalString? Newline + : '设置剧情文本的属性' '位置' SetTextPosition_List '偏移像素' EvalString? '对齐' SetTextAlign_List? BGNL? '标题颜色' EvalString? Colour '正文颜色' EvalString? Colour '背景色' EvalString? Colour BGNL? '粗体' B_1_List '标题字体大小' EvalString? '正文字体大小' EvalString? '打字间隔' EvalString? Newline /* setText_s tooltip : setText:设置剧情文本的属性,颜色为RGB三元组或RGBA四元组,打字间隔为剧情文字添加的时间间隔,为整数或不填 helpUrl : https://h5mota.com/games/template/docs/#/event?id=settext%EF%BC%9A%E8%AE%BE%E7%BD%AE%E5%89%A7%E6%83%85%E6%96%87%E6%9C%AC%E7%9A%84%E5%B1%9E%E6%80%A7 -default : [null,"","",'rgba(255,255,255,1)',"",'rgba(255,255,255,1)',"",'rgba(255,255,255,1)',null,"","",""] +default : [null,"",null,"",'rgba(255,255,255,1)',"",'rgba(255,255,255,1)',"",'rgba(255,255,255,1)',null,"","",""] SetTextPosition_List_0 =SetTextPosition_List_0==='null'?'': ', "position": "'+SetTextPosition_List_0+'"'; +SetTextAlign_List_0 =SetTextAlign_List_0==='null'?'': ', "align": "'+SetTextAlign_List_0+'"'; var colorRe = /^(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)?$/; if (EvalString_0) { if (!/^\d+$/.test(EvalString_0))throw new Error('像素偏移量必须是整数或不填'); @@ -438,7 +440,7 @@ if (EvalString_6) { EvalString_6 = ', "time": '+EvalString_6; } B_1_List_0 = B_1_List_0==='null'?'':', "bold": '+B_1_List_0; -var code = '{"type": "setText"'+SetTextPosition_List_0+EvalString_0+EvalString_1+EvalString_2+B_1_List_0+EvalString_3+EvalString_4+EvalString_5+EvalString_6+'},\n'; +var code = '{"type": "setText"'+SetTextPosition_List_0+EvalString_0+SetTextAlign_List_0+EvalString_1+EvalString_2+B_1_List_0+EvalString_3+EvalString_4+EvalString_5+EvalString_6+'},\n'; return code; */; @@ -1132,34 +1134,54 @@ return code; */; showImage_s - : '显示图片' '图片编号' Int '图片' EvalString '起点像素位置' 'x' PosString 'y' PosString BGNL? - '放大率 : x' Int '% y' Int '% 不透明度' Number '时间' Int '不等待执行完毕' Bool Newline + : '显示图片' '图片编号' Int '图片' EvalString BGNL? + '绘制的起点像素' 'x' PosString 'y' PosString '不透明度' Number '时间' Int '不等待执行完毕' Bool Newline /* showImage_s tooltip : showImage:显示图片 helpUrl : https://h5mota.com/games/template/docs/#/event?id=showImage%ef%bc%9a%e6%98%be%e7%a4%ba%e5%9b%be%e7%89%87 -default : [1,"bg.jpg","0","0",100,100,1,0,false] +default : [1,"bg.jpg","0","0",1,0,false] colour : this.printColor if(Int_0<=0 || Int_0>50) throw new Error('图片编号在1~50之间'); var async = Bool_0?', "async": true':''; -var code = '{"type": "showImage", "code": '+Int_0+', "image": "'+EvalString_0+'", "loc": ['+PosString_0+','+PosString_1+'], "dw": '+Int_1+', "dh": '+Int_2+', "opacity": '+Number_0+', "time": '+Int_3+async+'},\n'; +var code = '{"type": "showImage", "code": '+Int_0+', "image": "'+EvalString_0+'", "loc": ['+PosString_0+','+PosString_1+'], "opacity": '+Number_0+', "time": '+Int_1+async+'},\n'; +return code; +*/; + +showImage_1_s + : '显示图片' '图片编号' Int '图片' EvalString BGNL? + '裁剪的起点像素' 'x' PosString 'y' PosString '宽' PosString? '高' PosString? '不透明度' Number BGNL? + '绘制的起点像素' 'x' PosString 'y' PosString '宽' PosString? '高' PosString? '时间' Int '不等待执行完毕' Bool Newline + + +/* showImage_1_s +tooltip : showImage_1:显示图片 +helpUrl : https://h5mota.com/games/template/docs/#/event?id=showImage%ef%bc%9a%e6%98%be%e7%a4%ba%e5%9b%be%e7%89%87 +default : [1,"bg.jpg","0","0","","",1,"0","0","","",0,false] +colour : this.printColor +if(Int_0<=0 || Int_0>50) throw new Error('图片编号在1~50之间'); +var async = Bool_0?', "async": true':''; +var code = '{"type": "showImage", "code": '+Int_0+', "image": "'+EvalString_0+'", '+ + '"sloc": ['+PosString_0+','+PosString_1+','+PosString_2+','+PosString_3+'], '+ + '"loc": ['+PosString_4+','+PosString_5+','+PosString_6+','+PosString_7+'], '+ + '"opacity": '+Number_0+', "time": '+Int_1+async+'},\n'; return code; */; showTextImage_s : '显示图片化文本' '文本内容' EvalString BGNL? - '图片编号' Int '起点像素位置' 'x' PosString 'y' PosString '不透明度' Number '时间' Int '不等待执行完毕' Bool Newline + '图片编号' Int '起点像素' 'x' PosString 'y' PosString '行距' Number '不透明度' Number '时间' Int '不等待执行完毕' Bool Newline /* showTextImage_s tooltip : showTextImage:显示图片化文本 helpUrl : https://h5mota.com/games/template/docs/#/event?id=showTextImage%ef%bc%9a%e6%98%be%e7%a4%ba%e6%96%87%e6%9c%ac%e5%8c%96%e5%9b%be%e7%89%87 colour : this.printColor -default : ["可以使用setText事件来控制字体、颜色、大小、偏移量等",1,"0","0",1,0,false] +default : ["可以使用setText事件来控制字体、颜色、大小、偏移量等",1,"0","0",1.4,1,0,false] if(Int_0<=0 || Int_0>50) throw new Error('图片编号在1~50之间'); var async = Bool_0?', "async": true':''; -var code = '{"type": "showTextImage", "code": '+Int_0+', "text": "'+EvalString_0+'", "loc": ['+PosString_0+','+PosString_1+'], "opacity": '+Number_0+', "time": '+Int_1+async+'},\n'; +var code = '{"type": "showTextImage", "code": '+Int_0+', "text": "'+EvalString_0+'", "loc": ['+PosString_0+','+PosString_1+'], "lineHeight": '+Number_0+', "opacity": '+Number_1+', "time": '+Int_1+async+'},\n'; return code; */; @@ -1872,6 +1894,10 @@ SetTextPosition_List : '不改变'|'距离顶部'|'居中'|'距离底部' /*SetTextPosition_List ['null','up','center','down']*/; +SetTextAlign_List + : '不改变'|'左对齐'|'左右居中'|'右对齐' + /*SetTextAlign_List ['null','left','center','right']*/; + ShopUse_List : '金币' | '经验' /*ShopUse_List ['money','experience']*/; @@ -2151,7 +2177,7 @@ ActionParser.prototype.parseAction = function() { break; case "scrollText": this.next = MotaActionBlocks['scrollText_s'].xmlText([ - data.time, data.async||false, this.EvalString(data.text), this.next]); + data.time, data.lineHeight||1.4, data.async||false, this.EvalString(data.text), this.next]); break; case "comment": // 注释 this.next = MotaActionBlocks['comment_s'].xmlText([this.EvalString(data.text),this.next],null,data.text); @@ -2163,7 +2189,7 @@ ActionParser.prototype.parseAction = function() { if (!/^\w+\.png$/.test(data.background)) data.background=setTextfunc(data.background); this.next = MotaActionBlocks['setText_s'].xmlText([ - data.position,data.offset,data.title,'rgba('+data.title+')', + data.position,data.offset,data.align,data.title,'rgba('+data.title+')', data.text,'rgba('+data.text+')',data.background,'rgba('+data.background+')', data.bold,data.titlefont,data.textfont,data.time,this.next]); break; @@ -2308,8 +2334,16 @@ ActionParser.prototype.parseAction = function() { break; case "showImage": // 显示图片 data.loc=data.loc||['',''] - this.next = MotaActionBlocks['showImage_s'].xmlText([ - data.code,data.image||data.name,data.loc[0],data.loc[1],data.dw,data.dh,data.opacity,data.time||0,data.async||false,this.next]); + if (data.sloc) { + this.next = MotaActionBlocks['showImage_1_s'].xmlText([ + data.code,data.image||data.name,data.sloc[0],data.sloc[1],data.sloc[2],data.sloc[3],data.opacity, + data.loc[0],data.loc[1],data.loc[2],data.loc[3],data.time||0,data.async||false,this.next + ]); + } + else { + this.next = MotaActionBlocks['showImage_s'].xmlText([ + data.code,data.image||data.name,data.loc[0],data.loc[1],data.opacity,data.time||0,data.async||false,this.next]); + } break; case "hideImage": // 清除图片 this.next = MotaActionBlocks['hideImage_s'].xmlText([ @@ -2318,7 +2352,7 @@ ActionParser.prototype.parseAction = function() { case "showTextImage": // 显示图片化文本 data.loc=data.loc||['',''] this.next = MotaActionBlocks['showTextImage_s'].xmlText([ - this.EvalString(data.text),data.code,data.loc[0],data.loc[1],data.opacity,data.time||0,data.async||false,this.next]); + this.EvalString(data.text),data.code,data.loc[0],data.loc[1],data.lineHeight||1.4,data.opacity,data.time||0,data.async||false,this.next]); break; case "moveImage": // 移动图片 data.to=data.to||['',''] diff --git a/_server/editor_blockly.js b/_server/editor_blockly.js index 7fdf310f..9ebabaac 100644 --- a/_server/editor_blockly.js +++ b/_server/editor_blockly.js @@ -54,6 +54,7 @@ editor_blockly = function () { MotaActionBlocks['scrollText_s'].xmlText(), MotaActionBlocks['setText_s'].xmlText(), MotaActionBlocks['showImage_s'].xmlText(), + MotaActionBlocks['showImage_1_s'].xmlText(), MotaActionBlocks['hideImage_s'].xmlText(), MotaActionBlocks['showTextImage_s'].xmlText(), MotaActionBlocks['moveImage_s'].xmlText(), diff --git a/libs/events.js b/libs/events.js index 5aa7f0a4..e15598e3 100644 --- a/libs/events.js +++ b/libs/events.js @@ -885,7 +885,7 @@ events.prototype._action_autoText = function (data, x, y, prefix) { events.prototype._action_scrollText = function (data, x, y, prefix) { if (this.__action_checkReplaying()) return; - this.__action_doAsyncFunc(data.async, core.ui.drawScrollText, data.text, data.time || 5000); + this.__action_doAsyncFunc(data.async, core.ui.drawScrollText, data.text, data.lineHeight || 1.4, data.time || 5000); } events.prototype._action_comment = function (data, x, y, prefix) { @@ -893,7 +893,7 @@ events.prototype._action_comment = function (data, x, y, prefix) { } events.prototype._action_setText = function (data, x, y, prefix) { - ["position", "offset", "bold", "titlefont", "textfont", "time"].forEach(function (t) { + ["position", "offset", "align", "bold", "titlefont", "textfont", "time"].forEach(function (t) { if (data[t] != null) core.status.textAttribute[t] = data[t]; }); ["background", "title", "text"].forEach(function (t) { @@ -1030,10 +1030,9 @@ events.prototype._action_changePos = function (data, x, y, prefix) { } events.prototype._action_showImage = function (data, x, y, prefix) { - var loc = this.__action_getLoc(data.loc, 0, 0, prefix); if (core.isReplaying()) data.time = 0; this.__action_doAsyncFunc(data.async || data.time == 0, this.showImage, - data.code, data.image, loc[0], loc[1], data.dw, data.dh, data.opacity, data.time); + data.code, data.image, data.sloc, data.loc, data.opacity, data.time); } events.prototype._action_showTextImage = function (data, x, y, prefix) { @@ -1815,21 +1814,27 @@ events.prototype.closeDoor = function (x, y, id, callback) { } ////// 显示图片 ////// -events.prototype.showImage = function (code, image, x, y, dw, dh, opacityVal, time, callback) { - dw /= 100; - dh /= 100; - x = core.calValue(x) || 0; - y = core.calValue(y) || 0; +events.prototype.showImage = function (code, image, sloc, loc, opacityVal, time, callback) { if (typeof image == 'string') image = core.material.images.images[image]; if (!image) { if (callback) callback(); return; } + sloc = sloc || []; + var sx = core.calValue(sloc[0]) || 0, sy = core.calValue(sloc[1]) || 0; + var sw = core.calValue(sloc[2]), sh = core.calValue(sloc[3]); + if (sw == null) sw = image.width; + if (sh == null) sh = image.height; + loc = loc || []; + var x = core.calValue(loc[0]) || 0, y = core.calValue(loc[1]) || 0; + var w = core.calValue(loc[2]), h = core.calValue(loc[3]); + if (w == null) w = sw; + if (h == null) h = sh; var zIndex = code + 100; time = time || 0; var name = "image" + zIndex; - var ctx = core.createCanvas(name, x, y, image.width * dw, image.height * dh, zIndex); - ctx.drawImage(image, 0, 0, image.width * dw, image.height * dh); + var ctx = core.createCanvas(name, x, y, w, h, zIndex); + ctx.drawImage(image, sx, sy, sw, sh, 0, 0, w, h); if (time == 0) { core.setOpacity(name, opacityVal); if (callback) callback(); diff --git a/libs/loader.js b/libs/loader.js index 5613c33d..b2da0c6e 100644 --- a/libs/loader.js +++ b/libs/loader.js @@ -38,7 +38,7 @@ loader.prototype._load = function (callback) { loader.prototype._loadIcons = function () { this.loadImage("icons.png", function (id, image) { - var images = core.cropImage(image); + var images = core.splitImage(image); for (var key in core.statusBar.icons) { if (typeof core.statusBar.icons[key] == 'number') { core.statusBar.icons[key] = images[core.statusBar.icons[key]]; diff --git a/libs/ui.js b/libs/ui.js index 72adee7c..73ce42f8 100644 --- a/libs/ui.js +++ b/libs/ui.js @@ -873,29 +873,31 @@ ui.prototype._createTextCanvas = function (content, lineHeight) { ctx.canvas.width = width; ctx.canvas.height = height; ctx.clearRect(0, 0, width, height); + return ctx; } ////// 绘制滚动字幕 ////// -ui.prototype.drawScrollText = function (content, time, callback) { +ui.prototype.drawScrollText = function (content, time, lineHeight, callback) { content = core.replaceText(content || ""); + lineHeight = lineHeight || 1.4; time = time || 5000; clearInterval(core.status.event.interval); core.status.event.interval = null; var offset = core.status.textAttribute.offset || 15; - var lineHeight = core.status.textAttribute.textfont * 1.4; + lineHeight *= core.status.textAttribute.textfont; var ctx = this._createTextCanvas(content, lineHeight); var obj = { align: core.status.textAttribute.align, lineHeight: lineHeight }; if (obj.align == 'right') obj.left = this.PIXEL - offset; else if (obj.align != 'center') obj.left = offset; this.drawTextContent(ctx, content, obj); - this._drawScrollText_animate(ctx, height, time, callback); + this._drawScrollText_animate(ctx, time, callback); } -ui.prototype._drawScrollText_animate = function (ctx, height, time, callback) { +ui.prototype._drawScrollText_animate = function (ctx, time, callback) { // 开始绘制到UI上 core.clearMap('ui'); - var per_pixel = 1, per_time = time * per_pixel / (416+height); - var currH = 416; + var per_pixel = 1, height = ctx.canvas.height, per_time = time * per_pixel / (this.PIXEL+height); + var currH = this.PIXEL; core.drawImage('ui', ctx.canvas, 0, currH); var animate = setInterval(function () { core.clearMap('ui'); @@ -913,9 +915,10 @@ ui.prototype._drawScrollText_animate = function (ctx, height, time, callback) { } ////// 文本图片化 ////// -ui.prototype.textImage = function (content) { +ui.prototype.textImage = function (content, lineHeight) { content = core.replaceText(content || ""); - var lineHeight = core.status.textAttribute.textfont * 1.4; + lineHeight = lineHeight || 1.4; + lineHeight *= core.status.textAttribute.textfont; var ctx = this._createTextCanvas(content, lineHeight); this.drawTextContent(ctx, content, { align: core.status.textAttribute.align, lineHeight: lineHeight }); return ctx.canvas; diff --git a/libs/utils.js b/libs/utils.js index 4ebdffe9..1bca52b0 100644 --- a/libs/utils.js +++ b/libs/utils.js @@ -311,19 +311,25 @@ utils.prototype.clone = function (data) { } ////// 裁剪图片 ////// -utils.prototype.cropImage = function (image, size) { - size = size || 32; +utils.prototype.splitImage = function (image, width, height) { + if (typeof image == "string") + image = core.material.images.images[image]; + if (!image) return []; + width = width || 32; + height = height || width; var canvas = document.createElement("canvas"); var context = canvas.getContext("2d"); - canvas.width = size; - canvas.height = size; + canvas.width = width; + canvas.height = height; var ans = []; - for (var i = 0; i < image.height; i += size) { - context.drawImage(image, 0, i, size, size, 0, 0, size, size); - var img = new Image(); - img.src = canvas.toDataURL("image/png"); - ans.push(img); - context.clearRect(0, 0, size, size); + for (var j = 0; j < image.height; j += height) { + for (var i = 0; i < image.width; i += width) { + context.drawImage(image, i, j, width, height, 0, 0, width, height); + var img = new Image(); + img.src = canvas.toDataURL("image/png"); + ans.push(img); + context.clearRect(0, 0, width, height); + } } return ans; } From 798a751f2f18f673a5fc22f7373a459398ddc5d1 Mon Sep 17 00:00:00 2001 From: oc Date: Mon, 25 Mar 2019 11:04:17 +0800 Subject: [PATCH 04/33] Fix bigmap bug --- libs/maps.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/maps.js b/libs/maps.js index a457b23b..cb7dbb7b 100644 --- a/libs/maps.js +++ b/libs/maps.js @@ -412,7 +412,7 @@ maps.prototype._canMoveHero_checkPoint = function (x, y, direction, floorId, ext return false; var nx = x + core.utils.scan[direction].x, ny = y + core.utils.scan[direction].y; - if (nx < 0 || ny < 0 || nx >= core.floors[floorId].width || ny >= core.floors[floorId].width) + if (nx < 0 || ny < 0 || nx >= core.floors[floorId].width || ny >= core.floors[floorId].height) return false; // 2. 检查该点素材的 cannotOut 和下一个点的 cannotIn From 400d91f697d6e5a76a8367af74717533194b1f40 Mon Sep 17 00:00:00 2001 From: oc Date: Mon, 25 Mar 2019 23:03:07 +0800 Subject: [PATCH 05/33] drawConfirmBox, drawPagination --- libs/control.js | 4 +- libs/ui.js | 191 ++++++++++++++++-------------------------------- 2 files changed, 64 insertions(+), 131 deletions(-) diff --git a/libs/control.js b/libs/control.js index 70f6ac48..e3946a74 100644 --- a/libs/control.js +++ b/libs/control.js @@ -1610,11 +1610,11 @@ control.prototype.syncSave = function (type) { core.ui.drawWaiting("正在同步,请稍后..."); core.control.getSaves(type=='all'?null:core.saves.saveIndex, function (saves) { if (!saves) return core.drawText("没有要同步的存档"); - core.control._syncSave_http(saves); + core.control._syncSave_http(type, saves); }) } -control.prototype._syncSave_http = function (saves) { +control.prototype._syncSave_http = function (type, saves) { var formData = new FormData(); formData.append('type', 'save'); formData.append('name', core.firstData.name); diff --git a/libs/ui.js b/libs/ui.js index 73ce42f8..dba2f7b9 100644 --- a/libs/ui.js +++ b/libs/ui.js @@ -218,9 +218,7 @@ ui.prototype.drawImage = function (name, image, x, y, w, h, x1, y1, w1, h1) { ////// 结束一切事件和绘制,关闭UI窗口,返回游戏进程 ////// ui.prototype.closePanel = function () { - core.status.boxAnimateObjs = []; - clearInterval(core.status.event.interval); - core.clearSelector(); + this.clearUI(); core.maps.generateGroundPattern(); core.updateStatusBar(); core.unLockControl(); @@ -231,6 +229,15 @@ ui.prototype.closePanel = function () { core.status.event.interval = null; } +ui.prototype.clearUI = function () { + clearInterval(core.status.event.interval); + core.status.event.interval = null; + core.status.boxAnimateObjs = []; + core.clearSelector(); + core.clearMap('ui'); + core.setAlpha('ui', 1); +} + ////// 清除光标 ////// ui.prototype.clearSelector = function () { if (core.dymCanvas._selector) core.deleteCanvas("_selector"); @@ -390,6 +397,8 @@ ui.prototype._getPosition = function (content) { ////// 绘制选择光标 ui.prototype.drawWindowSelector = function(background, x, y, w, h) { + 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); @@ -671,11 +680,7 @@ ui.prototype.drawTextBox = function(content, showAll) { if (core.status.event && core.status.event.id == 'action') core.status.event.ui = content; - clearInterval(core.status.event.interval); - core.status.event.interval = null; - core.status.boxAnimateObjs = []; - core.clearSelector(); - core.clearMap('ui'); + this.clearUI(); content = core.replaceText(content); @@ -881,8 +886,7 @@ ui.prototype.drawScrollText = function (content, time, lineHeight, callback) { content = core.replaceText(content || ""); lineHeight = lineHeight || 1.4; time = time || 5000; - clearInterval(core.status.event.interval); - core.status.event.interval = null; + this.clearUI(); var offset = core.status.textAttribute.offset || 15; lineHeight *= core.status.textAttribute.textfont; var ctx = this._createTextCanvas(content, lineHeight); @@ -895,7 +899,6 @@ ui.prototype.drawScrollText = function (content, time, lineHeight, callback) { ui.prototype._drawScrollText_animate = function (ctx, time, callback) { // 开始绘制到UI上 - core.clearMap('ui'); var per_pixel = 1, height = ctx.canvas.height, per_time = time * per_pixel / (this.PIXEL+height); var currH = this.PIXEL; core.drawImage('ui', ctx.canvas, 0, currH); @@ -929,11 +932,7 @@ ui.prototype.drawChoices = function(content, choices) { choices = core.clone(choices || []); core.status.event.ui = {"text": content, "choices": choices}; - clearInterval(core.status.event.interval); - core.status.event.interval = null; - core.status.boxAnimateObjs = []; - core.clearSelector(); - core.clearMap('ui'); + this.clearUI(); content = core.replaceText(content || ""); var titleInfo = this._getTitleAndIcon(content); @@ -1047,75 +1046,49 @@ ui.prototype._drawChoices_drawChoices = function (choices, isWindowSkin, hPos, v ////// 绘制一个确认/取消的警告页面 ////// ui.prototype.drawConfirmBox = function (text, yesCallback, noCallback) { core.lockControl(); + text = core.replaceText(text || ""); core.status.event.id = 'confirmBox'; core.status.event.data = {'yes': yesCallback, 'no': noCallback}; core.status.event.ui = text; + if (core.status.event.selection != 0) core.status.event.selection = 1; + this.clearUI(); - if (!core.isset(core.status.event.selection) || core.status.event.selection>1) core.status.event.selection=1; - if (core.status.event.selection<0) core.status.event.selection=0; - - core.clearSelector(); - - var background = core.status.textAttribute.background; - var isWindowSkin = false; - if (typeof background == 'string') { - background = core.material.images.images[background]; - if (core.isset(background) && background.width==192 && background.height==128) isWindowSkin = true; - else background = core.initStatus.textAttribute.background; - } - if (!isWindowSkin) background = core.arrayToRGBA(background); - var borderColor = core.status.globalAttribute.borderColor; - var textColor = core.arrayToRGBA(core.status.textAttribute.text); - - var globalFont = core.status.globalAttribute.font; - core.setFont('ui', "bold 19px "+globalFont); - - var contents = text.split('\n'); - var lines = contents.length; - var max_length = 0; - for (var i in contents) { - max_length = Math.max(max_length, core.calWidth('ui', contents[i])); - } - - var left = Math.min(208 - 40 - parseInt(max_length / 2), 100); - var top = 140 - (lines-1)*30; - var right = 416 - left, bottom = 416 - 140, width = right - left, height = bottom - top; - - core.clearMap('ui'); - if (isWindowSkin) { - core.setAlpha('ui', 0.85); - this.drawWindowSkin(background,'ui',left,top,width,height); - } - else { - core.fillRect('ui', left, top, width, height, background); - core.strokeRect('ui', left - 1, top - 1, width + 1, height + 1, borderColor, 2); - } - core.setAlpha('ui', 1); + core.setFont('ui', this._buildFont(19, true)); + var contents = text.split("\n"); + var rect = this._drawConfirmBox_getRect(contents); + var isWindowSkin = this._drawTextBox_drawBackground({}, {}, rect, rect); core.setTextAlign('ui', 'center'); + core.setFillStyle('ui', core.arrayToRGBA(core.status.textAttribute.text)) for (var i in contents) { - core.fillText('ui', contents[i], 208, top + 50 + i*30, textColor); + core.fillText('ui', contents[i], this.HPIXEL, rect.top + 50 + i*30); } - core.fillText('ui', "确定", 208 - 38, bottom - 35, null, "bold 17px "+globalFont); - core.fillText('ui', "取消", 208 + 38, bottom - 35); - + core.fillText('ui', "确定", this.HPIXEL - 38, rect.bottom - 35, null, this._buildFont(17, true)); + core.fillText('ui', "取消", this.HPIXEL + 38, rect.bottom - 35); var len=core.calWidth('ui', "确定"); - - var strokeLeft = 208 + (76*core.status.event.selection-38) - parseInt(len/2) - 5; + var strokeLeft = this.HPIXEL + (76*core.status.event.selection-38) - parseInt(len/2) - 5; if (isWindowSkin) - this.drawWindowSelector(background, strokeLeft, bottom-35-20, len+10, 28); + this.drawWindowSelector(core.status.textAttribute.background, strokeLeft, rect.bottom-35-20, len+10, 28); else - core.strokeRect('ui', strokeLeft, bottom-35-20, len+10, 28, "#FFD700", 2); + core.strokeRect('ui', strokeLeft, rect.bottom-35-20, len+10, 28, "#FFD700", 2); } +ui.prototype._drawConfirmBox_getRect = function (contents) { + var max_width = contents.reduce(function (pre, curr) { + return Math.max(pre, core.calWidth('ui', curr)); + }, 0); + var left = Math.min(this.HPIXEL - 40 - parseInt(max_width / 2), 100), right = this.PIXEL - left; + var top = this.HPIXEL - 68 - (contents.length-1)*30, bottom = this.HPIXEL + 68; + return { top: top, left: left, bottom: bottom, right: right, width: right - left, height: bottom - top }; +} + ////// 绘制系统设置界面 ////// ui.prototype.drawSwitchs = function() { core.status.event.id = 'switchs'; - var choices = [ "背景音乐: "+(core.musicStatus.bgmStatus ? "[ON]" : "[OFF]"), "背景音效: "+(core.musicStatus.soundStatus ? "[ON]" : "[OFF]"), @@ -1133,7 +1106,6 @@ ui.prototype.drawSwitchs = function() { ////// 绘制系统菜单栏 ////// ui.prototype.drawSettings = function () { core.status.event.id = 'settings'; - this.drawChoices(null, [ "系统设置", "虚拟键盘", "浏览地图", "绘图模式", "同步存档", "游戏信息", "返回标题", "返回游戏" ]); @@ -1141,68 +1113,37 @@ ui.prototype.drawSettings = function () { ////// 绘制快捷商店选择栏 ////// ui.prototype.drawQuickShop = function () { - core.status.event.id = 'selectShop'; - - var shopList = core.status.shops, keys = Object.keys(shopList).filter(function (shopId) {return shopList[shopId].visited || !shopList[shopId].mustEnable}); + var shopList = core.status.shops, keys = Object.keys(shopList).filter(function (shopId) { + return shopList[shopId].visited || !shopList[shopId].mustEnable + }); var choices = keys.map(function (shopId) { return {"text": shopList[shopId].textInList, "color": shopList[shopId].visited?null:"#999999"}; }); - choices.push("返回游戏"); this.drawChoices(null, choices); } ////// 绘制等待界面 ////// ui.prototype.drawWaiting = function(text) { - core.lockControl(); core.status.event.id = 'waiting'; - core.clearSelector(); - - var background = core.status.textAttribute.background; - var isWindowSkin = false; - if (typeof background == 'string') { - background = core.material.images.images[background]; - if (core.isset(background) && background.width==192 && background.height==128) isWindowSkin = true; - else background = core.initStatus.textAttribute.background; - } - if (!isWindowSkin) background = core.arrayToRGBA(background); - var borderColor = core.status.globalAttribute.borderColor; - var textColor = core.arrayToRGBA(core.status.textAttribute.text); - - var globalFont = core.status.globalAttribute.font; - var text_length = core.calWidth('ui', text, "bold 19px "+globalFont); - - var right = Math.max(text_length+50, 220); - var left = 208-parseInt(right/2), top = 208 - 32 - 16, bottom = 416 - 2 * top; - - core.clearMap('ui'); - if (isWindowSkin) { - core.setAlpha('ui', 0.85); - this.drawWindowSkin(background,'ui',left,top,right,bottom); - } - else { - core.fillRect('ui', left, top, right, bottom, background); - core.strokeRect('ui', left - 1, top - 1, right + 1, bottom + 1, borderColor, 2); - } - core.setAlpha('ui', 1); - + text = core.replaceText(text || ""); + var text_length = core.calWidth('ui', text, this._buildFont(19, true)); + var width = Math.max(text_length + 80, 220), left = this.HPIXEL - parseInt(width / 2), right = left + width; + var top = this.HPIXEL - 48, height = 96, bottom = top + height; + this._drawTextBox_drawBackground({}, {}, {left: left, right: right}, {top: top, bottom: bottom}); core.setTextAlign('ui', 'center'); - core.fillText('ui', text, 208, top + 56, textColor); - + core.fillText('ui', text, 208, top + 56, core.arrayToRGBA(core.status.textAttribute.text)); } ////// 绘制存档同步界面 ////// ui.prototype.drawSyncSave = function () { - core.status.event.id = 'syncSave'; - this.drawChoices(null, [ "同步存档到服务器", "从服务器加载存档", "存档至本地文件", "从本地文件读档", "回放当前录像", "下载当前录像", "清空本地存档", "返回主菜单" ]); - } ////// 绘制存档同步选择页面 ////// @@ -1247,44 +1188,36 @@ ui.prototype.drawGameInfo = function () { ////// 绘制分页 ////// ui.prototype.drawPagination = function (page, totalPage, top) { // if (totalPage 1) - core.fillText('ui', '上一页', 208 - 80, top*32+19); + core.fillText('ui', '上一页', this.HPIXEL - 80, top*32+19); if (page < totalPage) - core.fillText('ui', '下一页', 208 + 80, top*32+19); + core.fillText('ui', '下一页', this.HPIXEL + 80, top*32+19); } ////// 绘制键盘光标 ////// ui.prototype.drawCursor = function () { - - if (!core.isset(core.status.automaticRoute.cursorX)) - core.status.automaticRoute.cursorX=core.getHeroLoc('x'); - if (core.status.automaticRoute.cursorX<0) core.status.automaticRoute.cursorX=0; - if (core.status.automaticRoute.cursorX>12) core.status.automaticRoute.cursorX=12; - if (!core.isset(core.status.automaticRoute.cursorY)) - core.status.automaticRoute.cursorY=core.getHeroLoc('y'); - if (core.status.automaticRoute.cursorY<0) core.status.automaticRoute.cursorY=0; - if (core.status.automaticRoute.cursorY>12) core.status.automaticRoute.cursorY=12; - + var automaticRoute = core.status.automaticRoute; + if (automaticRoute.cursorX == null) + automaticRoute.cursorX = core.getHeroLoc('x'); + if (automaticRoute.cursorY == null) + automaticRoute.cursorY = core.getHeroLoc('y'); + automaticRoute.cursorX = core.clamp(automaticRoute.cursorX, 0, this.LAST); core.status.event.id = 'cursor'; core.lockControl(); - - core.clearMap('ui'); - core.setAlpha('ui', 1); - + core.clearUI(); var width = 4; - core.strokeRect('ui', 32*core.status.automaticRoute.cursorX+width/2, 32*core.status.automaticRoute.cursorY+width/2, + core.strokeRect('ui', 32*automaticRoute.cursorX+width/2, 32*automaticRoute.cursorY+width/2, 32-width, 32-width, '#FFD700', width); } From 2cdac4930a6cbe05b7dd51e75d868d7acab854a1 Mon Sep 17 00:00:00 2001 From: oc Date: Mon, 25 Mar 2019 23:05:44 +0800 Subject: [PATCH 06/33] drawConfirmBox, drawPagination --- libs/ui.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/ui.js b/libs/ui.js index dba2f7b9..7473fd11 100644 --- a/libs/ui.js +++ b/libs/ui.js @@ -1135,7 +1135,7 @@ ui.prototype.drawWaiting = function(text) { var top = this.HPIXEL - 48, height = 96, bottom = top + height; this._drawTextBox_drawBackground({}, {}, {left: left, right: right}, {top: top, bottom: bottom}); core.setTextAlign('ui', 'center'); - core.fillText('ui', text, 208, top + 56, core.arrayToRGBA(core.status.textAttribute.text)); + core.fillText('ui', text, this.HPIXEL, top + 56, core.arrayToRGBA(core.status.textAttribute.text)); } ////// 绘制存档同步界面 ////// From f25a29574222bf180b3ec1509f4d2f88944a77ac Mon Sep 17 00:00:00 2001 From: oc Date: Mon, 25 Mar 2019 23:35:10 +0800 Subject: [PATCH 07/33] drawKeyboard --- libs/actions.js | 71 ++++++++++++++++--------------- libs/ui.js | 111 ++++++++++++++++++++---------------------------- 2 files changed, 81 insertions(+), 101 deletions(-) diff --git a/libs/actions.js b/libs/actions.js index 37f39db2..9b68d44f 100644 --- a/libs/actions.js +++ b/libs/actions.js @@ -2252,11 +2252,12 @@ actions.prototype._keyUpGameInfo = function (keycode) { ////// “虚拟键盘”界面时的点击操作 ////// actions.prototype._clickKeyBoard = function (x, y) { - if (y == 3 && x >= 1 && x <= 11) { + var m = this.HSIZE; + if (y == m - 3 && x >= m - 5 && x <= m + 5) { core.ui.closePanel(); - core.keyUp(112 + x - 1); // F1-F12: 112-122 + core.keyUp(112 + x + 5 - m); } - if (y == 3 && x == 12) { + if (y == m - 3 && x == m + 6) { var val = prompt(); if (val != null) { try { @@ -2266,9 +2267,9 @@ actions.prototype._clickKeyBoard = function (x, y) { } } } - if (y == 4 && x >= 1 && x <= 10) { + if (y == m - 2 && x >= m - 5 && x <= m + 4) { core.ui.closePanel(); - core.keyUp(x == 10 ? 48 : 48 + x); // 1-9: 49-57; 0: 48 + core.keyUp(x == m + 4 ? 48 : 49 + x + 5 - m); // 1-9: 49-57; 0: 48 } // 字母 var lines = [ @@ -2276,46 +2277,46 @@ actions.prototype._clickKeyBoard = function (x, y) { ["A", "S", "D", "F", "G", "H", "J", "K", "L"], ["Z", "X", "C", "V", "B", "N", "M"], ]; - if (y == 5 && x >= 1 && x <= 10) { + if (y == m - 1 && x >= m - 5 && x <= m + 4) { core.ui.closePanel(); - core.keyUp(lines[0][x - 1].charCodeAt(0)); + core.keyUp(lines[0][x + 5 - m].charCodeAt(0)); } - if (y == 6 && x >= 1 && x <= 9) { + if (y == m && x >= m - 5 && x <= m + 3) { core.ui.closePanel(); - core.keyUp(lines[1][x - 1].charCodeAt(0)); + core.keyUp(lines[1][x + 5 - m].charCodeAt(0)); } - if (y == 7 && x >= 1 && x <= 7) { + if (y == m + 1 && x >= m - 5 && x <= m + 1) { core.ui.closePanel(); - core.keyUp(lines[2][x - 1].charCodeAt(0)); + core.keyUp(lines[2][x + 5 - m].charCodeAt(0)); } - if (y == 8 && x >= 1 && x <= 11) { + if (y == m + 2 && x >= m - 5 && x <= m + 5) { core.ui.closePanel(); - if (x == 1) core.keyUp(189); // - - if (x == 2) core.keyUp(187); // = - if (x == 3) core.keyUp(219); // [ - if (x == 4) core.keyUp(221); // ] - if (x == 5) core.keyUp(220); // \ - if (x == 6) core.keyUp(186); // ; - if (x == 7) core.keyUp(222); // ' - if (x == 8) core.keyUp(188); // , - if (x == 9) core.keyUp(190); // . - if (x == 10) core.keyUp(191); // / - if (x == 11) core.keyUp(192); // ` + if (x == m - 5) core.keyUp(189); // - + if (x == m - 4) core.keyUp(187); // = + if (x == m - 3) core.keyUp(219); // [ + if (x == m - 2) core.keyUp(221); // ] + if (x == m - 1) core.keyUp(220); // \ + if (x == m) core.keyUp(186); // ; + if (x == m + 1) core.keyUp(222); // ' + if (x == m + 2) core.keyUp(188); // , + if (x == m + 3) core.keyUp(190); // . + if (x == m + 4) core.keyUp(191); // / + if (x == m + 5) core.keyUp(192); // ` } - if (y == 9 && x >= 1 && x <= 10) { + if (y == m + 3 && x >= m - 5 && x <= m + 4) { core.ui.closePanel(); - if (x == 1) core.keyUp(27); // ESC - if (x == 2) core.keyUp(9); // TAB - if (x == 3) core.keyUp(20); // CAPS - if (x == 4) core.keyUp(16); // SHIFT - if (x == 5) core.keyUp(17); // CTRL - if (x == 6) core.keyUp(18); // ALT - if (x == 7) core.keyUp(32); // SPACE - if (x == 8) core.keyUp(8); // BACKSPACE - if (x == 9) core.keyUp(13); // ENTER - if (x == 10) core.keyUp(46); // DEL + if (x == m - 5) core.keyUp(27); // ESC + if (x == m - 4) core.keyUp(9); // TAB + if (x == m - 3) core.keyUp(20); // CAPS + if (x == m - 2) core.keyUp(16); // SHIFT + if (x == m - 1) core.keyUp(17); // CTRL + if (x == m) core.keyUp(18); // ALT + if (x == m + 1) core.keyUp(32); // SPACE + if (x == m + 2) core.keyUp(8); // BACKSPACE + if (x == m + 3) core.keyUp(13); // ENTER + if (x == m + 4) core.keyUp(46); // DEL } - if (y == 10 && x >= 9 && x <= 11) + if (y == m + 4 && x >= m + 3 && x <= m + 5) core.ui.closePanel(); } diff --git a/libs/ui.js b/libs/ui.js index 7473fd11..6654b05b 100644 --- a/libs/ui.js +++ b/libs/ui.js @@ -2148,41 +2148,19 @@ ui.prototype.drawSLPanel = function(index, refresh) { ui.prototype.drawKeyBoard = function () { core.lockControl(); core.status.event.id = 'keyBoard'; + core.clearUI(); - core.clearSelector(); - - var left = 16, top = 48, width = 416 - 2 * left, height = 416 - 2 * top; - - var background = core.status.textAttribute.background; - var isWindowSkin = false; - if (typeof background == 'string') { - background = core.material.images.images[background]; - if (core.isset(background) && background.width==192 && background.height==128) isWindowSkin = true; - else background = core.initStatus.textAttribute.background; - } - if (!isWindowSkin) background = core.arrayToRGBA(background); - var borderColor = core.status.globalAttribute.borderColor; - var titleColor = core.arrayToRGBA(core.status.textAttribute.title); - var textColor = core.arrayToRGBA(core.status.textAttribute.text); - - core.clearMap('ui'); - if (isWindowSkin) { - core.setAlpha('ui', 0.85); - this.drawWindowSkin(background,'ui',left,top,width,height); - } - else { - core.fillRect('ui', left, top, width, height, background); - core.strokeRect('ui', left - 1, top - 1, width + 1, height + 1, borderColor, 2); - } - core.setAlpha('ui', 1); + var width = 384, height = 320; + var left = (this.PIXEL - width) / 2, right = left + width; + var top = (this.PIXEL - height) / 2, bottom = top + height; + var isWindowSkin = this._drawTextBox_drawBackground({}, {}, {left:left, right:right}, {top:top, bottom: bottom}); core.setTextAlign('ui', 'center'); - var globalFont = core.status.globalAttribute.font; - core.fillText('ui', "虚拟键盘", 208, top+35, titleColor, "bold 22px "+globalFont); - - core.setFont('ui', '17px '+globalFont); - core.setFillStyle('ui', textColor); - var offset = 128-9; + core.setFillStyle('ui', core.arrayToRGBA(core.status.textAttribute.title)); + core.fillText('ui', '虚拟键盘', this.HPIXEL, top + 35, null, this._buildFont(22, true)); + core.setFont('ui', this._buildFont(17, false)); + core.setFillStyle('ui', core.arrayToRGBA(core.status.textAttribute.text)); + var offset = this.HPIXEL - 89; var lines = [ ["F1","F2","F3","F4","F5","F6","F7","F8","F9","10","11"], @@ -2196,17 +2174,17 @@ ui.prototype.drawKeyBoard = function () { lines.forEach(function (line) { for (var i=0;i Date: Mon, 25 Mar 2019 23:37:43 +0800 Subject: [PATCH 08/33] drawKeyboard --- libs/ui.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/ui.js b/libs/ui.js index 6654b05b..126824d4 100644 --- a/libs/ui.js +++ b/libs/ui.js @@ -2179,7 +2179,7 @@ ui.prototype.drawKeyBoard = function () { offset+=32; }); - core.fillText("ui", "返回游戏", this.PIXEL - 80, offset-3, '#FFFFFF', this._buildFont(15, true)); + core.fillText("ui", "返回游戏", this.HPIXEL + 128, offset-3, '#FFFFFF', this._buildFont(15, true)); if (isWindowSkin) this.drawWindowSelector(core.status.textAttribute.background, this.HPIXEL + 92, offset - 22, 72, 27); From 45c74f44e0c30ec6e92c1ee45a3e6da65d4a8dc6 Mon Sep 17 00:00:00 2001 From: oc Date: Tue, 26 Mar 2019 00:43:08 +0800 Subject: [PATCH 09/33] drawStatistics & drawBookDetail --- libs/ui.js | 473 ++++++++++++++++++++++++++--------------------------- 1 file changed, 235 insertions(+), 238 deletions(-) diff --git a/libs/ui.js b/libs/ui.js index 126824d4..02bbf3a4 100644 --- a/libs/ui.js +++ b/libs/ui.js @@ -1375,60 +1375,96 @@ ui.prototype.drawBook = function (index) { ////// 绘制怪物属性的详细信息 ////// ui.prototype.drawBookDetail = function (index) { + var info = this._drawBookDetail_getInfo(index), enemy = info[0]; + var content = info[1].join("\n"); + core.status.event.id = 'book-detail'; + clearInterval(core.interval.tipAnimate); + core.clearMap('data'); + + var left = 10, width = this.PIXEL - 2 * left, right = left + width; + var content_left = left + 25, validWidth = right - content_left - 13; + var contents = core.splitLines("data", content, validWidth, this._buildFont(16, false)); + var height = Math.max(24 * contents.length + 55, 80), top = (this.PIXEL - height) / 2, bottom = top + height; + + core.setAlpha('data', 0.9); + core.fillRect('data', left, top, width, height, '#000000'); + core.setAlpha('data', 1); + core.strokeRect('data', left - 1, top - 1, width + 1, height + 1, + core.status.globalAttribute.borderColor, 2); + + this._drawBookDetail_drawContent(enemy, contents, {top: top, content_left: content_left, bottom: bottom}); +} + +ui.prototype._drawBookDetail_getInfo = function (index) { var floorId = core.floorIds[(core.status.event.ui||{}).index] || core.status.floorId; var enemys = core.enemys.getCurrentEnemys(floorId); - if (enemys.length==0) return; - if (index<0) index=0; - if (index>=enemys.length) index=enemys.length-1; - + index = core.clamp(index, 0, enemys.length - 1); var enemy = enemys[index], enemyId = enemy.id; - var hints=core.enemys.getSpecialHint(enemyId); + var texts=core.enemys.getSpecialHint(enemyId); var damageInfo = core.enemys.getDamageInfo(enemy, null, null, null, floorId); + if (texts.length == 0) texts.push("该怪物无特殊属性。"); + texts.push(""); + this._drawBookDetail_getTexts(enemy, floorId, texts); + return [enemy, texts]; +} - if (hints.length==0) - hints.push("该怪物无特殊属性。"); +ui.prototype._drawBookDetail_getTexts = function (enemy, floorId, texts) { + // --- 模仿临界计算器 + this._drawBookDetail_mofang(enemy, texts); + // --- 吸血怪最低生命值 + this._drawBookDetail_vampire(enemy, texts); + // --- 仇恨伤害 + this._drawBookDetail_hatred(enemy, texts); + // --- 战斗回合数,临界表 + this._drawBookDetail_turnAndCriticals(enemy, floorId, texts); +} +ui.prototype._drawBookDetail_mofang = function (enemy, texts) { // 模仿临界计算器 if (core.enemys.hasSpecial(enemy.special, 10)) { var hp = enemy.hp; var delta = core.status.hero.atk - core.status.hero.def; if (delta0) { - hints.push(""); - hints.push("模仿临界计算器:(当前攻防差"+core.formatBigNumber(delta)+")"); - var arr = []; - (function () { - var last=0, start=0; - for (var i=1;i=0) { var x1 = text.substring(0, index+1); - core.fillText('data', x1, content_left, content_top, '#FF6A6A', 'bold 16px '+globalFont); + core.fillText('data', x1, pos.content_left, content_top, '#FF6A6A', this._buildFont(16, true)); var len=core.calWidth('data', x1); - core.fillText('data', text.substring(index+1), content_left+len, content_top, '#FFFFFF', '16px '+globalFont); + core.fillText('data', text.substring(index+1), pos.content_left+len, content_top, '#FFFFFF', this._buildFont(16, false)); } else { - core.fillText('data', contents[i], content_left, content_top, '#FFFFFF', '16px '+globalFont); + core.fillText('data', contents[i], pos.content_left, content_top, '#FFFFFF', this._buildFont(16, false)); } content_top+=24; } - - core.fillText('data', '<点击任意位置继续>', 270, top+height-13, '#CCCCCC', '13px '+globalFont); } ////// 绘制楼层传送器 ////// @@ -2193,177 +2207,21 @@ ui.prototype.drawStatusBar = function () { } ////// 绘制“数据统计”界面 ////// -ui.prototype.drawStatistics = function () { - - // 数据统计要统计如下方面: - // 1. 当前全塔剩余下的怪物数量,总金币数,总经验数,总加点数 - // 2. 当前全塔剩余的黄蓝红铁门数量,和对应的钥匙数量 - // 3. 当前全塔剩余的三种宝石数量,血瓶数量,装备数量;总共增加的攻防生命值 - // 4. 当前层的上述信息 - // 5. 当前已走的步数;瞬间移动的步数,瞬间移动的次数(和少走的步数);游戏时长 - // 6. 当前已恢复的生命值;当前总伤害、战斗伤害、阻激夹域血网伤害、中毒伤害。 - - var ori = this.uidata.drawStatistics(); - var ids = ori.filter(function (e) { - return e.endsWith("Door") || core.isset(core.material.items[e]); +ui.prototype.drawStatistics = function (floorIds) { + var obj = this._drawStatistics_buildObj(); + if (typeof floorIds == 'string') floorIds = [floorIds]; + (floorIds || core.floorIds).forEach(function (floorId) { + core.ui._drawStatistics_floorId(floorId, obj); }); - var obj = {}; - var cls = {}; - ids.forEach(function (e) { - if (e.endsWith("Door")) cls[e] = "doors"; - else cls[e] = core.material.items[e].cls; - obj[e] = 0; - }) - var order = ["doors", "keys", "items", "tools", "constants", "equips"]; - ids.sort(function (a, b) { - var c1 = order.indexOf(cls[a]), c2 = order.indexOf(cls[b]); - if (c1==c2) return ori.indexOf(a)-ori.indexOf(b); - return c1-c2; - }); - var ext = {}; - - var total = { - 'monster': { - 'count': 0, 'money': 0, 'experience': 0, 'point': 0, - }, - 'count': obj, - 'add': { - 'hp': 0, 'atk': 0, 'def': 0, 'mdef': 0 - } - }; - var current = core.clone(total); - - core.floorIds.forEach(function (floorId) { - var floor=core.status.maps[floorId]||core.floors[floorId]; - var blocks=core.status.maps[floorId].blocks; - // 隐藏层不给看 - if (floor.cannotViewMap && floorId!=core.status.floorId) return; - - blocks.forEach(function (block) { - if (block.disable) return; - var event = block.event; - if (event.cls.indexOf("enemy")==0) { - var enemyId = event.id, enemy = core.material.enemys[enemyId]; - total.monster.money+=enemy.money||0; - total.monster.experience+=enemy.experience||0; - total.monster.point+=enemy.point||0; - total.monster.count++; - if (floorId==core.status.floorId) { - current.monster.money+=enemy.money||0; - current.monster.experience+=enemy.experience||0; - current.monster.point+=enemy.point||0; - current.monster.count++; - } - } - else { - var id = event.id; - - if (core.isset(total.count[id])) { - var hp=0, atk=0, def=0, mdef=0; - - if (cls[id]=='items' && id!='superPotion') { - var temp = core.clone(core.status.hero); - core.setFlag("__statistics__", true); - var ratio = floor.item_ratio||1; - if (core.isset(core.items.itemEffect[id])) { - try { - // 需要检查是否是测试状态... - eval(core.items.itemEffect[id]); - } - catch (e) {} - } - hp = core.status.hero.hp - temp.hp; - atk = core.status.hero.atk - temp.atk; - def = core.status.hero.def - temp.def; - mdef = core.status.hero.mdef - temp.mdef; - core.status.hero = temp; - } - else { - // 装备 - if (cls[id]=='equips') { - var values = core.material.items[id].equip||{}; - atk = values.atk||0; - def = values.def||0; - mdef = values.mdef||0; - } - } - - if (id.indexOf('sword')==0 || id.indexOf('shield')==0 || cls[id]=='equips') { - var t = ""; - if (atk>0) t+=atk+"攻"; - if (def>0) t+=def+"防"; - if (mdef>0) t+=mdef+"魔防"; - if (t!="") ext[id]=t; - } - - total.count[id]++; - total.add.hp+=hp; - total.add.atk+=atk; - total.add.def+=def; - total.add.mdef+=mdef; - if (floorId==core.status.floorId) { - current.count[id]++; - current.add.hp+=hp; - current.add.atk+=atk; - current.add.def+=def; - current.add.mdef+=mdef; - } - } - } - }) - }) - - var getText = function (type, data) { - var text = type+"地图中:\n"; - text += "共有怪物"+data.monster.count+"个"; - if (core.flags.enableMoney) text+=",总金币数"+data.monster.money; - if (core.flags.enableExperience) text+=",总经验数"+data.monster.experience; - if (core.flags.enableAddPoint) text+=",总加点数"+data.monster.point; - text+="。\n"; - - var prev = ""; - ids.forEach(function (key) { - var value = data.count[key]; - if (value==0) return; - var c = cls[key]; - if (c!=prev) { - if (prev != "") text += "。"; - text += "\n"; - } - else - text += ","; - prev = c; - var name = null; - if (key=='yellowDoor') name="黄门"; - else if (key=='blueDoor') name="蓝门"; - else if (key=='redDoor') name="红门"; - else if (key=='greenDoor') name="绿门"; - else if (key=='steelDoor') name="铁门"; - else name=core.material.items[key].name; - text+=name+value+"个"; - if (core.isset(ext[key])) - text+="("+ext[key]+")"; - }) - - if (prev!="") text+="。"; - text+="\n\n"; - text+="共加生命值"+core.formatBigNumber(data.add.hp)+"点,攻击" - +core.formatBigNumber(data.add.atk)+"点,防御" - +core.formatBigNumber(data.add.def)+"点,魔防" - +core.formatBigNumber(data.add.mdef)+"点。"; - return text; - } - var formatTime = function (time) { return core.setTwoDigits(parseInt(time/3600000)) +":"+core.setTwoDigits(parseInt(time/60000)%60) +":"+core.setTwoDigits(parseInt(time/1000)%60); } - var statistics = core.status.hero.statistics; core.drawText([ - getText("全塔", total), - getText("当前", current), + this._drawStatistics_generateText(obj, "全塔", obj.total), + this._drawStatistics_generateText(obj, "当前", obj.current), "当前总步数:"+core.status.hero.steps+",当前游戏时长:"+formatTime(statistics.currTime) +",总游戏时长"+formatTime(statistics.totalTime) +"。\n瞬间移动次数:"+statistics.moveDirectly+",共计少走"+statistics.ignoreSteps+"步。" @@ -2375,10 +2233,148 @@ ui.prototype.drawStatistics = function () { +",领域/夹击/阻击/血网伤害"+core.formatBigNumber(statistics.extraDamage)+"点。", "\t[说明]1. 地图数据统计的效果仅模拟当前立刻获得该道具的效果。\n2. 不会计算“不可被浏览地图”的隐藏层的数据。\n" + "3. 不会计算任何通过事件得到的道具(显示事件、改变图块、或直接增加道具等)。\n"+ - "4. 在自定义道具(例如其他宝石)后,需在ui.js的drawStatistics中注册,不然不会进行统计。\n"+ + "4. 在自定义道具(例如其他宝石)后,需在脚本编辑的drawStatistics中注册,不然不会进行统计。\n"+ "5. 所有统计信息仅供参考,如有错误,概不负责。" ]) +} +ui.prototype._drawStatistics_buildObj = function () { + // 数据统计要统计如下方面: + // 1. 当前全塔剩余下的怪物数量,总金币数,总经验数,总加点数 + // 2. 当前全塔剩余的黄蓝红铁门数量,和对应的钥匙数量 + // 3. 当前全塔剩余的三种宝石数量,血瓶数量,装备数量;总共增加的攻防生命值 + // 4. 当前层的上述信息 + // 5. 当前已走的步数;瞬间移动的步数,瞬间移动的次数(和少走的步数);游戏时长 + // 6. 当前已恢复的生命值;当前总伤害、战斗伤害、阻激夹域血网伤害、中毒伤害。 + var ori = this.uidata.drawStatistics(); + var ids = ori.filter(function (e) { + return e.endsWith("Door") || core.material.items[e]; + }); + var cnt = {}, cls = {}, ext = {}; + ids.forEach(function (e) { + if (e.endsWith("Door")) cls[e] = "doors"; + else cls[e] = core.material.items[e].cls; + cnt[e] = 0; + }) + var order = ["doors", "keys", "items", "tools", "constants", "equips"]; + ids.sort(function (a, b) { + var c1 = order.indexOf(cls[a]), c2 = order.indexOf(cls[b]); + if (c1==c2) return ori.indexOf(a)-ori.indexOf(b); + return c1-c2; + }); + var obj = { + 'monster': { + 'count': 0, 'money': 0, 'experience': 0, 'point': 0, + }, + 'count': cnt, + 'add': { + 'hp': 0, 'atk': 0, 'def': 0, 'mdef': 0 + } + }; + return {ids: ids, cls: cls, ext: ext, total: core.clone(obj), current: core.clone(obj)}; +} + +ui.prototype._drawStatistics_add = function (floorId, obj, x1, x2, value) { + obj.total[x1][x2] += value || 0; + if (floorId == core.status.floorId) + obj.current[x1][x2] += value || 0; +} + +ui.prototype._drawStatistics_floorId = function (floorId, obj) { + var floor = core.status.maps[floorId], blocks = floor.blocks; + // 隐藏层不给看 + if (floor.cannotViewMap && floorId!=core.status.floorId) return; + blocks.forEach(function (block) { + if (block.disable) return; + var event = block.event; + if (event.cls.indexOf("enemy")==0) { + core.ui._drawStatistics_enemy(floorId, event.id, obj); + } + else { + var id = event.id; + if (obj.total.count[id] != null) + core.ui._drawStatistics_items(floorId, floor, id, obj); + } + }) +} + +ui.prototype._drawStatistics_enemy = function (floorId, id, obj) { + var enemy = core.material.enemys[id]; + this._drawStatistics_add(floorId, obj, 'monster', 'money', enemy.money); + this._drawStatistics_add(floorId, obj, 'monster', 'experience', enemy.experience); + this._drawStatistics_add(floorId, obj, 'monster', 'point', enemy.point); + this._drawStatistics_add(floorId, obj, 'monster', 'count', 1); +} + +ui.prototype._drawStatistics_items = function (floorId, floor, id, obj) { + var hp=0, atk=0, def=0, mdef=0; + if (obj.cls[id]=='items' && id!='superPotion') { + var temp = core.clone(core.status.hero); + core.setFlag("__statistics__", true); + var ratio = floor.item_ratio||1; + try { eval(core.items.itemEffect[id]); } + catch (e) {} + hp = core.status.hero.hp - temp.hp; + atk = core.status.hero.atk - temp.atk; + def = core.status.hero.def - temp.def; + mdef = core.status.hero.mdef - temp.mdef; + core.status.hero = temp; + } + else if (obj.cls[id]=='equips') { + var values = core.material.items[id].equip || {}; + atk = values.atk || 0; + def = values.def || 0; + mdef = values.mdef || 0; + } + if (id.indexOf('sword')==0 || id.indexOf('shield')==0 || obj.cls[id]=='equips') { + var t = ""; + if (atk > 0) t += atk + "攻"; + if (def > 0) t += def + "防"; + if (mdef > 0) t += mdef + "魔防"; + if (t != "") obj.ext[id] = t; + } + this._drawStatistics_add(floorId, obj, 'count', id, 1); + this._drawStatistics_add(floorId, obj, 'add', 'hp', hp); + this._drawStatistics_add(floorId, obj, 'add', 'atk', atk); + this._drawStatistics_add(floorId, obj, 'add', 'def', def); + this._drawStatistics_add(floorId, obj, 'add', 'mdef', mdef); +} + +ui.prototype._drawStatistics_generateText = function (obj, type, data) { + var text = type+"地图中:\n"; + text += "共有怪物"+data.monster.count+"个"; + if (core.flags.enableMoney) text+=",总金币数"+data.monster.money; + if (core.flags.enableExperience) text+=",总经验数"+data.monster.experience; + if (core.flags.enableAddPoint) text+=",总加点数"+data.monster.point; + text+="。\n"; + + var prev = ""; + obj.ids.forEach(function (key) { + var value = data.count[key]; + if (value==0) return; + if (obj.cls[key] != prev) { + if (prev != "") text += "。"; + text += "\n"; + } + else text += ","; + prev = obj.cls[key]; + text+=core.ui._drawStatistics_getName(key)+value+"个"; + if (obj.ext[key]) + text+="("+obj.ext[key]+")"; + }) + if (prev!="") text+="。"; + + text+="\n\n"; + text+="共加生命值"+core.formatBigNumber(data.add.hp)+"点,攻击" + +core.formatBigNumber(data.add.atk)+"点,防御" + +core.formatBigNumber(data.add.def)+"点,魔防" + +core.formatBigNumber(data.add.mdef)+"点。"; + return text; +} + +ui.prototype._drawStatistics_getName = function (key) { + return {"yellowDoor": "黄门", "blueDoor": "蓝门", "redDoor": "红门", "greenDoor": "绿门", + "steelDoor": "铁门"}[key] || core.material.items[key].name; } ////// 绘制“关于”界面 ////// @@ -2434,7 +2430,8 @@ ui.prototype.drawHelp = function () { core.status.event.id = 'help'; core.lockControl(); core.setAlpha('ui', 1); - core.drawImage('ui', core.material.images.keyboard, 0, 0); + core.fillRect('ui', 0, 0, this.PIXEL, this.PIXEL, '#FFFFFF'); + core.drawImage('ui', core.material.images.keyboard, 32 * (this.HSIZE - 6), 32 * (this.HSIZE - 6)); } else { core.drawText([ From c91831841e6c551e16ec9f9526098972f4b26e9d Mon Sep 17 00:00:00 2001 From: oc Date: Tue, 26 Mar 2019 00:55:11 +0800 Subject: [PATCH 10/33] drawFly --- libs/ui.js | 31 ++++++++++++++----------------- 1 file changed, 14 insertions(+), 17 deletions(-) diff --git a/libs/ui.js b/libs/ui.js index 02bbf3a4..cb56a773 100644 --- a/libs/ui.js +++ b/libs/ui.js @@ -1525,34 +1525,31 @@ ui.prototype._drawBookDetail_drawContent = function (enemy, contents, pos) { ////// 绘制楼层传送器 ////// ui.prototype.drawFly = function(page) { - core.status.event.data = page; - var floorId = core.floorIds[page]; var title = core.status.maps[floorId].title; - core.clearMap('ui'); core.setAlpha('ui', 0.85); - core.fillRect('ui', 0, 0, 416, 416, '#000000'); + core.fillRect('ui', 0, 0, this.PIXEL, this.PIXEL, '#000000'); core.setAlpha('ui', 1); core.setTextAlign('ui', 'center'); - var globalFont = core.status.globalAttribute.font - core.fillText('ui', '楼层跳跃', 208, 60, '#FFFFFF', "bold 28px "+globalFont); - core.fillText('ui', '返回游戏', 208, 403, '#FFFFFF', "bold 15px "+globalFont) - core.fillText('ui', title, 356, 247, '#FFFFFF', "bold 19px "+globalFont); + core.fillText('ui', '楼层跳跃', this.HPIXEL, 60, '#FFFFFF', this._buildFont(28, true)); + core.fillText('ui', '返回游戏', this.HPIXEL, this.PIXEL - 13, null, this._buildFont(15, true)) + core.fillText('ui', title, this.PIXEL - 60, this.HPIXEL + 39, null, this._buildFont(19, true)); + var middle = this.HPIXEL + 39; if (core.actions._getNextFlyFloor(1) != page) { - core.fillText('ui', '▲', 356, 247 - 64, '#FFFFFF', "17px "+globalFont); - core.fillText('ui', '▲', 356, 247 - 96, '#FFFFFF', "17px "+globalFont); - core.fillText('ui', '▲', 356, 247 - 96 - 7, '#FFFFFF', "17px "+globalFont); + core.fillText('ui', '▲', this.PIXEL - 60, middle - 64, null, this._buildFont(17, false)); + core.fillText('ui', '▲', this.PIXEL - 60, middle - 96,); + core.fillText('ui', '▲', this.PIXEL - 60, middle - 96 - 7); } if (core.actions._getNextFlyFloor(-1) != page) { - core.fillText('ui', '▼', 356, 247 + 64, '#FFFFFF', "17px "+globalFont); - core.fillText('ui', '▼', 356, 247 + 96, '#FFFFFF', "17px "+globalFont); - core.fillText('ui', '▼', 356, 247 + 96 + 7, '#FFFFFF', "17px "+globalFont); + core.fillText('ui', '▼', this.PIXEL - 60, middle + 64, null, this._buildFont(17, false)); + core.fillText('ui', '▼', this.PIXEL - 60, middle + 96); + core.fillText('ui', '▼', this.PIXEL - 60, middle + 96 + 7); } - core.strokeRect('ui', 20, 100, 273, 273, '#FFFFFF', 2); - - core.drawThumbnail(floorId, null, null, {ctx: 'ui', x: 20, y: 100, size: 273}); + var size = this.PIXEL - 143; + core.strokeRect('ui', 20, 100, size, size, '#FFFFFF', 2); + core.drawThumbnail(floorId, null, null, {ctx: 'ui', x: 20, y: 100, size: size}); } ////// 绘制中心对称飞行器 From 5c0e3ade0b8d3a09c607ba099023c60c1b2d81cc Mon Sep 17 00:00:00 2001 From: oc Date: Tue, 26 Mar 2019 02:16:06 +0800 Subject: [PATCH 11/33] drawMaps --- libs/actions.js | 34 +++++------ libs/ui.js | 159 +++++++++++++++++++++++------------------------- 2 files changed, 93 insertions(+), 100 deletions(-) diff --git a/libs/actions.js b/libs/actions.js index 9b68d44f..c8e9baeb 100644 --- a/libs/actions.js +++ b/libs/actions.js @@ -1055,60 +1055,60 @@ actions.prototype._clickViewMaps = function (x, y) { core.ui.drawMaps(core.floorIds.indexOf(core.status.floorId)); return; } - var now = core.floorIds.indexOf(core.status.floorId); var index = core.status.event.data.index; var cx = core.status.event.data.x, cy = core.status.event.data.y; var floorId = core.floorIds[index], mw = core.floors[floorId].width, mh = core.floors[floorId].height; + var per = this.HSIZE - 4; - if (x == 0 && y == 0) { + if (x <= per - 2 && y <= per - 2) { core.status.event.data.damage = !core.status.event.data.damage; core.ui.drawMaps(index, cx, cy); return; } - if (x == 0 && y == 12) { + if (x <= per - 2 && y >= this.SIZE + 1 - per) { core.status.event.data.paint = !core.status.event.data.paint; core.ui.drawMaps(index, cx, cy); return; } - if (x == 12 && y == 0) { + if (x >= this.SIZE + 1 - per && y <= per - 2) { core.status.event.data.all = !core.status.event.data.all; core.ui.drawMaps(index, cx, cy); return; } - if (x >= 2 && x <= 10 && y <= 1 && mh > 13) { + if (x >= per && x <= this.LAST - per && y <= per - 1 && mh > this.SIZE) { core.ui.drawMaps(index, cx, cy - 1); return; } - if (x >= 2 && x <= 10 && y >= 11 && mh > 13) { + if (x >= per && x <= this.LAST - per && y >= this.SIZE - per && mh > this.SIZE) { core.ui.drawMaps(index, cx, cy + 1); return; } - if (x <= 1 && y >= 2 && y <= 10) { + if (x <= per - 1 && y >= per && y <= this.LAST - per) { core.ui.drawMaps(index, cx - 1, cy); return; } - if (x >= 11 && y >= 2 && y <= 10) { + if (x >= this.SIZE - per && y >= per && y <= this.LAST - per) { core.ui.drawMaps(index, cx + 1, cy); return; } - if (y <= 4 && (mh == 13 || (x >= 2 && x <= 10))) { + if (y <= this.HSIZE - 2 && (mh == this.SIZE || (x >= per && x <= this.LAST - per))) { index++; while (index < core.floorIds.length && index != now && core.status.maps[core.floorIds[index]].cannotViewMap) index++; if (index < core.floorIds.length) core.ui.drawMaps(index); } - else if (y >= 8 && (mh == 13 || (x >= 2 && x <= 10))) { + else if (y >= this.HSIZE + 2 && (mh == this.SIZE || (x >= per && x <= this.LAST - per))) { index--; while (index >= 0 && index != now && core.status.maps[core.floorIds[index]].cannotViewMap) index--; if (index >= 0) core.ui.drawMaps(index); } - else if (x >= 2 && x <= 10 && y >= 5 && y <= 7) { + else if (x >= per && x <= this.LAST - per && y >= this.HSIZE - 1 && y <= this.HSIZE + 1) { core.clearMap('data'); core.ui.closePanel(); } @@ -1120,12 +1120,12 @@ actions.prototype._keyDownViewMaps = function (keycode) { var floorId = core.floorIds[core.status.event.data.index], mh = core.floors[floorId].height; - if (keycode == 38 || keycode == 33) this._clickViewMaps(6, 3); - if (keycode == 40 || keycode == 34) this._clickViewMaps(6, 9); - if (keycode == 87 && mh > 13) this._clickViewMaps(6, 0); - if (keycode == 65) this._clickViewMaps(0, 6); - if (keycode == 83 && mh > 13) this._clickViewMaps(6, 12); - if (keycode == 68) this._clickViewMaps(12, 6); + if (keycode == 38 || keycode == 33) this._clickViewMaps(this.HSIZE, this.HSIZE - 3); + if (keycode == 40 || keycode == 34) this._clickViewMaps(this.HSIZE, this.HSIZE + 3); + if (keycode == 87 && mh > this.SIZE) this._clickViewMaps(this.HSIZE, 0); + if (keycode == 65) this._clickViewMaps(0, this.HSIZE); + if (keycode == 83 && mh > this.SIZE) this._clickViewMaps(this.HSIZE, this.LAST); + if (keycode == 68) this._clickViewMaps(this.LAST, this.HSIZE); return; } diff --git a/libs/ui.js b/libs/ui.js index cb56a773..304f5d8f 100644 --- a/libs/ui.js +++ b/libs/ui.js @@ -1402,7 +1402,6 @@ ui.prototype._drawBookDetail_getInfo = function (index) { index = core.clamp(index, 0, enemys.length - 1); var enemy = enemys[index], enemyId = enemy.id; var texts=core.enemys.getSpecialHint(enemyId); - var damageInfo = core.enemys.getDamageInfo(enemy, null, null, null, floorId); if (texts.length == 0) texts.push("该怪物无特殊属性。"); texts.push(""); this._drawBookDetail_getTexts(enemy, floorId, texts); @@ -1600,100 +1599,94 @@ ui.prototype.drawShop = function (shopId) { ui.prototype.drawMaps = function (index, x, y) { core.lockControl(); core.status.event.id = 'viewMaps'; - - if (!core.isset(index)) { - core.status.event.data = null; - core.clearSelector(); - - core.fillRect('ui', 0, 0, 416, 416, 'rgba(0,0,0,0.4)'); - - core.strokeRect('ui', 66, 2, 284, 60, "#FFD700", 4); - core.strokeRect('ui', 2, 66, 60, 284); - core.strokeRect('ui', 66, 416-62, 284, 60); - core.strokeRect('ui', 416-62, 66, 60, 284); - core.strokeRect('ui', 66, 66, 284, 92); - core.strokeRect('ui', 66, 32*8+2, 284, 92); - core.setTextAlign('ui', 'center'); - core.fillText('ui', "上移地图 [W]", 208, 38, '#FFD700', '20px Arial'); - core.fillText('ui', "下移地图 [S]", 208, 390); - - core.strokeRect('ui', 2, 2, 28, 28); - core.fillText('ui', 'V', 16, 24); - core.strokeRect('ui', 2, 416-30, 28, 28); - core.fillText('ui', 'M', 16, 408); - core.strokeRect('ui', 416-30, 2, 28, 28); - core.fillText('ui', 'Z', 400, 24); - - var top = 150; - core.fillText('ui', "左", 32, top); - core.fillText('ui', "移", 32, top+32); - core.fillText('ui', "地", 32, top+32*2); - core.fillText('ui', "图", 32, top+32*3); - core.fillText('ui', "[A]", 32, top+32*4); - core.fillText('ui', "右", 384, top); - core.fillText('ui', "移", 384, top+32); - core.fillText('ui', "地", 384, top+32*2); - core.fillText('ui', "图", 384, top+32*3); - core.fillText('ui', "[D]", 384, top+32*4); - - core.fillText('ui', "前张地图 [▲ / PGUP]", 208, 64+54); - core.fillText('ui', "后张地图 [▼ / PGDN]", 208, 32*8+54); - - core.fillText('ui', "退出 [ESC / ENTER]", 208, 208+8); - core.fillText('ui', "[X] 可查看怪物手册", 285, 208+40, null, '13px Arial'); - - return; - } - - var damage = (core.status.event.data||{}).damage, paint = (core.status.event.data||{}).paint; - var all = (core.status.event.data||{}).all; - if (core.isset(index.damage)) damage=index.damage; - if (core.isset(index.paint)) paint=index.paint; - if (core.isset(index.all)) all=index.all; - - if (core.isset(index.index)) { - x=index.x; - y=index.y; - index=index.index; - } - - if (index<0) index=0; - if (index>=core.floorIds.length) index=core.floorIds.length-1; - var floorId = core.floorIds[index], mw = core.floors[floorId].width, mh = core.floors[floorId].height; - if (!core.isset(x)) x = parseInt(mw/2); - if (!core.isset(y)) y = parseInt(mh/2); - if (x<6) x=6; - if (x>mw-7) x=mw-7; - if (y<6) y=6; - if (y>mh-7) y=mh-7; - - core.status.event.data = {"index": index, "x": x, "y": y, "damage": damage, "paint": paint, "all": all}; - + this.clearUI(); + if (index == null) return this._drawMaps_drawHint(); clearTimeout(core.interval.tipAnimate); - core.clearSelector(); core.status.checkBlock.cache = {}; - core.drawThumbnail(floorId, null, {damage: damage}, {ctx: 'ui', centerX: x, centerY: y, all: all}); - + var data = this._drawMaps_buildData(index, x, y); + core.drawThumbnail(data.floorId, null, {damage: data.damage}, + {ctx: 'ui', centerX: data.x, centerY: data.y, all: data.all}); // 绘图 - if (core.status.event.data.paint) { - var offsetX = core.clamp(x-6, 0, mw-13), offsetY = core.clamp(y-6, 0, mh-13); - var value = core.paint[floorId]; - if (core.isset(value)) value = lzw_decode(value).split(","); - core.utils.decodeCanvas(value, 32*mw, 32*mh); - core.drawImage('ui', core.bigmap.tempCanvas.canvas, offsetX*32, offsetY*32, 416, 416, 0, 0, 416, 416); + if (data.paint) { + var offsetX = 32 * (data.x - this.HSIZE), offsetY = 32 * (data.y - this.HSIZE); + var value = core.paint[data.floorId]; + if (value) value = lzw_decode(value).split(","); + core.utils.decodeCanvas(value, 32 * data.mw, 32 * data.mh); + core.drawImage('ui', core.bigmap.tempCanvas.canvas, offsetX * 32, offsetY * 32, + this.PIXEL, this.PIXEL, 0, 0, this.PIXEL, this.PIXEL); } - core.clearMap('data'); core.setTextAlign('data', 'left'); core.setFont('data', '16px Arial'); - - var text = core.status.maps[floorId].title; - if (!all && (mw>13 || mh>13)) text+=" ["+(x-6)+","+(y-6)+"]"; + var text = core.status.maps[data.floorId].title; + if (!data.all && (data.mw>this.SIZE || data.mh>this.SIZE)) + text+=" ["+(data.x-this.HSIZE)+","+(data.y-this.HSIZE)+"]"; var textX = 16, textY = 18, width = textX + core.calWidth('data', text) + 16, height = 42; core.fillRect('data', 5, 5, width, height, 'rgba(0,0,0,0.4)'); core.fillText('data', text, textX + 5, textY + 15, 'rgba(255,255,255,0.6)'); } +ui.prototype._drawMaps_drawHint = function () { + core.fillRect('ui', 0, 0, this.PIXEL, this.PIXEL, 'rgba(0,0,0,0.4)'); + core.setTextAlign('ui', 'center'); + var stroke = function (left, top, width, height, fillStyle, lineWidth) { + core.strokeRect('ui', left*32+2, top*32+2, width*32-4, height*32-4, fillStyle, lineWidth); + } + var per = this.HSIZE - 4; + stroke(per, 0, 9, per, '#FFD700', 4); // up + stroke(0, per, per, 9); // left + stroke(per, this.SIZE - per, 9, per); // down + stroke(this.SIZE - per, per, per, 9); // right + stroke(per, per, 9, 3); // prev + stroke(per, this.SIZE - per - 3, 9, 3); // next + stroke(0, 0, per-1, per-1); // left top + stroke(this.SIZE-(per - 1), 0, per-1, per-1); // right top + stroke(0, this.SIZE-(per-1), per-1, per-1); // left bottom + + core.setTextBaseline('ui', 'middle'); + core.fillText('ui', "上移地图 [W]", this.HPIXEL, per * 16, '#FFD700', '20px Arial'); + core.fillText('ui', "下移地图 [S]", this.HPIXEL, this.PIXEL - per * 16); + core.fillText('ui', 'V', (per-1)*16, (per-1)*16); + core.fillText('ui', 'Z', this.PIXEL - (per-1)*16, (per-1)*16); + core.fillText('ui', 'M', (per-1)*16, this.PIXEL - (per-1)*16); + + var top = this.HPIXEL - 66, left = per * 16, right = this.PIXEL - left; + var lt = ["左", "移", "地", "图", "[A]"], rt = ["右", "移", "地", "图", "[D]"]; + for (var i = 0; i < 5; ++i) { + core.fillText("ui", lt[i], left, top + 32 * i); + core.fillText("ui", rt[i], right, top + 32 * i); + } + core.fillText('ui', "前张地图 [▲ / PGUP]", this.HPIXEL, 32 * per + 48); + core.fillText('ui', "后张地图 [▼ / PGDN]", this.HPIXEL, this.PIXEL - (32 * per + 48)); + + core.fillText('ui', "退出 [ESC / ENTER]", this.HPIXEL, this.HPIXEL); + core.fillText('ui', "[X] 可查看怪物手册", this.HPIXEL + 77, this.HPIXEL + 32, null, '13px Arial'); + + core.setTextBaseline('ui', 'alphabetic'); +} + +ui.prototype._drawMaps_buildData = function (index, x, y) { + var damage = (core.status.event.data||{}).damage; + var paint = (core.status.event.data||{}).paint; + var all = (core.status.event.data||{}).all; + if (index.damage != null) damage=index.damage; + if (index.paint != null) paint=index.paint; + if (index.all != null) all=index.all; + if (index.index != null) { x=index.x; y=index.y; index=index.index; } + index = core.clamp(index, 0, core.floorIds.length-1); + if (damage == null) damage = true; // 浏览地图默认开显伤好了 + + var floorId = core.floorIds[index], mw = core.floors[floorId].width, mh = core.floors[floorId].height; + if (x == null) x = parseInt(mw / 2); + if (y == null) y = parseInt(mh / 2); + x = core.clamp(x, this.HSIZE, mw - this.HSIZE - 1); + y = core.clamp(y, this.HSIZE, mh - this.HSIZE - 1); + + core.status.event.data = {index: index, x: x, y: y, floorId: floorId, mw: mw, mh: mh, + damage: damage, paint: paint, all: all }; + return core.status.event.data; +} + ////// 绘制道具栏 ////// ui.prototype.drawToolbox = function(index) { // 设定eventdata From 4e8c4c1798523ce30595d2f306adc374c5feba89 Mon Sep 17 00:00:00 2001 From: oc Date: Tue, 26 Mar 2019 22:32:21 +0800 Subject: [PATCH 12/33] startGame replay & init sys flags --- libs/core.js | 17 ++++++++++------- libs/events.js | 8 ++++++-- project/functions.js | 1 + 3 files changed, 17 insertions(+), 9 deletions(-) diff --git a/libs/core.js b/libs/core.js index 58d41ec9..4ef06a69 100644 --- a/libs/core.js +++ b/libs/core.js @@ -227,13 +227,7 @@ core.prototype._init_flags = function () { core.flags = core.clone(core.data.flags); core.values = core.clone(core.data.values); core.firstData = core.clone(core.data.firstData); - - if (!core.flags.enableExperience) core.flags.enableLevelUp = false; - if (!core.flags.enableLevelUp) core.flags.levelUpLeftMode = false; - if (core.flags.equipboxButton) core.flags.equipment = true; - core.flags.displayEnemyDamage = core.getLocalStorage('enemyDamage', core.flags.displayEnemyDamage); - core.flags.displayCritical = core.getLocalStorage('critical', core.flags.displayCritical); - core.flags.displayExtraDamage = core.getLocalStorage('extraDamage', core.flags.displayExtraDamage); + this._init_sys_flags(); core.dom.versionLabel.innerHTML = core.firstData.version; core.dom.logoLabel.innerHTML = core.firstData.title; @@ -248,6 +242,15 @@ core.prototype._init_flags = function () { core.material.icons = core.icons.getIcons(); } +core.prototype._init_sys_flags = function () { + if (!core.flags.enableExperience) core.flags.enableLevelUp = false; + if (!core.flags.enableLevelUp) core.flags.levelUpLeftMode = false; + if (core.flags.equipboxButton) core.flags.equipment = true; + core.flags.displayEnemyDamage = core.getLocalStorage('enemyDamage', core.flags.displayEnemyDamage); + core.flags.displayCritical = core.getLocalStorage('critical', core.flags.displayCritical); + core.flags.displayExtraDamage = core.getLocalStorage('extraDamage', core.flags.displayExtraDamage); +} + core.prototype._init_platform = function () { core.platform.isOnline = location.protocol.indexOf("http") == 0; if (!core.platform.isOnline) alert("请勿直接打开html文件!使用启动服务或者APP进行离线游戏。"); diff --git a/libs/events.js b/libs/events.js index e15598e3..fd81f219 100644 --- a/libs/events.js +++ b/libs/events.js @@ -16,7 +16,7 @@ events.prototype._init = function () { /// 初始化游戏 events.prototype.resetGame = function (hero, hard, floorId, maps, values) { - return this.eventdata.resetGame(hero, hard, floorId, maps, values); + this.eventdata.resetGame(hero, hard, floorId, maps, values); } ////// 游戏开始事件 ////// @@ -75,7 +75,11 @@ events.prototype._startGame_afterStart = function (nowLoc, callback) { core.ui.closePanel(); core.showStatusBar(); core.dom.musicBtn.style.display = 'none'; - core.changeFloor(core.firstData.floorId, null, nowLoc, null, callback); + core.changeFloor(core.firstData.floorId, null, nowLoc, null, function () { + // 插入一个空事件避免直接回放录像出错 + core.insertAction([]); + if (callback) callback(); + }); this._startGame_upload(); } diff --git a/project/functions.js b/project/functions.js index 64fc7537..64e05bf8 100644 --- a/project/functions.js +++ b/project/functions.js @@ -34,6 +34,7 @@ var functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a = var globalFlags = core.getFlag("globalFlags", {}); for (var key in globalFlags) core.flags[key] = globalFlags[key]; + core._init_sys_flags(); // 初始化界面,状态栏等 core.resize(); core.updateGlobalAttribute(); From 209f10d7a29c096e1320fde8697d31248cdc4ddf Mon Sep 17 00:00:00 2001 From: oc Date: Wed, 27 Mar 2019 00:33:18 +0800 Subject: [PATCH 13/33] drawBook --- libs/ui.js | 267 ++++++++++++++++++++++++++++------------------------- 1 file changed, 143 insertions(+), 124 deletions(-) diff --git a/libs/ui.js b/libs/ui.js index 304f5d8f..14007f9a 100644 --- a/libs/ui.js +++ b/libs/ui.js @@ -1226,151 +1226,170 @@ ui.prototype.drawCursor = function () { ui.prototype.drawBook = function (index) { var floorId = core.floorIds[(core.status.event.ui||{}).index] || core.status.floorId; var enemys = core.enemys.getCurrentEnemys(floorId); - - core.clearSelector(); + core.clearUI(); core.clearMap('data'); + if (this._drawBook_drawBackground(floorId, enemys)) return; + index = core.clamp(index, 0, enemys.length - 1); + var perpage = this.HSIZE, page = parseInt(index / perpage) + 1; + var totalPage = parseInt((enemys.length - 1) / perpage) + 1; + core.status.event.data = index; + var start = (page - 1) * perpage, end = Math.min(page * perpage, enemys.length); + enemys = enemys.slice(start, end); + + for (var i = 0; i < enemys.length; i++) { + this._drawBook_drawOne(floorId, i, enemys[i]); + } + + if (index - start >= 0 && index - start < enemys.length) { + core.strokeRect('ui', 10, 62 * (index - start) + 13, this.PIXEL - 10 * 2, 62, '#FFD700'); + } + + core.drawBoxAnimate(); + this.drawPagination(page, totalPage); + core.fillText('ui', '返回游戏', this.PIXEL - 46, this.PIXEL - 13,'#DDDDDD', this._buildFont(15, true)); +} + +ui.prototype._drawBook_drawBackground = function (floorId, enemys) { // 生成groundPattern core.maps.generateGroundPattern(floorId); core.setFillStyle('ui', core.material.groundPattern); - core.fillRect('ui', 0, 0, 416, 416); + core.fillRect('ui', 0, 0, this.PIXEL, this.PIXEL); core.setAlpha('ui', 0.6); core.setFillStyle('ui', '#000000'); - core.fillRect('ui', 0, 0, 416, 416); + core.fillRect('ui', 0, 0, this.PIXEL, this.PIXEL); core.setAlpha('ui', 1); - core.setTextAlign('ui', 'left'); - var globalFont = core.status.globalAttribute.font; - core.setFont('ui', 'bold 15px '+globalFont); - if (enemys.length == 0) { - core.fillText('ui', "本层无怪物", 83, 222, '#999999', "bold 50px "+globalFont); - // 退出 core.setTextAlign('ui', 'center'); - core.fillText('ui', '返回游戏', 370, 403,'#DDDDDD', 'bold 15px '+globalFont); - return; + core.fillText('ui', "本层无怪物", this.HPIXEL, this.HPIXEL + 14, '#999999', this._buildFont(50, true)); + core.fillText('ui', '返回游戏', this.PIXEL - 46, this.PIXEL - 13,'#DDDDDD', this._buildFont(15, true)); + return true; } + return false; +} - if (index<0) index=0; - if (index>=enemys.length) index=enemys.length-1; - var perpage = 6; - var page=parseInt(index/perpage)+1; - var totalPage = parseInt((enemys.length - 1) / perpage) + 1; - core.status.event.data = index; - var start = (page - 1) * perpage, end = Math.min(page * perpage, enemys.length); +ui.prototype._drawBook_drawOne = function (floorId, index, enemy) { + // --- 区域规划:每个区域总高度为62,宽度为 PIXEL + var top = 62 * index + 12; // 最上面margin是12px + // 横向规划: + // 22 + 42 = 64 是头像框 + this._drawBook_drawBox(index, enemy, top); + // 剩余 PIXEL - 64 的宽度,按照 10 : 9 : 8 : 8 的比例划分 + var left = 64, total_width = this.PIXEL - left; + var name_width = total_width * 10 / 35, + col1_width = total_width * 9 / 35, col1_offset = left + name_width, + col2_width = total_width * 8 / 35, col2_offset = col1_offset + col2_width, + col3_width = total_width * 8 / 35, col3_offset = col2_offset + col3_width; + this._drawBook_drawNameCol(index, enemy, top, left, name_width); - enemys = enemys.slice(start, end); - core.status.boxAnimateObjs = []; - for (var i = 0; i < enemys.length; i++) { - // 边框 - var enemy = enemys[i]; - core.strokeRect('ui', 22, 62 * i + 22, 42, 42, '#DDDDDD', 2); + // 第二行:金币、加点、经验 + var second_line = []; + if (core.flags.enableMoney) second_line.push(["金币", core.formatBigNumber(enemy.money || 0)]); + if (core.flags.enableAddPoint) second_line.push(["加点", core.formatBigNumber(enemy.point || 0)]); + if (core.flags.enableExperience && second_line.length < 2) + second_line.push(["经验", core.formatBigNumber(enemy.experience || 0)]); + var cnt = second_line.length; - var cls = 'enemys'; - if (core.isset(core.material.icons.enemy48[enemy.id])) - cls = 'enemy48'; - var height = cls=='enemy48'?48:32; - var animate = cls=='enemy48'?4:2; + this._drawBook_drawCol1(index, enemy, top, col1_offset, col1_width, second_line); + this._drawBook_drawCol2(index, enemy, top, col2_offset, col2_width, second_line); + this._drawBook_drawCol3(index, enemy, top, col3_offset, col3_width); - // 怪物 - core.status.boxAnimateObjs.push({ - 'bgx': 22, 'bgy': 62 * i + 22, 'bgWidth': 42, 'bgHeight': 42, - 'x': 27, 'y': 62 * i + 27, 'height': 32, 'animate': animate, - 'image': core.material.images[cls], - 'pos': core.material.icons[cls][enemy.id] * height - }); + // get damage offset + var damageOffset = col1_offset + (col1_width + col2_width + col3_width) / 2 - 12; + if (cnt == 1) damageOffset = col2_offset + (col2_width + col3_width) / 2 - 12; + else if (cnt == 2) damageOffset = col3_offset + col3_width / 2 - 12; + this._drawBook_drawDamage(index, enemy, top, damageOffset); +} - // 数据 - core.setTextAlign('ui', 'center'); +ui.prototype._drawBook_drawBox = function (index, enemy, top) { + // 横向:22+42;纵向:10 + 42 + 10(正好居中);内部图像 32x32 + var border_top = top + 10, border_left = 22; + var img_top = border_top + 5, img_left = border_left + 5; + core.strokeRect('ui', 22, border_top, 42, 42, '#DDDDDD', 2); + var blockInfo = core.getBlockInfo(enemy.id); + core.status.boxAnimateObjs.push({ + 'bgx': border_left, 'bgy': border_top, 'bgWidth': 42, 'bgHeight': 42, + 'x': img_left, 'y': img_top, 'height': 32, 'animate': blockInfo.animate, + 'image': blockInfo.image, 'pos': blockInfo.posY * blockInfo.height + }); +} - if (enemy.specialText=='') { - core.fillText('ui', enemy.name, 115, 62 * i + 47, '#DDDDDD', 'bold 17px '+globalFont); - } - else { - core.fillText('ui', enemy.name, 115, 62 * i + 40, '#DDDDDD', 'bold 17px '+globalFont); - core.fillText('ui', enemy.specialText, 115, 62 * i + 62, '#FF6A6A', 'bold 15px '+globalFont); - } - core.setTextAlign('ui', 'left'); - core.fillText('ui', '生命', 165, 62 * i + 32, '#DDDDDD', '13px '+globalFont); - core.fillText('ui', core.formatBigNumber(enemy.hp||0), 195, 62 * i + 32, '#DDDDDD', 'bold 13px '+globalFont); - core.fillText('ui', '攻击', 255, 62 * i + 32, '#DDDDDD', '13px '+globalFont); - core.fillText('ui', core.formatBigNumber(enemy.atk||0), 285, 62 * i + 32, '#DDDDDD', 'bold 13px '+globalFont); - core.fillText('ui', '防御', 335, 62 * i + 32, '#DDDDDD', '13px '+globalFont); - core.fillText('ui', core.formatBigNumber(enemy.def||0), 365, 62 * i + 32, '#DDDDDD', 'bold 13px '+globalFont); - - var expOffset = 165, line_cnt=0; - if (core.flags.enableMoney) { - core.fillText('ui', '金币', 165, 62 * i + 50, '#DDDDDD', '13px '+globalFont); - core.fillText('ui', core.formatBigNumber(enemy.money||0), 195, 62 * i + 50, '#DDDDDD', 'bold 13px '+globalFont); - expOffset = 255; - line_cnt++; - } - - // 加点 - if (core.flags.enableAddPoint) { - core.setTextAlign('ui', 'left'); - core.fillText('ui', '加点', expOffset, 62 * i + 50, '#DDDDDD', '13px '+globalFont); - core.fillText('ui', core.formatBigNumber(enemy.point||0), expOffset + 30, 62 * i + 50, '#DDDDDD', 'bold 13px '+globalFont); - expOffset = 255; - line_cnt++; - } - - if (core.flags.enableExperience && line_cnt<2) { - core.setTextAlign('ui', 'left'); - core.fillText('ui', '经验', expOffset, 62 * i + 50, '#DDDDDD', '13px '+globalFont); - core.fillText('ui', core.formatBigNumber(enemy.experience||0), expOffset + 30, 62 * i + 50, '#DDDDDD', 'bold 13px '+globalFont); - line_cnt++; - } - - var damageOffset = 281; - if (line_cnt==1) damageOffset=326; - if (line_cnt==2) damageOffset=361; - - core.setTextAlign('ui', 'center'); - - var damage = enemy.damage; - var color = '#FFFF00'; - if (damage == null) { - damage = '无法战斗'; - color = '#FF0000'; - } - else { - if (damage >= core.status.hero.hp) color = '#FF0000'; - if (damage<=0) color = '#00FF00'; - - damage = core.formatBigNumber(damage); - if (core.enemys.hasSpecial(enemy, 19)) - damage += "+"; - if (core.enemys.hasSpecial(enemy, 21)) - damage += "-"; - if (core.enemys.hasSpecial(enemy, 11)) - damage += "^"; - } - if (enemy.notBomb) - damage += "[b]"; - core.fillText('ui', damage, damageOffset, 62 * i + 50, color, 'bold 13px '+globalFont); - - core.setTextAlign('ui', 'left'); - - core.fillText('ui', '临界', 165, 62 * i + 68, '#DDDDDD', '13px '+globalFont); - core.fillText('ui', core.formatBigNumber(enemy.critical||0), 195, 62 * i + 68, '#DDDDDD', 'bold 13px '+globalFont); - core.fillText('ui', '减伤', 255, 62 * i + 68, '#DDDDDD', '13px '+globalFont); - core.fillText('ui', core.formatBigNumber(enemy.criticalDamage||0), 285, 62 * i + 68, '#DDDDDD', 'bold 13px '+globalFont); - core.fillText('ui', '1防', 335, 62 * i + 68, '#DDDDDD', '13px '+globalFont); - core.fillText('ui', core.formatBigNumber(enemy.defDamage||0), 365, 62 * i + 68, '#DDDDDD', 'bold 13px '+globalFont); - - if (index == start+i) { - core.strokeRect('ui', 10, 62 * i + 13, 416-10*2, 62, '#FFD700'); - } - - } - core.drawBoxAnimate(); - this.drawPagination(page, totalPage, 12); +ui.prototype._drawBook_drawNameCol = function (index, enemy, top, left, width) { + // 绘制第零列(名称和特殊属性) + // 如果需要添加自己的比如怪物的称号等,也可以在这里绘制 core.setTextAlign('ui', 'center'); - // 退出 - core.fillText('ui', '返回游戏', 370, 403,'#DDDDDD', 'bold 15px '+globalFont); + if (enemy.specialText=='') { + core.fillText('ui', enemy.name, left + width / 2, + top + 35, '#DDDDDD', this._buildFont(17, true)); + } + else { + core.fillText('ui', enemy.name, left + width / 2, + top + 28, '#DDDDDD', this._buildFont(17, true)); + core.fillText('ui', enemy.specialText, left + width / 2, + top + 50, '#FF6A6A', this._buildFont(15, true)); + } +} + +ui.prototype._drawBook_drawCol1 = function (index, enemy, top, left, width, second_line) { + // 绘制第一列 + core.setTextAlign('ui', 'left'); + var b13 = this._buildFont(13, true), f13 = this._buildFont(13, false); + core.fillText('ui', '生命', left, top + 20, '#DDDDDD', f13); + core.fillText('ui', core.formatBigNumber(enemy.hp||0), left + 30, top + 20, null, b13); + if (second_line.length>0) { + var one = second_line.shift(); + core.fillText('ui', one[0], left, top + 38, '#DDDDDD', f13); + core.fillText('ui', one[1], left + 30, top + 38, null, b13); + } + core.fillText('ui', '临界', left, top + 56, '#DDDDDD', f13); + core.fillText('ui', core.formatBigNumber(enemy.critical||0), left + 30, top + 56, null, b13); +} + +ui.prototype._drawBook_drawCol2 = function (index, enemy, top, left, width, second_line) { + // 绘制第二列 + core.setTextAlign('ui', 'left'); + var b13 = this._buildFont(13, true), f13 = this._buildFont(13, false); + core.fillText('ui', '攻击', left, top + 20, '#DDDDDD', f13); + core.fillText('ui', core.formatBigNumber(enemy.atk||0), left + 30, top + 20, null, b13); + if (second_line.length>0) { + var one = second_line.shift(); + core.fillText('ui', one[0], left, top + 38, '#DDDDDD', f13); + core.fillText('ui', one[1], left + 30, top + 38, null, b13); + } + core.fillText('ui', '减伤', left, top + 56, '#DDDDDD', f13); + core.fillText('ui', core.formatBigNumber(enemy.criticalDamage||0), left + 30, top + 56, null, b13); +} + +ui.prototype._drawBook_drawCol3 = function (index, enemy, top, left, width) { + // 绘制第三列 + core.setTextAlign('ui', 'left'); + var b13 = this._buildFont(13, true), f13 = this._buildFont(13, false); + core.fillText('ui', '防御', left, top + 20, '#DDDDDD', f13); + core.fillText('ui', core.formatBigNumber(enemy.def||0), left + 30, top + 20, null, b13); + core.fillText('ui', '1防', left, top + 56, '#DDDDDD', f13); + core.fillText('ui', core.formatBigNumber(enemy.defDamage||0), left + 30, top + 56, null, b13); +} + +ui.prototype._drawBook_drawDamage = function (index, enemy, top, damageOffset) { + core.setTextAlign('ui', 'center'); + var damage = enemy.damage, color = '#FFFF00'; + if (damage == null) { + damage = '无法战斗'; + color = '#FF0000'; + } + else { + if (damage >= core.status.hero.hp) color = '#FF0000'; + if (damage <= 0) color = '#00FF00'; + damage = core.formatBigNumber(damage); + if (core.enemys.hasSpecial(enemy, 19)) damage += "+"; + if (core.enemys.hasSpecial(enemy, 21)) damage += "-"; + if (core.enemys.hasSpecial(enemy, 11)) damage += "^"; + } + if (enemy.notBomb) damage += "[b]"; + core.fillText('ui', damage, damageOffset, top + 38, color, this._buildFont(13, true)); } ////// 绘制怪物属性的详细信息 ////// From eb9dbf1953ebb66fdef5acb1920afded6e1b3c50 Mon Sep 17 00:00:00 2001 From: ckcz123 Date: Wed, 27 Mar 2019 17:46:34 +0800 Subject: [PATCH 14/33] drawBook_row & drawBackground --- libs/ui.js | 275 +++++++++++++++++++++++++++-------------------------- 1 file changed, 138 insertions(+), 137 deletions(-) diff --git a/libs/ui.js b/libs/ui.js index 14007f9a..7cdd32b7 100644 --- a/libs/ui.js +++ b/libs/ui.js @@ -455,6 +455,57 @@ ui.prototype.drawWindowSkin = function(background, ctx, x, y, w, h, direction, p // 仿RM窗口皮肤 ↑ } +////// 绘制一个背景图,可绘制 winskin 或纯色背景;支持小箭头绘制 +ui.prototype.drawBackground = function (left, top, right, bottom, posInfo) { + posInfo = posInfo || {}; + var px = posInfo.px == null ? null : posInfo.px * 32 - core.bigmap.offsetX; + var py = posInfo.py == null ? null : posInfo.py * 32 - core.bigmap.offsetY; + var xoffset = posInfo.xoffset || 0, yoffset = posInfo.yoffset || 0; + var background = core.status.textAttribute.background; + + 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', 0.85); + this.drawWindowSkin(image, 'ui', left, top, right - left, bottom - top, posInfo.position, px, py); + core.setAlpha('ui', 1); + return true; + } + background = core.initStatus.textAttribute.background; + } + + var alpha = background[3]; + core.setAlpha('ui', alpha); + core.setStrokeStyle('ui', core.status.globalAttribute.borderColor); + core.setFillStyle('ui', core.arrayToRGB(background)); + core.setLineWidth('ui', 2); + + // 绘制 + var ctx = core.canvas.ui; + ctx.beginPath(); + ctx.moveTo(left, top); + // 上边缘三角 + if (posInfo.position == 'down' && px != null && py != null) { + ctx.lineTo(px + xoffset, top); + ctx.lineTo(px + 16, top - yoffset); + ctx.lineTo(px + 32 - xoffset, top); + } + ctx.lineTo(right, top); + ctx.lineTo(right, bottom); + // 下边缘三角 + if (posInfo.position == 'up' && px != null && py != null) { + ctx.lineTo(px + 32 - xoffset, bottom); + ctx.lineTo(px + 16, bottom + yoffset); + ctx.lineTo(px + xoffset, bottom); + } + ctx.lineTo(left, bottom); + ctx.closePath(); + ctx.fill(); + ctx.stroke(); + core.setAlpha('ui', 1); + return false; +} + ////// 计算有效文本框的宽度 ui.prototype.calTextBoxWidth = function (ctx, content, min_width, max_width, font) { // 无限长度自动换行 @@ -697,8 +748,10 @@ ui.prototype.drawTextBox = function(content, showAll) { var vPos = this._drawTextBox_getVerticalPosition(content, titleInfo, posInfo, hPos.validWidth); // Step 3: 绘制背景图 - var isWindowSkin = this._drawTextBox_drawBackground(titleInfo, posInfo, hPos, vPos); - var alpha = isWindowSkin ? 0.85 : (textAttribute.background[3] || core.initStatus.textAttribute.background[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 alpha = isWindowSkin ? 0.85 : textAttribute.background[3]; // Step 4: 绘制标题、头像、 var content_top = this._drawTextBox_drawTitleAndIcon(titleInfo, hPos, vPos, alpha); @@ -780,56 +833,6 @@ ui.prototype._drawTextBox_getVerticalPosition = function (content, titleInfo, po return { top: top, height: height, bottom: top + height, yoffset: yoffset, lineHeight: lineHeight }; } -ui.prototype._drawTextBox_drawBackground = function (titleInfo, posInfo, hPos, vPos) { - var background = core.status.textAttribute.background; - var px = posInfo.px == null ? null : posInfo.px * 32 - core.bigmap.offsetX; - var py = posInfo.py == null ? null : posInfo.py * 32 - core.bigmap.offsetY; - var xoffset = hPos.xoffset, yoffset = vPos.yoffset - 4; - var left = hPos.left, right = hPos.right, top = vPos.top, bottom = vPos.bottom; - - 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', 0.85); - this.drawWindowSkin(image, 'ui', left, top, right - left, bottom - top, posInfo.position, px, py); - core.setAlpha('ui', 1); - return true; - } - background = core.initStatus.textAttribute.background; - } - - var alpha = background[3]; - core.setAlpha('ui', alpha); - core.setStrokeStyle('ui', core.status.globalAttribute.borderColor); - core.setFillStyle('ui', core.arrayToRGB(background)); - core.setLineWidth('ui', 2); - - // 绘制 - var ctx = core.canvas.ui; - ctx.beginPath(); - ctx.moveTo(left, top); - // 上边缘三角 - if (posInfo.position == 'down' && px != null && py != null) { - ctx.lineTo(px + xoffset, top); - ctx.lineTo(px + 16, top - yoffset); - ctx.lineTo(px + 32 - xoffset, top); - } - ctx.lineTo(right, top); - ctx.lineTo(right, bottom); - // 下边缘三角 - if (posInfo.position == 'up' && px != null && py != null) { - ctx.lineTo(px + 32 - xoffset, bottom); - ctx.lineTo(px + 16, bottom + yoffset); - ctx.lineTo(px + xoffset, bottom); - } - ctx.lineTo(left, bottom); - ctx.closePath(); - ctx.fill(); - ctx.stroke(); - core.setAlpha('ui', 1); - return false; -} - ui.prototype._drawTextBox_drawTitleAndIcon = function (titleInfo, hPos, vPos, alpha) { core.setTextAlign('ui', 'left'); var textAttribute = core.status.textAttribute; @@ -939,7 +942,7 @@ ui.prototype.drawChoices = function(content, choices) { var hPos = this._drawChoices_getHorizontalPosition(titleInfo, choices); var vPos = this._drawChoices_getVerticalPosition(titleInfo, choices, hPos); - var isWindowSkin = this._drawTextBox_drawBackground(titleInfo, {}, hPos, vPos); + 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); } @@ -1035,7 +1038,7 @@ ui.prototype._drawChoices_drawChoices = function (choices, isWindowSkin, hPos, v 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.material.images.images[core.status.textAttribute.background], + 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.strokeRect('ui', this.HPIXEL - len/2 - 5, vPos.choice_top + 32 * core.status.event.selection - 20, @@ -1057,7 +1060,7 @@ ui.prototype.drawConfirmBox = function (text, yesCallback, noCallback) { core.setFont('ui', this._buildFont(19, true)); var contents = text.split("\n"); var rect = this._drawConfirmBox_getRect(contents); - var isWindowSkin = this._drawTextBox_drawBackground({}, {}, rect, rect); + var isWindowSkin = this.drawBackground(rect.left, rect.top, rect.right, rect.bottom); core.setTextAlign('ui', 'center'); core.setFillStyle('ui', core.arrayToRGBA(core.status.textAttribute.text)) @@ -1133,7 +1136,7 @@ ui.prototype.drawWaiting = function(text) { var text_length = core.calWidth('ui', text, this._buildFont(19, true)); var width = Math.max(text_length + 80, 220), left = this.HPIXEL - parseInt(width / 2), right = left + width; var top = this.HPIXEL - 48, height = 96, bottom = top + height; - this._drawTextBox_drawBackground({}, {}, {left: left, right: right}, {top: top, bottom: bottom}); + this.drawBackground(left, top, right, bottom); core.setTextAlign('ui', 'center'); core.fillText('ui', text, this.HPIXEL, top + 56, core.arrayToRGBA(core.status.textAttribute.text)); } @@ -1228,50 +1231,43 @@ ui.prototype.drawBook = function (index) { var enemys = core.enemys.getCurrentEnemys(floorId); core.clearUI(); core.clearMap('data'); + // 生成groundPattern + core.maps.generateGroundPattern(floorId); + this._drawBook_drawBackground(); + core.setAlpha('ui', 1); + + if (enemys.length == 0) { + core.setTextAlign('ui', 'center'); + core.fillText('ui', "本层无怪物", this.HPIXEL, this.HPIXEL + 14, '#999999', this._buildFont(50, true)); + core.fillText('ui', '返回游戏', this.PIXEL - 46, this.PIXEL - 13,'#DDDDDD', this._buildFont(15, true)); + return; + } - if (this._drawBook_drawBackground(floorId, enemys)) return; index = core.clamp(index, 0, enemys.length - 1); - var perpage = this.HSIZE, page = parseInt(index / perpage) + 1; - var totalPage = parseInt((enemys.length - 1) / perpage) + 1; core.status.event.data = index; - var start = (page - 1) * perpage, end = Math.min(page * perpage, enemys.length); - enemys = enemys.slice(start, end); + var perpage = this.HSIZE, page = parseInt(index / perpage) + 1, totalPage = Math.ceil(enemys.length / perpage); + var start = (page - 1) * perpage; + enemys = enemys.slice(start, page * perpage); - for (var i = 0; i < enemys.length; i++) { - this._drawBook_drawOne(floorId, i, enemys[i]); - } - - if (index - start >= 0 && index - start < enemys.length) { - core.strokeRect('ui', 10, 62 * (index - start) + 13, this.PIXEL - 10 * 2, 62, '#FFD700'); - } + for (var i = 0; i < enemys.length; i++) + this._drawBook_drawOne(floorId, i, enemys[i], index == start + i); core.drawBoxAnimate(); this.drawPagination(page, totalPage); core.fillText('ui', '返回游戏', this.PIXEL - 46, this.PIXEL - 13,'#DDDDDD', this._buildFont(15, true)); } -ui.prototype._drawBook_drawBackground = function (floorId, enemys) { - // 生成groundPattern - core.maps.generateGroundPattern(floorId); - +ui.prototype._drawBook_drawBackground = function () { + core.setAlpha('ui', 1); core.setFillStyle('ui', core.material.groundPattern); core.fillRect('ui', 0, 0, this.PIXEL, this.PIXEL); core.setAlpha('ui', 0.6); core.setFillStyle('ui', '#000000'); core.fillRect('ui', 0, 0, this.PIXEL, this.PIXEL); - - core.setAlpha('ui', 1); - if (enemys.length == 0) { - core.setTextAlign('ui', 'center'); - core.fillText('ui', "本层无怪物", this.HPIXEL, this.HPIXEL + 14, '#999999', this._buildFont(50, true)); - core.fillText('ui', '返回游戏', this.PIXEL - 46, this.PIXEL - 13,'#DDDDDD', this._buildFont(15, true)); - return true; - } - return false; } -ui.prototype._drawBook_drawOne = function (floorId, index, enemy) { +ui.prototype._drawBook_drawOne = function (floorId, index, enemy, selected) { // --- 区域规划:每个区域总高度为62,宽度为 PIXEL var top = 62 * index + 12; // 最上面margin是12px // 横向规划: @@ -1279,29 +1275,11 @@ ui.prototype._drawBook_drawOne = function (floorId, index, enemy) { this._drawBook_drawBox(index, enemy, top); // 剩余 PIXEL - 64 的宽度,按照 10 : 9 : 8 : 8 的比例划分 var left = 64, total_width = this.PIXEL - left; - var name_width = total_width * 10 / 35, - col1_width = total_width * 9 / 35, col1_offset = left + name_width, - col2_width = total_width * 8 / 35, col2_offset = col1_offset + col2_width, - col3_width = total_width * 8 / 35, col3_offset = col2_offset + col3_width; - this._drawBook_drawNameCol(index, enemy, top, left, name_width); - - // 第二行:金币、加点、经验 - var second_line = []; - if (core.flags.enableMoney) second_line.push(["金币", core.formatBigNumber(enemy.money || 0)]); - if (core.flags.enableAddPoint) second_line.push(["加点", core.formatBigNumber(enemy.point || 0)]); - if (core.flags.enableExperience && second_line.length < 2) - second_line.push(["经验", core.formatBigNumber(enemy.experience || 0)]); - var cnt = second_line.length; - - this._drawBook_drawCol1(index, enemy, top, col1_offset, col1_width, second_line); - this._drawBook_drawCol2(index, enemy, top, col2_offset, col2_width, second_line); - this._drawBook_drawCol3(index, enemy, top, col3_offset, col3_width); - - // get damage offset - var damageOffset = col1_offset + (col1_width + col2_width + col3_width) / 2 - 12; - if (cnt == 1) damageOffset = col2_offset + (col2_width + col3_width) / 2 - 12; - else if (cnt == 2) damageOffset = col3_offset + col3_width / 2 - 12; - this._drawBook_drawDamage(index, enemy, top, damageOffset); + var name_width = total_width * 10 / 35; + this._drawBook_drawName(index, enemy, top, left, name_width); + this._drawBook_drawContent(index, enemy, top, left + name_width); + if (selected) + core.strokeRect('ui', 10, top + 1, this.PIXEL - 10 * 2, 62, '#FFD700'); } ui.prototype._drawBook_drawBox = function (index, enemy, top) { @@ -1317,7 +1295,7 @@ ui.prototype._drawBook_drawBox = function (index, enemy, top) { }); } -ui.prototype._drawBook_drawNameCol = function (index, enemy, top, left, width) { +ui.prototype._drawBook_drawName = function (index, enemy, top, left, width) { // 绘制第零列(名称和特殊属性) // 如果需要添加自己的比如怪物的称号等,也可以在这里绘制 core.setTextAlign('ui', 'center'); @@ -1333,47 +1311,70 @@ ui.prototype._drawBook_drawNameCol = function (index, enemy, top, left, width) { } } -ui.prototype._drawBook_drawCol1 = function (index, enemy, top, left, width, second_line) { - // 绘制第一列 +ui.prototype._drawBook_drawContent = function (index, enemy, top, left) { + var width = this.PIXEL - left; // 9 : 8 : 8 划分三列 + this._drawBook_drawRow1(index, enemy, top, left, width, top + 20); + this._drawBook_drawRow2(index, enemy, top, left, width, top + 38); + this._drawBook_drawRow3(index, enemy, top, left, width, top + 56); +} + +ui.prototype._drawBook_drawRow1 = function (index, enemy, top, left, width, position) { + // 绘制第一行 core.setTextAlign('ui', 'left'); var b13 = this._buildFont(13, true), f13 = this._buildFont(13, false); - core.fillText('ui', '生命', left, top + 20, '#DDDDDD', f13); - core.fillText('ui', core.formatBigNumber(enemy.hp||0), left + 30, top + 20, null, b13); - if (second_line.length>0) { + var col1 = left, col2 = left + width * 9 / 25, col3 = left + width * 17 / 25; + core.fillText('ui', '生命', col1, position, '#DDDDDD', f13); + core.fillText('ui', core.formatBigNumber(enemy.hp||0), col1 + 30, position, null, b13); + core.fillText('ui', '攻击', col2, position, null, f13); + core.fillText('ui', core.formatBigNumber(enemy.atk||0), col2 + 30, position, null, b13); + core.fillText('ui', '防御', col3, position, null, f13); + core.fillText('ui', core.formatBigNumber(enemy.def||0), col3 + 30, position, null, b13); +} + +ui.prototype._drawBook_drawRow2 = function (index, enemy, top, left, width, position) { + // 绘制第三行 + core.setTextAlign('ui', 'left'); + var b13 = this._buildFont(13, true), f13 = this._buildFont(13, false); + var col1 = left, col2 = left + width * 9 / 25, col3 = left + width * 17 / 25; + // 获得第二行绘制的内容 + var second_line = []; + if (core.flags.enableMoney) second_line.push(["金币", core.formatBigNumber(enemy.money || 0)]); + if (core.flags.enableAddPoint) second_line.push(["加点", core.formatBigNumber(enemy.point || 0)]); + if (core.flags.enableExperience) second_line.push(["经验", core.formatBigNumber(enemy.experience || 0)]); + + var damage_offset = col1 + (this.PIXEL - col1) / 2 - 12; + // 第一列 + if (second_line.length > 0) { var one = second_line.shift(); - core.fillText('ui', one[0], left, top + 38, '#DDDDDD', f13); - core.fillText('ui', one[1], left + 30, top + 38, null, b13); + core.fillText('ui', one[0], col1, position, '#DDDDDD', f13); + core.fillText('ui', one[1], col1 + 30, position, null, b13); + damage_offset = col2 + (this.PIXEL - col2) / 2 - 12; } - core.fillText('ui', '临界', left, top + 56, '#DDDDDD', f13); - core.fillText('ui', core.formatBigNumber(enemy.critical||0), left + 30, top + 56, null, b13); -} - -ui.prototype._drawBook_drawCol2 = function (index, enemy, top, left, width, second_line) { - // 绘制第二列 - core.setTextAlign('ui', 'left'); - var b13 = this._buildFont(13, true), f13 = this._buildFont(13, false); - core.fillText('ui', '攻击', left, top + 20, '#DDDDDD', f13); - core.fillText('ui', core.formatBigNumber(enemy.atk||0), left + 30, top + 20, null, b13); - if (second_line.length>0) { + // 第二列 + if (second_line.length > 0) { var one = second_line.shift(); - core.fillText('ui', one[0], left, top + 38, '#DDDDDD', f13); - core.fillText('ui', one[1], left + 30, top + 38, null, b13); + core.fillText('ui', one[0], col2, position, '#DDDDDD', f13); + core.fillText('ui', one[1], col2 + 30, position, null, b13); + damage_offset = col3 + (this.PIXEL - col3) / 2 - 12; } - core.fillText('ui', '减伤', left, top + 56, '#DDDDDD', f13); - core.fillText('ui', core.formatBigNumber(enemy.criticalDamage||0), left + 30, top + 56, null, b13); + // 忽略第三列,直接绘制伤害 + this._drawBook_drawDamage(index, enemy, damage_offset, position); } -ui.prototype._drawBook_drawCol3 = function (index, enemy, top, left, width) { - // 绘制第三列 +ui.prototype._drawBook_drawRow3 = function (index, enemy, top, left, width, position) { + // 绘制第三行 core.setTextAlign('ui', 'left'); var b13 = this._buildFont(13, true), f13 = this._buildFont(13, false); - core.fillText('ui', '防御', left, top + 20, '#DDDDDD', f13); - core.fillText('ui', core.formatBigNumber(enemy.def||0), left + 30, top + 20, null, b13); - core.fillText('ui', '1防', left, top + 56, '#DDDDDD', f13); - core.fillText('ui', core.formatBigNumber(enemy.defDamage||0), left + 30, top + 56, null, b13); + var col1 = left, col2 = left + width * 9 / 25, col3 = left + width * 17 / 25; + core.fillText('ui', '临界', col1, position, '#DDDDDD', f13); + core.fillText('ui', core.formatBigNumber(enemy.critical||0), col1 + 30, position, null, b13); + core.fillText('ui', '减伤', col2, position, null, f13); + core.fillText('ui', core.formatBigNumber(enemy.criticalDamage||0), col2 + 30, position, null, b13); + core.fillText('ui', '1防', col3, position, null, f13); + core.fillText('ui', core.formatBigNumber(enemy.defDamage||0), col3 + 30, position, null, b13); } -ui.prototype._drawBook_drawDamage = function (index, enemy, top, damageOffset) { +ui.prototype._drawBook_drawDamage = function (index, enemy, offset, position) { core.setTextAlign('ui', 'center'); var damage = enemy.damage, color = '#FFFF00'; if (damage == null) { @@ -1389,7 +1390,7 @@ ui.prototype._drawBook_drawDamage = function (index, enemy, top, damageOffset) { if (core.enemys.hasSpecial(enemy, 11)) damage += "^"; } if (enemy.notBomb) damage += "[b]"; - core.fillText('ui', damage, damageOffset, top + 38, color, this._buildFont(13, true)); + core.fillText('ui', damage, offset, position, color, this._buildFont(13, true)); } ////// 绘制怪物属性的详细信息 ////// @@ -2177,7 +2178,7 @@ ui.prototype.drawKeyBoard = function () { var left = (this.PIXEL - width) / 2, right = left + width; var top = (this.PIXEL - height) / 2, bottom = top + height; - var isWindowSkin = this._drawTextBox_drawBackground({}, {}, {left:left, right:right}, {top:top, bottom: bottom}); + var isWindowSkin = this.drawBackground(left, top, right, bottom); core.setTextAlign('ui', 'center'); core.setFillStyle('ui', core.arrayToRGBA(core.status.textAttribute.title)); core.fillText('ui', '虚拟键盘', this.HPIXEL, top + 35, null, this._buildFont(22, true)); From 13b09ff91160b891ef03dcb8f50beea9542c0d69 Mon Sep 17 00:00:00 2001 From: oc Date: Thu, 28 Mar 2019 00:24:13 +0800 Subject: [PATCH 15/33] type:insert set args --- libs/events.js | 3 ++- libs/ui.js | 5 +++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/libs/events.js b/libs/events.js index fd81f219..a79963ff 100644 --- a/libs/events.js +++ b/libs/events.js @@ -1163,7 +1163,8 @@ events.prototype._action_insert = function (data, x, y, prefix) { if (data.args instanceof Array) { for (var i = 0; i < data.args.length; ++i) { try { - core.setFlag('arg'+(i+1), core.calValue(data.args[i], prefix)); + if (data.args[i] != null) + core.setFlag('arg'+(i+1), data.args[i]); } catch (e) { main.log(e); } } } diff --git a/libs/ui.js b/libs/ui.js index 7cdd32b7..956234ba 100644 --- a/libs/ui.js +++ b/libs/ui.js @@ -1332,7 +1332,7 @@ ui.prototype._drawBook_drawRow1 = function (index, enemy, top, left, width, posi } ui.prototype._drawBook_drawRow2 = function (index, enemy, top, left, width, position) { - // 绘制第三行 + // 绘制第二行 core.setTextAlign('ui', 'left'); var b13 = this._buildFont(13, true), f13 = this._buildFont(13, false); var col1 = left, col2 = left + width * 9 / 25, col3 = left + width * 17 / 25; @@ -1396,6 +1396,7 @@ ui.prototype._drawBook_drawDamage = function (index, enemy, offset, position) { ////// 绘制怪物属性的详细信息 ////// ui.prototype.drawBookDetail = function (index) { var info = this._drawBookDetail_getInfo(index), enemy = info[0]; + if (!enemy) return; var content = info[1].join("\n"); core.status.event.id = 'book-detail'; clearInterval(core.interval.tipAnimate); @@ -1418,7 +1419,7 @@ ui.prototype.drawBookDetail = function (index) { ui.prototype._drawBookDetail_getInfo = function (index) { var floorId = core.floorIds[(core.status.event.ui||{}).index] || core.status.floorId; var enemys = core.enemys.getCurrentEnemys(floorId); - if (enemys.length==0) return; + if (enemys.length==0) return []; index = core.clamp(index, 0, enemys.length - 1); var enemy = enemys[index], enemyId = enemy.id; var texts=core.enemys.getSpecialHint(enemyId); From dd48678d2d43c108fe2447cf157230f1e904cc01 Mon Sep 17 00:00:00 2001 From: oc Date: Thu, 28 Mar 2019 00:40:22 +0800 Subject: [PATCH 16/33] Fix animateBlock for none --- libs/maps.js | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/libs/maps.js b/libs/maps.js index cb7dbb7b..f09d6b27 100644 --- a/libs/maps.js +++ b/libs/maps.js @@ -1696,6 +1696,7 @@ maps.prototype.animateBlock = function (loc, type, time, callback) { var isHide = type == 'hide'; if (typeof loc[0] == 'number' && typeof loc[1] == 'number') loc = [loc]; + // --- 检测所有是0的点 var list = this._animateBlock_getList(loc); if (list.length == 0) { if (callback) callback(); @@ -1714,7 +1715,8 @@ maps.prototype._animateBlock_doAnimate = function (loc, list, isHide, delta, cal delete core.animateFrame.asyncId[animate]; clearInterval(animate); list.forEach(function (t) { - core.maps._deleteDetachedBlock(t.canvases); + if (t.blockInfo) + core.maps._deleteDetachedBlock(t.canvases); }); loc.forEach(function (t) { if (isHide) core.removeBlock(t[0], t[1]); @@ -1735,7 +1737,10 @@ maps.prototype._animateBlock_getList = function (loc) { block = block.block; var blockInfo = core.maps.getBlockInfo(block); - if (blockInfo == null) return; + if (blockInfo == null) { + list.push({ 'x': t[0], 'y': t[1] }); + return; + } var canvases = core.maps._initDetachedBlock(blockInfo, t[0], t[1], block.event.displayDamage !== false); list.push({ @@ -1748,7 +1753,8 @@ maps.prototype._animateBlock_getList = function (loc) { maps.prototype._animateBlock_drawList = function (list, opacity) { list.forEach(function (t) { - core.maps._moveDetachedBlock(t.blockInfo, t.x * 32, t.y * 32, opacity, t.canvases); + if (t.blockInfo) + core.maps._moveDetachedBlock(t.blockInfo, t.x * 32, t.y * 32, opacity, t.canvases); }); } From 2b0de5127d72176c673de36556d42197c77f14a0 Mon Sep 17 00:00:00 2001 From: oc Date: Thu, 28 Mar 2019 01:26:59 +0800 Subject: [PATCH 17/33] fix drawHero in gameOver --- libs/control.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/control.js b/libs/control.js index e3946a74..9b5272d9 100644 --- a/libs/control.js +++ b/libs/control.js @@ -795,7 +795,7 @@ control.prototype.tryMoveDirectly = function (destX, destY) { ////// 绘制勇士 ////// control.prototype.drawHero = function (status, offset) { - if (!core.isPlaying() || !core.status.floorId) return; + if (!core.isPlaying() || !core.status.floorId || core.status.gameOver) return; var x = core.getHeroLoc('x'), y = core.getHeroLoc('y'), direction = core.getHeroLoc('direction'); status = status || 'stop'; offset = offset || 0; From bf20f9ce929bf30d0a933bef0ea60ce1c98c54ce Mon Sep 17 00:00:00 2001 From: ckcz123 Date: Thu, 28 Mar 2019 15:19:20 +0800 Subject: [PATCH 18/33] buildFont --- libs/ui.js | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/libs/ui.js b/libs/ui.js index 956234ba..9c326cc7 100644 --- a/libs/ui.js +++ b/libs/ui.js @@ -543,7 +543,8 @@ ui.prototype._getDrawableIconInfo = function (id) { } ui.prototype._buildFont = function (fontSize, bold) { - var textAttribute = core.status.textAttribute, globalAttribute = core.status.globalAttribute; + var textAttribute = core.status.textAttribute || core.initStatus.textAttribute, + globalAttribute = core.status.globalAttribute || core.initStatus.globalAttribute; if (bold == null) bold = textAttribute.bold; return (bold?"bold ":"") + (fontSize || textAttribute.textfont) + "px " + globalAttribute.font; } @@ -844,7 +845,7 @@ ui.prototype._drawTextBox_drawTitleAndIcon = function (titleInfo, hPos, vPos, al core.setStrokeStyle('ui', core.arrayToRGB(textAttribute.title)); // --- title也要居中或者右对齐? - var title_width = core.calWidth('ui', titleInfo.title, 'bold '+titlefont+'px '+core.status.globalAttribute.font); + var title_width = core.calWidth('ui', 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; @@ -950,7 +951,7 @@ ui.prototype.drawChoices = function(content, choices) { ui.prototype._drawChoices_getHorizontalPosition = function (titleInfo, choices) { // 宽度计算:考虑选项的长度 var width = 246; - core.setFont('ui', "bold 17px "+core.status.globalAttribute.font); + core.setFont('ui', this._buildFont(17, true)); for (var i = 0; i < choices.length; i++) { if (typeof choices[i] === 'string') choices[i] = {"text": choices[i]}; @@ -1002,7 +1003,7 @@ ui.prototype._drawChoices_drawTitle = function (titleInfo, hPos, vPos) { }; core.fillText('ui', titleInfo.title, title_offset, vPos.top + 27, - core.arrayToRGBA(core.status.textAttribute.title), 'bold 19px '+core.status.globalAttribute.font); + core.arrayToRGBA(core.status.textAttribute.title), this._buildFont(19, true)); } core.setTextAlign('ui', 'left'); @@ -1015,7 +1016,7 @@ ui.prototype._drawChoices_drawTitle = function (titleInfo, hPos, vPos) { ui.prototype._drawChoices_drawChoices = function (choices, isWindowSkin, hPos, vPos) { // 选项 core.setTextAlign('ui', 'center'); - core.setFont('ui', "bold 17px " + core.status.globalAttribute.font); + core.setFont('ui', this._buildFont(17, true)); for (var i = 0; i < choices.length; i++) { var color = choices[i].color || core.status.textAttribute.text; if (color instanceof Array) color = core.arrayToRGBA(color); @@ -1195,8 +1196,7 @@ ui.prototype.drawPagination = function (page, totalPage, top) { if (top == null) top = this.LAST; core.setFillStyle('ui', '#DDDDDD'); - var length = core.calWidth('ui', page + " / " + page, - "bold 15px " + (core.status.globalAttribute || core.initStatus.globalAttribute).font); + var length = core.calWidth('ui', page + " / " + page, this._buildFont(15, true)); core.setTextAlign('ui', 'left'); core.fillText('ui', page + " / " + totalPage, parseInt((this.PIXEL - length) / 2), top*32+19); From d7fb0a2f3f742d48dc86ee5476dc7b1aac237560 Mon Sep 17 00:00:00 2001 From: ckcz123 Date: Thu, 28 Mar 2019 15:58:01 +0800 Subject: [PATCH 19/33] Custom System Event --- _server/comment.js | 4 ++-- libs/events.js | 7 ++++++- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/_server/comment.js b/_server/comment.js index cdf576e4..d4c1ac53 100644 --- a/_server/comment.js +++ b/_server/comment.js @@ -227,8 +227,8 @@ var comment_c456ea59_6018_45ef_8bcc_211a24c627dc = "openDoor", "passNet", "changeLight", - "ski", - "pushBox" + "pushBox", + "custom" ] }, "_data": "该图块的默认触发器" diff --git a/libs/events.js b/libs/events.js index a79963ff..7a0bef05 100644 --- a/libs/events.js +++ b/libs/events.js @@ -251,7 +251,7 @@ events.prototype.unregisterSystemEvent = function (type) { events.prototype.doSystemEvent = function (type, data, callback) { if (this.systemEvents[type]) { try { - return core.doFunc(this.systemEvents[type], this, data, data, callback); + return core.doFunc(this.systemEvents[type], this, data, callback); } catch (e) { main.log(e); @@ -688,6 +688,11 @@ events.prototype._sys_action = function (data, callback) { this.insertAction(ev, ex, ey, callback); } +events.prototype._sys_custom = function (data, callback) { + core.insertAction(["请使用\r[yellow]core.registerSystemEvent('custom', func)\r来处理自己添加的系统触发器!"], + data.x, data.y, callback); +} + // ------ 自定义事件的处理 ------ // ////// 注册一个自定义事件 ////// From 5e978fa2d416f5f4399a342244d2e9beed827924 Mon Sep 17 00:00:00 2001 From: ckcz123 Date: Thu, 28 Mar 2019 19:38:44 +0800 Subject: [PATCH 20/33] format date --- libs/ui.js | 9 ++------- libs/utils.js | 6 ++++++ 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/libs/ui.js b/libs/ui.js index 9c326cc7..e145f275 100644 --- a/libs/ui.js +++ b/libs/ui.js @@ -2224,17 +2224,12 @@ ui.prototype.drawStatistics = function (floorIds) { (floorIds || core.floorIds).forEach(function (floorId) { core.ui._drawStatistics_floorId(floorId, obj); }); - var formatTime = function (time) { - return core.setTwoDigits(parseInt(time/3600000)) - +":"+core.setTwoDigits(parseInt(time/60000)%60) - +":"+core.setTwoDigits(parseInt(time/1000)%60); - } var statistics = core.status.hero.statistics; core.drawText([ this._drawStatistics_generateText(obj, "全塔", obj.total), this._drawStatistics_generateText(obj, "当前", obj.current), - "当前总步数:"+core.status.hero.steps+",当前游戏时长:"+formatTime(statistics.currTime) - +",总游戏时长"+formatTime(statistics.totalTime) + "当前总步数:"+core.status.hero.steps+",当前游戏时长:"+core.formatTime(statistics.currTime) + +",总游戏时长"+core.formatTime(statistics.totalTime) +"。\n瞬间移动次数:"+statistics.moveDirectly+",共计少走"+statistics.ignoreSteps+"步。" +"\n\n总计通过血瓶恢复生命值为"+core.formatBigNumber(statistics.hp)+"点。\n\n" +"总计打死了"+statistics.battle+"个怪物,得到了"+core.formatBigNumber(statistics.money)+"金币,"+core.formatBigNumber(statistics.experience)+"点经验。\n\n" diff --git a/libs/utils.js b/libs/utils.js index 1bca52b0..d3bac9d3 100644 --- a/libs/utils.js +++ b/libs/utils.js @@ -348,6 +348,12 @@ utils.prototype.formatDate2 = function (date) { + core.setTwoDigits(date.getHours()) + core.setTwoDigits(date.getMinutes()) + core.setTwoDigits(date.getSeconds()); } +utils.prototype.formatTime = function (time) { + return core.setTwoDigits(parseInt(time/3600000)) + +":"+core.setTwoDigits(parseInt(time/60000)%60) + +":"+core.setTwoDigits(parseInt(time/1000)%60); +} + ////// 两位数显示 ////// utils.prototype.setTwoDigits = function (x) { return parseInt(x) < 10 ? "0" + x : x; From 90407e94a09587ab654a600cf724b0abbb3c7262 Mon Sep 17 00:00:00 2001 From: oc Date: Fri, 29 Mar 2019 00:43:26 +0800 Subject: [PATCH 21/33] drawToolbox --- libs/actions.js | 85 +++++++++++----------- libs/ui.js | 182 +++++++++++++++++++++--------------------------- 2 files changed, 124 insertions(+), 143 deletions(-) diff --git a/libs/actions.js b/libs/actions.js index c8e9baeb..31089b5b 100644 --- a/libs/actions.js +++ b/libs/actions.js @@ -1234,49 +1234,47 @@ actions.prototype._keyUpQuickShop = function (keycode) { ////// 工具栏界面时的点击操作 ////// actions.prototype._clickToolbox = function (x, y) { // 装备栏 - if (x >= 10 && x <= 12 && y == 0) { + if (x >= this.LAST - 2 && y == 0) { core.ui.closePanel(); core.openEquipbox(); return; } - // 返回 - if (x >= 10 && x <= 12 && y == 12) { + if (x >= this.LAST - 2 && y == this.LAST) { core.ui.closePanel(); return; } + var toolsPage = core.status.event.data.toolsPage; var constantsPage = core.status.event.data.constantsPage; // 上一页 - if (x == 3 || x == 4) { - if (y == 7 && toolsPage > 1) { + if (x == this.HSIZE-2 || x == this.HSIZE-3) { + if (y == this.LAST - 5 && toolsPage > 1) { core.status.event.data.toolsPage--; core.ui.drawToolbox(core.status.event.selection); } - if (y == 12 && constantsPage > 1) { + if (y == this.LAST && constantsPage > 1) { core.status.event.data.toolsPage--; core.ui.drawToolbox(core.status.event.selection); } } // 下一页 - if (x == 8 || x == 9) { - if (y == 7 && toolsPage < Math.ceil(Object.keys(core.status.hero.items.tools).length / 12)) { + if (x == this.HSIZE+2 || x == this.HSIZE+3) { + if (y == this.LAST - 5 && toolsPage < Math.ceil(Object.keys(core.status.hero.items.tools).length / this.LAST)) { core.status.event.data.toolsPage++; core.ui.drawToolbox(core.status.event.selection); } - if (y == 12 && constantsPage < Math.ceil(Object.keys(core.status.hero.items.constants).length / 12)) { + if (y == this.LAST && constantsPage < Math.ceil(Object.keys(core.status.hero.items.constants).length / this.LAST)) { core.status.event.data.constantsPage++; core.ui.drawToolbox(core.status.event.selection); } } var index = parseInt(x / 2); - ; - if (y == 4) index += 0; - else if (y == 6) index += 6; - else if (y == 9) index += 12; - else if (y == 11) index += 18; + if (y == this.LAST - 8) index += 0; + else if (y == this.LAST - 6) index += this.HSIZE; + else if (y == this.LAST - 3) index += this.LAST; + else if (y == this.LAST - 1) index += this.LAST + this.HSIZE; else index = -1; - if (index >= 0) this._clickToolboxIndex(index); } @@ -1285,12 +1283,12 @@ actions.prototype._clickToolbox = function (x, y) { actions.prototype._clickToolboxIndex = function (index) { var items = null; var select; - if (index < 12) { - select = index + 12 * (core.status.event.data.toolsPage - 1); + if (index < this.LAST) { + select = index + this.LAST * (core.status.event.data.toolsPage - 1); items = Object.keys(core.status.hero.items.tools).sort(); } else { - select = index % 12 + 12 * (core.status.event.data.constantsPage - 1); + select = index % this.LAST + this.LAST * (core.status.event.data.constantsPage - 1); items = Object.keys(core.status.hero.items.constants).sort(); } if (items == null) return; @@ -1308,33 +1306,35 @@ actions.prototype._clickToolboxIndex = function (index) { actions.prototype._keyDownToolbox = function (keycode) { if (core.status.event.data == null) return; + var last_index = this.LAST - 1; + var tools = Object.keys(core.status.hero.items.tools).sort(); var constants = Object.keys(core.status.hero.items.constants).sort(); var index = core.status.event.selection; var toolsPage = core.status.event.data.toolsPage; var constantsPage = core.status.event.data.constantsPage; - var toolsTotalPage = Math.ceil(tools.length / 12); - var constantsTotalPage = Math.ceil(constants.length / 12); - var toolsLastIndex = toolsPage < toolsTotalPage ? 11 : (tools.length + 11) % 12; - var constantsLastIndex = 12 + (constantsPage < constantsTotalPage ? 11 : (constants.length + 11) % 12); + var toolsTotalPage = Math.ceil(tools.length / this.LAST); + var constantsTotalPage = Math.ceil(constants.length / this.LAST); + var toolsLastIndex = toolsPage < toolsTotalPage ? last_index : (tools.length + last_index) % this.LAST; + var constantsLastIndex = this.LAST + (constantsPage < constantsTotalPage ? last_index : (constants.length + last_index) % this.LAST); if (keycode == 37) { // left if (index == 0) { // 处理向前翻页 if (toolsPage > 1) { core.status.event.data.toolsPage--; - index = 11; + index = last_index; } else return; // 第一页不向前翻 } - else if (index == 12) { + else if (index == this.LAST) { if (constantsPage == 1) { if (toolsTotalPage == 0) return; core.status.event.data.toolsPage = toolsTotalPage; - index = (tools.length + 11) % 12; + index = (tools.length + last_index) % this.LAST; } else { core.status.event.data.constantsPage--; - index = 23; + index = 2 * this.LAST - 1; } } else index -= 1; @@ -1342,29 +1342,29 @@ actions.prototype._keyDownToolbox = function (keycode) { return; } if (keycode == 38) { // up - if (index >= 12 && index <= 17) { // 进入tools + if (index >= this.LAST && index < this.LAST + this.HSIZE) { // 进入tools if (toolsTotalPage == 0) return; - if (toolsLastIndex >= 6) index = Math.min(toolsLastIndex, index - 6); - else index = Math.min(toolsLastIndex, index - 12); + if (toolsLastIndex >= this.HSIZE) index = Math.min(toolsLastIndex, index - this.HSIZE); + else index = Math.min(toolsLastIndex, index - this.LAST); } - else if (index < 6) return; // 第一行没有向上 - else index -= 6; + else if (index < this.HSIZE) return; // 第一行没有向上 + else index -= this.HSIZE; this._clickToolboxIndex(index); return; } if (keycode == 39) { // right - if (toolsPage < toolsTotalPage && index == 11) { + if (toolsPage < toolsTotalPage && index == last_index) { core.status.event.data.toolsPage++; index = 0; } - else if (constantsPage < constantsTotalPage && index == 23) { + else if (constantsPage < constantsTotalPage && index == 2 * this.LAST - 1) { core.status.event.data.constantsPage++; - index = 12; + index = this.LAST; } else if (index == toolsLastIndex) { if (constantsTotalPage == 0) return; core.status.event.data.constantsPage = 1; - index = 12; + index = this.LAST; } else if (index == constantsLastIndex) // 一个物品无操作 return; @@ -1374,16 +1374,17 @@ actions.prototype._keyDownToolbox = function (keycode) { } if (keycode == 40) { // down var nextIndex = null; - if (index <= 5) { - if (toolsLastIndex > 5) nextIndex = Math.min(toolsLastIndex, index + 6); - else index += 6; + if (index < this.HSIZE) { + if (toolsLastIndex >= this.HSIZE) nextIndex = Math.min(toolsLastIndex, index + this.HSIZE); + else index += this.HSIZE; } - if (nextIndex == null && index <= 11) { + if (nextIndex == null && index < this.LAST) { if (constantsTotalPage == 0) return; - nextIndex = Math.min(index + 6, constantsLastIndex); + nextIndex = Math.min(index + this.HSIZE, constantsLastIndex); } - if (nextIndex == null && index <= 17) { - if (constantsLastIndex > 17) nextIndex = Math.min(constantsLastIndex, index + 6); + if (nextIndex == null && index < this.LAST + this.HSIZE) { + if (constantsLastIndex >= this.LAST + this.HSIZE) + nextIndex = Math.min(constantsLastIndex, index + this.HSIZE); } if (nextIndex != null) { this._clickToolboxIndex(nextIndex); diff --git a/libs/ui.js b/libs/ui.js index e145f275..294c2043 100644 --- a/libs/ui.js +++ b/libs/ui.js @@ -1710,149 +1710,129 @@ ui.prototype._drawMaps_buildData = function (index, x, y) { ////// 绘制道具栏 ////// ui.prototype.drawToolbox = function(index) { - // 设定eventdata - if (!core.isset(core.status.event.data) || !core.isset(core.status.event.data.toolsPage) || !core.isset(core.status.event.data.constantsPage)) - core.status.event.data = {"toolsPage":1, "constantsPage":1, "selectId":null} + var info = this._drawToolbox_getInfo(index); + this._drawToolbox_drawBackground(); + // 绘制线 + core.setAlpha('ui', 1); + core.setStrokeStyle('ui', '#DDDDDD'); + core.canvas.ui.lineWidth = 2; + core.canvas.ui.strokeWidth = 2; + core.setTextAlign('ui', 'right'); + var line1 = this.PIXEL - 306; + this._drawToolbox_drawLine(line1, "消耗道具"); + var line2 = this.PIXEL - 146; + this._drawToolbox_drawLine(line2, "永久道具"); + + this._drawToolbox_drawDescription(info, line1); + + this._drawToolbox_drawContent(info, line1, info.tools, info.toolsPage, true); + this.drawPagination(info.toolsPage, info.toolsTotalPage, this.LAST - 5); + this._drawToolbox_drawContent(info, line2, info.constants, info.constantsPage); + this.drawPagination(info.constantsPage, info.constantsTotalPage); + + core.setTextAlign('ui', 'center'); + core.fillText('ui', '[装备栏]', this.PIXEL - 46, 25, '#DDDDDD', this._buildFont(15, true)); + core.fillText('ui', '返回游戏', this.PIXEL - 46, this.PIXEL - 13,'#DDDDDD'); +} + +ui.prototype._drawToolbox_getInfo = function (index) { + // 设定eventdata + if (!core.status.event.data || core.status.event.data.toolsPage == null) + core.status.event.data = {"toolsPage":1, "constantsPage":1, "selectId":null} // 获取物品列表 var tools = Object.keys(core.status.hero.items.tools).sort(); var constants = Object.keys(core.status.hero.items.constants).sort(); - // 处理页数 var toolsPage = core.status.event.data.toolsPage; var constantsPage = core.status.event.data.constantsPage; - var toolsTotalPage = Math.ceil(tools.length/12); - var constantsTotalPage = Math.ceil(constants.length/12); - + var toolsTotalPage = Math.ceil(tools.length/this.LAST); + var constantsTotalPage = Math.ceil(constants.length/this.LAST); // 处理index - if (!core.isset(index)) { - if (tools.length>0) index=0; - else if (constants.length>0) index=12; - else index=0; - } + if (index == null) + index = tools.length == 0 && constants.length > 0 ? this.LAST : 0; core.status.event.selection=index; - // 确认选择对象 - var select; - var selectId; - if (index<12) { - select = index + (toolsPage-1)*12; + var select, selectId; + if (index=tools.length) select=Math.max(0, tools.length-1); selectId = tools[select]; } else { - select = index%12 + (constantsPage-1)*12; + select = index%this.LAST + (constantsPage-1)*this.LAST; if (select>=constants.length) select=Math.max(0, constants.length-1); selectId = constants[select]; } if (!core.hasItem(selectId)) selectId=null; core.status.event.data.selectId=selectId; + return { + index: index, tools: tools, constants: constants, toolsPage: toolsPage, constantsPage: constantsPage, + toolsTotalPage: toolsTotalPage, constantsTotalPage: constantsTotalPage, selectId: selectId + }; +} +ui.prototype._drawToolbox_drawBackground = function () { // 绘制 core.clearMap('ui'); core.setAlpha('ui', 0.85); - core.fillRect('ui', 0, 0, 416, 416, '#000000'); - core.setAlpha('ui', 1); + core.fillRect('ui', 0, 0, this.PIXEL, this.PIXEL, '#000000'); +} + +ui.prototype._drawToolbox_drawLine = function (yoffset, text) { core.setFillStyle('ui', '#DDDDDD'); - core.setStrokeStyle('ui', '#DDDDDD'); - core.canvas.ui.lineWidth = 2; - core.canvas.ui.strokeWidth = 2; - - var ydelta = 20; - - // 画线 core.canvas.ui.beginPath(); - core.canvas.ui.moveTo(0, 130-ydelta); - core.canvas.ui.lineTo(416, 130-ydelta); + core.canvas.ui.moveTo(0, yoffset); + core.canvas.ui.lineTo(this.PIXEL, yoffset); core.canvas.ui.stroke(); core.canvas.ui.beginPath(); - core.canvas.ui.moveTo(416,129-ydelta); - core.canvas.ui.lineTo(416,105-ydelta); - core.canvas.ui.lineTo(416-72,105-ydelta); - core.canvas.ui.lineTo(416-102,129-ydelta); + core.canvas.ui.moveTo(this.PIXEL, yoffset-1); + core.canvas.ui.lineTo(this.PIXEL, yoffset-25); + core.canvas.ui.lineTo(this.PIXEL-72, yoffset-25); + core.canvas.ui.lineTo(this.PIXEL-102, yoffset-1); core.canvas.ui.fill(); + core.fillText('ui', text, this.PIXEL - 5, yoffset-6, '#333333', this._buildFont(16, true)); +} - core.canvas.ui.beginPath(); - core.canvas.ui.moveTo(0, 290-ydelta); - core.canvas.ui.lineTo(416, 290-ydelta); - core.canvas.ui.stroke(); - core.canvas.ui.beginPath(); - core.canvas.ui.moveTo(416,289-ydelta); - core.canvas.ui.lineTo(416,265-ydelta); - core.canvas.ui.lineTo(416-72,265-ydelta); - core.canvas.ui.lineTo(416-102,289-ydelta); - core.canvas.ui.fill(); - - // 文字 - core.setTextAlign('ui', 'right'); - var globalFont = core.status.globalAttribute.font; - core.fillText('ui', "消耗道具", 411, 124-ydelta, '#333333', "bold 16px "+globalFont); - core.fillText('ui', "永久道具", 411, 284-ydelta); - +ui.prototype._drawToolbox_drawDescription = function (info, max_height) { core.setTextAlign('ui', 'left'); // 描述 - if (core.isset(selectId)) { - var item=core.material.items[selectId]; - core.fillText('ui', item.name, 10, 32, '#FFD700', "bold 20px "+globalFont) - + if (info.selectId) { + var item=core.material.items[info.selectId]; + core.fillText('ui', item.name, 10, 32, '#FFD700', this._buildFont(20, true)) var text = item.text||"该道具暂无描述。"; try { // 检查能否eval text = core.replaceText(text); } catch (e) {} - - var lines = core.splitLines('ui', text, 406, '17px '+globalFont); - - core.fillText('ui', lines[0], 10, 62, '#FFFFFF', '17px '+globalFont); - - if (lines.length==1) { - core.fillText('ui', '<继续点击该道具即可进行使用>', 10, 89, '#CCCCCC', '14px '+globalFont); + var lines = core.splitLines('ui', text, this.PIXEL - 15, this._buildFont(17, false)); + // --- 开始逐行绘制 + var curr = 62, line_height = 25; + core.setFillStyle('ui', '#FFFFFF'); + for (var i=0;i=max_height) break; } - else { - var leftText = text.substring(lines[0].length); - core.fillText('ui', leftText, 10, 89, '#FFFFFF', '17px '+globalFont); + if (curr < max_height) { + core.fillText('ui', '<继续点击该道具即可进行使用>', 10, curr, '#CCCCCC', this._buildFont(14, false)); } } +} +ui.prototype._drawToolbox_drawContent = function (info, line, items, page, drawCount) { core.setTextAlign('ui', 'right'); - var images = core.material.images.items; - - // 消耗道具 - for (var i=0;i<12;i++) { - var tool=tools[12*(toolsPage-1)+i]; - if (!core.isset(tool)) break; - var yoffset = 144 + Math.floor(i/6)*54 + 5 - ydelta; - var icon=core.material.icons.items[tool]; - core.drawImage('ui', images, 0, icon*32, 32, 32, 16*(4*(i%6)+1)+5, yoffset, 32, 32) - // 个数 - core.fillText('ui', core.itemCount(tool), 16*(4*(i%6)+1)+40, yoffset+33, '#FFFFFF', "bold 14px "+globalFont); - if (selectId == tool) - core.strokeRect('ui', 16*(4*(i%6)+1)+1, yoffset-4, 40, 40, '#FFD700'); + for (var i = 0; i < this.LAST; i++) { + var item = items[this.LAST * (page - 1) + i]; + if (!item) continue; + var yoffset = line + 54 * Math.floor(i / this.HSIZE) + 19; + var icon = core.material.icons.items[item], image = core.material.images.items; + core.drawImage('ui', image, 0, 32 * icon, 32, 32, 64 * (i % this.HSIZE) + 21, yoffset, 32, 32); + if (drawCount) + core.fillText('ui', core.itemCount(item), 64 * (i % this.HSIZE) + 56, yoffset + 33, '#FFFFFF', this._buildFont(14, true)); + if (info.selectId == item) + core.strokeRect('ui', 64 * (i % this.HSIZE) + 17, yoffset - 4, 40, 40, '#FFD700'); } - - // 永久道具 - for (var i=0;i<12;i++) { - var constant=constants[12*(constantsPage-1)+i]; - if (!core.isset(constant)) break; - var yoffset = 304+Math.floor(i/6)*54+5-ydelta; - var icon=core.material.icons.items[constant]; - core.drawImage('ui', images, 0, icon*32, 32, 32, 16*(4*(i%6)+1)+5, yoffset, 32, 32) - if (selectId == constant) - core.strokeRect('ui', 16*(4*(i%6)+1)+1, yoffset-4, 40, 40, '#FFD700'); - } - - // 分页 - this.drawPagination(toolsPage, toolsTotalPage, 7); - this.drawPagination(constantsPage, constantsTotalPage, 12); - - core.setTextAlign('ui', 'center'); - - // 装备栏 - // if (core.flags.equipment) - core.fillText('ui', '[装备栏]', 370, 25,'#DDDDDD', 'bold 15px '+globalFont); - // core.fillText('ui', '删除道具', 370, 32,'#DDDDDD', 'bold 15px '+globalFont); - // 退出 - core.fillText('ui', '返回游戏', 370, 403,'#DDDDDD', 'bold 15px '+globalFont); } ////// 绘制装备界面 ////// From 9aa7cca037b1c5833ac66f2d9724124e9ff6b272 Mon Sep 17 00:00:00 2001 From: dljgs1 <906348668@qq.com> Date: Fri, 29 Mar 2019 06:52:04 +0800 Subject: [PATCH 22/33] drawSLPanel --- libs/actions.js | 155 +++++++++++++++++++------- libs/ui.js | 284 ++++++++++++++++++++++++++++++------------------ 2 files changed, 293 insertions(+), 146 deletions(-) diff --git a/libs/actions.js b/libs/actions.js index c8e9baeb..c44030e9 100644 --- a/libs/actions.js +++ b/libs/actions.js @@ -686,8 +686,9 @@ actions.prototype._sys_onmousewheel = function (direct) { // 存读档 if (core.status.lockControl && (core.status.event.id == 'save' || core.status.event.id == 'load')) { - if (direct == 1) core.ui.drawSLPanel(core.status.event.data - 10); - if (direct == -1) core.ui.drawSLPanel(core.status.event.data + 10); + var index = core.status.event.data.page*10+core.status.event.data.offset; + if (direct == 1) core.ui.drawSLPanel(index - 10); + if (direct == -1) core.ui.drawSLPanel(index + 10); return; } @@ -1576,23 +1577,24 @@ actions.prototype._keyUpEquipbox = function (keycode, altKey) { } ////// 存读档界面时的点击操作 ////// -actions.prototype._clickSL = function (x, y) { - - var index = core.status.event.data; - var page = parseInt(index / 10), offset = index % 10; +actions.prototype._clickSL = function (x, y, px, py) { + var page = core.status.event.data.page, offset = core.status.event.data.offset; + var index = page*10 + offset; + //var index = core.status.event.data; + //var page = parseInt(index / 10), offset = index % 10; // 上一页 - if ((x == 3 || x == 4) && y == 12) { + if ((x == this.HSIZE-2 || x == this.HSIZE-3) && y == this.LAST) { core.ui.drawSLPanel(10 * (page - 1) + offset); return; } // 下一页 - if ((x == 8 || x == 9) && y == 12) { + if ((x == this.HSIZE+2 || x == this.HSIZE+3) && y == this.LAST) { core.ui.drawSLPanel(10 * (page + 1) + offset); return; } // 返回 - if (x >= 10 && x <= 12 && y == 12) { + if (x >= this.LAST-2 && y == this.LAST) { if (core.events.recoverEvents(core.status.event.interval)) { return; } @@ -1603,32 +1605,52 @@ actions.prototype._clickSL = function (x, y) { return; } // 删除 - if (x >= 0 && x <= 2 && y == 12) { - + if (x >= 0 && x <= 2 && y == this.LAST) { if (core.status.event.id == 'save') { core.status.event.selection = !core.status.event.selection; core.ui.drawSLPanel(index); } - else { - core.myprompt("请输入读档编号", null, function (index) { - index = parseInt(index) || 0; - if (index > 0) - core.doSL(index, core.status.event.id); - }); + else {// 显示收藏 + core.status.event.data.mode = core.status.event.data.mode == 'all'?'fav':'all'; + core.saves.index = {}; + for(var i in core.saves.favorite){ + core.saves.index[i] = core.saves.favorite[i]; + } + core.ui.drawSLPanel(index,true); } return; } + // 收藏 + var fav = null; + var centerX = parseInt(this.SIZE/2), leftX = 2, rightX = this.LAST-2; - var id = null; - if (y >= 1 && y <= 4) { - if (x >= 1 && x <= 3) id = "autoSave"; - if (x >= 5 && x <= 7) id = 5 * page + 1; - if (x >= 9 && x <= 11) id = 5 * page + 2; + // 三个关键坐标: + var xLeft = parseInt(this.SIZE/3),xRight = parseInt(this.SIZE*2/3); + var topY1 = 0, topY2 = parseInt(this.SIZE/2); + + if(y==topY1){ + if (x >= xLeft && x < xRight) fav = 5 * page + 1; + if (x >= xRight) fav = 5 * page + 2; } - if (y >= 7 && y <= 10) { - if (x >= 1 && x <= 3) id = 5 * page + 3; - if (x >= 5 && x <= 7) id = 5 * page + 4; - if (x >= 9 && x <= 11) id = 5 * page + 5; + if(y==topY2){ + if (x < xLeft) fav = 5 * page + 3; + if (x >= xLeft && x < xRight) fav = 5 * page + 4; + if (x >= xRight) fav = 5 * page + 5; + } + if (fav != null){ + this._keyDownFav(page,fav%5); + } + var id = null; + var topSpan = parseInt(this.SIZE/7); + if (y >= topY1 + topSpan && y <= topY1 + topSpan + 3) { + if (x < xLeft) id = "autoSave"; + if (x >= xLeft && x < xRight) id = 5 * page + 1; + if (x >= xRight) id = 5 * page + 2; + } + if (y >= topY2+1 && y <= topY2+5) { + if (x < xLeft) id = 5 * page + 3; + if (x >= xLeft && x < xRight) id = 5 * page + 4; + if (x >= xRight) id = 5 * page + 5; } if (id != null) { if (core.status.event.selection) { @@ -1638,13 +1660,19 @@ actions.prototype._clickSL = function (x, y) { else { // core.removeLocalStorage("save"+id); core.removeLocalForage("save" + id, function () { - core.ui.drawSLPanel(index, true); + var idx = core.saves.favorite.indexOf(id); + core.saves.favorite.splice(idx,1); + delete core.saves.favName[id]; + core.ui._drawSLPanel_saveFav(function(){ + core.ui._drawSLPanel_flushIndex(); + core.ui.drawSLPanel(index, true)}); }, function () { core.drawTip("无法删除存档!"); }) } } else { + if(core.status.event.data.mode=='fav')id = core.saves.favIndex[id]; core.doSL(id, core.status.event.id); } } @@ -1653,8 +1681,9 @@ actions.prototype._clickSL = function (x, y) { ////// 存读档界面时,按下某个键的操作 ////// actions.prototype._keyDownSL = function (keycode) { - var index = core.status.event.data; - var page = parseInt(index / 10), offset = index % 10; +// var index = core.status.event.data; + var page = core.status.event.data.page, offset = core.status.event.data.offset; + var index = page*10 + offset; if (keycode == 37) { // left if (offset == 0) { @@ -1700,13 +1729,46 @@ actions.prototype._keyDownSL = function (keycode) { core.ui.drawSLPanel(10 * (page + 1) + offset); return; } + if (keycode == 70){ // F + this._keyDownFav(page,offset); + } +} +actions.prototype._keyDownFav = function(page, offset){ + var fav = page*5+offset; + var idx = fav; + var index = page*10 + offset; + if(core.status.event.data.mode=='fav'){//收藏模式下点击的下标直接对应favorite + fav = core.saves.favIndex[idx]; + var dataIdx = index; + core.myprompt("请输入想要显示的存档名(长度不超过5字符)", null, function (index) { + if(index && index.length<=5 && index.length>0){ + core.saves.favName[fav]=index; + core.ui._drawSLPanel_saveFav(function(){core.ui.drawSLPanel(dataIdx, false)}); + }else{ + alert("无效的输入!"); + } + }); + }else{ + idx = core.saves.favorite.indexOf(fav); + if(idx>=0){ + core.saves.favorite.splice(idx,1); + delete core.saves.favName[fav]; + }else{ + if(core.hasSave(fav)){ + core.saves.favorite.push(fav); + core.saves.favName[idx] = fav;//暂时的 收藏下标到名字的映射(实际存储的是收藏ID到名字的映射) + } + } + core.ui._drawSLPanel_saveFav(function(){ + core.ui._drawSLPanel_flushIndex(); + core.ui.drawSLPanel(index, false)}); + } } ////// 存读档界面时,放开某个键的操作 ////// actions.prototype._keyUpSL = function (keycode) { - - var index = core.status.event.data; - var page = parseInt(index / 10), offset = index % 10; + var page = core.status.event.data.page, offset = core.status.event.data.offset; + var index = page*10 + offset; if (keycode == 27 || keycode == 88 || (core.status.event.id == 'save' && keycode == 83) || (core.status.event.id == 'load' && keycode == 68)) { if (core.events.recoverEvents(core.status.event.interval)) { @@ -1723,16 +1785,20 @@ actions.prototype._keyUpSL = function (keycode) { core.doSL("autoSave", core.status.event.id); } else { - core.doSL(5 * page + offset, core.status.event.id); + var id = 5 * page + offset; + if(core.status.event.data.mode=='fav')id = core.saves.favIndex[id]; + core.doSL(id, core.status.event.id); } return; } - if (keycode == 69 && core.status.event.id != 'save') { // E - core.myprompt("请输入读档编号", null, function (index) { - index = parseInt(index) || 0; - if (index > 0) - core.doSL(index, core.status.event.id); - }); + if (keycode == 69 && core.status.event.id != 'save') { // E 收藏切换 + core.status.event.data.mode = core.status.event.data.mode == 'all'?'fav':'all'; + core.saves.index = {}; + for(var i in core.saves.favorite){ + core.saves.index[i] = core.saves.favorite[i]; + } + core.ui.drawSLPanel(core.saves.saveIndex,true); + return; } if (keycode == 46) { @@ -1740,10 +1806,14 @@ actions.prototype._keyUpSL = function (keycode) { core.drawTip("无法删除自动存档!"); } else { - // core.removeLocalStorage("save"+(5*page+offset)); - // core.ui.drawSLPanel(index); core.removeLocalForage("save" + (5 * page + offset), function () { - core.ui.drawSLPanel(index, true); + var id = 5 * page + offset; + var idx = core.saves.favorite.indexOf(id); + core.saves.favorite.splice(idx,1); + delete core.saves.favName[id]; + core.ui._drawSLPanel_saveFav(function(){ + core.ui._drawSLPanel_flushIndex(); + core.ui.drawSLPanel(index, true)}); }, function () { core.drawTip("无法删除存档!"); }) @@ -1751,6 +1821,7 @@ actions.prototype._keyUpSL = function (keycode) { } } + ////// 系统设置界面时的点击操作 ////// actions.prototype._clickSwitchs = function (x, y) { if (x < this.CHOICES_LEFT || x > this.CHOICES_RIGHT) return; diff --git a/libs/ui.js b/libs/ui.js index e145f275..c50a56d5 100644 --- a/libs/ui.js +++ b/libs/ui.js @@ -2047,129 +2047,205 @@ ui.prototype.drawSLPanel = function(index, refresh) { var page = parseInt(index/10), offset=index%10; var max_page = main.savePages || 30; + if(core.status.event.data && core.status.event.data.mode=='fav') + max_page = Math.ceil((core.saves.favorite||[]).length/5); if (page>=max_page) page=max_page - 1; if (offset>5) offset=5; index=10*page+offset; var last_page = -1; + var mode = 'all'; if (core.isset(core.status.event.data)) { - last_page = parseInt(core.status.event.data/10); + //last_page = parseInt(core.status.event.data/10); + last_page = core.status.event.data.page; + mode = core.status.event.data.mode; } - core.status.event.data=index; + core.status.event.data={ + 'page':page, + 'offset':offset, + 'mode':mode + }; if (!core.isset(core.status.event.ui)) core.status.event.ui = []; - var u=416/6, size=118; - - var strokeColor = '#FFD700'; - if (core.status.event.selection) strokeColor = '#FF6A6A'; - var globalFont = (core.status.globalAttribute||core.initStatus.globalAttribute).font; - - var drawBg = function() { - core.clearMap('ui'); - core.setAlpha('ui', 0.85); - core.fillRect('ui', 0, 0, 416, 416, '#000000'); - core.setAlpha('ui', 1); - - core.ui.drawPagination(page+1, max_page, 12); - core.setTextAlign('ui', 'center'); - // 退出 - core.fillText('ui', '返回游戏', 370, 403,'#DDDDDD', 'bold 15px '+globalFont); - - if (core.status.event.selection) - core.setFillStyle('ui', '#FF6A6A'); - if (core.status.event.id=='save') - core.fillText('ui', '删除模式', 48, 403); - else - core.fillText('ui', '输入编号', 48, 403); - } - - var draw = function (data, i) { - var name=core.status.event.id=='save'?"存档":core.status.event.id=='load'?"读档":core.status.event.id=='replayLoad'?"回放":""; - core.status.event.ui[i] = data; - var id=5*page+i; - if (i<3) { - core.fillText('ui', i==0?"自动存档":name+id, (2*i+1)*u, 30, '#FFFFFF', "bold 17px "+globalFont); - core.strokeRect('ui', (2*i+1)*u-size/2, 45, size, size, i==offset?strokeColor:'#FFFFFF', i==offset?6:2); - if (core.isset(data) && core.isset(data.floorId)) { - core.drawThumbnail(data.floorId, core.maps.loadMap(data.maps, data.floorId).blocks, { - heroLoc: data.hero.loc, heroIcon: data.hero.flags.heroIcon, flags: data.hero.flags - }, { - ctx: 'ui', x: (2*i+1)*u-size/2, y: 45, size: size, centerX: data.hero.loc.x, centerY: data.hero.loc.y - }); - var v = core.formatBigNumber(data.hero.hp,true)+"/"+core.formatBigNumber(data.hero.atk,true)+"/"+core.formatBigNumber(data.hero.def,true); - var v2 = "/"+core.formatBigNumber(data.hero.mdef,true); - if (v.length+v2.length<=21) v+=v2; - core.fillText('ui', v, (2*i+1)*u, 60+size, '#FFD700', '10px '+globalFont); - core.fillText('ui', core.formatDate(new Date(data.time)), (2*i+1)*u, 73+size, data.hero.flags.__consoleOpened__?'#FF6A6A':'#FFFFFF'); - } - else { - core.fillRect('ui', (2*i+1)*u-size/2, 45, size, size, '#333333', 2); - core.fillText('ui', '空', (2*i+1)*u, 112, '#FFFFFF', 'bold 30px '+globalFont); - } - } - else { - core.fillText('ui', name+id, (2*i-5)*u, 218, '#FFFFFF', "bold 17px "+globalFont); - core.strokeRect('ui', (2*i-5)*u-size/2, 233, size, size, i==offset?strokeColor:'#FFFFFF', i==offset?6:2); - if (core.isset(data) && core.isset(data.floorId)) { - core.drawThumbnail(data.floorId, core.maps.loadMap(data.maps, data.floorId).blocks, { - heroLoc: data.hero.loc, heroIcon: data.hero.flags.heroIcon, flags: data.hero.flags - }, { - ctx: 'ui', x: (2*i-5)*u-size/2, y: 233, size: size, centerX: data.hero.loc.x, centerY: data.hero.loc.y - }); - var v = core.formatBigNumber(data.hero.hp,true)+"/"+core.formatBigNumber(data.hero.atk,true)+"/"+core.formatBigNumber(data.hero.def,true); - var v2 = "/"+core.formatBigNumber(data.hero.mdef,true); - if (v.length+v2.length<=21) v+=v2; - core.fillText('ui', v, (2*i-5)*u, 248+size, '#FFD700', '10px '+globalFont); - core.fillText('ui', core.formatDate(new Date(data.time)), (2*i-5)*u, 261+size, data.hero.flags.__consoleOpened__?'#FF6A6A':'#FFFFFF', '10px '+globalFont); - } - else { - core.fillRect('ui', (2*i-5)*u-size/2, 233, size, size, '#333333', 2); - core.fillText('ui', '空', (2*i-5)*u, 297, '#FFFFFF', 'bold 30px '+globalFont); - } - } - }; - - function loadSave(i, callback) { - if (i==6) { - callback(); - return; - } - - if (i==0) { - if (core.saves.autosave.data!=null) { - core.status.event.ui[i] = core.saves.autosave.data; - loadSave(1, callback); - } - else { - core.getLocalForage("autoSave", null, function(data) { - core.saves.autosave.data = data; - core.status.event.ui[i]=data; - loadSave(i+1, callback); - }, function(err) {main.log(err);}); - } - } - else { - core.getLocalForage("save"+(5*page+i), null, function(data) { - core.status.event.ui[i]=data; - loadSave(i+1, callback); - }, function(err) {main.log(err);}); - } - } - function drawAll() { - drawBg(); - for (var i=0;i<6;i++) - draw(core.status.event.ui[i], i); + core.ui._drawSLPanel_drawBg(page,max_page); + core.ui._drawSLPanel_drawNRecords(6); } if (refresh || page!=last_page) { core.status.event.ui = []; - loadSave(0, drawAll); + this._drawSLPanel_loadFav( + function(){ + core.ui._drawSLPanel_loadSave(page, 0, drawAll); + } + ); } else drawAll(); } +// 存档读档的背景 页码 +ui.prototype._drawSLPanel_drawBg = function(page, max_page) { + core.clearMap('ui'); + core.setAlpha('ui', 0.85); + core.fillRect('ui', 0, 0, this.PIXEL, this.PIXEL, '#000000');//可改成背景图图 + core.setAlpha('ui', 1); + var globalFont = (core.status.globalAttribute||core.initStatus.globalAttribute).font; + + core.ui.drawPagination(page+1, max_page, null); + core.setTextAlign('ui', 'center'); + // 退出 + //core.fillText('ui', '返回游戏', 370, 403,'#DDDDDD', 'bold 15px '+globalFont); + var bottom = this.PIXEL-13; + core.fillText('ui', '返回游戏', this.PIXEL-48, bottom,'#DDDDDD', 'bold 15px '+globalFont); + + if (core.status.event.selection) + core.setFillStyle('ui', '#FF6A6A'); + if (core.status.event.id=='save') + core.fillText('ui', '删除模式', 48, bottom); + else{ + if(core.status.event.data.mode=='all'){ + core.fillText('ui', '[E]显示收藏', 48, bottom); + }else{ + core.fillText('ui', '[E]显示全部', 48, bottom); + } + } +} + +ui.prototype._drawSLPanel_flushIndex = function(){ + core.saves.favIndex = {}; + for(var i in core.saves.favorite){ + core.saves.favIndex[parseInt(i)+1]=core.saves.favorite[i]; + } +} + +// 读取收藏信息到core.saves.favorite中 +ui.prototype._drawSLPanel_loadFav = function(callback){ + if(!core.saves.favorite || !core.saves.favName){ + core.getLocalForage("favorite", null, function(data) { + core.saves.favorite = data || []; + core.ui._drawSLPanel_flushIndex(); + core.getLocalForage("favName", null, function(data) { + core.saves.favName = data || {}; + callback(); + })}); + }else{ + callback(); + } +} +// 写入收藏信息 | 收藏信息包括收藏id列表favorite、id到收藏名的映射favName +ui.prototype._drawSLPanel_saveFav = function(callback){ + if(!core.saves.favorite){ + core.saves.favorite = []; + core.saves.favName = {}; + } + core.setLocalForage("favorite", core.saves.favorite, + function(){ + core.setLocalForage("favName", core.saves.favName,callback) + }); +} + + +// TODO:递归改并发 | 读取page页的i号存档数据到ui数组中 +ui.prototype._drawSLPanel_loadSave = function(page, i, callback) { + if (i==6) { + callback(); + return; + } + if (i==0) { + if (core.saves.autosave.data!=null) { + core.status.event.ui[i] = core.saves.autosave.data; + core.ui._drawSLPanel_loadSave(page, 1, callback); + } + else { + core.getLocalForage("autoSave", null, function(data) { + core.saves.autosave.data = data; + core.status.event.ui[i]=data; + core.ui._drawSLPanel_loadSave(page, i+1, callback); + }, function(err) {main.log(err);}); + } + } + else { + var id = 5*page+i; + if(core.status.event.data.mode=='fav'){ + id = core.saves.favorite[id-1];//因为favorite第一个不是自动存档 所以要偏移1 + } + core.getLocalForage("save"+id, null, function(data) { + core.status.event.ui[i]=data; + core.ui._drawSLPanel_loadSave(page, i+1, callback); + }, function(err) {main.log(err);}); + } +} + +// 在以x为中心轴 y为顶坐标 的位置绘制一条宽为size的记录 cho表示是否被选中 选中会加粗 highlight表示高亮标题 ✐ +ui.prototype._drawSLPanel_drawRecord = function(title, data, x, y, size, cho, highLight){ + var globalFont = (core.status.globalAttribute||core.initStatus.globalAttribute).font; + var strokeColor = '#FFD700'; + if (core.status.event.selection) strokeColor = '#FF6A6A'; + + if (!core.isset(data) || !core.isset(data.floorId)) { //存在数据时才高亮 + highLight = false; + } + core.fillText('ui', title, x, y, highLight?'#FFD700':'#FFFFFF', this._buildFont(17))//"bold 17px "+globalFont);//名字 + + core.strokeRect('ui', x-size/2, y+15, size, size, cho?strokeColor:'#FFFFFF', cho?6:2); + if (core.isset(data) && core.isset(data.floorId)) { + core.drawThumbnail(data.floorId, core.maps.loadMap(data.maps, data.floorId).blocks, { + heroLoc: data.hero.loc, heroIcon: data.hero.flags.heroIcon, flags: data.hero.flags + }, { + ctx: 'ui', x: x-size/2, y: y+15, size: size, centerX: data.hero.loc.x, centerY: data.hero.loc.y + }); + var v = core.formatBigNumber(data.hero.hp,true)+"/"+core.formatBigNumber(data.hero.atk,true)+"/"+core.formatBigNumber(data.hero.def,true); + var v2 = "/"+core.formatBigNumber(data.hero.mdef,true); + if (v.length+v2.length<=21) v+=v2; + core.fillText('ui', v, x, y+30+size, '#FFD700', this._buildFont(10)); + core.fillText('ui', core.formatDate(new Date(data.time)), x, y+43+size, data.hero.flags.__consoleOpened__?'#FF6A6A':'#FFFFFF', this._buildFont(10));//'10px '+globalFont); + } + else { + core.fillRect('ui', x-size/2, y+15, size, size, '#333333', 2); + core.fillText('ui', '空', x, parseInt(y+15+size/2), '#FFFFFF', this._buildFont(30))//'bold 30px '+globalFont); + } +} + +// 绘制n条记录到画板 +ui.prototype._drawSLPanel_drawNRecords = function (n) +{ + var page = core.status.event.data.page;//Math.floor(core.status.event.data/10); + var offset = core.status.event.data.offset;//core.status.event.data%10; + var u = Math.floor(this.PIXEL/6), size = Math.floor(this.PIXEL/3-20);//118 + for (var i=0;i=0 || core.status.event.data.mode=='fav'; + if(highLight)title = '★ ' + title + else title = '☆ ' + title; + var fid = id; + if(core.status.event.data.mode=='fav' && i!=0){//收藏模式下显示修改符号以及自己标识的名字 + fid = core.saves.favIndex[id]; + if(!data && i>0){ + continue; + } +// name = core.saves.favName[fid] ? core.status.event.id=='save'?"S:":core.status.event.id=='load'?"L:":core.status.event.id=='replayLoad'?"re:":"" : name; + title = name + (core.saves.favName[fid]||fid) + '✐'; + }else{ +// name = core.saves.favName[fid] ? core.status.event.id=='save'?"S:":core.status.event.id=='load'?"L:":core.status.event.id=='replayLoad'?"re:":"" : name; + title += name + (core.saves.favName[fid]||fid); + } + var charSize = 32;// 字体占用像素范围 + var topSpan = parseInt((this.PIXEL-charSize-2*(charSize*2 + size))/3);// Margin + var yTop1 = topSpan+parseInt(charSize/2);//文字的中心 + var yTop2 = yTop1+charSize*2+size+topSpan; + if (i<3) { + this._drawSLPanel_drawRecord(i==0?"自动存档":title, data, (2*i+1)*u, yTop1, size, i==offset, highLight); + } + else { + this._drawSLPanel_drawRecord(title, data, (2*i-5)*u, yTop2, size, i==offset, highLight); + } + } +}; + ui.prototype.drawKeyBoard = function () { core.lockControl(); core.status.event.id = 'keyBoard'; From 9b4572feb765d58a03b7989ff6cb4657fae42a26 Mon Sep 17 00:00:00 2001 From: dljgs1 <906348668@qq.com> Date: Fri, 29 Mar 2019 07:00:15 +0800 Subject: [PATCH 23/33] drawSLPanel --- libs/ui.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libs/ui.js b/libs/ui.js index c50a56d5..2cd3b480 100644 --- a/libs/ui.js +++ b/libs/ui.js @@ -2186,7 +2186,7 @@ ui.prototype._drawSLPanel_drawRecord = function(title, data, x, y, size, cho, hi if (!core.isset(data) || !core.isset(data.floorId)) { //存在数据时才高亮 highLight = false; } - core.fillText('ui', title, x, y, highLight?'#FFD700':'#FFFFFF', this._buildFont(17))//"bold 17px "+globalFont);//名字 + core.fillText('ui', title, x, y, highLight?'#FFD700':'#FFFFFF', this._buildFont(17,true));//"bold 17px "+globalFont);//名字 core.strokeRect('ui', x-size/2, y+15, size, size, cho?strokeColor:'#FFFFFF', cho?6:2); if (core.isset(data) && core.isset(data.floorId)) { @@ -2203,7 +2203,7 @@ ui.prototype._drawSLPanel_drawRecord = function(title, data, x, y, size, cho, hi } else { core.fillRect('ui', x-size/2, y+15, size, size, '#333333', 2); - core.fillText('ui', '空', x, parseInt(y+15+size/2), '#FFFFFF', this._buildFont(30))//'bold 30px '+globalFont); + core.fillText('ui', '空', x, parseInt(y+15+size/2), '#FFFFFF', this._buildFont(30,true));//'bold 30px '+globalFont); } } From 46aa0c82788a8773876d753cca990c198786cbf4 Mon Sep 17 00:00:00 2001 From: oc Date: Sat, 30 Mar 2019 00:30:56 +0800 Subject: [PATCH 24/33] drawSL --- libs/actions.js | 190 +++++++++++++++++++-------------------------- libs/control.js | 107 +++++++++++++++++++------ libs/core.js | 2 + libs/events.js | 6 +- libs/ui.js | 202 ++++++++++++++++-------------------------------- 5 files changed, 234 insertions(+), 273 deletions(-) diff --git a/libs/actions.js b/libs/actions.js index 18e1f560..96008b98 100644 --- a/libs/actions.js +++ b/libs/actions.js @@ -1578,11 +1578,9 @@ actions.prototype._keyUpEquipbox = function (keycode, altKey) { } ////// 存读档界面时的点击操作 ////// -actions.prototype._clickSL = function (x, y, px, py) { +actions.prototype._clickSL = function (x, y) { var page = core.status.event.data.page, offset = core.status.event.data.offset; - var index = page*10 + offset; - //var index = core.status.event.data; - //var page = parseInt(index / 10), offset = index % 10; + var index = page * 10 + offset; // 上一页 if ((x == this.HSIZE-2 || x == this.HSIZE-3) && y == this.LAST) { @@ -1596,13 +1594,11 @@ actions.prototype._clickSL = function (x, y, px, py) { } // 返回 if (x >= this.LAST-2 && y == this.LAST) { - if (core.events.recoverEvents(core.status.event.interval)) { + if (core.events.recoverEvents(core.status.event.interval)) return; - } core.ui.closePanel(); - if (!core.isPlaying()) { + if (!core.isPlaying()) core.showStartAnimate(true); - } return; } // 删除 @@ -1611,36 +1607,31 @@ actions.prototype._clickSL = function (x, y, px, py) { core.status.event.selection = !core.status.event.selection; core.ui.drawSLPanel(index); } - else {// 显示收藏 + else { // 显示收藏 core.status.event.data.mode = core.status.event.data.mode == 'all'?'fav':'all'; - core.saves.index = {}; - for(var i in core.saves.favorite){ - core.saves.index[i] = core.saves.favorite[i]; + if (core.status.event.data.mode == 'fav') + core.ui.drawSLPanel(1, true); + else { + page = parseInt((core.saves.saveIndex-1)/5); + offset = core.saves.saveIndex-5*page; + core.ui.drawSLPanel(10*page + offset); } - core.ui.drawSLPanel(index,true); } return; } - // 收藏 - var fav = null; - var centerX = parseInt(this.SIZE/2), leftX = 2, rightX = this.LAST-2; - - // 三个关键坐标: - var xLeft = parseInt(this.SIZE/3),xRight = parseInt(this.SIZE*2/3); - var topY1 = 0, topY2 = parseInt(this.SIZE/2); - + // 点存档名 + var xLeft = parseInt(this.SIZE/3), xRight = parseInt(this.SIZE*2/3); + var topY1 = 0, topY2 = this.HSIZE; if(y==topY1){ - if (x >= xLeft && x < xRight) fav = 5 * page + 1; - if (x >= xRight) fav = 5 * page + 2; + if (x >= xLeft && x < xRight) return this._clickSL_favorite(page, 1); + if (x >= xRight) return this._clickSL_favorite(page, 2); } if(y==topY2){ - if (x < xLeft) fav = 5 * page + 3; - if (x >= xLeft && x < xRight) fav = 5 * page + 4; - if (x >= xRight) fav = 5 * page + 5; - } - if (fav != null){ - this._keyDownFav(page,fav%5); + if (x < xLeft) return this._clickSL_favorite(page, 3); + if (x >= xLeft && x < xRight) return this._clickSL_favorite(page, 4); + if (x >= xRight) return this._clickSL_favorite(page, 5); } + var id = null; var topSpan = parseInt(this.SIZE/7); if (y >= topY1 + topSpan && y <= topY1 + topSpan + 3) { @@ -1655,30 +1646,52 @@ actions.prototype._clickSL = function (x, y, px, py) { } if (id != null) { if (core.status.event.selection) { - if (id == 'autoSave') { + if (id == 'autoSave') core.drawTip("无法删除自动存档!"); - } else { - // core.removeLocalStorage("save"+id); - core.removeLocalForage("save" + id, function () { - var idx = core.saves.favorite.indexOf(id); - core.saves.favorite.splice(idx,1); - delete core.saves.favName[id]; - core.ui._drawSLPanel_saveFav(function(){ - core.ui._drawSLPanel_flushIndex(); - core.ui.drawSLPanel(index, true)}); - }, function () { - core.drawTip("无法删除存档!"); - }) + core.removeSave(id, function () { + core.ui.drawSLPanel(index, true); + }); } } else { - if(core.status.event.data.mode=='fav')id = core.saves.favIndex[id]; + if(core.status.event.data.mode == 'fav' && id != 'autoSave') + id = core.saves.favorite[id - 1]; core.doSL(id, core.status.event.id); } } } +actions.prototype._clickSL_favorite = function (page, offset) { + if (offset == 0) return; + var index = 5 * page + offset; + if (core.status.event.data.mode == 'fav') { // 收藏模式下点击的下标直接对应favorite + index = core.saves.favorite[index - 1]; + core.myprompt("请输入想要显示的存档名(长度不超过5字符)", null, function (value) { + if(value && value.length <= 5){ + core.saves.favoriteName[index] = value; + core.control._updateFavoriteSaves(); + core.drawSLPanel(10 * page + offset); + } else if (value) { + alert("无效的输入!"); + } + }); + } else { + var v = core.saves.favorite.indexOf(index); + if (v >= 0) { // 已经处于收藏状态:取消收藏 + core.saves.favorite.splice(v, 1); + delete core.saves.favoriteName[index]; + } + else if (core.hasSave(index)) { // 存在存档则进行收藏 + core.saves.favorite.push(index); + core.saves.favorite = core.saves.favorite.sort(function (a,b) {return a-b;}); // 保证有序 + core.drawTip("收藏成功!"); + } + core.control._updateFavoriteSaves(); + core.ui.drawSLPanel(10 * page + offset); + } +} + ////// 存读档界面时,按下某个键的操作 ////// actions.prototype._keyDownSL = function (keycode) { @@ -1730,76 +1743,30 @@ actions.prototype._keyDownSL = function (keycode) { core.ui.drawSLPanel(10 * (page + 1) + offset); return; } - if (keycode == 70){ // F - this._keyDownFav(page,offset); - } -} -actions.prototype._keyDownFav = function(page, offset){ - var fav = page*5+offset; - var idx = fav; - var index = page*10 + offset; - if(core.status.event.data.mode=='fav'){//收藏模式下点击的下标直接对应favorite - fav = core.saves.favIndex[idx]; - var dataIdx = index; - core.myprompt("请输入想要显示的存档名(长度不超过5字符)", null, function (index) { - if(index && index.length<=5 && index.length>0){ - core.saves.favName[fav]=index; - core.ui._drawSLPanel_saveFav(function(){core.ui.drawSLPanel(dataIdx, false)}); - }else{ - alert("无效的输入!"); - } - }); - }else{ - idx = core.saves.favorite.indexOf(fav); - if(idx>=0){ - core.saves.favorite.splice(idx,1); - delete core.saves.favName[fav]; - }else{ - if(core.hasSave(fav)){ - core.saves.favorite.push(fav); - core.saves.favName[idx] = fav;//暂时的 收藏下标到名字的映射(实际存储的是收藏ID到名字的映射) - } - } - core.ui._drawSLPanel_saveFav(function(){ - core.ui._drawSLPanel_flushIndex(); - core.ui.drawSLPanel(index, false)}); - } } ////// 存读档界面时,放开某个键的操作 ////// actions.prototype._keyUpSL = function (keycode) { var page = core.status.event.data.page, offset = core.status.event.data.offset; - var index = page*10 + offset; + var index = page * 10 + offset; - if (keycode == 27 || keycode == 88 || (core.status.event.id == 'save' && keycode == 83) || (core.status.event.id == 'load' && keycode == 68)) { - if (core.events.recoverEvents(core.status.event.interval)) { - return; - } - core.ui.closePanel(); - if (!core.isPlaying()) { - core.showStartAnimate(true); - } + if (keycode == 27 || keycode == 88 || (core.status.event.id == 'save' && keycode == 83) + || (core.status.event.id == 'load' && keycode == 68)) { + this._clickSL(this.LAST, this.LAST); return; } if (keycode == 13 || keycode == 32 || keycode == 67) { - if (offset == 0) { + if (offset == 0) core.doSL("autoSave", core.status.event.id); - } else { var id = 5 * page + offset; - if(core.status.event.data.mode=='fav')id = core.saves.favIndex[id]; + if(core.status.event.data.mode == 'fav') id = core.saves.favorite[id - 1]; core.doSL(id, core.status.event.id); } return; } if (keycode == 69 && core.status.event.id != 'save') { // E 收藏切换 - core.status.event.data.mode = core.status.event.data.mode == 'all'?'fav':'all'; - core.saves.index = {}; - for(var i in core.saves.favorite){ - core.saves.index[i] = core.saves.favorite[i]; - } - core.ui.drawSLPanel(core.saves.saveIndex,true); - + this._clickSL(0, this.LAST); return; } if (keycode == 46) { @@ -1807,19 +1774,16 @@ actions.prototype._keyUpSL = function (keycode) { core.drawTip("无法删除自动存档!"); } else { - core.removeLocalForage("save" + (5 * page + offset), function () { - var id = 5 * page + offset; - var idx = core.saves.favorite.indexOf(id); - core.saves.favorite.splice(idx,1); - delete core.saves.favName[id]; - core.ui._drawSLPanel_saveFav(function(){ - core.ui._drawSLPanel_flushIndex(); - core.ui.drawSLPanel(index, true)}); - }, function () { - core.drawTip("无法删除存档!"); - }) + var id = 5 * page + offset; + if(core.status.event.data.mode == 'fav') id = core.saves.favorite[id - 1]; + core.removeSave(id, function () { + core.ui.drawSLPanel(index, true); + }); } } + if (keycode == 70 && core.status.event.data.mode == 'all') { // F + this._clickSL_favorite(page, offset); + } } @@ -2098,7 +2062,7 @@ actions.prototype._clickLocalSaveSelect = function (x, y) { var selection = y - topIndex; core.status.event.selection = selection; if (selection < 2) { - core.control.getSaves(selection == 0 ? null : core.saves.saveIndex, function (saves) { + core.getAllSaves(selection == 0 ? null : core.saves.saveIndex, function (saves) { if (saves) { var content = { "name": core.firstData.name, @@ -2154,9 +2118,12 @@ actions.prototype._clickStorageRemove_all = function () { core.saves.autosave.data = null; core.saves.autosave.updated = false; core.ui.closePanel(); - core.drawText("\t[操作成功]你的所有存档已被清空。"); core.saves.saveIndex = 1; + core.saves.favorite = []; + core.saves.favoriteName = {}; + core.control._updateFavoriteSaves(); core.removeLocalStorage('saveIndex'); + core.drawText("\t[操作成功]你的所有存档已被清空。"); }; if (core.platform.useLocalForage) { core.ui.drawWaiting("正在清空,请稍后..."); @@ -2175,9 +2142,12 @@ actions.prototype._clickStorageRemove_current = function () { core.saves.autosave.data = null; core.saves.autosave.updated = false; core.ui.closePanel(); - core.drawText("\t[操作成功]当前塔的存档已被清空。"); core.saves.saveIndex = 1; + core.saves.favorite = []; + core.saves.favoriteName = {}; + core.control._updateFavoriteSaves(); core.removeLocalStorage('saveIndex'); + core.drawText("\t[操作成功]当前塔的存档已被清空。"); } if (core.platform.useLocalForage) { core.ui.drawWaiting("正在清空,请稍后..."); diff --git a/libs/control.js b/libs/control.js index 9b5272d9..7f9b5324 100644 --- a/libs/control.js +++ b/libs/control.js @@ -1608,7 +1608,7 @@ control.prototype._doSL_replayLoad_afterGet = function (id, data) { ////// 同步存档到服务器 ////// control.prototype.syncSave = function (type) { core.ui.drawWaiting("正在同步,请稍后..."); - core.control.getSaves(type=='all'?null:core.saves.saveIndex, function (saves) { + core.getAllSaves(type=='all'?null:core.saves.saveIndex, function (saves) { if (!saves) return core.drawText("没有要同步的存档"); core.control._syncSave_http(type, saves); }) @@ -1702,32 +1702,54 @@ control.prototype.loadData = function (data, callback) { return this.controldata.loadData(data, callback); } -control.prototype.getSaves = function (index, callback) { - if (index != null) { - core.getLocalForage("save"+index, null, function(data) { - if (callback) callback(data); - }, function(err) { - main.log(err); - if (callback) callback(null); - }) +control.prototype.getSave = function (index, callback) { + if (index == 0) { + // --- 自动存档先从缓存中获取 + if (core.saves.autosave.data != null) + callback(core.clone(core.saves.autosave.data)); + else { + core.getLocalForage("autoSave", null, function(data) { + callback(data); + }, function(err) { + main.log(err); + callback(null); + }); + } return; } - var ids = Object.keys(core.saves.ids).filter(function(x){return x!=0;}) - .sort(function(a,b) {return a-b;}), number = ids.length, saves = []; - var load = function (index, callback) { - if (index > number) { - if (callback) callback(saves); - return; - } - core.getLocalForage("save"+ids[index], null, function (data) { - saves.push(data); - load(index+1, callback); - }, function(err) { - main.log(err); - load(index+1, callback); - }) + core.getLocalForage("save"+index, null, function(data) { + if (callback) callback(data); + }, function(err) { + main.log(err); + if (callback) callback(null); + }); +} + +control.prototype.getSaves = function (ids, callback) { + if (!(ids instanceof Array)) return this.getSave(ids, callback); + var count = ids.length, data = {}; + for (var i = 0; i < ids.length; ++i) { + (function (i) { + core.getSave(ids[i], function (result) { + data[i] = result; + if (Object.keys(data).length == count) + callback(data); + }) + })(i); } - load(0, callback); +} + +control.prototype.getAllSaves = function (id, callback) { + if (id != null) return this.getSave(id, callback); + var ids = Object.keys(core.saves.ids).filter(function(x){return x!=0;}) + .sort(function(a,b) {return a-b;}), saves = []; + this.getSaves(ids, function (data) { + for (var i = 0; i < ids.length; ++i) { + if (data[i] != null) + saves.push(data[i]); + } + callback(saves); + }); } ////// 获得所有存在存档的存档位 ////// @@ -1761,6 +1783,43 @@ control.prototype.hasSave = function (index) { return core.saves.ids[index] || false; } +////// 删除一个或多个存档 +control.prototype.removeSave = function (index, callback) { + if (index == 0 || index == "autoSave") { + index = "autoSave"; + core.removeLocalForage(index, function () { + core.saves.autosave.data = null; + core.saves.autosave.updated = false; + if (callback) callback(); + }); + return; + } + core.removeLocalForage("save" + index, function () { + core.saves.favorite = core.saves.favorite.filter(function (i) { return core.hasSave(i); }); + delete core.saves.favoriteName[index]; + core.control._updateFavoriteSaves(); + if (callback) callback(); + }, function () { + core.drawTip("无法删除存档!"); + if (callback) callback(); + }); +} + +////// 读取收藏信息 +control.prototype._loadFavoriteSaves = function () { + core.saves.favorite = core.getLocalStorage("favorite", []); + // --- 移除不存在的收藏 + core.saves.favorite = core.saves.favorite.filter(function (i) { return core.hasSave(i); }); + core.saves.favoriteName = core.getLocalStorage("favoriteName", {}); +} + +control.prototype._updateFavoriteSaves = function () { + core.setLocalStorage("favorite", core.saves.favorite); + core.setLocalStorage("favoriteName", core.saves.favoriteName); +} + +////// 加载某个存档 + // ------ 属性,状态,位置,buff,变量,锁定控制等 ------ // ////// 设置勇士属性 ////// diff --git a/libs/core.js b/libs/core.js index 4ef06a69..fb6d0077 100644 --- a/libs/core.js +++ b/libs/core.js @@ -67,6 +67,7 @@ function core() { 'isPC': true, // 是否是PC 'isAndroid': false, // 是否是Android 'isIOS': false, // 是否是iOS + 'string': 'PC', 'isWeChat': false, // 是否是微信 'isQQ': false, // 是否是QQ 'isChrome': false, // 是否是Chrome @@ -272,6 +273,7 @@ core.prototype._init_platform = function () { core.platform.isPC = false; } }); + core.platform.string = core.platform.isPC ? "PC" : core.platform.isAndroid ? "Android" : core.platform.isIOS ? "iOS" : ""; core.platform.supportCopy = document.queryCommandSupported || document.queryCommandSupported("copy"); var chrome = /Chrome\/(\d+)\./i.exec(navigator.userAgent); if (chrome && parseInt(chrome[1]) >= 50) core.platform.isChrome = true; diff --git a/libs/events.js b/libs/events.js index 7a0bef05..2751d87b 100644 --- a/libs/events.js +++ b/libs/events.js @@ -89,7 +89,7 @@ events.prototype._startGame_upload = function () { formData.append('type', 'people'); formData.append('name', core.firstData.name); formData.append('version', core.firstData.version); - formData.append('platform', core.platform.isPC ? "PC" : core.platform.isAndroid ? "Android" : core.platform.isIOS ? "iOS" : ""); + formData.append('platform', core.platform.string); formData.append('hard', core.encodeBase64(core.status.hard)); formData.append('hardCode', core.getFlag('hard', 0)); formData.append('base64', 1); @@ -171,7 +171,7 @@ events.prototype._gameOver_doUpload = function (username, ending, norank) { formData.append('type', 'score'); formData.append('name', core.firstData.name); formData.append('version', core.firstData.version); - formData.append('platform', core.platform.isPC ? "PC" : core.platform.isAndroid ? "Android" : core.platform.isIOS ? "iOS" : ""); + formData.append('platform', core.platform.string); formData.append('hard', core.encodeBase64(core.status.hard)); formData.append('username', core.encodeBase64(username || "")); formData.append('ending', core.encodeBase64(ending)); @@ -2205,7 +2205,7 @@ events.prototype.uploadCurrent = function (username) { formData.append('type', 'score'); formData.append('name', core.firstData.name); formData.append('version', core.firstData.version); - formData.append('platform', core.platform.isPC ? "PC" : core.platform.isAndroid ? "Android" : core.platform.isIOS ? "iOS" : ""); + formData.append('platform', core.platform.string); formData.append('hard', core.encodeBase64(core.status.hard)); formData.append('username', core.encodeBase64(username || "current")); formData.append('lv', core.status.hero.lv); diff --git a/libs/ui.js b/libs/ui.js index cc867ec4..4d924361 100644 --- a/libs/ui.js +++ b/libs/ui.js @@ -2022,8 +2022,9 @@ ui.prototype.drawEquipbox = function(index) { ////// 绘制存档/读档界面 ////// ui.prototype.drawSLPanel = function(index, refresh) { - if (!core.isset(index)) index=1; - if (index<0) index=0; + core.control._loadFavoriteSaves(); + if (index == null) index = 1; + if (index < 0) index = 0; var page = parseInt(index/10), offset=index%10; var max_page = main.savePages || 30; @@ -2031,53 +2032,35 @@ ui.prototype.drawSLPanel = function(index, refresh) { max_page = Math.ceil((core.saves.favorite||[]).length/5); if (page>=max_page) page=max_page - 1; if (offset>5) offset=5; - index=10*page+offset; + if (core.status.event.data && core.status.event.data.mode=='fav' && page == max_page - 1) { + offset = Math.min(offset, (core.saves.favorite||[]).length - 5 * page); + } var last_page = -1; var mode = 'all'; - if (core.isset(core.status.event.data)) { - //last_page = parseInt(core.status.event.data/10); + if (core.status.event.data) { last_page = core.status.event.data.page; mode = core.status.event.data.mode; } - - core.status.event.data={ - 'page':page, - 'offset':offset, - 'mode':mode - }; - if (!core.isset(core.status.event.ui)) + core.status.event.data={ 'page':page, 'offset':offset, 'mode':mode }; + core.status.event.ui = core.status.event.ui || []; + if (refresh || page != last_page) { core.status.event.ui = []; - - function drawAll() { - core.ui._drawSLPanel_drawBg(page,max_page); - core.ui._drawSLPanel_drawNRecords(6); + this._drawSLPanel_loadSave(page, function () { + core.ui._drawSLPanel_draw(page, max_page); + }); } - if (refresh || page!=last_page) { - core.status.event.ui = []; - this._drawSLPanel_loadFav( - function(){ - core.ui._drawSLPanel_loadSave(page, 0, drawAll); - } - ); - } - else drawAll(); + else this._drawSLPanel_draw(page, max_page); } -// 存档读档的背景 页码 -ui.prototype._drawSLPanel_drawBg = function(page, max_page) { - core.clearMap('ui'); - core.setAlpha('ui', 0.85); - core.fillRect('ui', 0, 0, this.PIXEL, this.PIXEL, '#000000');//可改成背景图图 - core.setAlpha('ui', 1); - var globalFont = (core.status.globalAttribute||core.initStatus.globalAttribute).font; - - core.ui.drawPagination(page+1, max_page, null); +ui.prototype._drawSLPanel_draw = function (page, max_page) { + // --- 绘制背景 + this._drawSLPanel_drawBackground(); + // --- 绘制文字 + core.ui.drawPagination(page+1, max_page); core.setTextAlign('ui', 'center'); - // 退出 - //core.fillText('ui', '返回游戏', 370, 403,'#DDDDDD', 'bold 15px '+globalFont); var bottom = this.PIXEL-13; - core.fillText('ui', '返回游戏', this.PIXEL-48, bottom,'#DDDDDD', 'bold 15px '+globalFont); + core.fillText('ui', '返回游戏', this.PIXEL-48, bottom, '#DDDDDD', this._buildFont(15, true)); if (core.status.event.selection) core.setFillStyle('ui', '#FF6A6A'); @@ -2085,91 +2068,47 @@ ui.prototype._drawSLPanel_drawBg = function(page, max_page) { core.fillText('ui', '删除模式', 48, bottom); else{ if(core.status.event.data.mode=='all'){ - core.fillText('ui', '[E]显示收藏', 48, bottom); + core.fillText('ui', '[E]显示收藏', 52, bottom); }else{ - core.fillText('ui', '[E]显示全部', 48, bottom); + core.fillText('ui', '[E]显示全部', 52, bottom); } } + // --- 绘制记录 + this._drawSLPanel_drawRecords(); } -ui.prototype._drawSLPanel_flushIndex = function(){ - core.saves.favIndex = {}; - for(var i in core.saves.favorite){ - core.saves.favIndex[parseInt(i)+1]=core.saves.favorite[i]; +ui.prototype._drawSLPanel_drawBackground = function() { + core.clearMap('ui'); + core.setAlpha('ui', 0.85); + core.fillRect('ui', 0, 0, this.PIXEL, this.PIXEL, '#000000');//可改成背景图图 + core.setAlpha('ui', 1); +} + +ui.prototype._drawSLPanel_loadSave = function(page, callback) { + var ids = [0]; + for (var i = 1; i <= 5; ++i) { + var id = 5 * page + i; + if(core.status.event.data.mode=='fav') + id = core.saves.favorite[id - 1]; // 因为favorite第一个不是自动存档 所以要偏移1 + ids.push(id); } -} - -// 读取收藏信息到core.saves.favorite中 -ui.prototype._drawSLPanel_loadFav = function(callback){ - if(!core.saves.favorite || !core.saves.favName){ - core.getLocalForage("favorite", null, function(data) { - core.saves.favorite = data || []; - core.ui._drawSLPanel_flushIndex(); - core.getLocalForage("favName", null, function(data) { - core.saves.favName = data || {}; - callback(); - })}); - }else{ + core.getSaves(ids, function (data) { + for (var i = 0; i < ids.length; ++i) + core.status.event.ui[i] = data[i]; + core.saves.autosave.data = data[0]; callback(); - } -} -// 写入收藏信息 | 收藏信息包括收藏id列表favorite、id到收藏名的映射favName -ui.prototype._drawSLPanel_saveFav = function(callback){ - if(!core.saves.favorite){ - core.saves.favorite = []; - core.saves.favName = {}; - } - core.setLocalForage("favorite", core.saves.favorite, - function(){ - core.setLocalForage("favName", core.saves.favName,callback) - }); -} - - -// TODO:递归改并发 | 读取page页的i号存档数据到ui数组中 -ui.prototype._drawSLPanel_loadSave = function(page, i, callback) { - if (i==6) { - callback(); - return; - } - if (i==0) { - if (core.saves.autosave.data!=null) { - core.status.event.ui[i] = core.saves.autosave.data; - core.ui._drawSLPanel_loadSave(page, 1, callback); - } - else { - core.getLocalForage("autoSave", null, function(data) { - core.saves.autosave.data = data; - core.status.event.ui[i]=data; - core.ui._drawSLPanel_loadSave(page, i+1, callback); - }, function(err) {main.log(err);}); - } - } - else { - var id = 5*page+i; - if(core.status.event.data.mode=='fav'){ - id = core.saves.favorite[id-1];//因为favorite第一个不是自动存档 所以要偏移1 - } - core.getLocalForage("save"+id, null, function(data) { - core.status.event.ui[i]=data; - core.ui._drawSLPanel_loadSave(page, i+1, callback); - }, function(err) {main.log(err);}); - } + }); } // 在以x为中心轴 y为顶坐标 的位置绘制一条宽为size的记录 cho表示是否被选中 选中会加粗 highlight表示高亮标题 ✐ ui.prototype._drawSLPanel_drawRecord = function(title, data, x, y, size, cho, highLight){ - var globalFont = (core.status.globalAttribute||core.initStatus.globalAttribute).font; var strokeColor = '#FFD700'; if (core.status.event.selection) strokeColor = '#FF6A6A'; + if (!data || !data.floorId) highLight = false; - if (!core.isset(data) || !core.isset(data.floorId)) { //存在数据时才高亮 - highLight = false; - } - core.fillText('ui', title, x, y, highLight?'#FFD700':'#FFFFFF', this._buildFont(17,true));//"bold 17px "+globalFont);//名字 - + core.fillText('ui', title, x, y, highLight?'#FFD700':'#FFFFFF', this._buildFont(17, true)); core.strokeRect('ui', x-size/2, y+15, size, size, cho?strokeColor:'#FFFFFF', cho?6:2); - if (core.isset(data) && core.isset(data.floorId)) { + if (data && data.floorId) { core.drawThumbnail(data.floorId, core.maps.loadMap(data.maps, data.floorId).blocks, { heroLoc: data.hero.loc, heroIcon: data.hero.flags.heroIcon, flags: data.hero.flags }, { @@ -2177,45 +2116,36 @@ ui.prototype._drawSLPanel_drawRecord = function(title, data, x, y, size, cho, hi }); var v = core.formatBigNumber(data.hero.hp,true)+"/"+core.formatBigNumber(data.hero.atk,true)+"/"+core.formatBigNumber(data.hero.def,true); var v2 = "/"+core.formatBigNumber(data.hero.mdef,true); - if (v.length+v2.length<=21) v+=v2; - core.fillText('ui', v, x, y+30+size, '#FFD700', this._buildFont(10)); - core.fillText('ui', core.formatDate(new Date(data.time)), x, y+43+size, data.hero.flags.__consoleOpened__?'#FF6A6A':'#FFFFFF', this._buildFont(10));//'10px '+globalFont); + if (core.calWidth('ui', v + v2, this._buildFont(10, false)) <= size) v += v2; + core.fillText('ui', v, x, y+30+size, '#FFD700'); + core.fillText('ui', core.formatDate(new Date(data.time)), x, y+43+size, data.hero.flags.__consoleOpened__?'#FF6A6A':'#FFFFFF'); } else { core.fillRect('ui', x-size/2, y+15, size, size, '#333333', 2); - core.fillText('ui', '空', x, parseInt(y+15+size/2), '#FFFFFF', this._buildFont(30,true));//'bold 30px '+globalFont); + core.fillText('ui', '空', x, parseInt(y+15+size/2), '#FFFFFF', this._buildFont(30,true)); } } -// 绘制n条记录到画板 -ui.prototype._drawSLPanel_drawNRecords = function (n) -{ - var page = core.status.event.data.page;//Math.floor(core.status.event.data/10); - var offset = core.status.event.data.offset;//core.status.event.data%10; - var u = Math.floor(this.PIXEL/6), size = Math.floor(this.PIXEL/3-20);//118 - for (var i=0;i=0 || core.status.event.data.mode=='fav'; - if(highLight)title = '★ ' + title - else title = '☆ ' + title; - var fid = id; - if(core.status.event.data.mode=='fav' && i!=0){//收藏模式下显示修改符号以及自己标识的名字 - fid = core.saves.favIndex[id]; - if(!data && i>0){ - continue; - } -// name = core.saves.favName[fid] ? core.status.event.id=='save'?"S:":core.status.event.id=='load'?"L:":core.status.event.id=='replayLoad'?"re:":"" : name; - title = name + (core.saves.favName[fid]||fid) + '✐'; - }else{ -// name = core.saves.favName[fid] ? core.status.event.id=='save'?"S:":core.status.event.id=='load'?"L:":core.status.event.id=='replayLoad'?"re:":"" : name; - title += name + (core.saves.favName[fid]||fid); + var id = 5 * page + i; + var highLight = (i>0&&core.saves.favorite.indexOf(id)>=0) || core.status.event.data.mode=='fav'; + var title = (highLight?'★ ':'☆ ') + (core.saves.favoriteName[id] || (name + id)); + if (i != 0 && core.status.event.data.mode=='fav') { + if (!data) break; + var real_id = core.saves.favorite[id - 1]; + title = (core.saves.favoriteName[real_id] || (name + real_id)) + ' ✐'; } + var charSize = 32;// 字体占用像素范围 var topSpan = parseInt((this.PIXEL-charSize-2*(charSize*2 + size))/3);// Margin - var yTop1 = topSpan+parseInt(charSize/2);//文字的中心 + var yTop1 = topSpan+parseInt(charSize/2) + 8;//文字的中心 var yTop2 = yTop1+charSize*2+size+topSpan; if (i<3) { this._drawSLPanel_drawRecord(i==0?"自动存档":title, data, (2*i+1)*u, yTop1, size, i==offset, highLight); From f961cc25ece3ee9548fc15732c419d89b5db7da1 Mon Sep 17 00:00:00 2001 From: oc Date: Sat, 30 Mar 2019 00:43:35 +0800 Subject: [PATCH 25/33] drawSL --- libs/actions.js | 11 ++++++----- libs/ui.js | 2 +- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/libs/actions.js b/libs/actions.js index 96008b98..8c30b831 100644 --- a/libs/actions.js +++ b/libs/actions.js @@ -1622,24 +1622,23 @@ actions.prototype._clickSL = function (x, y) { // 点存档名 var xLeft = parseInt(this.SIZE/3), xRight = parseInt(this.SIZE*2/3); var topY1 = 0, topY2 = this.HSIZE; - if(y==topY1){ + if(y >= topY1 && y <= topY1 + 1) { if (x >= xLeft && x < xRight) return this._clickSL_favorite(page, 1); if (x >= xRight) return this._clickSL_favorite(page, 2); } - if(y==topY2){ + if(y >= topY2 && y <= topY2 + 1) { if (x < xLeft) return this._clickSL_favorite(page, 3); if (x >= xLeft && x < xRight) return this._clickSL_favorite(page, 4); if (x >= xRight) return this._clickSL_favorite(page, 5); } var id = null; - var topSpan = parseInt(this.SIZE/7); - if (y >= topY1 + topSpan && y <= topY1 + topSpan + 3) { + if (y >= topY1 + 2 && y < this.HSIZE - 1) { if (x < xLeft) id = "autoSave"; if (x >= xLeft && x < xRight) id = 5 * page + 1; if (x >= xRight) id = 5 * page + 2; } - if (y >= topY2+1 && y <= topY2+5) { + if (y >= topY2 + 2 && y < this.SIZE - 1) { if (x < xLeft) id = 5 * page + 3; if (x >= xLeft && x < xRight) id = 5 * page + 4; if (x >= xRight) id = 5 * page + 5; @@ -2115,6 +2114,7 @@ actions.prototype._clickStorageRemove = function (x, y) { actions.prototype._clickStorageRemove_all = function () { core.myconfirm("你确定要清除【全部塔】的所有本地存档?\n此行为不可逆!!!", function () { var done = function () { + core.saves.ids = {}; core.saves.autosave.data = null; core.saves.autosave.updated = false; core.ui.closePanel(); @@ -2139,6 +2139,7 @@ actions.prototype._clickStorageRemove_all = function () { actions.prototype._clickStorageRemove_current = function () { core.myconfirm("你确定要清除本塔的所有本地存档?\n此行为不可逆!!!", function () { var done = function () { + core.saves.ids = {}; core.saves.autosave.data = null; core.saves.autosave.updated = false; core.ui.closePanel(); diff --git a/libs/ui.js b/libs/ui.js index 4d924361..010c2cfe 100644 --- a/libs/ui.js +++ b/libs/ui.js @@ -2122,7 +2122,7 @@ ui.prototype._drawSLPanel_drawRecord = function(title, data, x, y, size, cho, hi } else { core.fillRect('ui', x-size/2, y+15, size, size, '#333333', 2); - core.fillText('ui', '空', x, parseInt(y+15+size/2), '#FFFFFF', this._buildFont(30,true)); + core.fillText('ui', '空', x, parseInt(y+22+size/2), '#FFFFFF', this._buildFont(30,true)); } } From f98c1b0916565188a8d0442afea46bd9821437e6 Mon Sep 17 00:00:00 2001 From: oc Date: Sat, 30 Mar 2019 00:49:19 +0800 Subject: [PATCH 26/33] drawSL --- libs/actions.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/actions.js b/libs/actions.js index 8c30b831..742cb09f 100644 --- a/libs/actions.js +++ b/libs/actions.js @@ -1614,7 +1614,7 @@ actions.prototype._clickSL = function (x, y) { else { page = parseInt((core.saves.saveIndex-1)/5); offset = core.saves.saveIndex-5*page; - core.ui.drawSLPanel(10*page + offset); + core.ui.drawSLPanel(10*page + offset, true); } } return; From 25d0ce95acddabff7cc91ab410f5781dfa7a9b2e Mon Sep 17 00:00:00 2001 From: oc Date: Sat, 30 Mar 2019 01:13:40 +0800 Subject: [PATCH 27/33] Fix compress --- libs/ui.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/ui.js b/libs/ui.js index 010c2cfe..2d35c988 100644 --- a/libs/ui.js +++ b/libs/ui.js @@ -1559,7 +1559,7 @@ ui.prototype.drawFly = function(page) { var middle = this.HPIXEL + 39; if (core.actions._getNextFlyFloor(1) != page) { core.fillText('ui', '▲', this.PIXEL - 60, middle - 64, null, this._buildFont(17, false)); - core.fillText('ui', '▲', this.PIXEL - 60, middle - 96,); + core.fillText('ui', '▲', this.PIXEL - 60, middle - 96); core.fillText('ui', '▲', this.PIXEL - 60, middle - 96 - 7); } if (core.actions._getNextFlyFloor(-1) != page) { From 254484541d7dcd3b65b90dfbdfde3e16a7bb0c12 Mon Sep 17 00:00:00 2001 From: oc Date: Sat, 30 Mar 2019 16:46:02 +0800 Subject: [PATCH 28/33] drawEquipbox --- libs/actions.js | 91 +++++++------- libs/control.js | 4 +- libs/core.js | 11 +- libs/items.js | 25 ++-- libs/ui.js | 317 +++++++++++++++++++++-------------------------- project/icons.js | 2 +- project/items.js | 2 +- project/maps.js | 2 +- 8 files changed, 212 insertions(+), 242 deletions(-) diff --git a/libs/actions.js b/libs/actions.js index 742cb09f..5ec68a78 100644 --- a/libs/actions.js +++ b/libs/actions.js @@ -1416,64 +1416,65 @@ actions.prototype._keyUpToolbox = function (keycode) { ////// 装备栏界面时的点击操作 ////// actions.prototype._clickEquipbox = function (x, y) { // 道具栏 - if (x >= 10 && x <= 12 && y == 0) { + if (x >= this.LAST - 2 && y == 0) { core.ui.closePanel(); core.openToolbox(); return; } // 返回 - if (x >= 10 && x <= 12 && y == 12) { + if (x >= this.LAST - 2 && y == this.LAST) { core.ui.closePanel(); return; } - // 当前页面 - var page = core.status.event.data.page; - // 上一页 - if ((x == 3 || x == 4) && y == 12) { - if (page > 1) { + if ((x == this.HSIZE-2 || x == this.HSIZE-3) && y == this.LAST) { + if (core.status.event.data.page > 1) { core.status.event.data.page--; core.ui.drawEquipbox(core.status.event.selection); } return; } // 下一页 - if ((x == 8 || x == 9) && y == 12) { - var lastPage = Math.ceil(Object.keys(core.status.hero.items.equips).length / 12); - if (page < lastPage) { + if ((x == this.HSIZE+2 || x == this.HSIZE+3) && y == this.LAST) { + var lastPage = Math.ceil(Object.keys(core.status.hero.items.equips).length / this.LAST); + if (core.status.event.data.page < lastPage) { core.status.event.data.page++; core.ui.drawEquipbox(core.status.event.selection); } return; } - var index = parseInt(x / 2); - if (y == 4) index += 0; - else if (y == 6) index += 6; - else if (y == 9) index += 12; - else if (y == 11) index += 18; - else index = -1; - - if (index >= 0) { - if (index < 12) index = parseInt(index / 2); - this._clickEquipboxIndex(index); + var per_page = this.HSIZE - 3, v = this.SIZE / per_page; + if (y == this.LAST - 8) { + for (var i = 0; i < per_page; ++i) + if (x >= i * v && x <= (i + 1) * v) + return this._clickEquipboxIndex(i); } + else if (y == this.LAST - 6) { + for (var i = 0; i < per_page; ++i) + if (x >= i * v && x <= (i + 1) * v) + return this._clickEquipboxIndex(per_page + i); + } + else if (y == this.LAST - 3) + this._clickEquipboxIndex(this.LAST + parseInt(x / 2)) + else if (y == this.LAST - 1) + this._clickEquipboxIndex(this.LAST + this.HSIZE + parseInt(x / 2)); } ////// 选择装备栏界面中某个Index后的操作 ////// actions.prototype._clickEquipboxIndex = function (index) { - if (index < 6) { + if (index < this.LAST) { if (index >= core.status.globalAttribute.equipName.length) return; if (index == core.status.event.selection && core.status.hero.equipment[index]) { core.unloadEquip(index); core.status.route.push("unEquip:" + index); } } - else if (index >= 12) { + else { var equips = Object.keys(core.status.hero.items.equips || {}).sort(); if (index == core.status.event.selection) { - var equipId = equips[index - 12 + (core.status.event.data.page - 1) * 12]; + var equipId = equips[index - this.LAST + (core.status.event.data.page - 1) * this.LAST]; core.loadEquip(equipId); core.status.route.push("equip:" + equipId); } @@ -1483,21 +1484,23 @@ actions.prototype._clickEquipboxIndex = function (index) { ////// 装备栏界面时,按下某个键的操作 ////// actions.prototype._keyDownEquipbox = function (keycode) { - if (core.status.event.data != null) return; + if (core.status.event.data == null) return; + var last_index = this.LAST - 1; + var per_line = this.HSIZE - 3; var equipCapacity = core.status.globalAttribute.equipName.length; var ownEquipment = Object.keys(core.status.hero.items.equips).sort(); var index = core.status.event.selection; var page = core.status.event.data.page; - var totalPage = Math.ceil(ownEquipment.length / 12); - var totalLastIndex = 12 + (page < totalPage ? 11 : (ownEquipment.length + 11) % 12); + var totalPage = Math.ceil(ownEquipment.length / this.LAST); + var totalLastIndex = this.LAST + (page < totalPage ? last_index : (ownEquipment.length + last_index) % this.LAST); if (keycode == 37) { // left if (index == 0) return; - if (index == 12) { + if (index == this.LAST) { if (page > 1) { core.status.event.data.page--; - index = 23; + index = this.LAST + last_index; } else if (page == 1) index = equipCapacity - 1; @@ -1508,25 +1511,25 @@ actions.prototype._keyDownEquipbox = function (keycode) { return; } if (keycode == 38) { // up - if (index < 3) return; - else if (index < 6) index -= 3; - else if (index < 18) { - index = parseInt((index - 12) / 2); - if (equipCapacity > 3) index = Math.min(equipCapacity - 1, index + 3); + if (index < per_line) return; + else if (index < 2 * per_line) index -= per_line; + else if (index < this.LAST + this.HSIZE) { + index = parseInt((index - this.LAST) / 2); + if (equipCapacity > per_line) index = Math.min(equipCapacity - 1, index + per_line); else index = Math.min(equipCapacity - 1, index); } - else index -= 6; + else index -= this.HSIZE; this._clickEquipboxIndex(index); return; } if (keycode == 39) { // right - if (page < totalPage && index == 23) { + if (page < totalPage && index == this.LAST + last_index) { core.status.event.data.page++; - index = 12; + index = this.LAST; } else if (index == equipCapacity - 1) { if (totalPage == 0) return; - index = 12; + index = this.LAST; } else if (index == totalLastIndex) return; @@ -1535,19 +1538,19 @@ actions.prototype._keyDownEquipbox = function (keycode) { return; } if (keycode == 40) { // down - if (index < 3) { - if (equipCapacity > 3) index = Math.min(index + 3, equipCapacity - 1); + if (index < per_line) { + if (equipCapacity > per_line) index = Math.min(index + per_line, equipCapacity - 1); else { if (totalPage == 0) return; - index = Math.min(2 * index + 1 + 12, totalLastIndex); + index = Math.min(2 * index + 1 + this.LAST, totalLastIndex); } } - else if (index < 6) { + else if (index < 2 * per_line) { if (totalPage == 0) return; - index = Math.min(2 * (index - 3) + 1 + 12, totalLastIndex); + index = Math.min(2 * (index - per_line) + 1 + this.LAST, totalLastIndex); } - else if (index < 18) - index = Math.min(index + 6, totalLastIndex); + else if (index < this.LAST + this.HSIZE) + index = Math.min(index + this.HSIZE, totalLastIndex); else return; this._clickEquipboxIndex(index); return; diff --git a/libs/control.js b/libs/control.js index 7f9b5324..052cbed0 100644 --- a/libs/control.js +++ b/libs/control.js @@ -1865,12 +1865,12 @@ control.prototype.getRealStatusOrDefault = function (status, name) { ////// 设置某个属性的增幅值 ////// control.prototype.setBuff = function (name, value) { - this.setFlag('flag:__'+name+'_buff__', value); + this.setFlag('__'+name+'_buff__', value); } ////// 加减某个属性的增幅值 ////// control.prototype.addBuff = function (name, value) { - this.setFlag('flag:__'+name+'_buff__', this.getBuff(name) + value); + this.setFlag('__'+name+'_buff__', this.getBuff(name) + value); } ////// 获得某个属性的增幅值 ////// diff --git a/libs/core.js b/libs/core.js index fb6d0077..966aa4d0 100644 --- a/libs/core.js +++ b/libs/core.js @@ -103,7 +103,9 @@ function core() { "data": null, "time": 0, "updated": false, - } + }, + "favorite": [], + "favoriteName": {} } this.initStatus = { 'played': false, @@ -295,7 +297,7 @@ core.prototype._init_platform = function () { } core.prototype._init_checkLocalForage = function () { - core.platform.useLocalForage = core.getLocalStorage('useLocalForage', !core.platform.isIOS); + core.platform.useLocalForage = core.getLocalStorage('useLocalForage', true); var _error = function (e) { main.log(e); core.platform.useLocalForage = false; @@ -384,13 +386,16 @@ core.prototype._forwardFunc = function (name, funcname) { } if (core[funcname]) { - console.error("ERROR: Cannot forward function " + funcname + " from " + name + "!"); + console.error("ERROR: 无法转发 "+name+" 中的函数 "+funcname+" 到 core 中!同名函数已存在。"); return; } var parameterInfo = /^\s*function\s*[\w_$]*\(([\w_,$\s]*)\)\s*\{/.exec(core[name][funcname].toString()); var parameters = (parameterInfo == null ? "" : parameterInfo[1]).replace(/\s*/g, '').replace(/,/g, ', '); // core[funcname] = new Function(parameters, "return core."+name+"."+funcname+"("+parameters+");"); eval("core." + funcname + " = function (" + parameters + ") {\n\treturn core." + name + "." + funcname + "(" + parameters + ");\n}"); + if (name == 'plugin') { + main.log("插件函数转发:core."+funcname+" = core.plugin."+funcname); + } } core.prototype.doFunc = function (func, _this) { diff --git a/libs/items.js b/libs/items.js index 58faca5c..23056d8d 100644 --- a/libs/items.js +++ b/libs/items.js @@ -311,20 +311,17 @@ items.prototype.unloadEquip = function (equipType, callback) { } items.prototype.compareEquipment = function (compareEquipId, beComparedEquipId) { - var compareAtk = 0, compareDef = 0, compareMdef = 0; - if (compareEquipId) { - var compareEquip = core.material.items[compareEquipId]; - compareAtk += (compareEquip.equip || {}).atk || 0; - compareDef += (compareEquip.equip || {}).def || 0; - compareMdef += (compareEquip.equip || {}).mdef || 0; + var result = {}; + var first = core.material.items[compareEquipId], second = core.material.items[beComparedEquipId]; + for (var name in core.status.hero) { + if (typeof core.status.hero[name] == 'number') { + var ans = 0; + if (first) ans += (first.equip || {})[name] || 0; + if (second) ans -= (second.equip || {})[name] || 0; + if (ans != 0) result[name] = ans; + } } - if (beComparedEquipId) { - var beComparedEquip = core.material.items[beComparedEquipId]; - compareAtk -= (beComparedEquip.equip || {}).atk || 0; - compareDef -= (beComparedEquip.equip || {}).def || 0; - compareMdef -= (beComparedEquip.equip || {}).mdef || 0; - } - return {"atk": compareAtk, "def": compareDef, "mdef": compareMdef}; + return result; } ////// 实际换装的效果 ////// @@ -349,7 +346,7 @@ items.prototype._realLoadEquip = function (type, loadId, unloadId, callback) { var loadPercentage = loadEquip.equip.percentage, unloadPercentage = unloadEquip.equip.percentage; - if (loadPercentage != null && unloadPercentage != null && loadPercentage != unloadPercentage) { + if (loadId && unloadId && (loadPercentage || false) != (unloadPercentage || false)) { this.unloadEquip(type); this.loadEquip(loadId); if (callback) callback(); diff --git a/libs/ui.js b/libs/ui.js index 2d35c988..2d1ecf01 100644 --- a/libs/ui.js +++ b/libs/ui.js @@ -1733,7 +1733,7 @@ ui.prototype.drawToolbox = function(index) { core.setTextAlign('ui', 'center'); core.fillText('ui', '[装备栏]', this.PIXEL - 46, 25, '#DDDDDD', this._buildFont(15, true)); - core.fillText('ui', '返回游戏', this.PIXEL - 46, this.PIXEL - 13,'#DDDDDD'); + core.fillText('ui', '返回游戏', this.PIXEL - 46, this.PIXEL - 13); } ui.prototype._drawToolbox_getInfo = function (index) { @@ -1795,28 +1795,25 @@ ui.prototype._drawToolbox_drawLine = function (yoffset, text) { } ui.prototype._drawToolbox_drawDescription = function (info, max_height) { - core.setTextAlign('ui', 'left'); - // 描述 - if (info.selectId) { - var item=core.material.items[info.selectId]; - core.fillText('ui', item.name, 10, 32, '#FFD700', this._buildFont(20, true)) - var text = item.text||"该道具暂无描述。"; - try { - // 检查能否eval - text = core.replaceText(text); - } catch (e) {} - var lines = core.splitLines('ui', text, this.PIXEL - 15, this._buildFont(17, false)); - // --- 开始逐行绘制 - var curr = 62, line_height = 25; - core.setFillStyle('ui', '#FFFFFF'); - for (var i=0;i=max_height) break; - } - if (curr < max_height) { - core.fillText('ui', '<继续点击该道具即可进行使用>', 10, curr, '#CCCCCC', this._buildFont(14, false)); - } + if (!info.selectId) return; + var item=core.material.items[info.selectId]; + core.fillText('ui', item.name, 10, 32, '#FFD700', this._buildFont(20, true)) + var text = item.text||"该道具暂无描述。"; + try { + // 检查能否eval + text = core.replaceText(text); + } catch (e) {} + var lines = core.splitLines('ui', text, this.PIXEL - 15, this._buildFont(17, false)); + // --- 开始逐行绘制 + var curr = 62, line_height = 25; + core.setFillStyle('ui', '#FFFFFF'); + for (var i=0;i=max_height) break; + } + if (curr < max_height) { + core.fillText('ui', '<继续点击该道具即可进行使用>', 10, curr, '#CCCCCC', this._buildFont(14, false)); } } @@ -1837,187 +1834,155 @@ ui.prototype._drawToolbox_drawContent = function (info, line, items, page, drawC ////// 绘制装备界面 ////// ui.prototype.drawEquipbox = function(index) { - // 设定eventdata - if (!core.isset(core.status.event.data) || !core.isset(core.status.event.data.page)) - core.status.event.data = {"page":1, "selectId":null}; + var info = this._drawEquipbox_getInfo(index); + this._drawToolbox_drawBackground(); + core.setAlpha('ui', 1); + core.setStrokeStyle('ui', '#DDDDDD'); + core.canvas.ui.lineWidth = 2; + core.canvas.ui.strokeWidth = 2; + core.setTextAlign('ui', 'right'); + var line1 = this.PIXEL - 306; + this._drawToolbox_drawLine(line1, "当前装备"); + var line2 = this.PIXEL - 146; + this._drawToolbox_drawLine(line2, "拥有装备"); + + this._drawEquipbox_description(info, line1); + + this._drawEquipbox_drawEquiped(info, line1); + this._drawToolbox_drawContent(info, line2, info.ownEquipment, info.page, true); + this.drawPagination(info.page, info.totalPage); + + core.setTextAlign('ui', 'center'); + core.fillText('ui', '[道具栏]', this.PIXEL - 46, 25, '#DDDDDD', this._buildFont(15, true)); + core.fillText('ui', '返回游戏', this.PIXEL - 46, this.PIXEL - 13); +} + +ui.prototype._drawEquipbox_getInfo = function (index) { + if (!core.status.event.data || core.status.event.data.page == null) + core.status.event.data = {"page":1, "selectId":null}; var allEquips = core.status.globalAttribute.equipName; var equipLength = allEquips.length; - - if (!core.isset(core.status.hero.equipment)) core.status.hero.equipment = []; - + if (!core.status.hero.equipment) core.status.hero.equipment = []; var equipEquipment = core.status.hero.equipment; var ownEquipment = Object.keys(core.status.hero.items.equips).sort(); - var page = core.status.event.data.page; - var totalPage = Math.ceil(ownEquipment.length/12); - + var totalPage = Math.ceil(ownEquipment.length / this.LAST); // 处理index - if (!core.isset(index)) { - if (equipLength>0 && core.isset(equipEquipment[0])) index=0; - else if (ownEquipment.length>0) index=12; - else index=0; + if (index == null) { + if (equipLength > 0 && equipEquipment[0]) index = 0; + else if (ownEquipment.length > 0) index = this.LAST; + else index = 0; } - if (index>=12 && ownEquipment.length==0) index = 0; + if (index >= this.LAST && ownEquipment.length == 0) index = 0; var selectId=null; - if (index<12) { + if (index < this.LAST) { if (index >= equipLength) index=Math.max(0, equipLength - 1); - selectId = equipEquipment[index]||null; + selectId = equipEquipment[index] || null; } else { - if (page == totalPage) index = Math.min(index, (ownEquipment.length+11)%12+12); - selectId = ownEquipment[index-12 + (page-1)*12]; + if (page == totalPage) index = Math.min(index, (ownEquipment.length+this.LAST-1)%this.LAST+this.LAST); + selectId = ownEquipment[index - this.LAST + (page - 1) * this.LAST]; if (!core.hasItem(selectId)) selectId=null; } core.status.event.selection=index; core.status.event.data.selectId=selectId; + return { index: index, selectId: selectId, page: page, totalPage: totalPage, allEquips: allEquips, + equipLength: equipLength, equipEquipment: equipEquipment, ownEquipment: ownEquipment}; +} - core.clearMap('ui', 0, 0, 416, 416); - core.setAlpha('ui', 0.85); - core.fillRect('ui', 0, 0, 416, 416, '#000000'); - core.setAlpha('ui', 1); - core.setFillStyle('ui', '#DDDDDD'); - core.setStrokeStyle('ui', '#DDDDDD'); - core.canvas.ui.lineWidth = 2; - core.canvas.ui.strokeWidth = 2; - - var ydelta = 20; - - // 画线 - core.canvas.ui.beginPath(); - core.canvas.ui.moveTo(0, 130-ydelta); - core.canvas.ui.lineTo(416, 130-ydelta); - core.canvas.ui.stroke(); - core.canvas.ui.beginPath(); - core.canvas.ui.moveTo(416,129-ydelta); - core.canvas.ui.lineTo(416,105-ydelta); - core.canvas.ui.lineTo(416-72,105-ydelta); - core.canvas.ui.lineTo(416-102,129-ydelta); - core.canvas.ui.fill(); - - core.canvas.ui.beginPath(); - core.canvas.ui.moveTo(0, 290-ydelta); - core.canvas.ui.lineTo(416, 290-ydelta); - core.canvas.ui.stroke(); - core.canvas.ui.beginPath(); - core.canvas.ui.moveTo(416,289-ydelta); - core.canvas.ui.lineTo(416,265-ydelta); - core.canvas.ui.lineTo(416-72,265-ydelta); - core.canvas.ui.lineTo(416-102,289-ydelta); - core.canvas.ui.fill(); - - // 文字 - core.setTextAlign('ui', 'right'); - var globalFont = core.status.globalAttribute.font; - core.fillText('ui', "当前装备", 411, 124-ydelta, '#333333', "bold 16px "+globalFont); - core.fillText('ui', "拥有装备", 411, 284-ydelta); - +ui.prototype._drawEquipbox_description = function (info, max_height) { core.setTextAlign('ui', 'left'); + if (!info.selectId) return; + var equip=core.material.items[info.selectId]; + // --- 标题 + if (!equip.equip) equip.equip = {"type": 0}; + var equipType = equip.equip.type, equipString; + if (typeof equipType === 'string') { + equipString = equipType || "未知部位"; + equipType = core.items.getEquipTypeByName(equipType); + } + else equipString = info.allEquips[equipType] || "未知部位"; + core.fillText('ui', equip.name + "(" + equipString + ")", 10, 32, '#FFD700', this._buildFont(20, true)) + // --- 描述 + var text = equip.text || "该装备暂无描述。"; + try { + text = core.replaceText(text); + } catch (e) {} + var lines = core.splitLines('ui', text, this.PIXEL - 15, this._buildFont(17, false)); + var curr = 62, line_height = 25; + core.setFillStyle('ui', '#FFFFFF'); + for (var i = 0; i < lines.length; ++i) { + core.fillText('ui', lines[i], 10, curr); + curr += line_height; + if (curr >= max_height) break; + } + // --- 变化值 + if (curr >= max_height) return; + this._drawEquipbox_drawStatusChanged(info, curr, equip, equipType); +} - // 描述 - if (core.isset(selectId)) { - var equip=core.material.items[selectId]; - if (!core.isset(equip.equip)) equip.equip = {"type": 0}; - var equipType = equip.equip.type; - var equipString; - if (typeof equipType === 'string') { - equipString = equipType||"未知部位"; - equipType = core.items.getEquipTypeByName(equipType); - } - else equipString = allEquips[equipType]||"未知部位"; - - core.fillText('ui', equip.name + "(" + equipString + ")", 10, 32, '#FFD700', "bold 20px "+globalFont) - - var text = equip.text||"该装备暂无描述。"; - try { - text = core.replaceText(text); - } catch (e) {} - var lines = core.splitLines('ui', text, 406, '17px '+globalFont); - - core.fillText('ui', lines[0], 10, 62, '#FFFFFF', '17px '+globalFont); - - // 比较属性 - if (lines.length==1) { - var compare, differentMode = null; - if (index<12) compare = core.compareEquipment(null, selectId); - else { - if (equipType<0) { - differentMode = '<当前没有该装备的空位,请先卸下装备>'; - } - else { - var last = core.material.items[equipEquipment[equipType]]||{}; - // 检查是不是数值模式和比例模式之间的切换 - if (core.isset(last.equip) && (last.equip.percentage||false) != (equip.equip.percentage||false)) { - differentMode = '<数值和比例模式之间的切换不显示属性变化>'; - } - else { - compare = core.compareEquipment(selectId, equipEquipment[equipType]); - } - } - } - if (differentMode != null) { - core.fillText('ui', differentMode, 10, 89, '#CCCCCC', '14px '+globalFont); - } - else { - var drawOffset = 10; - [['攻击','atk'], ['防御','def'], ['魔防','mdef']].forEach(function (t) { - var title = t[0], name = t[1]; - if (!core.isset(compare[name]) || compare[name]==0) return; - var color = '#00FF00'; - if (compare[name]<0) color = '#FF0000'; - var nowValue = core.getStatus(name), newValue = nowValue + compare[name]; - if (equip.equip.percentage) { - var nowBuff = core.getBuff(name), newBuff = nowBuff+compare[name]/100; - nowValue = Math.floor(nowBuff*core.getStatus(name)); - newValue = Math.floor(newBuff*core.getStatus(name)); - } - var content = title + ' ' + nowValue + '->'; - core.fillText('ui', content, drawOffset, 89, '#CCCCCC', 'bold 14px '+globalFont); - drawOffset += core.calWidth('ui', content); - core.fillText('ui', newValue, drawOffset, 89, color); - drawOffset += core.calWidth('ui', newValue) + 15; - }) - } - } +ui.prototype._drawEquipbox_drawStatusChanged = function (info, y, equip, equipType) { + var compare, differentMode = null; + if (info.index < this.LAST) compare = core.compareEquipment(null, info.selectId); + else { + if (equipType<0) differentMode = '<当前没有该装备的空位,请先卸下装备>'; else { - var leftText = text.substring(lines[0].length); - core.fillText('ui', leftText, 10, 89, '#FFFFFF', '17px '+globalFont); + var last = core.material.items[info.equipEquipment[equipType]]||{}; + if (last.equip && (last.equip.percentage || false) != (equip.equip.percentage || false)) + differentMode = '<数值和比例模式之间的切换不显示属性变化>'; + else + compare = core.compareEquipment(info.selectId, info.equipEquipment[equipType]); } } + if (differentMode != null) { + core.fillText('ui', differentMode, 10, y, '#CCCCCC', this._buildFont(14, false)); + return; + } + var drawOffset = 10; + // --- 变化值... + core.setFont('ui', this._buildFont(14, true)); + for (var name in compare) { + var img = core.statusBar.icons[name]; + if (img) { // 绘制图标 + core.drawImage('ui', img, 0, 0, 32, 32, drawOffset, y - 13, 16, 16); + drawOffset += 20; + } + else { // 绘制文字 + core.fillText('ui', name + " ", drawOffset, y, '#CCCCCC'); + drawOffset += core.calWidth('ui', name + " "); + } + var nowValue = core.getStatus(name) * core.getBuff(name), newValue = (nowValue + compare[name]) * core.getBuff(name); + if (equip.equip.percentage) { + var nowBuff = core.getBuff(name), newBuff = nowBuff + compare[name] / 100; + nowValue = Math.floor(nowBuff * core.getStatus(name)); + newValue = Math.floor(newBuff * core.getStatus(name)); + } + nowValue = core.formatBigNumber(nowValue); + newValue = core.formatBigNumber(newValue); + core.fillText('ui', nowValue + "->", drawOffset, y, '#CCCCCC'); + drawOffset += core.calWidth('ui', nowValue + "->"); + core.fillText('ui', newValue, drawOffset, y, compare[name]>0?'#00FF00':'#FF0000'); + drawOffset += core.calWidth('ui', newValue) + 8; + } +} +ui.prototype._drawEquipbox_drawEquiped = function (info, line) { core.setTextAlign('ui', 'right'); - var images = core.material.images.items; - + var per_line = this.HSIZE - 3, width = Math.floor(this.PIXEL / (per_line + 0.25)); // 当前装备 - for (var i = 0 ; i < equipLength ; i++) { - var equipId = equipEquipment[i] || null; - if (core.isset(equipId)) { + for (var i = 0; i < info.equipLength ; i++) { + var equipId = info.equipEquipment[i] || null; + var offset_text = width * (i % per_line) + 56; + var offset_image = width * (i % per_line) + width * 2 / 3; + var y = line + 54 * Math.floor(i / per_line) + 19; + if (equipId) { var icon = core.material.icons.items[equipId]; - core.drawImage('ui', images, 0, icon*32, 32, 32, 16*(8*(i%3)+5)+5, 144+Math.floor(i/3)*54+5-ydelta, 32, 32); + core.drawImage('ui', core.material.images.items, 0, 32 * icon, 32, 32, offset_image, y, 32, 32); } - core.fillText('ui', allEquips[i]||"未知", 16*(8*(i%3)+1)+40, 144+Math.floor(i/3)*54+32-ydelta, '#FFFFFF', "bold 16px "+globalFont); - core.strokeRect('ui', 16*(8*(i%3)+5)+1, 144+Math.floor(i/3)*54+1-ydelta, 40, 40, index==i?'#FFD700':"#FFFFFF"); + core.fillText('ui', info.allEquips[i] || "未知", offset_text, y + 27, '#FFFFFF', this._buildFont(16, true)) + core.strokeRect('ui', offset_image - 4, y - 4, 40, 40, info.index==i?'#FFD700':"#FFFFFF"); } - - // 现有装备 - for (var i=0;i<12;i++) { - var ownEquip=ownEquipment[12*(page-1)+i]; - if (!core.isset(ownEquip)) continue; - var icon=core.material.icons.items[ownEquip]; - core.drawImage('ui', images, 0, icon*32, 32, 32, 16*(4*(i%6)+1)+5, 304+Math.floor(i/6)*54+5-ydelta, 32, 32) - // 个数 - if (core.itemCount(ownEquip)>1) - core.fillText('ui', core.itemCount(ownEquip), 16*(4*(i%6)+1)+40, 304+Math.floor(i/6)*54+38-ydelta, '#FFFFFF', "bold 14px "+globalFont); - if (index>=12 && selectId == ownEquip) - core.strokeRect('ui', 16*(4*(i%6)+1)+1, 304+Math.floor(i/6)*54+1-ydelta, 40, 40, '#FFD700'); - } - - this.drawPagination(page, totalPage, 12); - // 道具栏 - core.setTextAlign('ui', 'center'); - core.fillText('ui', '[道具栏]', 370, 25,'#DDDDDD', 'bold 15px '+globalFont); - // 退出按钮 - core.fillText('ui', '返回游戏', 370, 403,'#DDDDDD', 'bold 15px '+globalFont); } ////// 绘制存档/读档界面 ////// diff --git a/project/icons.js b/project/icons.js index 71bce353..0fe339c2 100644 --- a/project/icons.js +++ b/project/icons.js @@ -259,7 +259,7 @@ var icons_4665ee12_3a1f_44a4_bea3_0fccba634dc1 = "hammer": 48, "jumpShoes": 49, "skill1": 30, - "I73": 10 + "wand": 10 }, "autotile": { "autotile": 0, diff --git a/project/items.js b/project/items.js index 83b236c7..efda5b71 100644 --- a/project/items.js +++ b/project/items.js @@ -303,7 +303,7 @@ var items_296f5d02_12fd_4166_a7c1_b5e830c9ee3a = "text": "可以打开或关闭主动技能二倍斩", "hideInReplay": true }, - "I73": { + "wand": { "cls": "items", "name": "新物品" } diff --git a/project/maps.js b/project/maps.js index 78a610d0..d631d0ba 100644 --- a/project/maps.js +++ b/project/maps.js @@ -67,7 +67,7 @@ var maps_90f36752_8815_4be8_b32b_d7fad1d0542e = "70": {"cls":"items","id":"sword0"}, "71": {"cls":"items","id":"shield0"}, "72": {"cls":"items","id":"skill1"}, - "73": {"cls":"items","id":"I73"}, + "73": {"cls":"items","id":"wand"}, "81": {"cls":"terrains","id":"yellowDoor","trigger":"openDoor"}, "82": {"cls":"terrains","id":"blueDoor","trigger":"openDoor"}, "83": {"cls":"terrains","id":"redDoor","trigger":"openDoor"}, From 67f98f2da634384870e77135dac909f2048ed9a6 Mon Sep 17 00:00:00 2001 From: oc Date: Sat, 30 Mar 2019 17:04:48 +0800 Subject: [PATCH 29/33] toolbox textalign --- libs/ui.js | 1 + 1 file changed, 1 insertion(+) diff --git a/libs/ui.js b/libs/ui.js index 2d1ecf01..8a569922 100644 --- a/libs/ui.js +++ b/libs/ui.js @@ -1795,6 +1795,7 @@ ui.prototype._drawToolbox_drawLine = function (yoffset, text) { } ui.prototype._drawToolbox_drawDescription = function (info, max_height) { + core.setTextAlign('ui', 'left'); if (!info.selectId) return; var item=core.material.items[info.selectId]; core.fillText('ui', item.name, 10, 32, '#FFD700', this._buildFont(20, true)) From f7056d699f9ded847463716445c582adab038e95 Mon Sep 17 00:00:00 2001 From: oc Date: Sat, 30 Mar 2019 17:15:12 +0800 Subject: [PATCH 30/33] fix status:x --- libs/control.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/control.js b/libs/control.js index 052cbed0..d85b2cf6 100644 --- a/libs/control.js +++ b/libs/control.js @@ -1841,7 +1841,7 @@ control.prototype.addStatus = function (name, value) { control.prototype.getStatus = function (name) { if (!core.status.hero) return null; if (name == 'x' || name == 'y' || name == 'direction') - return this.getHeroLoc('x'); + return this.getHeroLoc(name); if (name == 'exp') name = 'experience'; return core.status.hero[name]; } From 16980c527ab7f817a7e0201dfab5212679658d05 Mon Sep 17 00:00:00 2001 From: oc Date: Sat, 30 Mar 2019 19:18:57 +0800 Subject: [PATCH 31/33] quickCommonEvents --- _docs/event.md | 6 +++ _server/MotaAction.g4 | 17 +++++++++ _server/data.comment.js | 6 +++ _server/editor_blockly.js | 1 + libs/actions.js | 50 ++++++++++++++++++------- libs/control.js | 11 ++++++ libs/events.js | 27 +++++++++++++- libs/ui.js | 18 ++++++--- libs/utils.js | 7 +++- main.js | 2 +- project/data.js | 1 + project/events.js | 77 +++++++++++++++++++++++++++++++++++++++ project/functions.js | 2 +- 13 files changed, 200 insertions(+), 25 deletions(-) diff --git a/_docs/event.md b/_docs/event.md index 3beb965a..57825ba7 100644 --- a/_docs/event.md +++ b/_docs/event.md @@ -682,6 +682,12 @@ revisit常常使用在一些商人之类的地方,当用户购买物品后不 ] ``` +### addToList:将本公共事件插入到快捷列表中 + +使用 `{"type": "addToList"}` 可以将当前公共事件插入到快捷商店列表中。 + +此项只能在公共事件中被执行。详见[公共事件](personalization#公共事件)。 + ### setBlock:设置某个图块 我们可以采用 `{"type": "setBlock"}` 来改变某个地图块。 diff --git a/_server/MotaAction.g4 b/_server/MotaAction.g4 index 1aa58715..c1c31050 100644 --- a/_server/MotaAction.g4 +++ b/_server/MotaAction.g4 @@ -240,6 +240,7 @@ action | insert_2_s | revisit_s | exit_s + | addToList_s | setBlock_s | showFloorImg_s | hideFloorImg_s @@ -693,6 +694,18 @@ var code = '{"type": "exit"},\n'; return code; */; +addToList_s + : '将本公共事件插入到快捷列表中' Newline + + +/* addToList_s +tooltip : addToList: 将本公共事件插入到快捷列表中 +helpUrl : https://h5mota.com/games/template/docs/#/event?id=exit%EF%BC%9A%E7%AB%8B%E5%88%BB%E7%BB%93%E6%9D%9F%E5%BD%93%E5%89%8D%E4%BA%8B%E4%BB%B6 +colour : this.eventColor +var code = '{"type": "addToList"},\n'; +return code; +*/; + setBlock_s : '转变图块为' Int 'x' PosString? ',' 'y' PosString? '楼层' IdString? Newline @@ -2604,6 +2617,10 @@ ActionParser.prototype.parseAction = function() { this.next = MotaActionBlocks['exit_s'].xmlText([ this.next]); break; + case "addToList": // 立刻结束事件 + this.next = MotaActionBlocks['addToList_s'].xmlText([ + this.next]); + break; case "animateImage": // 兼容 animateImage break; default: diff --git a/_server/data.comment.js b/_server/data.comment.js index c4ad3175..8df587e1 100644 --- a/_server/data.comment.js +++ b/_server/data.comment.js @@ -660,6 +660,12 @@ var data_comment_c456ea59_6018_45ef_8bcc_211a24c627dc = "_bool": "bool", "_data": "是否在经过领域/夹击/路障等伤害后禁用快捷商店。" }, + "quickCommonEvents": { + "_leaf": true, + "_type": "checkbox", + "_bool": "bool", + "_data": "是否使用自定义的公共事件列表来代替快捷商店列表。\n如果此项开启,则快捷商店列表中将会显示加入的公共事件。" + }, "checkConsole": { "_leaf": true, "_type": "checkbox", diff --git a/_server/editor_blockly.js b/_server/editor_blockly.js index 9ebabaac..ee887b02 100644 --- a/_server/editor_blockly.js +++ b/_server/editor_blockly.js @@ -123,6 +123,7 @@ editor_blockly = function () { MotaActionBlocks['hideBgFgMap_s'].xmlText(), MotaActionBlocks['trigger_s'].xmlText(), MotaActionBlocks['insert_1_s'].xmlText(), + MotaActionBlocks['addToList_s'].xmlText(), MotaActionBlocks['insert_2_s'].xmlText(), MotaActionBlocks['move_s'].xmlText(), MotaActionBlocks['jump_s'].xmlText(), diff --git a/libs/actions.js b/libs/actions.js index 5ec68a78..ad1c3c1d 100644 --- a/libs/actions.js +++ b/libs/actions.js @@ -1198,20 +1198,35 @@ actions.prototype._keyUpShop = function (keycode) { ////// 快捷商店界面时的点击操作 ////// actions.prototype._clickQuickShop = function (x, y) { - var shopList = core.status.shops, keys = Object.keys(shopList).filter(function (shopId) { - return shopList[shopId].visited || !shopList[shopId].mustEnable - }); + var keys = []; + if (core.flags.quickCommonEvents) { + keys = core.getFlag("__commonEventList__", []); + } + else { + keys = Object.keys(core.status.shops).filter(function (shopId) { + return core.status.shops[shopId].visited || !core.status.shops[shopId].mustEnable + }); + } + if (x >= this.CHOICES_LEFT && x <= this.CHOICES_RIGHT) { var topIndex = this.HSIZE - parseInt(keys.length / 2); if (y >= topIndex && y < topIndex + keys.length) { - var reason = core.events.canUseQuickShop(keys[y - topIndex]); - if (!core.flags.enableDisabledShop && reason) { - core.drawText(reason); - return; + if (core.flags.quickCommonEvents) { + var name = keys[y - topIndex]; + core.ui.closePanel(); + core.status.route.push("common:" + core.encodeBase64(name)); + core.insertAction(name); + } + else { + var reason = core.events.canUseQuickShop(keys[y - topIndex]); + if (!core.flags.enableDisabledShop && reason) { + core.drawText(reason); + return; + } + core.events.openShop(keys[y - topIndex], true); + if (core.status.event.id == 'shop') + core.status.event.data.fromList = true; } - core.events.openShop(keys[y - topIndex], true); - if (core.status.event.id == 'shop') - core.status.event.data.fromList = true; } // 离开 else if (y == topIndex + keys.length) @@ -1225,10 +1240,17 @@ actions.prototype._keyUpQuickShop = function (keycode) { core.ui.closePanel(); return; } - var shopList = core.status.shops, keys = Object.keys(shopList).filter(function (shopId) { - return shopList[shopId].visited || !shopList[shopId].mustEnable - }); - this._selectChoices(keys.length + 1, keycode, this._clickQuickShop); + var length = 0; + if (core.flags.quickCommonEvents) { + length = core.getFlag("__commonEventList__", []).length; + } + else { + var shopList = core.status.shops, keys = Object.keys(shopList).filter(function (shopId) { + return shopList[shopId].visited || !shopList[shopId].mustEnable + }); + length = keys.length; + } + this._selectChoices(length + 1, keycode, this._clickQuickShop); return; } diff --git a/libs/control.js b/libs/control.js index d85b2cf6..b980955b 100644 --- a/libs/control.js +++ b/libs/control.js @@ -33,6 +33,7 @@ control.prototype._init = function () { this.registerReplayAction("fly", this._replayAction_fly); this.registerReplayAction("shop", this._replayAction_shop); this.registerReplayAction("turn", this._replayAction_turn); + this.registerReplayAction("common", this._replayAction_common); this.registerReplayAction("getNext", this._replayAction_getNext); this.registerReplayAction("moveDirectly", this._replayAction_moveDirectly); this.registerReplayAction("key", this._replayAction_key); @@ -1441,6 +1442,16 @@ control.prototype._replayAction_turn = function (action) { return true; } +control.prototype._replayAction_common = function (action) { + if (action.indexOf("common:") != 0) return false; + var name = core.decodeBase64(action.substring(7)); + if (core.getFlag("__commonEventList__").indexOf(name) == -1) return false; + core.status.route.push(action); + core.insertAction(name); + setTimeout(core.replay); + return true; +} + control.prototype._replayAction_getNext = function (action) { if (action != "getNext") return false; if (!core.getNextItem()) return false; diff --git a/libs/events.js b/libs/events.js index 2751d87b..4a1be196 100644 --- a/libs/events.js +++ b/libs/events.js @@ -806,7 +806,10 @@ events.prototype.insertAction = function (action, x, y, callback, addToLast) { // ------ 判定commonEvent var commonEvent = this.getCommonEvent(action); - if (commonEvent instanceof Array) action = commonEvent; + if (commonEvent instanceof Array) { + this._addCommentEventToList(action, commonEvent); + action = commonEvent; + } if (!action) return; if (core.status.event.id != 'action') { @@ -827,6 +830,22 @@ events.prototype.getCommonEvent = function (name) { return this.commonEvent[name] || null; } +events.prototype._addCommentEventToList = function (name, list) { + if (list == null) list = this.getCommonEvent(name); + if (!list || !core.flags.quickCommonEvents) return; + var addToList = false; + for (var x in list) { + if (list[x].type == 'addToList') { + addToList = true; + break; + } + } + if (!addToList) return; + var obj = core.getFlag("__commonEventList__", []); + if (obj.indexOf(name) == -1) obj.push(name); + core.setFlag("__commonEventList__", obj); +} + ////// 恢复一个事件 ////// events.prototype.recoverEvents = function (data) { if (data) { @@ -1175,7 +1194,7 @@ events.prototype._action_insert = function (data, x, y, prefix) { } if (data.name) { // 公共事件 core.setFlag('arg0', data.name); - core.insertAction(this.getCommonEvent(data.name)); + core.insertAction(data.name); } else { var loc = this.__action_getLoc(data.loc, x, y, prefix); @@ -1188,6 +1207,10 @@ events.prototype._action_insert = function (data, x, y, prefix) { core.doAction(); } +events.prototype._action_addToList = function (data, x, y, prefix) { + core.doAction(); +} + events.prototype._action_playBgm = function (data, x, y, prefix) { core.playBgm(data.name); core.doAction(); diff --git a/libs/ui.js b/libs/ui.js index 8a569922..7529f589 100644 --- a/libs/ui.js +++ b/libs/ui.js @@ -1118,12 +1118,18 @@ ui.prototype.drawSettings = function () { ////// 绘制快捷商店选择栏 ////// ui.prototype.drawQuickShop = function () { core.status.event.id = 'selectShop'; - var shopList = core.status.shops, keys = Object.keys(shopList).filter(function (shopId) { - return shopList[shopId].visited || !shopList[shopId].mustEnable - }); - var choices = keys.map(function (shopId) { - return {"text": shopList[shopId].textInList, "color": shopList[shopId].visited?null:"#999999"}; - }); + var choices; + if (core.flags.quickCommonEvents) { + choices = core.clone(core.getFlag("__commonEventList__", [])); + } + else { + var shopList = core.status.shops, keys = Object.keys(shopList).filter(function (shopId) { + return shopList[shopId].visited || !shopList[shopId].mustEnable + }); + choices = keys.map(function (shopId) { + return {"text": shopList[shopId].textInList, "color": shopList[shopId].visited?null:"#999999"}; + }); + } choices.push("返回游戏"); this.drawChoices(null, choices); } diff --git a/libs/utils.js b/libs/utils.js index d3bac9d3..4dbd3e34 100644 --- a/libs/utils.js +++ b/libs/utils.js @@ -467,6 +467,8 @@ utils.prototype._encodeRoute_encodeOne = function (t) { return "P" + t.substring(6); else if (t.indexOf('input2:') == 0) return "Q" + t.substring(7) + ":"; + else if (t.indexOf('common:') == 0) + return "c" + t.substring(7) + ":"; else if (t == 'no') return 'N'; else if (t.indexOf('move:') == 0) @@ -525,7 +527,7 @@ utils.prototype._decodeRoute_number2id = function (number) { } utils.prototype._decodeRoute_decodeOne = function (decodeObj, c) { - var nxt = (c == 'I' || c == 'e' || c == 'F' || c == 'S' || c == 'Q' || c == 't') ? + var nxt = (c == 'I' || c == 'e' || c == 'F' || c == 'S' || c == 'Q' || c == 't' || c == 'c') ? this._decodeRoute_getString(decodeObj) : this._decodeRoute_getNumber(decodeObj); var mp = {"U": "up", "D": "down", "L": "left", "R": "right"}; @@ -570,6 +572,9 @@ utils.prototype._decodeRoute_decodeOne = function (decodeObj, c) { case "Q": decodeObj.ans.push("input2:" + nxt); break; + case "c": + decodeObj.ans.push("common:" + nxt); + break; case "N": decodeObj.ans.push("no"); break; diff --git a/main.js b/main.js index a6c60bba..9d26b266 100644 --- a/main.js +++ b/main.js @@ -675,7 +675,7 @@ window.onblur = function () { if (main.core && main.core.control) { try { main.core.control.checkAutosave(); - } catch (e) {main.log(e);} + } catch (e) {} } } diff --git a/project/data.js b/project/data.js index 878a6ca0..6173ffed 100644 --- a/project/data.js +++ b/project/data.js @@ -397,6 +397,7 @@ var data_a1e2fb4a_e986_4524_b0da_9b7ba7c0874d = "enableMoveDirectly": true, "enableDisabledShop": true, "disableShopOnDamage": false, + "quickCommonEvents": false, "checkConsole": false } } \ No newline at end of file diff --git a/project/events.js b/project/events.js index 85eb07ca..b546b4a2 100644 --- a/project/events.js +++ b/project/events.js @@ -237,6 +237,83 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = ], "false": [] } + ], + "回收钥匙商店": [ + { + "type": "comment", + "text": "公共事件:回收钥匙商店" + }, + { + "type": "addToList" + }, + { + "type": "comment", + "text": "使用上述事件并在全塔属性打开quickCommonEvent开关" + }, + { + "type": "comment", + "text": "就可以在快捷列表(V键)中使用本公共事件" + }, + { + "type": "while", + "condition": "1", + "data": [ + { + "type": "choices", + "text": "\t[商人,woman]你有多余的钥匙想要出售吗?", + "choices": [ + { + "text": "黄钥匙(10金币)", + "color": [ + 255, + 255, + 0, + 1 + ], + "action": [ + { + "type": "if", + "condition": "item:yellowKey >= 1", + "true": [ + { + "type": "addValue", + "name": "item:yellowKey", + "value": "-1" + }, + { + "type": "addValue", + "name": "status:money", + "value": "10" + } + ], + "false": [ + "\t[商人,woman]你没有黄钥匙!" + ] + } + ] + }, + { + "text": "蓝钥匙(50金币)", + "color": [ + 0, + 0, + 255, + 1 + ], + "action": [] + }, + { + "text": "离开", + "action": [ + { + "type": "exit" + } + ] + } + ] + } + ] + } ] } } \ No newline at end of file diff --git a/project/functions.js b/project/functions.js index 64e05bf8..2044fe73 100644 --- a/project/functions.js +++ b/project/functions.js @@ -699,7 +699,7 @@ var functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a = gid = guards[i][2]; // 递归计算支援怪伤害信息,这里不传x,y保证不会重复调用 // 这里的mdef传0,因为护盾应该只会被计算一次 - var info = core.enemys.getDamageInfo(core.material.enemys[gid], origin_hero_hp, origin_hero_atk, origin_hero_def, 0); + var info = core.enemys.getDamageInfo(core.material.enemys[gid], { hp: origin_hero_hp, atk: origin_hero_atk, def: origin_hero_def, mdef: 0 }); if (info == null) { // 小队中任何一个怪物不可战斗,直接返回null return null; } From e822543bf1732e0dbbf8cf1e1f35a4480820b9ad Mon Sep 17 00:00:00 2001 From: oc Date: Sat, 30 Mar 2019 20:15:43 +0800 Subject: [PATCH 32/33] prev replays --- libs/control.js | 8 ++++++-- libs/maps.js | 13 ++++++++----- 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/libs/control.js b/libs/control.js index b980955b..fa0eaf5a 100644 --- a/libs/control.js +++ b/libs/control.js @@ -1302,8 +1302,12 @@ control.prototype._replay_save = function () { control.prototype._replay_error = function (action) { core.status.replay.replaying = false; - main.log("录像文件出错,当前操作:" + action + - "\n接下来10个操作是:"+core.status.replay.toReplay.slice(0, 10).toString()); + var len = core.status.replay.toReplay.length; + var prevList = core.status.replay.totalList.slice(-len - 11, -len - 1); + var nextList = core.status.replay.toReplay.slice(0, 10); + main.log("录像文件出错,当前操作:" + action); + main.log("之前的10个操作是:\n" + prevList.toString()); + main.log("接下来10个操作是:\n" + nextList.toString()); core.ui.drawConfirmBox("录像文件出错,你想回到上个节点吗?", function () { core.ui.closePanel(); if (core.status.replay.save.length > 0) { diff --git a/libs/maps.js b/libs/maps.js index f09d6b27..9d05a272 100644 --- a/libs/maps.js +++ b/libs/maps.js @@ -30,11 +30,14 @@ maps.prototype.loadFloor = function (floorId, map) { map = {"map": map}; } var content = {}; - ["floorId", "title", "name", "canFlyTo", "canUseQuickShop", "cannotViewMap", "cannotMoveDirectly", "color", "weather", - "defaultGround", "images", "item_ratio", "upFloor", "bgm", "downFloor", "underGround"].forEach(function (e) { - if (map[e] != null) content[e] = core.clone(map[e]); - else content[e] = core.clone(floor[e]); - }); + for (var name in floor) { + if (name != 'map' && name != 'bgmap' && name != 'fgmap' && floor[name] != null) + content[name] = core.clone(floor[name]); + } + for (var name in map) { + if (name != 'map' && name != 'bgmap' && name != 'fgmap' && map[name] != null) + content[name] = core.clone(map[name]); + } map = this.decompressMap(map.map, floorId); // 事件处理 content['blocks'] = this._mapIntoBlocks(map, floor, floorId); From 6e5e8f46abd31cb18bca5eae974c47ac2c5dcf74 Mon Sep 17 00:00:00 2001 From: YouWei Zhao Date: Sat, 30 Mar 2019 11:13:11 -0400 Subject: [PATCH 33/33] shop_event & unknow_event --- _docs/event.md | 6 ---- _server/MotaAction.g4 | 71 ++++++++++++++++++++++++++++----------- _server/data.comment.js | 6 ---- _server/editor_blockly.js | 7 +++- project/data.js | 11 ++++++ project/events.js | 31 +++++++++++++---- 6 files changed, 93 insertions(+), 39 deletions(-) diff --git a/_docs/event.md b/_docs/event.md index 57825ba7..3beb965a 100644 --- a/_docs/event.md +++ b/_docs/event.md @@ -682,12 +682,6 @@ revisit常常使用在一些商人之类的地方,当用户购买物品后不 ] ``` -### addToList:将本公共事件插入到快捷列表中 - -使用 `{"type": "addToList"}` 可以将当前公共事件插入到快捷商店列表中。 - -此项只能在公共事件中被执行。详见[公共事件](personalization#公共事件)。 - ### setBlock:设置某个图块 我们可以采用 `{"type": "setBlock"}` 来改变某个地图块。 diff --git a/_server/MotaAction.g4 b/_server/MotaAction.g4 index c1c31050..1fa52eba 100644 --- a/_server/MotaAction.g4 +++ b/_server/MotaAction.g4 @@ -65,6 +65,7 @@ return code; shoplist : shopsub + | shopcommonevent | emptyshop ; @@ -77,6 +78,24 @@ var code = ' \n'; return code; */; +shopcommonevent + : '商店 id' IdString '快捷商店栏中名称' EvalString BGNL? '未开启状态则不显示在列表中' Bool BGNL? '执行的公共事件 id' EvalString '参数列表' EvalString? + +/* shopcommonevent +tooltip : 全局商店, 执行一个公共事件 +helpUrl : https://h5mota.com/games/template/docs/#/ +default : ["shop1","回收钥匙商店",false,"回收钥匙商店",""] +var code = { + 'id': IdString_0, + 'textInList': EvalString_0, + 'mustEnable': Bool_0, + 'commonEvent': EvalString_1, + 'args': EvalString_2 +} +code=JSON.stringify(code,null,2)+',\n'; +return code; +*/; + shopsub : '商店 id' IdString '标题' EvalString '图标' IdString BGNL? Newline '快捷商店栏中名称' EvalString '共用times' Bool BGNL? Newline '未开启状态则不显示在列表中' Bool BGNL? NewLine '使用' ShopUse_List '消耗' EvalString BGNL? Newline '显示文字' EvalString BGNL? Newline shopChoices+ BEND @@ -240,7 +259,6 @@ action | insert_2_s | revisit_s | exit_s - | addToList_s | setBlock_s | showFloorImg_s | hideFloorImg_s @@ -304,6 +322,7 @@ action | callBook_s | callSave_s | callLoad_s + | unknow_s | function_s | pass_s ; @@ -694,18 +713,6 @@ var code = '{"type": "exit"},\n'; return code; */; -addToList_s - : '将本公共事件插入到快捷列表中' Newline - - -/* addToList_s -tooltip : addToList: 将本公共事件插入到快捷列表中 -helpUrl : https://h5mota.com/games/template/docs/#/event?id=exit%EF%BC%9A%E7%AB%8B%E5%88%BB%E7%BB%93%E6%9D%9F%E5%BD%93%E5%89%8D%E4%BA%8B%E4%BB%B6 -colour : this.eventColor -var code = '{"type": "addToList"},\n'; -return code; -*/; - setBlock_s : '转变图块为' Int 'x' PosString? ',' 'y' PosString? '楼层' IdString? Newline @@ -1739,6 +1746,19 @@ var code = '{"type": "callLoad"},\n'; return code; */; +unknow_s + : '自定义事件' BGNL? RawEvalString + +/* unknow_s +tooltip : 通过脚本自定义的事件类型, 以及编辑器不识别的事件类型 +helpUrl : https://h5mota.com/games/template/docs/#/ +default : ['{"type":"eventType1"}'] +colour : this.dataColor +var tempobj={}; +eval("tempobj='"+RawEvalString_0+"'"); +var code = tempobj +',\n'; +return code; +*/; function_s : '自定义JS脚本' '不自动执行下一个事件' Bool BGNL? Newline RawEvalString Newline BEND Newline @@ -2127,10 +2147,21 @@ ActionParser.prototype.parse = function (obj,type) { obj.id,obj.name,obj.icon,obj.textInList,obj.commonTimes,obj.mustEnable,obj.use,obj.need,parser.EvalString(obj.text),text_choices,next ]); } + var buildcommentevent = function(obj,parser,next){ + return MotaActionBlocks['shopcommonevent'].xmlText([ + obj.id,parser.EvalString(obj.textInList),obj.mustEnable,parser.EvalString(obj.commonEvent),parser.EvalString(obj.args),next + ]); + } var next=null; if(!obj)obj=[]; while(obj.length){ - next=buildsub(obj.pop(),this,next); + var shopobj=obj.pop() + if(shopobj.choices) + next=buildsub(shopobj,this,next); + else if(shopobj.commonEvent) + next=buildcommentevent(shopobj,this,next); + else + throw new Error("[警告]出错啦!\n"+shopobj.id+" 无效的商店"); } return MotaActionBlocks['shop_m'].xmlText([next]); @@ -2617,14 +2648,16 @@ ActionParser.prototype.parseAction = function() { this.next = MotaActionBlocks['exit_s'].xmlText([ this.next]); break; - case "addToList": // 立刻结束事件 - this.next = MotaActionBlocks['addToList_s'].xmlText([ - this.next]); - break; case "animateImage": // 兼容 animateImage break; default: - throw new Error("[警告]出错啦!\n"+data.type+" 事件不被支持..."); + var rawdata = JSON.stringify(data,function(k,v){ + if(typeof(v)=='string')return v.split('\n').join('\\n'); + else return v; + },2); + rawdata=rawdata.split('\n').join('\\n'); + this.next = MotaActionBlocks['unknow_s'].xmlText([ + rawdata,this.next]); } this.parseAction(); return; diff --git a/_server/data.comment.js b/_server/data.comment.js index 8df587e1..c4ad3175 100644 --- a/_server/data.comment.js +++ b/_server/data.comment.js @@ -660,12 +660,6 @@ var data_comment_c456ea59_6018_45ef_8bcc_211a24c627dc = "_bool": "bool", "_data": "是否在经过领域/夹击/路障等伤害后禁用快捷商店。" }, - "quickCommonEvents": { - "_leaf": true, - "_type": "checkbox", - "_bool": "bool", - "_data": "是否使用自定义的公共事件列表来代替快捷商店列表。\n如果此项开启,则快捷商店列表中将会显示加入的公共事件。" - }, "checkConsole": { "_leaf": true, "_type": "checkbox", diff --git a/_server/editor_blockly.js b/_server/editor_blockly.js index ee887b02..92ecfee2 100644 --- a/_server/editor_blockly.js +++ b/_server/editor_blockly.js @@ -37,6 +37,11 @@ editor_blockly = function () { {"text": "防御+4", "effect": "status:def+=4"}, {"text": "魔防+10", "effect": "status:mdef+=10"} ] + },{ + "id": "keyShop1", + "textInList": "回收钥匙商店", + "commonEvent": "回收钥匙商店", + "args": "" }],'shop'), MotaActionBlocks['afterBattle_m'].xmlText(), MotaActionBlocks['afterGetItem_m'].xmlText(), @@ -123,7 +128,6 @@ editor_blockly = function () { MotaActionBlocks['hideBgFgMap_s'].xmlText(), MotaActionBlocks['trigger_s'].xmlText(), MotaActionBlocks['insert_1_s'].xmlText(), - MotaActionBlocks['addToList_s'].xmlText(), MotaActionBlocks['insert_2_s'].xmlText(), MotaActionBlocks['move_s'].xmlText(), MotaActionBlocks['jump_s'].xmlText(), @@ -584,6 +588,7 @@ function omitedcheckUpdateFunction(event) { 'showTextImage_s': 'EvalString_0', 'function_s': 'RawEvalString_0', 'shopsub': 'EvalString_3', + 'unknow_s': 'RawEvalString_0', } var f = b ? textStringDict[b.type] : null; if (f) { diff --git a/project/data.js b/project/data.js index 6173ffed..5b612081 100644 --- a/project/data.js +++ b/project/data.js @@ -249,6 +249,8 @@ var data_a1e2fb4a_e986_4524_b0da_9b7ba7c0874d = "name": "贪婪之神", "icon": "blueShop", "textInList": "1F金币商店", + "commonTimes": false, + "mustEnable": false, "use": "money", "need": "20+10*times*(times+1)", "text": "勇敢的武士啊,给我${need}金币就可以:", @@ -276,6 +278,8 @@ var data_a1e2fb4a_e986_4524_b0da_9b7ba7c0874d = "name": "经验之神", "icon": "pinkShop", "textInList": "1F经验商店", + "commonTimes": false, + "mustEnable": false, "use": "experience", "need": "-1", "text": "勇敢的武士啊,给我若干经验就可以:", @@ -296,6 +300,13 @@ var data_a1e2fb4a_e986_4524_b0da_9b7ba7c0874d = "effect": "status:def+=5" } ] + }, + { + "id": "keyShop1", + "textInList": "1F回收钥匙商店", + "mustEnable": false, + "commonEvent": "回收钥匙商店", + "args": "" } ], "levelUp": [ diff --git a/project/events.js b/project/events.js index b546b4a2..cfc58540 100644 --- a/project/events.js +++ b/project/events.js @@ -241,18 +241,15 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "回收钥匙商店": [ { "type": "comment", - "text": "公共事件:回收钥匙商店" - }, - { - "type": "addToList" + "text": "此事件在全局商店中被引用了(全局商店keyShop1)" }, { "type": "comment", - "text": "使用上述事件并在全塔属性打开quickCommonEvent开关" + "text": "解除引用前勿删除此事件" }, { "type": "comment", - "text": "就可以在快捷列表(V键)中使用本公共事件" + "text": "玩家在快捷列表(V键)中可以使用本公共事件" }, { "type": "while", @@ -300,7 +297,27 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = 255, 1 ], - "action": [] + "action": [ + { + "type": "if", + "condition": "item:blueKey >= 1", + "true": [ + { + "type": "addValue", + "name": "item:blueKey", + "value": "-1" + }, + { + "type": "addValue", + "name": "status:money", + "value": "50" + } + ], + "false": [ + "\t[商人,woman]你没有蓝钥匙!" + ] + } + ] }, { "text": "离开",