diff --git a/_docs/api.md b/_docs/api.md
index b003bf23..af535cda 100644
--- a/_docs/api.md
+++ b/_docs/api.md
@@ -1126,6 +1126,9 @@ callback: 图片旋转完毕后的回调函数,可选
save: fn(fromUserAction?: bool)
点击存档按钮时的打开操作
+scaleImage: fn(code: number, center?: [number], scale?: number, moveMode?: string, time?: number, callback?: fn())
+放缩一张图片
+
setEnemy: fn(id: string, name: string, value: ?, operator?: string, prefix?: string)
设置一项敌人属性并计入存档
例如:core.setEnemy('greenSlime', 'def', 0); // 把绿头怪的防御设为0
diff --git a/_docs/instruction.md b/_docs/instruction.md
index f0464956..28a28d80 100644
--- a/_docs/instruction.md
+++ b/_docs/instruction.md
@@ -159,6 +159,9 @@ V2.8.1起,下拉框中没有的项都可以通过在json区输入并点击“
* time同样不能填0,如果想瞬间得到旋转后的结果,请填1
* 比起移动,旋转本身不支持同时透明度渐变,您可以先写一个不指定终点的移动指令且“不等待执行完毕”来实现单纯的淡入淡出,然后再写一个耗时相同或略长的旋转指令,这样两个指令就会一起执行了。
* 当不指定旋转中心时,本指令可以和移动指令同时使用,从而得到“图片的中心做直线运动、同时图片还在绕着中心自转”的效果。
+5. **图片放缩:**V2.8.1新增,同样支持加速度,放缩中心坐标不填则取图片中心。
+ * 此指令对应`core.scaleImage(code, center, scale, moveMode, time, callback)`函数
+ * time可以为0,代表立刻进行放缩
5. **显示或清除动图:**需要填写动图的文件名(带.gif后缀),“起点像素位置”含义如前且必须填写,可以双击指令块来预览第一帧的效果。
* 动图不支持淡入淡出和伸缩移动,如果不填任何参数则清除所有动图(只支持全部清除)。
* 该指令对应`core.showGif(name, x, y)`函数。
diff --git a/_server/CodeMirror/defs.js b/_server/CodeMirror/defs.js
index 848e3c26..236dc58b 100644
--- a/_server/CodeMirror/defs.js
+++ b/_server/CodeMirror/defs.js
@@ -3860,6 +3860,10 @@ var terndefs_f6783a0a_522d_417e_8407_94c67b692e50 = [
"!doc": "旋转一张图片
code: 图片编号
center: 旋转中心像素坐标(以屏幕为基准);不填视为图片本身中心
angle: 旋转角度;正数为顺时针,负数为逆时针
moveMode: 旋转模式
time: 旋转用时,单位为毫秒。不填视为1秒
callback: 图片旋转完毕后的回调函数,可选",
"!type": "fn(code: number, center?: [number], angle?: number, moveMode?: string, time?: number, callback?: fn())"
},
+ "scaleImage": {
+ "!doc": "放缩一张图片",
+ "!type": "fn(code: number, center?: [number], scale?: number, moveMode?: string, time?: number, callback?: fn())"
+ },
"moveTextBox": {
"!doc": "移动对话框",
"!type": "fn(code: number, loc: [number], relative?: bool, moveMode?: string, time?: number, callback?: fn())"
diff --git a/_server/MotaAction.g4 b/_server/MotaAction.g4
index 30afdf0b..c9b4bbd6 100644
--- a/_server/MotaAction.g4
+++ b/_server/MotaAction.g4
@@ -838,6 +838,7 @@ action
| showTextImage_s
| moveImage_s
| rotateImage_s
+ | scaleImage_s
| showGif_s
| setCurtain_0_s
| setCurtain_1_s
@@ -2217,6 +2218,24 @@ var code = '{"type": "rotateImage", "code": '+NInt_0+loc+', "angle": '+NInt_1+Mo
return code;
*/;
+scaleImage_s
+ : '图片放缩' '图片编号' NInt '中心点像素' 'x' PosString? 'y' PosString? '移动方式' MoveMode_List BGNL? '放缩比例' Number '动画时间' Int '不等待执行完毕' Bool Newline
+
+
+/* scaleImage_s
+tooltip : scaleImage:图片放缩
+helpUrl : /_docs/#/instruction
+default : [1,'','','',0.8,0,false]
+if (Number_0 <= 0) throw new Error('放缩比例需要大于0');
+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": "scaleImage", "code": '+NInt_0+loc+', "scale": '+Number_0+MoveMode_List_0+', "time": '+Int_0+async+'},\n';
+return code;
+*/;
+
setCurtain_0_s
: '更改画面色调' ColorString Colour '动画时间' IntString? BGNL? Newline '渐变方式' MoveMode_List '持续到下一个本事件' Bool '不等待执行完毕' Bool Newline
diff --git a/_server/MotaActionParser.js b/_server/MotaActionParser.js
index 8b63b287..c990026c 100644
--- a/_server/MotaActionParser.js
+++ b/_server/MotaActionParser.js
@@ -596,6 +596,11 @@ ActionParser.prototype.parseAction = function() {
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 "scaleImage": // 放缩图片
+ data.center=data.center||['','']
+ this.next = MotaActionBlocks['scaleImage_s'].xmlText([
+ data.code, data.center[0], data.center[1], data.moveMode||'', data.scale, 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 718bbbef..9b51fceb 100644
--- a/_server/editor_blocklyconfig.js
+++ b/_server/editor_blocklyconfig.js
@@ -102,23 +102,24 @@ editor_blocklyconfig=(function(){
MotaActionBlocks['autoText_s'].xmlText(),
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(),
- MotaActionBlocks['rotateImage_s'].xmlText(),
- MotaActionBlocks['showGif_s'].xmlText(),
MotaActionBlocks['tip_s'].xmlText(),
- MotaActionBlocks['win_s'].xmlText(),
- MotaActionBlocks['lose_s'].xmlText(),
- MotaActionBlocks['restart_s'].xmlText(),
MotaActionBlocks['confirm_s'].xmlText(),
MotaActionBlocks['choices_s'].xmlText([
'选择剑或者盾','流浪者','man',0,0,'',MotaActionBlocks['choicesContext'].xmlText([
'剑','','',null,'','',MotaActionFunctions.actionParser.parseList([{"type": "openDoor", "loc": [3,3]}]),
])
]),
+ MotaActionBlocks['win_s'].xmlText(),
+ MotaActionBlocks['lose_s'].xmlText(),
+ MotaActionBlocks['restart_s'].xmlText(),
+ MotaActionBlocks['showImage_s'].xmlText(),
+ MotaActionBlocks['showImage_1_s'].xmlText(),
+ MotaActionBlocks['hideImage_s'].xmlText(),
+ MotaActionBlocks['showTextImage_s'].xmlText(),
+ MotaActionBlocks['moveImage_s'].xmlText(),
+ MotaActionBlocks['rotateImage_s'].xmlText(),
+ MotaActionBlocks['scaleImage_s'].xmlText(),
+ MotaActionBlocks['showGif_s'].xmlText(),
],
'数据相关':[
MotaActionBlocks['setValue_s'].xmlText([
diff --git a/libs/events.js b/libs/events.js
index 2f978f6b..0d59d42a 100644
--- a/libs/events.js
+++ b/libs/events.js
@@ -1660,6 +1660,16 @@ events.prototype._precompile_rotateImage = function (data) {
return data;
}
+events.prototype._action_scaleImage = function (data, x, y, prefix) {
+ if (this.__action_checkReplaying()) return;
+ this.__action_doAsyncFunc(data.async, core.scaleImage, data.code, data.center, data.scale, data.moveMode, data.time);
+}
+
+events.prototype._precompile_scaleImage = 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, data.moveMode);
@@ -3330,6 +3340,65 @@ events.prototype._rotateImage_rotating = function (name, rotateInfo, callback) {
}
+////// 放缩一张图片 //////
+events.prototype.scaleImage = function (code, center, scale, moveMode, time, callback) {
+ center = center || [];
+ var name = "image" + (code + 100);
+ if (!core.dymCanvas[name]) {
+ if (callback) callback();
+ return;
+ }
+ var ctx = core.dymCanvas[name];
+ var currScale = 1.0;
+ if (ctx.canvas.hasAttribute('_scale')) {
+ currScale = parseFloat(ctx.canvas.getAttribute('_scale'));
+ }
+ var ratio = ctx.canvas.hasAttribute('isHD') ? core.domStyle.ratio : 1;
+ var width = ctx.canvas.width / ratio, height = ctx.canvas.height / ratio;
+ var currLeft = parseFloat(ctx.canvas.getAttribute("_left"));
+ var currTop = parseFloat(ctx.canvas.getAttribute("_top"));
+ var centerX = core.calValue(center[0]), centerY = core.calValue(center[1]);
+ if (centerX == null || centerY == null) {
+ centerX = currLeft + width * currScale / 2;
+ centerY = currTop + height * currScale / 2;
+ }
+ var scaleInfo = {
+ x: (currLeft - centerX) / currScale, y: (currTop - centerY) / currScale, centerX: centerX, centerY: centerY,
+ width: width, height: height, currScale: currScale, scale: scale, moveMode: moveMode, time: time
+ }
+ this._scaleImage_scale(ctx, scaleInfo, callback);
+}
+
+events.prototype._scaleInfo_scale = function (ctx, scaleInfo, scale) {
+ core.resizeCanvas(ctx, scaleInfo.width * scale, scaleInfo.height * scale, true);
+ core.relocateCanvas(ctx, scaleInfo.centerX + scaleInfo.x * scale, scaleInfo.centerY + scaleInfo.y * scale);
+ ctx.canvas.setAttribute('_scale', scale);
+}
+
+events.prototype._scaleImage_scale = function (ctx, scaleInfo, callback) {
+ if (!scaleInfo.time) {
+ this._scaleInfo_scale(ctx, scaleInfo, scaleInfo.scale);
+ if (callback) callback();
+ return;
+ }
+
+ var per_time = 10, step = 0, steps = parseInt(scaleInfo.time / per_time);
+ if (steps <= 0) steps = 1;
+ var moveFunc = core.applyEasing(scaleInfo.moveMode);
+
+ var animate = setInterval(function () {
+ step++;
+ var scale = scaleInfo.currScale + (scaleInfo.scale - scaleInfo.currScale) * moveFunc(step / steps);
+ core.events._scaleInfo_scale(ctx, scaleInfo, scale);
+ 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/runtime.d.ts b/runtime.d.ts
index 3da4eea2..372574eb 100644
--- a/runtime.d.ts
+++ b/runtime.d.ts
@@ -1009,6 +1009,9 @@ declare class events {
*/
rotateImage(code: number, center?: [number?, number?], angle: number, moveMode?: string, time?: number, callback?: () => void): void
+ /** 放缩一张图片 */
+ scaleImage(code: number, center?: [Number?, number?], scale: number, moveMode?: string, time?: number, callback?: () => void): void
+
/**
* 绘制一张动图或擦除所有动图
* @example core.showGif(); // 擦除所有动图