帧动画初步实现

This commit is contained in:
草莓 2024-12-31 16:09:50 +08:00
parent 30b1731ebc
commit d818ff36ff
5 changed files with 279 additions and 2 deletions

View File

@ -954,6 +954,7 @@ action
| removeMouse_s
| drawWarning_s
| addPop_s
| animationDrawable_s
| over_s
| overlist_s
| playStereo_s
@ -2475,6 +2476,91 @@ var code = '{"type": "scaleImage", "code": '+NInt_0+loc+', "scale": '+Number_0+M
return code;
*/;
animationDrawable_s
: '帧动画' '总显示帧数' IntString '底色' ColorString? Colour '底色透明度' Number BGNL?Newline
'图片序列同一帧后面覆盖先前的默认起始帧为0结束帧为最后一帧)'BGNL?Newline
'(剪裁区域不填写为全图,绘制区域不填写为全画面)'BGNL?Newline
animationDrawableimage+? Newline
'音频序列(到达对应帧进行播放)'BGNL?Newline
animationDrawablesound+? Newline
/* animationDrawable_s
tooltip : animationDrawable帧动画图片叠加
helpUrl : /_docs/#/instruction
default : [30,"",'rgb(0, 0, 0)',1]
allImages : ['EvalString_0']
colour : this.imageColor
if (Number_0 < 0||Number_0>1) throw new Error('透明度范围为0-1不填默认为1,0为透明1为不透明')
ColorString_0 = ColorString_0 ? (', "color": ['+ColorString_0+']') : '';
Number_0 = Number_0 ? (', "globalAlpha": '+Number_0+'') : '';
var imageList=animationDrawableimage_0?',"imageList": [\n'+animationDrawableimage_0.slice(0,-1)+'\n]':''
var soundList=animationDrawablesound_0?',"soundList": [\n'+animationDrawablesound_0.slice(0,-1)+'\n]':''
var code = '{"type": "animationDrawable", "allFarme": '+IntString_0+ColorString_0+Number_0+imageList+soundList+'},\n';
return code;
*/;
animationDrawableList
: animationDrawableimage
| animationDrawablesound
| animationDrawabletextEmpty;
animationDrawableimage
: '图片' EvalString? '起始帧' IntString? '起始透明度' Number BGNL? Newline
'剪裁坐标cx' IntString? 'cy' IntString? '宽' IntString? '高' IntString? '绘制坐标x'IntString? 'y' IntString? '宽' IntString? '高' IntString? BGNL? Newline
'结束帧' IntString? '结束透明度' Number '剪裁坐标cx' IntString? 'cy' IntString? '宽' IntString? '高' IntString? '绘制坐标x'IntString? 'y' IntString? '宽' IntString? '高' IntString? Newline
/* animationDrawableimage
tooltip : 帧动画图片列表
helpUrl : /_docs/#/instruction
default : ["","",1,"","","","","","","","","",1,"","","","","","","",""]
colour : this.subColor
allImages : ['EvalString_0']
if ((Number_0 < 0||Number_0>1)&&!Number_0||(Number_1 < 0||Number_1>1)&&!Number_1) throw new Error('透明度范围为0-1不填默认为1')
IntString_0 = IntString_0 ? (', "beforefarme": '+IntString_0+'') : '';
IntString_1 = IntString_1 ? (', "cx": '+IntString_1+'') : '';
IntString_2 = IntString_2 ? (', "cy": '+IntString_2+'') : '';
IntString_3 = IntString_3 ? (', "cw": '+IntString_3+'') : '';
IntString_4 = IntString_4 ? (', "ch": '+IntString_4+'') : '';
IntString_5 = IntString_5 ? (', "x": '+IntString_5+'') : '';
IntString_6 = IntString_6 ? (', "y": '+IntString_6+'') : '';
IntString_7 = IntString_7 ? (', "w": '+IntString_7+'') : '';
IntString_8 = IntString_8 ? (', "h": '+IntString_8+'') : '';
Number_0 = Number_0 ? (', "globalAlpha": '+Number_0+'') : '';
IntString_9 = IntString_9 ? (', "afterfarme": '+IntString_9+'') : '';
IntString_10 = IntString_10 ? (', "acx": '+IntString_10+'') : '';
IntString_11 = IntString_11 ? (', "acy": '+IntString_11+'') : '';
IntString_12 = IntString_12 ? (', "acw": '+IntString_12+'') : '';
IntString_13 = IntString_13 ? (', "ach": '+IntString_13+'') : '';
IntString_14 = IntString_14 ? (', "ax": '+IntString_14+'') : '';
IntString_15 = IntString_15 ? (', "ay": '+IntString_15+'') : '';
IntString_16 = IntString_16 ? (', "aw": '+IntString_16+'') : '';
IntString_17 = IntString_17 ? (', "ah": '+IntString_17+'') : '';
Number_1 = Number_1 ? (', "aglobalAlpha": '+Number_1+'') : '';
return '{ "image":"'+EvalString_0+'"'+IntString_0+IntString_1+IntString_2+IntString_3+IntString_4+IntString_5+IntString_6+IntString_7+IntString_8+Number_0+IntString_9+IntString_10+IntString_11+IntString_12+IntString_13+IntString_14+IntString_15+IntString_16+IntString_17+Number_1+'},'
*/;
animationDrawablesound
: '音效' EvalString? '起始帧' IntString '是否停止其他音效'Bool? Newline
/* animationDrawablesound
tooltip : 帧动画配音
helpUrl : /_docs/#/instruction
default : ["",0,false]
colour : this.subColor
allSounds : ['EvalString_0']
return '{ "sound":"'+EvalString_0+'","startfarme":'+IntString_0+',"stopbefore":'+Bool_0+'},'
*/;
animationDrawabletextEmpty
: Newline
/* animationDrawabletextEmpty
var code = [];
return code;
*/;
setCurtain_0_s
: '更改画面色调' ColorString Colour '动画时间' IntString? BGNL? Newline '渐变方式' MoveMode_List '持续到下一个本事件' Bool '不等待执行完毕' Bool Newline

View File

@ -703,6 +703,61 @@ MotaActionParser = function () {
this.next,
]);
break;
case "animationDrawable":
var buildanimationDrawableimage = function (obj) {
obj = MotaActionFunctions.processanimationDrawableimage(obj || []);
var res = null;
for (var ii = obj.length - 1, one; (one = obj[ii]); ii--) {
res = MotaActionBlocks["animationDrawableimage"].xmlText([
one[0],
one[1],
one[2],
one[3],
one[4],
one[5],
one[6],
one[7],
one[8],
one[9],
one[10],
one[11],
one[12],
one[13],
one[14],
one[15],
one[16],
one[17],
one[18],
one[19],
one[20],
res,
]);
}
return res;
};
var buildanimationDrawablesound = function (obj) {
obj = MotaActionFunctions.processanimationDrawablesound(obj || []);
var res = null;
for (var ii = obj.length - 1, one; (one = obj[ii]); ii--) {
res = MotaActionBlocks["animationDrawablesound"].xmlText([
one[0],
one[1],
one[2],
res,
]);
}
return res;
};
this.next = MotaActionBlocks["animationDrawable_s"].xmlText([
data.allFarme,
data.color,
"rgba(" + data.color + ")",
data.globalAlpha,
buildanimationDrawableimage(data.imageList),
buildanimationDrawablesound(data.soundList),
this.next,
]);
break;
case "tip":
this.next = MotaActionBlocks["tip_s"].xmlText([
data.text,
@ -2785,6 +2840,42 @@ MotaActionParser = function () {
});
return list;
};
MotaActionFunctions.processanimationDrawableimage = function (overList) {
var list = [];
overList.forEach(function (one) {
list.push([
one.image,
one.beforefarme,
one.globalAlpha,
one.cx,
one.cy,
one.cw,
one.ch,
one.x,
one.y,
one.w,
one.h,
one.afterfarme,
one.aglobalAlpha,
one.acx,
one.acy,
one.acw,
one.ach,
one.ax,
one.ay,
one.aw,
one.ah,
]);
});
return list;
};
MotaActionFunctions.processanimationDrawablesound = function (overList) {
var list = [];
overList.forEach(function (one) {
list.push([one.sound, one.startfarme, one.stopbefore]);
});
return list;
};
MotaActionFunctions.processMultiLoc = function (EvalString_0, EvalString_1) {
var floorstr = "";

View File

@ -1 +1 @@
{"viewportLoc":[0,0],"editorLastFloorId":"jiaotang"}
{"viewportLoc":[0,0],"editorLastFloorId":"street02"}

View File

@ -40,7 +40,24 @@ main.floors.street01=
],
"4,11": [
{
"type": "op"
"type": "animationDrawable",
"allFarme": 30,
"globalAlpha": 1,
"imageList": [
{
"image": "",
"h": 1,
"globalAlpha": 1,
"aglobalAlpha": 1
}
],
"soundList": [
{
"sound": "",
"startfarme": 0,
"stopbefore": false
}
]
}
]
},

View File

@ -141,6 +141,13 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 =
core.doAction()
}
})
core.registerEvent('animationDrawable', function (data) {
if (!main.replayChecking && !core.isReplaying()) {
core.animationDrawable(data.allFarme, data.color, data.globalAlpha, data.imageList, data.soundList)
} else {
core.doAction()
}
})
core.registerEvent("cgtext", function (data) {
if (!main.replayChecking && !core.isReplaying()) {
core.ui.cgText.image = data.bg;
@ -9418,6 +9425,7 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 =
MotaActionBlocks["callLoad_s"].xmlText(),
],
音像处理: [
MotaActionBlocks["animationDrawable_s"].xmlText(),
MotaActionBlocks["showImage_s"].xmlText(),
MotaActionBlocks["showImage_1_s"].xmlText(),
MotaActionBlocks["hideImage_s"].xmlText(),
@ -14189,5 +14197,80 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 =
})
};
},
"帧动画/图片叠拼": function () {
// 在此增加新插件
this.animationDrawable = function (
allFarme = 0,
color = "#000000",
globalAlpha = 1,
imageList = [{ image: '', beforefarme: 0, cx: 0, cy: 0, cw: 0, ch: 0, x: 0, y: 0, w: 0, h: 0, globalAlpha: 1, afterfarme: 0, acx: 0, acy: 0, acw: 0, ach: 0, ax: 0, ay: 0, aw: 0, ah: 0, aglobalAlpha: 1 }],
soundList = [{ sound: "", startfarme: 0, stopbefore: false }]
) {
if (!core.isPlaying()) {
return core.doAction();
}
const canvas = main.dom.over
const ctx = canvas.getContext('2d')
canvas.style.display = 'block'
let farme = 0
core.registerAnimationFrame('animationDrawable', function () {
if (core.domStyle.isVertical) {
canvas.width = 416 * 3;
canvas.height = 676 * 3;
ctx.save(); //保存设置
ctx.translate(416 * 3, 0); //重新定位右上角为基准
ctx.rotate(Math.PI / 2); //旋转90度
} else {
canvas.width = 676 * 3;
canvas.height = 416 * 3;
}
ctx.globalAlpha = globalAlpha
core.fillRect(ctx, 0, 0, canvas.width, canvas.height, color)
imageList.forEach(function (one) {
if (farme >= (one.beforefarme ?? 0) && farme <= (one.afterfarme ?? allFarme)) {
const img = core.material.images.images?.[one.image];
if (img) {
const gla = one.globalAlpha ?? 1;
const agla = one.aglobalAlpha ?? gla,
beforefarme = one.beforefarme ?? 0;
const afterfarme = one.afterfarme ?? allFarme;
ctx.globalAlpha = gla + (agla - gla) * (farme - beforefarme) / ((afterfarme - beforefarme) || 1)
const cx = one.cx ?? 0 + (one.acx ?? 0 - one.cx ?? 0) * (farme - one.beforefarme ?? 0) / ((one.afterfarme ?? 0 - one.beforefarme ?? 0) || 1),
cy = one.cy ?? 0 + (one.acy ?? 0 - one.cy ?? 0) * (farme - one.beforefarme ?? 0) / ((one.afterfarme ?? 0 - one.beforefarme ?? 0) || 1),
cw = one.cw ?? img.width + (one.acw ?? img.width - one.cw ?? img.width) * (farme - one.beforefarme ?? 0) / ((one.afterfarme ?? 0 - one.beforefarme ?? 0) || 1),
ch = one.ch ?? img.height + (one.acw ?? img.height - one.cw ?? img.height) * (farme - one.beforefarme ?? 0) / ((one.afterfarme ?? 0 - one.beforefarme ?? 0) || 1),
x = one.x ?? 0 + (one.ax ?? 0 - one.x ?? 0) * (farme - one.beforefarme ?? 0) / ((one.afterfarme ?? 0 - one.beforefarme ?? 0) || 1),
y = one.y ?? 0 + (one.ay ?? 0 - one.y ?? 0) * (farme - one.beforefarme ?? 0) / ((one.afterfarme ?? 0 - one.beforefarme ?? 0) || 1),
w = one.w ?? canvas.width + (one.aw ?? canvas.width - one.w ?? canvas.width) * (farme - one.beforefarme ?? 0) / ((one.afterfarme ?? 0 - one.beforefarme ?? 0) || 1),
h = one.h ?? canvas.height + (one.aw ?? canvas.height - one.w ?? canvas.height) * (farme - one.beforefarme ?? 0) / ((one.afterfarme ?? 0 - one.beforefarme ?? 0) || 1)
ctx.drawImage(img, cx, cy, cw, ch, x, y, w, h)
}
}
})
soundList.forEach(function (one) {
const lisen = one.sound && core.material.sounds[one.sound] && core.musicStatus.soundStatus;
if (frame == one.startfarme && lisen) {
if (one.stopbefore) core.stopSound()
core.playSound(sound);
}
})
farme++;
ctx.globalAlpha = 1
ctx.restore();
core.clearMap(ctx)
if (farme > allFarme) {
core.unregisterAnimationFrame('animationDrawable')
canvas.style.display = 'none'
core.doAction()
}
})
}
}
}