From 7876b74b9a8b2dd0bc84df47001a3f3b47d27adf Mon Sep 17 00:00:00 2001 From: ckcz123 Date: Fri, 30 Jul 2021 16:08:32 +0800 Subject: [PATCH] =?UTF-8?q?=E6=97=8B=E8=BD=AC=E5=9B=BE=E7=89=87?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- _docs/api.md | 13 +++++++++ _server/CodeMirror/defs.js | 8 ++++++ _server/MotaAction.g4 | 22 ++++++++++++++- _server/MotaActionParser.js | 5 ++++ _server/editor_blocklyconfig.js | 1 + libs/events.js | 50 ++++++++++++++++++++++++++++++++- libs/ui.js | 24 ++++++++++++++++ runtime.d.ts | 16 ++++++++++- 8 files changed, 136 insertions(+), 3 deletions(-) diff --git a/_docs/api.md b/_docs/api.md index ea875434..c5b644ba 100644 --- a/_docs/api.md +++ b/_docs/api.md @@ -1088,6 +1088,15 @@ resetGame: fn(hero?: ?, hard?: ?, floorId?: string, maps?: ?, values?: ?) restart: fn() 重新开始游戏;此函数将回到标题页面 +rotateImage: fn(code: number, center?: [number], angle?: number, moveMode?: string, time?: number, callback?: fn()) +旋转一张图片 +code: 图片编号 +center: 旋转中心像素坐标(以屏幕为基准);不填视为图片本身中心 +angle: 旋转角度;正数为顺时针,负数为逆时针 +moveMode: 旋转模式 +time: 旋转用时,单位为毫秒。不填视为1秒 +callback: 图片旋转完毕后的回调函数,可选 + save: fn(fromUserAction?: bool) 点击存档按钮时的打开操作 @@ -1952,6 +1961,10 @@ relocateCanvas: fn(name: string, x: number, y: number) resizeCanvas: fn(name: string, x: number, y: number) 重新设置一个自定义画布的大小 +rotateCanvas: fn(name: string, angle: number, centerX?: number, centerY?: number) +设置一个自定义画布的旋转角度 +centerX, centerY: 旋转中心(以屏幕像素为基准);不填视为图片正中心。 + saveCanvas: fn(name: string|CanvasRenderingContext2D) 保存某个canvas状态 diff --git a/_server/CodeMirror/defs.js b/_server/CodeMirror/defs.js index 308ea708..9cf5f9c3 100644 --- a/_server/CodeMirror/defs.js +++ b/_server/CodeMirror/defs.js @@ -3503,6 +3503,10 @@ var terndefs_f6783a0a_522d_417e_8407_94c67b692e50 = [ "!doc": "重新定位一个自定义画布", "!type": "fn(name: string, x: number, y: number)" }, + "rotateCanvas": { + "!doc": "设置一个自定义画布的旋转角度
centerX, centerY: 旋转中心(以屏幕像素为基准);不填视为图片正中心。", + "!type": "fn(name: string, angle: number, centerX?: number, centerY?: number)" + }, "closePanel": { "!doc": "结束一切事件和绘制,关闭UI窗口,返回游戏进程", "!type": "fn()" @@ -3828,6 +3832,10 @@ var terndefs_f6783a0a_522d_417e_8407_94c67b692e50 = [ "!doc": "移动一张图片并/或改变其透明度
例如:core.moveImage(1, null, 0.5); // 1秒内把1号图片变为50%透明
code: 图片编号
to: 新的左上角坐标,省略表示原地改变透明度
opacityVal: 新的透明度,省略表示不变
time: 移动用时,单位为毫秒。不填视为1秒
callback: 图片移动完毕后的回调函数,可选", "!type": "fn(code: number, to?: [number], opacityVal?: number, moveMode?: string, time?: number, callback?: fn())" }, + "rotateImage": { + "!doc": "旋转一张图片
code: 图片编号
center: 旋转中心像素坐标(以屏幕为基准);不填视为图片本身中心
angle: 旋转角度;正数为顺时针,负数为逆时针
moveMode: 旋转模式
time: 旋转用时,单位为毫秒。不填视为1秒
callback: 图片旋转完毕后的回调函数,可选", + "!type": "fn(code: number, center?: [number], angle?: number, moveMode?: string, time?: number, callback?: fn())" + }, "openSettings": { "!doc": "点击设置按钮时的操作", "!type": "fn(fromUserAction?: bool)" diff --git a/_server/MotaAction.g4 b/_server/MotaAction.g4 index 8d49f688..b99e8246 100644 --- a/_server/MotaAction.g4 +++ b/_server/MotaAction.g4 @@ -831,6 +831,7 @@ action | hideImage_s | showTextImage_s | moveImage_s + | rotateImage_s | showGif_s | setCurtain_0_s | setCurtain_1_s @@ -2205,6 +2206,7 @@ tooltip : showImage:显示图片 helpUrl : /_docs/#/instruction default : [1,"bg.jpg","null","0","0",1,0,false] allImages : ['EvalString_0'] +menu : [['选择图片','editor_blockly.selectMaterial(block, ["./project/images/", "EvalString_0"])']] previewBlock : true if (Reverse_List_0 && Reverse_List_0 != 'null') { Reverse_List_0 = ', "reverse": "' + Reverse_List_0 + '"'; @@ -2225,6 +2227,7 @@ tooltip : showImage_1:显示图片 helpUrl : /_docs/#/instruction default : [1,"bg.jpg","null","0","0","","",1,"0","0","","",0,false] allImages : ['EvalString_0'] +menu : [['选择图片','editor_blockly.selectMaterial(block, ["./project/images/", "EvalString_0"])']] previewBlock : true if (Reverse_List_0 && Reverse_List_0 != 'null') { Reverse_List_0 = ', "reverse": "' + Reverse_List_0 + '"'; @@ -2299,7 +2302,24 @@ if (PosString_0 && PosString_1) EvalString_0 = (EvalString_0!=='') ? (', "opacity": '+EvalString_0):''; MoveMode_List_0 = (MoveMode_List_0!=='') ? (', "moveMode": "'+MoveMode_List_0+'"'):''; var async = Bool_0?', "async": true':''; -var code = '{"type": "moveImage", "code": '+NInt_0+toloc+MoveMode_List_0+EvalString_0+',"time": '+Int_0+async+'},\n'; +var code = '{"type": "moveImage", "code": '+NInt_0+toloc+MoveMode_List_0+EvalString_0+', "time": '+Int_0+async+'},\n'; +return code; +*/; + +rotateImage_s + : '图片旋转' '图片编号' NInt '中心点像素' 'x' PosString? 'y' PosString? '移动方式' MoveMode_List BGNL? '旋转度数(正数顺时针,负数逆时针)' NInt '旋转时间' Int '不等待执行完毕' Bool Newline + + +/* rotateImage_s +tooltip : rotateImage:图片旋转 +helpUrl : /_docs/#/instruction +default : [1,'','','',90,500,false] +var loc = ''; +if (PosString_0 && PosString_1) + loc = ', "center": ['+PosString_0+','+PosString_1+']'; +MoveMode_List_0 = (MoveMode_List_0!=='') ? (', "moveMode": "'+MoveMode_List_0+'"'):''; +var async = Bool_0?', "async": true':''; +var code = '{"type": "rotateImage", "code": '+NInt_0+loc+', "angle": '+NInt_1+MoveMode_List_0+', "time": '+Int_0+async+'},\n'; return code; */; diff --git a/_server/MotaActionParser.js b/_server/MotaActionParser.js index 17803178..2118755d 100644 --- a/_server/MotaActionParser.js +++ b/_server/MotaActionParser.js @@ -580,6 +580,11 @@ ActionParser.prototype.parseAction = function() { this.next = MotaActionBlocks['moveImage_s'].xmlText([ data.code, data.to[0], data.to[1], data.opacity, data.moveMode||'', data.time||0, data.async||false, this.next]); break; + case "rotateImage": // 旋转图片 + data.center=data.center||['',''] + this.next = MotaActionBlocks['rotateImage_s'].xmlText([ + data.code, data.center[0], data.center[1], data.moveMode||'', data.angle||0, data.time||0, data.async||false, this.next]); + break; case "showGif": // 显示动图 data.loc=data.loc||['',''] this.next = MotaActionBlocks['showGif_s'].xmlText([ diff --git a/_server/editor_blocklyconfig.js b/_server/editor_blocklyconfig.js index 22f5a190..cba73bcf 100644 --- a/_server/editor_blocklyconfig.js +++ b/_server/editor_blocklyconfig.js @@ -105,6 +105,7 @@ editor_blocklyconfig=(function(){ MotaActionBlocks['hideImage_s'].xmlText(), MotaActionBlocks['showTextImage_s'].xmlText(), MotaActionBlocks['moveImage_s'].xmlText(), + MotaActionBlocks['rotateImage_s'].xmlText(), MotaActionBlocks['showGif_s'].xmlText(), MotaActionBlocks['tip_s'].xmlText(), MotaActionBlocks['win_s'].xmlText(), diff --git a/libs/events.js b/libs/events.js index 260f1cbe..9f1a9be6 100644 --- a/libs/events.js +++ b/libs/events.js @@ -1615,6 +1615,16 @@ events.prototype._precompile_moveImage = function (data) { return data; } +events.prototype._action_rotateImage = function (data, x, y, prefix) { + if (this.__action_checkReplaying()) return; + this.__action_doAsyncFunc(data.async, core.rotateImage, data.code, data.center, data.angle, data.moveMode, data.time); +} + +events.prototype._precompile_rotateImage = function (data) { + data.center = this.__precompile_array(data.center); + return data; +} + events.prototype._action_setCurtain = function (data, x, y, prefix) { if (data.async) { core.setCurtain(data.color, data.time); @@ -3091,7 +3101,7 @@ events.prototype._moveImage_moving = function (name, moveInfo, callback) { var moveFunc = core.applyEasing(moveInfo.moveMode); var animate = setInterval(function () { step++; - currOpacity = opacity + (toOpacity - opacity) * step / steps; + currOpacity = opacity + (toOpacity - opacity) * moveFunc(step / steps); currX = parseInt(fromX + (toX - fromX) * moveFunc(step / steps)); currY = parseInt(fromY + (toY - fromY) * moveFunc(step / steps)); core.setOpacity(name, currOpacity); @@ -3106,6 +3116,44 @@ events.prototype._moveImage_moving = function (name, moveInfo, callback) { core.animateFrame.asyncId[animate] = true; } +////// 旋转图片 ////// +events.prototype.rotateImage = function (code, center, angle, moveMode, time, callback) { + time = time || 1000; + center = center || []; + var name = "image" + (code + 100); + if (!core.dymCanvas[name]) { + if (callback) callback(); + return; + } + var canvas = core.dymCanvas[name].canvas; + var centerX = core.calValue(center[0]), centerY = core.calValue(center[1]); + + var fromAngle = parseFloat(canvas.getAttribute('_angle')) || 0; + var rotateInfo = { + fromAngle: fromAngle, angle: angle, centerX: centerX, centerY: centerY, + moveMode: moveMode, time: time / Math.max(core.status.replay.speed, 1) + } + this._rotateImage_rotating(name, rotateInfo, callback); +} + +events.prototype._rotateImage_rotating = function (name, rotateInfo, callback) { + var per_time = 10, step = 0, steps = parseInt(rotateInfo.time / per_time); + if (steps <= 0) steps = 1; + var moveFunc = core.applyEasing(rotateInfo.moveMode); + var animate = setInterval(function () { + step++; + var currAngle = rotateInfo.fromAngle + rotateInfo.angle * moveFunc(step / steps); + core.rotateCanvas(name, currAngle, rotateInfo.centerX, rotateInfo.centerY); + if (step == steps) { + delete core.animateFrame.asyncId[animate]; + clearInterval(animate); + if (callback) callback(); + } + }, per_time); + core.animateFrame.asyncId[animate] = true; + +} + ////// 绘制或取消一张gif图片 ////// events.prototype.showGif = function (name, x, y) { name = core.getMappedName(name); diff --git a/libs/ui.js b/libs/ui.js index 69898eca..804342a1 100644 --- a/libs/ui.js +++ b/libs/ui.js @@ -3149,8 +3149,11 @@ ui.prototype._drawStatistics_items = function (floorId, floor, id, obj) { if (obj.cls[id]=='items' && id!='superPotion') { var temp = core.clone(core.status.hero); core.setFlag("__statistics__", true); + var ratio = core.status.thisMap.ratio; + core.status.thisMap.ratio = core.clone(core.status.maps[floorId].ratio); try { eval(core.material.items[id].itemEffect); } catch (e) {} + core.status.thisMap.ratio = ratio; hp = core.status.hero.hp - temp.hp; atk = core.status.hero.atk - temp.atk; def = core.status.hero.def - temp.def; @@ -3299,6 +3302,27 @@ ui.prototype.relocateCanvas = function (name, x, y) { return ctx; } +////// canvas旋转 ////// +ui.prototype.rotateCanvas = function (name, angle, centerX, centerY) { + var ctx = core.getContextByName(name); + if (!ctx) return null; + var canvas = ctx.canvas; + angle = angle || 0; + if (centerX == null || centerY == null) { + canvas.style.transformOrigin = ''; + } else { + var left = parseFloat(canvas.getAttribute("_left")); + var top = parseFloat(canvas.getAttribute("_top")); + canvas.style.transformOrigin = (centerX - left) * core.domStyle.scale + 'px ' + (centerY - top) * core.domStyle.scale + 'px'; + } + if (angle == 0) { + canvas.style.transform = ''; + } else { + canvas.style.transform = 'rotate(' + angle +'deg)'; + } + canvas.setAttribute('_angle', angle); +} + ////// canvas重置 ////// ui.prototype.resizeCanvas = function (name, width, height, styleOnly) { var ctx = core.getContextByName(name); diff --git a/runtime.d.ts b/runtime.d.ts index 23405a5d..caf1e344 100644 --- a/runtime.d.ts +++ b/runtime.d.ts @@ -985,7 +985,18 @@ declare class events { * @param callback 图片移动完毕后的回调函数,可选 */ moveImage(code: number, to?: [number?, number?], opacityVal?: number, moveMode?: string, time?: number, callback?: () => void): void - + + /** + * 旋转一张图片 + * @param code 图片编号 + * @param center 旋转中心像素(以屏幕为基准);不填视为图片本身中心 + * @param angle 旋转角度;正数为顺时针,负数为逆时针 + * @param moveMode 旋转模式 + * @param time 移动用时,单位为毫秒。不填视为1秒 + * @param callback 图片移动完毕后的回调函数,可选 + */ + rotateImage(code: number, center?: [number?, number?], angle: number, moveMode?: string, time?: number, callback?: () => void): void + /** * 绘制一张动图或擦除所有动图 * @example core.showGif(); // 擦除所有动图 @@ -2110,6 +2121,9 @@ declare class ui { /** 重新设置一个自定义画布的大小 */ resizeCanvas(name: string, x: number, y: number): void + /** 设置一个自定义画布的旋转角度 */ + rotateCanvas(name: string, angle: number, centerX?: number, centerY?: number): void + /** 删除一个自定义画布 */ deleteCanvas(name: string): void