From 65f9fcb612b33a0c28664b3b9df9299b2a5e2cbf Mon Sep 17 00:00:00 2001 From: ckcz123 Date: Fri, 14 Dec 2018 20:52:55 +0800 Subject: [PATCH] Dynamic canvas --- _server/blockly/MotaAction.g4 | 63 +++++++++++---------- _server/editor_blockly.js | 7 ++- docs/event.md | 45 ++++++++------- editor-mobile.html | 2 +- editor.html | 2 +- libs/control.js | 101 ++++++---------------------------- libs/core.js | 6 ++ libs/enemys.js | 32 +++++++++++ libs/events.js | 65 ++++++++++++---------- libs/items.js | 2 +- libs/maps.js | 68 ++++++++--------------- libs/ui.js | 20 +++++-- main.js | 1 - 13 files changed, 197 insertions(+), 217 deletions(-) diff --git a/_server/blockly/MotaAction.g4 b/_server/blockly/MotaAction.g4 index 06b76d77..7d4929f3 100644 --- a/_server/blockly/MotaAction.g4 +++ b/_server/blockly/MotaAction.g4 @@ -265,7 +265,7 @@ action | showImage_s | hideImage_s | showTextImage_s - | animateImage_s + | moveImage_s | showGif_0_s | showGif_1_s | setFg_0_s @@ -1021,34 +1021,34 @@ return code; */; showImage_s - : '显示图片' '图片编号' Int '图片' EvalString '起点像素位置' 'x' PosString 'y' PosString BGNL - '放大率 : x' Int '% y' Int '% 透明度' Int '时间' Int '不等待执行完毕' Bool Newline + : '显示图片' '图片编号' Int '图片' EvalString '起点像素位置' 'x' PosString 'y' PosString BGNL? + '放大率 : x' Int '% y' Int '% 不透明度' 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,100,0,false] +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] colour : this.printColor -if(Int_3<0 || Int_3>100) throw new Error('透明度的值在0~100之间'); +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": '+Int_3+', "time": '+Int_4+async+'},\n'; +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'; return code; */; showTextImage_s - : '显示图片化文本' '图片编号' Int '文本' EvalString BGNL - '起点像素位置' 'x' PosString 'y' PosString '透明度' Int '时间' Int '不等待执行完毕' Bool Newline + : '显示图片化文本' '文本内容' EvalString BGNL? + '图片编号' Int '起点像素位置' 'x' PosString 'y' PosString '不透明度' Number '时间' Int '不等待执行完毕' Bool Newline /* showTextImage_s tooltip : showTextImage:显示图片化文本 -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 +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 : [1,"可以使用setText事件来控制字体、颜色、大小、偏移量等","0","0",100,0,false] -if(Int_1<0 || Int_1>100) throw new Error('透明度的值在0~100之间'); +default : ["可以使用setText事件来控制字体、颜色、大小、偏移量等",1,"0","0",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": '+Int_1+', "time": '+Int_2+async+'},\n'; +var code = '{"type": "showTextImage", "code": '+Int_0+', "text": "'+EvalString_0+'", "loc": ['+PosString_0+','+PosString_1+'], "opacity": '+Number_0+', "time": '+Int_1+async+'},\n'; return code; */; @@ -1058,9 +1058,10 @@ hideImage_s /* hideImage_s tooltip : hideImage:清除图片 -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 +helpUrl : https://h5mota.com/games/template/docs/#/event?id=hideImage%ef%bc%9a%e6%b8%85%e9%99%a4%e5%9b%be%e7%89%87 colour : this.printColor default : [1,0,false] +if(Int_0<=0 || Int_0>50) throw new Error('图片编号在1~50之间'); var async = Bool_0?', "async": true':''; var code = '{"type": "hideImage", "code": '+Int_0+', "time": '+Int_1+async+'},\n'; return code; @@ -1091,22 +1092,23 @@ var code = '{"type": "showGif"},\n'; return code; */; -animateImage_s - : '图片移动' '编号' Int '终点像素位置' 'x' PosString? 'y' PosString? BGNL - '透明度' PosString? '移动时间' Int '不等待执行完毕' Bool Newline +moveImage_s + : '图片移动' '图片编号' Int '终点像素位置' 'x' PosString? 'y' PosString? BGNL? + '不透明度' EvalString? '移动时间' Int '不等待执行完毕' Bool Newline -/* animateImage_s -tooltip : animateImage:图片移动 -helpUrl : https://h5mota.com/games/template/docs/#/event?id=moveimage%EF%BC%9A%E5%9B%BE%E7%89%87%E7%A7%BB%E5%8A%A8 -default : [1,"0","0",100,500,false] +/* moveImage_s +tooltip : moveImage:图片移动 +helpUrl : https://h5mota.com/games/template/docs/#/event?id=moveImage%ef%bc%9a%e5%9b%be%e7%89%87%e7%a7%bb%e5%8a%a8 +default : [1,'','','',500,false] colour : this.printColor +if(Int_0<=0 || Int_0>50) throw new Error('图片编号在1~50之间'); var toloc = ''; if (PosString_0 && PosString_1) - toloc = ', "to": ['+PosString_0+','+PosString_1+']' -PosString_2 = (PosString_2) ? (', "opacity": '+PosString_2):''; + toloc = ', "to": ['+PosString_0+','+PosString_1+']'; +EvalString_0 = (EvalString_0!=='') ? (', "opacity": '+EvalString_0):''; var async = Bool_0?', "async": true':''; -var code = '{"type": "animateImage", "code": '+Int_0+toloc+PosString_2+',"time": '+Int_1+async+'},\n'; +var code = '{"type": "moveImage", "code": '+Int_0+toloc+EvalString_0+',"time": '+Int_1+async+'},\n'; return code; */; @@ -2070,19 +2072,22 @@ ActionParser.prototype.parseAction = function() { this.next = MotaActionBlocks['vibrate_s'].xmlText([data.time||0, data.async||false, this.next]); break; case "showImage": // 显示图片 + data.loc=data.loc||['',''] this.next = MotaActionBlocks['showImage_s'].xmlText([ - data.code,data.image,data.loc[0],data.loc[1],data.dw||100,data.dw||100,data.opacity||100,data.time||0,data.async||false,this.next]); + data.code,data.image,data.loc[0],data.loc[1],data.dw,data.dh,data.opacity,data.time||0,data.async||false,this.next]); break; case "hideImage": // 清除图片 this.next = MotaActionBlocks['hideImage_s'].xmlText([ data.code,data.time||0,data.async||false,this.next]); break; case "showTextImage": // 显示图片化文本 + data.loc=data.loc||['',''] this.next = MotaActionBlocks['showTextImage_s'].xmlText([ - data.code,this.EvalString(data.text),data.loc[0],data.loc[1],data.opacity||100,data.time||0,data.async||false,this.next]); + this.EvalString(data.text),data.code,data.loc[0],data.loc[1],data.opacity,data.time||0,data.async||false,this.next]); break; - case "animateImage": // 移动图片 - this.next = MotaActionBlocks['animateImage_s'].xmlText([ + case "moveImage": // 移动图片 + data.to=data.to||['',''] + this.next = MotaActionBlocks['moveImage_s'].xmlText([ data.code, data.to[0], data.to[1], data.opacity, data.time||0, data.async||false, this.next]); break; case "showGif": // 显示动图 @@ -2341,7 +2346,7 @@ MotaActionFunctions.IdString_pre = function(IdString){ MotaActionFunctions.PosString_pre = function(PosString){ if (!PosString || /^-?\d+$/.test(PosString)) return PosString; - if (!(/^flag:[0-9a-zA-Z_][0-9a-zA-Z_\-:]*$/.test(PosString)))throw new Error(PosString+'中包含了0-9 a-z A-Z _ - :之外的字符,或者是没有以flag: 开头'); + if (!(/^flag:[0-9a-zA-Z_][0-9a-zA-Z_:]*$/.test(PosString)))throw new Error(PosString+'中包含了0-9 a-z A-Z _ :之外的字符,或者是没有以flag: 开头'); return '"'+PosString+'"'; } diff --git a/_server/editor_blockly.js b/_server/editor_blockly.js index 981a2746..15c48840 100644 --- a/_server/editor_blockly.js +++ b/_server/editor_blockly.js @@ -66,7 +66,7 @@ editor_blockly = function () { MotaActionBlocks['showImage_s'].xmlText(), MotaActionBlocks['hideImage_s'].xmlText(), MotaActionBlocks['showTextImage_s'].xmlText(), - MotaActionBlocks['animateImage_s'].xmlText(), + MotaActionBlocks['moveImage_s'].xmlText(), MotaActionBlocks['showGif_0_s'].xmlText(), MotaActionBlocks['showGif_1_s'].xmlText(), MotaActionBlocks['tip_s'].xmlText(), @@ -432,7 +432,7 @@ function omitedcheckUpdateFunction(event) { MotaActionFunctions.parse( eval('obj=' + codeAreaHL.getValue().replace(/[<>&]/g, function (c) { return {'<': '<', '>': '>', '&': '&'}[c]; - })), + }).replace(/\\r/g, '\\\\r').replace(/\\f/g, '\\\\f')), document.getElementById('entryType').value ); } @@ -447,7 +447,7 @@ function omitedcheckUpdateFunction(event) { var type = args.type; if (!type) return false; editor_blockly.id = id_; - codeAreaHL.setValue(input.value.replace(/\\r/g,'\\\\r').replace(/\\f/,'\\\\f')); + codeAreaHL.setValue(input.value); document.getElementById('entryType').value = type; editor_blockly.parse(); editor_blockly.show(); @@ -520,6 +520,7 @@ function omitedcheckUpdateFunction(event) { 'scrollText_s': 'EvalString_0', 'comment_s': 'EvalString_0', 'choices_s': 'EvalString_0', + 'showTextImage_s': 'EvalString_0', 'function_s': 'RawEvalString_0', 'shopsub': 'EvalString_3', } diff --git a/docs/event.md b/docs/event.md index d1e6d83f..90f38b1d 100644 --- a/docs/event.md +++ b/docs/event.md @@ -923,7 +923,7 @@ async可选,如果为true则会异步执行(即不等待当前事件执行 ] ``` -name为动画名,**请确保动画在main.js中的this.animates中被定义过。** +name为动画名,**请确保动画在全塔属性中的animates中被定义过。** loc为动画的位置,可以是`[x,y]`表示在(x,y)点显示,也可以是字符串`"hero"`表示在勇士点显示。 @@ -939,25 +939,27 @@ loc可忽略,如果忽略则显示为事件当前点。 ``` js "x,y": [ // 实际执行的事件列表 - {"type": "showImage", "code": 1, "image": "bg.jpg", "loc": [231,297], "dw": 100, "dy" : 100, "opacity": 100, "time" : 0}, // 在(231,297)显示bg.jpg - {"type": "showImage", "code": 12, "image": "1.png", "loc": [209,267], "dw": 100, "dy" : 100, "opacity": 50, "time" : 1000}, // 在(209,267)渐变显示1.png,渐变时间为1000毫秒,完成时透明度为0.5,这张图片将遮盖上一张 - {"type": "showImage", "code": 8, "image": "hero.png", "loc": [349,367], "dw": 50, "dy" : 50, "opacity": 100, "time" : 0}, // 在(209,267)渐变显示hero.png,大小为原图片的一半,渐变时间为1000毫秒,这张图片将被上一张遮盖 + {"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毫秒,异步执行;这张图片将被上一张遮盖 ] ``` -code为图片编号,如果两张图片重叠,编号较大的显示在上。建议编号取1~50之间的数。 +code为图片编号,如果两张图片重叠,编号较大会覆盖编号较小的。该值需要在1~50之间。 -image为图片名。**请确保图片在data.js中的images中被定义过。** +image为图片名。**请确保图片在全塔属性中的images中被定义过。** loc为图片左上角坐标,以像素为单位进行计算。 dw和dh为图片的横向、纵向放大率,默认值为100,即不进行缩放。 -opacity为图片透明度,默认值为100,即不透明。 +opacity为图片不透明度,在0~1之间,默认值为1,即不透明。 time为渐变时间,默认值为0,即不渐变直接显示。 -### showTextImage:显示图片 +async可选,如果为true则会异步执行(即不等待当前事件执行完毕,立刻执行下一个事件)。 + +### showTextImage:显示文本化图片 我们可以使用 `{"type": "showTextImage"}` 以图片的方式显示文本。 @@ -967,16 +969,20 @@ time为渐变时间,默认值为0,即不渐变直接显示。 ] ``` -code为图片编号,如果两张图片重叠,编号较大的显示在上。建议编号取1~50之间的数。 +code为图片编号,如果两张图片重叠,编号较大会覆盖编号较小的。该值需要在1~50之间。 text为要显示的文本。默认行宽为416。 loc为图片左上角坐标,以像素为单位进行计算。 -opacity为图片透明度。 +opacity为图片不透明度,在0~1之间,默认值为1,即不透明。 time为渐变时间,默认值为0,即不渐变直接显示。 +async可选,如果为true则会异步执行(即不等待当前事件执行完毕,立刻执行下一个事件)。 + +文本通过图片的方式显示后,即视为一张正常图片,可以被清除或者移动。 + ### hideImage:清除图片 我们可以使用 `{"type": "hideImage"}` 来清除一张图片。 @@ -992,6 +998,8 @@ time为渐变时间,默认值为0,即不渐变直接消除。 code为显示图片时输入的图片编号。 +async可选,如果为true则会异步执行(即不等待当前事件执行完毕,立刻执行下一个事件)。 + ### showGif:显示动图 我们可以使用 `{"type": "showGif"}` 来显示一张图片。 @@ -1003,30 +1011,29 @@ code为显示图片时输入的图片编号。 ] ``` -name为图片名。**请确保图片在data.js中的images中被定义过。** +name为图片名。**请确保图片在全塔属性中的images中被定义过。** loc为动图左上角坐标,以像素为单位进行计算。 如果不指定name则清除所有显示的动图。 -### animateImage:图片移动 +### moveImage:图片移动 -我们可以使用 `{"type": "animateImage"}` 来造成图片移动,淡入淡出等效果。 +我们可以使用 `{"type": "moveImage"}` 来造成图片移动,淡入淡出等效果。 ``` js "x,y": [ // 实际执行的事件列表 - {"type": "animateImage", "code": 1, "to": [22,333], "opacity": 1, "time": 1000}, - // 将1号图片移动到(22,333),动画时间为1000ms - {"type": "animateImage", "code": 12, "opacity": 0.5, "time": 500}, // 将二号图片的透明度变为0.5,动画时间500ms - {"type": "animateImage", "code": 1, "to": [109,167], "opacity": 0, "time": 300, "async": true}, // 将1号图片移动到(109,167),透明度设为0(不可见),动画时间300ms,异步执行 + {"type": "moveImage", "code": 1, "to": [22,333], "opacity": 1, "time": 1000}, // 将1号图片移动到(22,333),动画时间为1000ms + {"type": "moveImage", "code": 12, "opacity": 0.5, "time": 500}, // 将二号图片的透明度变为0.5,动画时间500ms + {"type": "moveImage", "code": 1, "to": [109,167], "opacity": 0, "time": 300, "async": true}, // 将1号图片移动到(109,167),透明度设为0(不可见),动画时间300ms,异步执行 ] ``` -image为图片名。**请确保图片在data.js中的images中被定义过。** +code为图片编号。该值需要在1~50之间。 to为终点图片左上角坐标,以像素为单位进行计算,不填写则视为当前图片位置。 -opacity为完成时图片透明度,移动过程中逐渐变化。 +opacity为完成时图片不透明度,移动过程中逐渐变化。在0~1之间。 time为总移动的时间。 diff --git a/editor-mobile.html b/editor-mobile.html index fedd1cb1..41818ed2 100644 --- a/editor-mobile.html +++ b/editor-mobile.html @@ -443,9 +443,9 @@ - 此浏览器不支持HTML5 +
diff --git a/editor.html b/editor.html index df51ae2e..0838ffcb 100644 --- a/editor.html +++ b/editor.html @@ -428,9 +428,9 @@ - 此浏览器不支持HTML5 +
diff --git a/libs/control.js b/libs/control.js index 7f786c75..0a6b4883 100644 --- a/libs/control.js +++ b/libs/control.js @@ -113,14 +113,14 @@ control.prototype.setRequestAnimationFrame = function () { // selectorTime if (timestamp-core.animateFrame.selectorTime>20 && core.isset(core.dymCanvas.selector)) { - var opac = parseFloat(core.dymCanvas.selector.canvas.style.opacity); - if (core.getFlag("seleUp", true)) - opac += 0.02; + var opacity = parseFloat(core.dymCanvas.selector.canvas.style.opacity); + if (core.animateFrame.selectorUp) + opacity += 0.02; else - opac -= 0.02; - if (opac > 0.9 || opac < 0.6) - core.setFlag("seleUp", !core.getFlag("seleUp", true)) - core.setOpacity("selector", opac); + opacity -= 0.02; + if (opacity > 0.95 || opacity < 0.55) + core.animateFrame.selectorUp = !core.animateFrame.selectorUp; + core.setOpacity("selector", opacity); core.animateFrame.selectorTime = timestamp; } @@ -129,10 +129,10 @@ control.prototype.setRequestAnimationFrame = function () { core.clearMap('animate'); core.status.animateObjs = core.status.animateObjs.filter(function (obj) { return obj.index < obj.animate.frames.length; - }) + }); core.status.animateObjs.forEach(function (obj) { core.maps.drawAnimateFrame(obj.animate, obj.centerX, obj.centerY, obj.index++); - }) + }); core.animateFrame.animateTime = timestamp; } @@ -1372,28 +1372,8 @@ control.prototype.snipe = function (snipes) { snipe.blockImage = core.material.images[cls]; snipe.height = height; - var damage = core.enemys.getDamage(block.event.id, x, y); - var color = '#000000'; - - if (damage == null) { - damage = "???"; - color = '#FF0000'; - } - else { - if (damage <= 0) color = '#00FF00'; - else if (damage < core.status.hero.hp / 3) color = '#FFFFFF'; - else if (damage < core.status.hero.hp * 2 / 3) color = '#FFFF00'; - else if (damage < core.status.hero.hp) color = '#FF7F00'; - else color = '#FF0000'; - - damage = core.formatBigNumber(damage, true); - if (core.enemys.hasSpecial(core.material.enemys[block.event.id], 19)) - damage += "+"; - if (core.enemys.hasSpecial(core.material.enemys[block.event.id], 21)) - damage += "-"; - if (core.enemys.hasSpecial(core.material.enemys[block.event.id], 11)) - damage += "^"; - } + var damageString = core.enemys.getDamageString(block.event.id, x, y); + var damage = damageString.damage, color = damageString.color; snipe.damage = damage; snipe.color = color; @@ -1454,14 +1434,7 @@ control.prototype.snipe = function (snipes) { if (core.hasItem('book')) { // drawDamage - core.setFillStyle('damage', '#000000'); - core.canvas.damage.fillText(snipe.damage, nowX + 2, nowY + 30); - core.canvas.damage.fillText(snipe.damage, nowX, nowY + 30); - core.canvas.damage.fillText(snipe.damage, nowX + 2, nowY + 32); - core.canvas.damage.fillText(snipe.damage, nowX, nowY + 32); - - core.setFillStyle('damage', snipe.color); - core.canvas.damage.fillText(snipe.damage, nowX + 1, nowY + 31); + core.fillBoldText(core.canvas.damage, snipe.damage, snipe.color, nowX+1, nowY+31); } }) @@ -1622,36 +1595,9 @@ control.prototype.updateDamage = function (floorId, canvas) { var id = mapBlocks[b].event.id; if (core.flags.displayEnemyDamage) { - var damage = core.enemys.getDamage(id, x, y); - var color = '#000000'; - - if (damage == null) { - damage = "???"; - color = '#FF0000'; - } - else { - if (damage <= 0) color = '#00FF00'; - else if (damage < hero_hp / 3) color = '#FFFFFF'; - else if (damage < hero_hp * 2 / 3) color = '#FFFF00'; - else if (damage < hero_hp) color = '#FF7F00'; - else color = '#FF0000'; - damage = core.formatBigNumber(damage, true); - if (core.enemys.hasSpecial(core.material.enemys[id], 19)) - damage += "+"; - if (core.enemys.hasSpecial(core.material.enemys[id], 21)) - damage += "-"; - if (core.enemys.hasSpecial(core.material.enemys[id], 11)) - damage += "^"; - } - - canvas.fillStyle = '#000000'; - canvas.fillText(damage, 32 * x + 2, 32 * (y + 1) - 2); - canvas.fillText(damage, 32 * x, 32 * (y + 1) - 2); - canvas.fillText(damage, 32 * x + 2, 32 * (y + 1)); - canvas.fillText(damage, 32 * x, 32 * (y + 1)); - - canvas.fillStyle = color; - canvas.fillText(damage, 32 * x + 1, 32 * (y + 1) - 1); + var damageString = core.enemys.getDamageString(id, x, y); + var damage = damageString.damage, color = damageString.color; + core.fillBoldText(canvas, damage, color, 32*x+1, 32*(y+1)-1); } // 临界显伤 @@ -1660,13 +1606,7 @@ control.prototype.updateDamage = function (floorId, canvas) { if (critical.length>0) critical=critical[0]; critical = core.formatBigNumber(critical[0], true); if (critical == '???') critical = '?'; - canvas.fillStyle = '#000000'; - canvas.fillText(critical, 32 * x + 2, 32 * (y + 1) - 2 - 10); - canvas.fillText(critical, 32 * x, 32 * (y + 1) - 2 - 10); - canvas.fillText(critical, 32 * x + 2, 32 * (y + 1) - 10); - canvas.fillText(critical, 32 * x, 32 * (y + 1) - 10); - canvas.fillStyle = '#FFFFFF'; - canvas.fillText(critical, 32 * x + 1, 32 * (y + 1) - 1 - 10); + core.fillBoldText(canvas, critical, '#FFFFFF', 32*x+1, 32*(y+1)-11); } } @@ -1691,14 +1631,7 @@ control.prototype.updateDamage = function (floorId, canvas) { var damage = core.status.checkBlock.damage[x+core.bigmap.width*y]; if (damage>0) { damage = core.formatBigNumber(damage, true); - canvas.fillStyle = '#000000'; - canvas.fillText(damage, 32 * x + 17, 32 * (y + 1) - 13); - canvas.fillText(damage, 32 * x + 15, 32 * (y + 1) - 15); - canvas.fillText(damage, 32 * x + 17, 32 * (y + 1) - 15); - canvas.fillText(damage, 32 * x + 15, 32 * (y + 1) - 13); - - canvas.fillStyle = '#FF7F00'; - canvas.fillText(damage, 32 * x + 16, 32 * (y + 1) - 14); + core.fillBoldText(canvas, damage, "#FF7F00", 32*x+16, 32*(y+1)-14); } } } diff --git a/libs/core.js b/libs/core.js index 6b5f1a8a..76dc3052 100644 --- a/libs/core.js +++ b/libs/core.js @@ -32,6 +32,8 @@ function core() { 'globalAnimate': false, 'globalTime': null, 'boxTime': null, + 'selectorTime': null, + 'selectorUp': true, 'animateTime': null, 'moveTime': null, 'lastLegTime': null, @@ -890,6 +892,10 @@ core.prototype.updateDamage = function () { core.control.updateDamage(); } +core.prototype.fillBoldText = function (canvas, text, color, x, y, font) { + core.ui.fillBoldText(canvas, text, color, x, y, font); +} + ////// 测试是否拥有某个特殊属性 ////// core.prototype.hasSpecial = function (special, test) { return core.enemys.hasSpecial(special, test); diff --git a/libs/enemys.js b/libs/enemys.js index bc1563b5..b6fb9027 100644 --- a/libs/enemys.js +++ b/libs/enemys.js @@ -127,6 +127,38 @@ enemys.prototype.getExtraDamage = function (enemy) { return extra_damage; } +enemys.prototype.getDamageString = function (enemy, x, y) { + if (typeof enemy == 'string') enemy = core.material.enemys[enemy]; + var damage = core.enemys.getDamage(enemy, x, y); + + var color = '#000000'; + + if (damage == null) { + damage = "???"; + color = '#FF0000'; + } + else { + if (damage <= 0) color = '#00FF00'; + else if (damage < core.status.hero.hp / 3) color = '#FFFFFF'; + else if (damage < core.status.hero.hp * 2 / 3) color = '#FFFF00'; + else if (damage < core.status.hero.hp) color = '#FF7F00'; + else color = '#FF0000'; + + damage = core.formatBigNumber(damage, true); + if (core.enemys.hasSpecial(enemy, 19)) + damage += "+"; + if (core.enemys.hasSpecial(enemy, 21)) + damage += "-"; + if (core.enemys.hasSpecial(enemy, 11)) + damage += "^"; + } + + return { + "damage": damage, + "color": color + }; +} + ////// 接下来N个临界值和临界减伤计算 ////// enemys.prototype.nextCriticals = function (enemy, number, x, y, floorId) { if (typeof enemy == 'string') enemy = core.material.enemys[enemy]; diff --git a/libs/events.js b/libs/events.js index 2cbd8ee6..9d380fee 100644 --- a/libs/events.js +++ b/libs/events.js @@ -212,8 +212,7 @@ events.prototype.gameOver = function (ending, fromReplay, norank) { // 清空图片和天气 core.clearMap('animate'); - core.clearMap('image'); - core.clearMap('weather') + core.clearMap('weather'); core.dom.gif2.innerHTML = ""; core.animateFrame.weather.type = null; core.animateFrame.weather.level = 0; @@ -724,6 +723,10 @@ events.prototype.doAction = function() { data.time = 0; } var image = core.material.images.images[data.image]; + if (!core.isset(image)) { + this.doAction(); + break; + } if (data.async || data.time == 0) { core.events.showImage(data.code, image, data.loc[0], data.loc[1], data.dw, data.dh, data.opacity, data.time); this.doAction(); @@ -781,17 +784,17 @@ events.prototype.doAction = function() { } this.doAction(); break; - case "animateImage": // 图片移动 + case "moveImage": // 图片移动 if (core.status.replay.replaying) { // 正在播放录像 this.doAction(); } else { if (data.async) { - core.events.animateImage(data.code, data.to, data.opacity, data.time); + core.events.moveImage(data.code, data.to, data.opacity, data.time); this.doAction(); } else { - core.events.animateImage(data.code, data.to, data.opacity, data.time, function() { + core.events.moveImage(data.code, data.to, data.opacity, data.time, function() { core.events.doAction(); }); } @@ -1558,8 +1561,12 @@ events.prototype.changeFloor = function (floorId, stair, heroLoc, time, callback ////// 显示图片 ////// events.prototype.showImage = function (code, image, x, y, dw, dh, opacityVal, time, callback) { - dw /= 100, dh /= 100, opacityVal /= 100; + dw /= 100; + dh /= 100; + x = core.calValue(x) || 0; + y = core.calValue(y) || 0; var zIndex = code + 100; + time = time || 0; var name = "image"+ zIndex; if (core.findCanvas(name) != -1) { core.relocateCanvas(name, x, y); @@ -1568,23 +1575,24 @@ events.prototype.showImage = function (code, image, x, y, dw, dh, opacityVal, ti } else core.createCanvas(name, x, y, image.width * dw, image.height * dh, zIndex); + core.dymCanvas[name].drawImage(image, 0, 0, image.width * dw, image.height * dh); if (time == 0) core.setOpacity(name, opacityVal); else { - clearInterval(core.interval.tipAnimate); - var opac = 0; + var per_time = 10, steps = parseInt(time / per_time), per_add = opacityVal / steps; + var opacity = 0; core.setOpacity(name, 0); var animate = setInterval(function () { - opac += opacityVal/20; - core.setOpacity(name, opac); - if (opac >= opacityVal) { + opacity += per_add; + core.setOpacity(name, opacity); + if (opacity >= opacityVal) { delete core.animateFrame.asyncId[animate]; clearInterval(animate); core.setOpacity(name, opacityVal); if (core.isset(callback)) callback(); } - }, time/20); + }, per_time); core.animateFrame.asyncId[animate] = true; } @@ -1592,27 +1600,28 @@ events.prototype.showImage = function (code, image, x, y, dw, dh, opacityVal, ti ////// 隐藏图片 ////// events.prototype.hideImage = function (code, time, callback) { + time = time || 0; var name = "image"+ (code+100); if (!core.isset(core.dymCanvas[name])) { console.log(code+"号图片不存在") + if (core.isset(callback)) callback(); return; } if (time == 0) core.deleteCanvas(name); else { - clearInterval(core.interval.tipAnimate); var opacityVal = parseFloat(core.dymCanvas[name].canvas.style.opacity); - var opac = opacityVal; + var per_time = 10, steps = parseInt(time / per_time), per_add = opacityVal / steps; var animate = setInterval(function () { - opac -= opacityVal/20; - core.setOpacity(name, opac); - if (opac < 0) { + opacityVal -= per_add; + core.setOpacity(name, opacityVal); + if (opacityVal < 0) { delete core.animateFrame.asyncId[animate]; clearInterval(animate); core.deleteCanvas(name); if (core.isset(callback)) callback(); } - }, time/20); + }, per_time); core.animateFrame.asyncId[animate] = true; } @@ -1632,7 +1641,7 @@ events.prototype.textImage = function (content) { if (textAttribute.bold) font = "bold "+font; var contents = core.splitLines('ui', content), lines = contents.length; - // 计算总高度,按1.2倍行距计算 + // 计算总高度,按1.4倍行距计算 var width = 416, height = textfont * 1.4 * lines; var tempCanvas = core.bigmap.tempCanvas; tempCanvas.canvas.width = width; @@ -1653,29 +1662,29 @@ events.prototype.textImage = function (content) { } ////// 移动图片 ////// -events.prototype.animateImage = function (code, to, opacityVal, time, callback) { +events.prototype.moveImage = function (code, to, opacityVal, time, callback) { time = time || 1000; - clearInterval(core.interval.tipAnimate); - // core.status.replay.animate=true; var name = "image"+ (code+100), index = core.findCanvas(name); if (index == -1) { console.log(code+"号图片不存在") + if (core.isset(callback)) callback(); return; } var fromX = core.dymCanvas._list[index].style.left, fromY = core.dymCanvas._list[index].style.top, - preX = fromX, preY = fromY; - if (core.isset(to)) - var toX = core.calValue(to[0]), toY = core.calValue(to[1]); - else - var toX = fromX, toY = fromY; + preX = fromX, preY = fromY, toX = fromX, toY = fromY; + + if (core.isset(to)) { + toX = core.calValue(to[0]) || toX; + toY = core.calValue(to[1]) || toY; + } var step = 0; var per_time = 10, steps = parseInt(time / per_time); var preOpac = parseFloat(core.dymCanvas[name].canvas.style.opacity), opacStep; if (core.isset(opacityVal)) { - opacityVal /= 100; + opacityVal = core.calValue(opacityVal); opacStep = (opacityVal - preOpac) / steps; } else diff --git a/libs/items.js b/libs/items.js index f8a7bfc1..d7c5a7ff 100644 --- a/libs/items.js +++ b/libs/items.js @@ -91,7 +91,7 @@ items.prototype.useItem = function (itemId, callback) { delete core.status.hero.items[itemCls][itemId]; core.updateStatusBar(); - core.status.event.data = null; + if (!core.isset(core.status.event.id)) core.status.event.data = null; if (core.isset(callback)) callback(); } diff --git a/libs/maps.js b/libs/maps.js index 8f4b0d80..67082943 100644 --- a/libs/maps.js +++ b/libs/maps.js @@ -817,11 +817,6 @@ maps.prototype.moveBlock = function(x,y,steps,time,keep,callback) { by = core.material.icons[block.event.cls][block.event.id]; faceIds = block.event.faceIds||{}; } - - var alpha = 1, name = 'move'+x+'_'+y; - core.createCanvas(name, block.x, block.y * 32 +32 - height, 32, height, 45); - core.dymCanvas[name].textAlign = 'left'; - core.dymCanvas[name].drawImage(image, bx * 32, by * height, 32, height, 0, 0, 32, height); // 要运行的轨迹:将steps展开 var moveSteps=[]; steps.forEach(function (e) { @@ -850,8 +845,31 @@ maps.prototype.moveBlock = function(x,y,steps,time,keep,callback) { var animateValue = block.event.animate || 1; var animateCurrent = 0; + if (block.event.cls=='tileset') { + animateCurrent = bx; + } var animateTime = 0; + var alpha = 1, name = 'move'+x+'_'+y; + core.createCanvas(name, block.x - core.bigmap.offsetX, block.y * 32 +32 - height - core.bigmap.offsetY, 32, height, 45); + core.dymCanvas[name].textAlign = 'left'; + + // 显伤 + var damage = null, damageColor = null; + if ((block.event.cls == 'enemys' || block.event.cls == 'enemy48') && core.hasItem('book')) { + var damageString = core.enemys.getDamageString(block.event.id, x, y); + damage = damageString.damage; damageColor = damageString.color; + } + + var draw = function() { + core.dymCanvas[name].clearRect(0, 0, 32, height); + core.dymCanvas[name].drawImage(image, animateCurrent*32, by*height, 32, height, 0, 0, 32, height); + // 绘制显伤 + if (damage != null) + core.fillBoldText(core.dymCanvas[name], damage, damageColor, 1, height-1); + }; + draw(); + var animate=window.setInterval(function() { animateTime += time / 16 / core.status.replay.speed; @@ -899,50 +917,12 @@ maps.prototype.moveBlock = function(x,y,steps,time,keep,callback) { by = tby; } } - step++; nowX+=scan[direction].x*2; nowY+=scan[direction].y*2; // 移动 core.relocateCanvas(name, nowX, nowY-height+32); - core.dymCanvas[name].drawImage(image, animateCurrent * 32, by * height, 32, height, 0, 0, 32, height); - // 显伤绘制 - if ((block.event.cls == 'enemys' || block.event.cls == 'enemy48') && core.hasItem('book')) { - // 鉴于移动过程中可能的主角状态改变,每次重新计算 - var damage = core.enemys.getDamage(block.event.id, x, y); - var color = '#000000'; - - if (damage == null) { - damage = "???"; - color = '#FF0000'; - } - else { - if (damage <= 0) color = '#00FF00'; - else if (damage < core.status.hero.hp / 3) color = '#FFFFFF'; - else if (damage < core.status.hero.hp * 2 / 3) color = '#FFFF00'; - else if (damage < core.status.hero.hp) color = '#FF7F00'; - else color = '#FF0000'; - - damage = core.formatBigNumber(damage); - if (core.enemys.hasSpecial(core.material.enemys[block.event.id], 19)) - damage += "+"; - if (core.enemys.hasSpecial(core.material.enemys[block.event.id], 21)) - damage += "-"; - if (core.enemys.hasSpecial(core.material.enemys[block.event.id], 11)) - damage += "^"; - } - // 清空上一次 - core.clearMap('damage', nowX-2*scan[direction].x, nowY-2*scan[direction].y, 32, 32); - - core.setFillStyle('damage', '#000000'); - core.canvas.damage.fillText(damage, nowX + 5, nowY + 30); - core.canvas.damage.fillText(damage, nowX + 3, nowY + 30); - core.canvas.damage.fillText(damage, nowX + 5, nowY + 32); - core.canvas.damage.fillText(damage, nowX + 3, nowY + 32); - - core.setFillStyle('damage', color); - core.canvas.damage.fillText(damage, nowX + 4, nowY + 31); - } + draw(); if (step==16) { // 该移动完毕,继续 step=0; diff --git a/libs/ui.js b/libs/ui.js index d658802a..cb545683 100644 --- a/libs/ui.js +++ b/libs/ui.js @@ -43,6 +43,18 @@ ui.prototype.fillText = function (map, text, x, y, style, font) { core.canvas[map].fillText(text, x, y); } +////// 在某个canvas上绘制粗体 ////// +ui.prototype.fillBoldText = function (canvas, text, color, x, y, font) { + if (core.isset(font)) canvas.font = font; + canvas.fillStyle = '#000000'; + canvas.fillText(text, x-1, y-1); + canvas.fillText(text, x-1, y+1); + canvas.fillText(text, x+1, y-1); + canvas.fillText(text, x+1, y+1); + canvas.fillStyle = color; + canvas.fillText(text, x, y); +} + ////// 在某个canvas上绘制一个矩形 ////// ui.prototype.fillRect = function (map, x, y, width, height, style) { if (core.isset(style)) { @@ -762,7 +774,7 @@ ui.prototype.drawScrollText = function (content, time, callback) { if (textAttribute.bold) font = "bold "+font; var contents = core.splitLines('ui', content), lines = contents.length; - // 计算总高度,按1.2倍行距计算 + // 计算总高度,按1.4倍行距计算 var width = 416, height = textfont * 1.4 * lines; var tempCanvas = core.bigmap.tempCanvas; tempCanvas.canvas.width = width; @@ -1477,9 +1489,6 @@ ui.prototype.drawCursor = function () { ui.prototype.drawBook = function (index) { var enemys = core.enemys.getCurrentEnemys(core.floorIds[(core.status.event.selection||{}).index]); - clearInterval(core.interval.tipAnimate); - core.clearMap('data'); - core.clearLastEvent(); core.setFillStyle('ui', core.material.groundPattern); core.fillRect('ui', 0, 0, 416, 416); @@ -1577,8 +1586,8 @@ ui.prototype.drawBook = function (index) { if (line_cnt==2) damageOffset=361; core.canvas.ui.textAlign = "center"; - var damage = enemy.damage; + var damage = enemy.damage; var color = '#FFFF00'; if (damage == null) { damage = '无法战斗'; @@ -1598,7 +1607,6 @@ ui.prototype.drawBook = function (index) { } if (enemy.notBomb) damage += "[b]"; - core.fillText('ui', damage, damageOffset, 62 * i + 50, color, 'bold 13px '+globalFont); core.canvas.ui.textAlign = "left"; diff --git a/main.js b/main.js index a697bccd..bb6be1bb 100644 --- a/main.js +++ b/main.js @@ -70,7 +70,6 @@ function main() { 'hard': document.getElementById('hard'), 'statusCanvas': document.getElementById('statusCanvas'), 'dymCanvas': document.getElementById('dymCanvas'), - 'dym': document.getElementsByClassName('dym'), }; this.mode = 'play'; this.loadList = [