我已经看了好几个小时,但我无法弄清楚如何满足我的需求。
我试图制作它,以便在触发后在特定的X和Y位置播放动画。 (例如,在坦克被摧毁后播放爆炸动画)
我有这样的功能:
var explosion = new Image();
explosion.src = "https://i.imgur.com/gWjqlKe.png";
function animate(img, x, y, width, height, steps){
steps = Math.floor(steps);
context.clearRect(x, y, width, height);
context.drawImage(img, width * step, 0, width, height);
step += .3;
requestAnimationFrame(animate(img, x, y, width, height, steps));
}
然后当我需要打电话时,我做了:
animate(explosions, tank.x, tank.y, 100, 100, 10);
但是当我摧毁坦克时没有任何反应。
我的代码基于本教程:https://www.youtube.com/watch?v=yna816VY8rg
任何帮助将不胜感激!非常感谢!
编辑:
我现在正在尝试使用setInterval,但它仍然没有用...
var explosion = new Image();
explosion.src = "https://i.imgur.com/gWjqlKe.png";
// Animation Functions
function animate(img, x, y, width, height, endframe){
var frame = 0;
frame = setInterval(animation(frame, img, x, y, width, height), 1000);
if (frame >= endframe){
clearInterval(frame)
}
}
function animation(frame, img, x, y, width, height){
ctx = gameArea.context;
ctx.drawImage(img, x * frame, y, width, height);
frame ++;
return frame;
编辑2:
我从我的Reddit中意识到我在requestAnimationFrame和setInterval中犯了一个错误,所以我再次编辑但它仍然不起作用:
function animate(img, x, y, width, height, endframe){
var frame = 0;
frame = setInterval(function() {
animation(frame, img, x, y, width, height);
}, 1000);
if (frame >= endframe){
clearInterval(frame)
}
}
function animation(frame, img, x, y, width, height){
ctx = gameArea.context;
ctx.drawImage(img, x * frame, y, width, height);
frame ++;
return frame;
}
function animate(img, x, y, width, height, steps){
steps = Math.floor(steps);
context.clearRect(x, y, width, height);
context.drawImage(img, width * step, 0, width, height);
step += .3;
requestAnimationFrame(animate(img, x, y, width, height, steps));
}
答案 0 :(得分:1)
使用事件计时器通过requestAnimationFrame启动动画循环将导致各种问题。 requestAnimationFrame
将以与最后一帧相同的顺序触发下一帧。如果超时在任何其他帧之前的帧中进入,它将是第一个绘制到画布的函数,那么其他帧将绘制在顶部。
评论中指出的nnnnnnn仅使用一个游戏循环,为了让渲染顺序正确,可以节省很多不必要的复杂性。
requestAnimationFrame
时间参数 requestAnimationFrame
提供了一个计时器作为第一个参数。此计时器是当前帧时间,而不是实际时间。这使您可以从V sync(显示刷新)计算时间
在设定的时间内为某些FX设置动画,记录开始时间,设置持续时间并为frame参数中给出的时间设置动画。
该示例显示了主循环中使用的简单爆炸计时器。您需要提供当前帧时间时开始计时器。当它处于活动状态时,你给它当前时间,它会更新自己的相对时间,完成后active
标志设置为false
。您可以通过current
时间从0到长度
这只是一个动画,你可以使用一堆这样的时间对象,为每个定时动画添加到堆栈中。
const explode = {
start : null,
length : 1000,
current : 0,
active : false,
begin(time,length = this.length){
this.start = time;
this.length = length;
this.active = true;
this.current = 0;
},
getCurrent(time){
this.current = time - this.start;
this.active = this.current <= this.length;
return this.current;
}
}
var tankDead = false;
function mainLoop(time){ // time is supplied by requestAnimationFrame
if(tankDead ) {
tankDead = false;
explode.begin(time,2000); // two seconds
}
if(explode.active){
explode.getCurrent(time);
if(explode.active){
// explode.current is the time
// draw the animation at time explode.current
} else {
// explosion is complete
}
}
requestAnimationFrame(mainLoop);
}
requestAnimationFrame(mainLoop);
虽然我更喜欢固定帧率方法,但只是倒计时定时器
var tankDead = false;
var explodeTick = 0;
function mainLoop(time){ // time is supplied by requestAnimationFrame
if(tankDead ) {
tankDead = false;
explodeTick = 60 * 2; // two seconds
}
if(explodeTick > 0){
explodeTick -= 1;
// draw the animation at time explosion
}
requestAnimationFrame(mainLoop);
}
requestAnimationFrame(mainLoop);
管理起来要简单得多,没有人会注意到你放弃了一两帧,而且只需要花费不到一秒的时间。