编辑器动画预览

This commit is contained in:
ckcz123 2020-06-03 14:33:44 +08:00
parent 3ecc62b11f
commit afbfb305ef
6 changed files with 127 additions and 21 deletions

View File

@ -1758,7 +1758,7 @@ tooltip : animate显示动画,位置填hero或者1,2形式的位置,或者不
helpUrl : https://h5mota.com/games/template/_docs/#/event?id=animate%EF%BC%9A%E6%98%BE%E7%A4%BA%E5%8A%A8%E7%94%BB
default : ["zone","hero",false,false]
allAnimates : ['IdString_0']
selectPoint : ["EvalString_0", "EvalString_0"]
material : ["./project/animates/", "IdString_0"]
colour : this.soundColor
if (EvalString_0) {
if(MotaActionFunctions.pattern.id2.test(EvalString_0)) {

View File

@ -341,6 +341,9 @@ editor_blockly = function () {
if (b && MotaActionBlocks[b.type].material) {
var material = JSON.parse(MotaActionBlocks[b.type].material);
editor.uievent.selectMaterial([b.getFieldValue(material[1])], '请选择素材', material[0], function (one) {
if (b.type == 'animate_s') {
return /^[-A-Za-z0-9_.]+\.animate$/.test(one) ? one.substring(0, one.length - 8) : null;
}
return /^[-A-Za-z0-9_.]+$/.test(one) ? one : null;
}, function (value) {
if (value instanceof Array && value.length > 0) {

View File

@ -350,6 +350,10 @@ editor_ui_wrapper = function (editor) {
uievent.close = function () {
uievent.isOpen = false;
uievent.elements.div.style.display = 'none';
if (uievent.values.interval) {
clearTimeout(uievent.values.interval);
clearInterval(uievent.values.interval);
}
uievent.values = {};
}
uievent.elements.no.onclick = uievent.close;
@ -715,6 +719,14 @@ editor_ui_wrapper = function (editor) {
<audio preload="none" src="${directory+one}" ontimeupdate="editor.uievent._previewMaterialAudio_onTimeUpdate(this)"></audio>
<progress value="0" max="1" style="display:none; width:100%" onclick="editor.uievent._previewMaterialAudio_seek(this, event)"></progress>`;
}
// 预览动画
if (directory.indexOf('animates') >= 0) {
html += "<button onclick='editor.uievent._previewMaterialAnimate(this)' style='margin-left: 10px'>预览</button>";
html += `<span style="display:none; margin-left: 10px" key="${directory+one+'.animate'}"><br/>音效:<input type="text" />
<button onclick="editor.uievent._previewMaterialAnimate_previewSound(this)" style='marin-left: 10px'>试听</button>
<button onclick="editor.uievent._previewMaterialAnimate_saveSound(this)">保存</button><br/>
</span>`;
}
html += '<br/>';
});
html += "</p>";
@ -780,6 +792,95 @@ editor_ui_wrapper = function (editor) {
if (audio.paused) audio.play();
}
var _previewMaterialAnimate = function (span, content) {
var input = span.children[1];
input.value = content.se || "";
// 创建dom
if (!uievent.values.dom) {
var dom = document.createElement('span');
dom.style.position = "relative";
dom.style.marginLeft = "-10px";
var canvas = document.createElement('canvas');
canvas.width = canvas.height = core.__PIXELS__;
canvas.style.position = 'absolute';
core.drawThumbnail(editor.currentFloorId, null, {}, canvas.getContext('2d'));
dom.appendChild(canvas);
var canvas2 = document.createElement('canvas');
canvas2.style.position = 'absolute';
canvas2.width = canvas2.height = core.__PIXELS__;
uievent.values.ctx = canvas2.getContext('2d');
dom.appendChild(canvas2);
var canvas3 = document.createElement('canvas');
canvas3.width = canvas3.height = core.__PIXELS__;
dom.appendChild(canvas3);
uievent.values.dom = dom;
}
span.appendChild(uievent.values.dom);
clearInterval(uievent.values.interval);
var frame = 0;
uievent.values.interval = setInterval(function () {
if (span.style.display == 'none') {
clearInterval(uievent.values.interval);
uievent.values.interval = null;
span.removeChild(uievent.values.dom);
return;
}
core.clearMap(uievent.values.ctx);
core.maps._drawAnimateFrame(uievent.values.ctx, content, core.__PIXELS__ / 2, core.__PIXELS__ / 2, frame++);
}, 50);
}
uievent._previewMaterialAnimate = function (button) {
var span = button.nextElementSibling;
var filename = span.getAttribute("key");
uievent.values.animates = uievent.values.animates || {};
if (span.style.display == 'none') {
button.innerText = '收起';
span.style.display = 'inline';
if (uievent.values.animates[filename]) {
_previewMaterialAnimate(span, uievent.values.animates[filename]);
} else {
fs.readFile(filename, 'utf-8', function (e, d) {
if (e) {
alert('无法打开动画文件!'+e); return;
}
uievent.values.animates[filename] = core.loader._loadAnimate(d);
if (uievent.values.animates[filename]) {
uievent.values.animates[filename + ':raw'] = JSON.parse(d);
_previewMaterialAnimate(span, uievent.values.animates[filename]);
}
})
}
} else {
button.innerText = '预览';
span.style.display = 'none';
}
}
uievent._previewMaterialAnimate_previewSound = function (button) {
var input = button.previousElementSibling;
if (!input.value) return;
if (!uievent.values.audio)
uievent.values.audio = new Audio();
uievent.values.audio.src = './project/sounds/' + input.value;
uievent.values.audio.play();
}
uievent._previewMaterialAnimate_saveSound = function (button) {
var input = button.previousElementSibling.previousElementSibling;
var filename = button.parentElement.getAttribute("key");
if (!filename || !uievent.values.animates[filename]) return;
uievent.values.animates[filename+':raw'].se = input.value || "";
fs.writeFile(filename, JSON.stringify(uievent.values.animates[filename+':raw']), 'utf-8', function (e, d) {
if (e) alert('无法修改音效文件!'+e);
else {
alert('动画音效修改成功!别忘了在全塔属性中注册本音效哦!');
}
})
}
// ------ 多选框 ------ //
uievent.popCheckboxSet = function (value, comments, title, callback) {
if (value == null) value = [];

View File

@ -176,9 +176,9 @@ control.prototype._animationFrame_animate = function (timestamp) {
});
core.status.animateObjs.forEach(function (obj) {
if (obj.hero) {
core.maps._drawAnimateFrame(obj.animate, core.status.heroCenter.px, core.status.heroCenter.py, obj.index++);
core.maps._drawAnimateFrame('animate', obj.animate, core.status.heroCenter.px, core.status.heroCenter.py, obj.index++);
} else {
core.maps._drawAnimateFrame(obj.animate, obj.centerX, obj.centerY, obj.index++);
core.maps._drawAnimateFrame('animate', obj.animate, obj.centerX, obj.centerY, obj.index++);
}
});
core.animateFrame.animateTime = timestamp;

View File

@ -301,8 +301,8 @@ loader.prototype._loadAnimates_sync = function () {
this._setStartLoadTipText("正在加载动画文件...");
core.animates.forEach(function (t) {
core.http('GET', 'project/animates/' + t + ".animate?v=" + main.version, null, function (content) {
core.loader._loadAnimate(t, content);
core.http('GET', 'project/animates/' + t + ".animate?v=" + main.version, null, function (content) {
core.material.animates[t] = core.loader._loadAnimate(content);
}, function (e) {
main.log(e);
core.material.animates[t] = null;
@ -316,14 +316,14 @@ loader.prototype._loadAnimates_async = function (onprogress, onfinished) {
if (name.endsWith(".animate")) {
var t = name.substring(0, name.length - 8);
if (core.animates.indexOf(t) >= 0)
core.loader._loadAnimate(t, animates[name]);
core.material.animates[t] = core.loader._loadAnimate(animates[name]);
}
}
onfinished();
}, null, true, onprogress);
}
loader.prototype._loadAnimate = function (name, content) {
loader.prototype._loadAnimate = function (content) {
try {
content = JSON.parse(content);
var data = {};
@ -362,12 +362,12 @@ loader.prototype._loadAnimate = function (name, content) {
})
})
data.frames.push(info);
})
core.material.animates[name] = data;
});
return data;
}
catch (e) {
main.log(e);
core.material.animates[name] = null;
return null;
}
}

View File

@ -2227,32 +2227,34 @@ maps.prototype.drawHeroAnimate = function (name, callback) {
}
////// 绘制动画的某一帧 //////
maps.prototype._drawAnimateFrame = function (animate, centerX, centerY, index) {
var frame = animate.frames[index];
maps.prototype._drawAnimateFrame = function (name, animate, centerX, centerY, index) {
var ctx = core.getContextByName(name);
if (!ctx) return;
var frame = animate.frames[index % animate.frame];
var ratio = animate.ratio;
frame.forEach(function (t) {
var image = animate.images[t.index];
if (!image) return;
var realWidth = image.width * ratio * t.zoom / 100;
var realHeight = image.height * ratio * t.zoom / 100;
core.setAlpha('animate', t.opacity / 255);
core.setAlpha(ctx, t.opacity / 255);
var cx = centerX + t.x, cy = centerY + t.y;
if (!t.mirror && !t.angle) {
core.drawImage('animate', image, cx - realWidth / 2 - core.bigmap.offsetX, cy - realHeight / 2 - core.bigmap.offsetY, realWidth, realHeight);
core.drawImage(ctx, image, cx - realWidth / 2 - core.bigmap.offsetX, cy - realHeight / 2 - core.bigmap.offsetY, realWidth, realHeight);
}
else {
core.saveCanvas('animate');
core.canvas.animate.translate(cx, cy);
core.saveCanvas(ctx);
ctx.translate(cx, cy);
if (t.angle)
core.canvas.animate.rotate(-t.angle * Math.PI / 180);
ctx.rotate(-t.angle * Math.PI / 180);
if (t.mirror)
core.canvas.animate.scale(-1, 1);
core.drawImage('animate', image, -realWidth / 2 - core.bigmap.offsetX, -realHeight / 2 - core.bigmap.offsetY, realWidth, realHeight);
core.loadCanvas('animate');
ctx.scale(-1, 1);
core.drawImage(ctx, image, -realWidth / 2 - core.bigmap.offsetX, -realHeight / 2 - core.bigmap.offsetY, realWidth, realHeight);
core.loadCanvas(ctx);
}
core.setAlpha('animate', 1);
core.setAlpha(ctx, 1);
})
}