Javascript 画布上的Glitchy动画
在玩家移动和电梯移动的主底层,我使用以下帧速率:Javascript 画布上的Glitchy动画,javascript,html,canvas,Javascript,Html,Canvas,在玩家移动和电梯移动的主底层,我使用以下帧速率: var requestAnimFrame = window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.msRequestAnima
var requestAnimFrame = window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.msRequestAnimationFrame ||
window.oRequestAnimationFrame ||
function(callback) {
window.setTimeout(callback, 1000/60);
};
当玩家死亡时,我将此帧速率用于爆炸动画
var requestAnimFrameExplode = function(callback) {
window.setTimeout(callback, 1000/15);
};
现在,所有这些都很好,但是在我的一个关卡上,我有电梯上下移动等,使用主要的底层帧速率,但是当播放器死亡时,爆炸帧速率播放器(使事情变慢,使你可以看到动画1秒),所以这使电梯减速1秒,使它看起来像是故障
在我的游戏循环中,我有:
if(Death ==true)
{
requestAnimFrameExplode(Loop); //calls loop again but slower so animation explode shows
DrawSpawnAnimation(); //this draws the explode animation
}
else
{
requestAnimFrame(Loop); //when Death is false it calls at normal fast framerate for player movement etc
}
我的问题是如何停止这个故障?即使正在播放动画,我如何使循环中的电梯和其他东西同时运行?听起来您试图通过控制帧率来控制动画的速度。我建议重构,使帧速率独立于动画速度 换句话说,不要通过降低帧速率来减缓爆炸速度。您应该通过减少火焰/碎片在每个帧之间的移动来降低速度
也就是说,当你死的时候,放慢整个楼层(电梯和所有电梯)的速度听起来是一种很好的效果;) 这是一个使用requestAnimationFrame和setTimeout的动画演示。 使用RAF来驱动这两个动画可能会更有效,但此处提供这两个动画都是为了进行说明 RAF动画循环运行电梯,如下所示:
var fps1 = 60;
function runElevator() {
setTimeout(function() {
// request another loop
raf1=requestAnimFrame(runElevator);
// update the elevator properties (current Y and directon)
elevatorY+=elevatorSpeed*elevatorDirection;
if(elevatorY+elevatorHeight>canvasB.height || elevatorY<30){
elevatorDirection= -elevatorDirection;
}
// call the function that draws the elevator frame
drawElevator(elevatorX,elevatorY,elevatorWidth,elevatorHeight)
}, 1000 / fps1);
}
var fps2 = 30;
function runExplosion() {
// update the explosion properties (the current radius of the explosion)
explosionRadius+=1.5;
// check if the explosion is done
if(explosionRadius<explosionMaxRadius){
// the explosion is not done, draw another explosion frame
drawExplosion(explosionX,explosionY,explosionRadius);
// and request another loop
setTimeout(runExplosion, 1000/fps2);
}else{
// the explosion is done, clear the top canvas and “we’re outta here!”
ctxT.clearRect(0,0,canvasT.width,canvasT.width);
}
}
var fps1=60;
函数runlifter(){
setTimeout(函数(){
//请求另一个循环
raf1=请求帧(运行电梯);
//更新电梯属性(当前Y和directon)
升降+=升降器速度*升降器方向;
如果(elevatorY+elevatorHeight>canvasB.height | | | elevatorYIt)听起来不错,但这太油嘴滑舌了,也许让它先向后再向前走可能会很酷。尽管我在编程方面没有足够的经验自己解决这个问题:(你能解释一下为什么一个动画不覆盖另一个吗?比如,如果你超时1秒,会不会让另一个动画变得不稳定?当然,很乐意解释:)setTimeout是异步的,这意味着当您请求setTimeout时,超时内的代码将在指定的超时后运行,但超时后的代码将立即运行(无超时)因此,设置超时后的任何代码都没有延迟,电梯动画可以不间断地运行…整洁,是吗?好的,但是超时,比如说半秒,在运行时,这不意味着整个程序暂停是因为超时了吗?因此电梯会出现故障动作?没有暂停…所有其他的r代码(超时代码除外)仍在运行,即使计时器正在倒计时以触发setTimeout代码……真的……这就是它的工作原理!
<!doctype html>
<html>
<head>
<link rel="stylesheet" type="text/css" media="all" href="css/reset.css" /> <!-- reset css -->
<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>
<style>
body{ background-color: ivory; padding:20px;}
#container{position:relative;}
canvas{border:1px solid red; position:absolute; top:0; left:0}
</style>
<script>
$(function(){
var canvasT=document.getElementById("canvasTop");
var ctxT=canvasT.getContext("2d");
var canvasB=document.getElementById("canvasBottom");
var ctxB=canvasB.getContext("2d");
window.requestAnimFrame = (function(callback) {
return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame ||
function(callback) {
window.setTimeout(callback, 1000 / 60);
};
})();
var elevatorX=30;
var elevatorY=30;
var elevatorWidth=40;
var elevatorHeight=60;
var elevatorSpeed=2;
var elevatorDirection=1;
ctxT.strokeStyle="orange";
var explosionX=100;
var explosionY=200;
var explosionStartingRadius=10;
var explosionEndingRadius=25;
var explosionRadius=explosionStartingRadius;
var raf1;
var raf2;
runElevator();
function explode(x,y,maxRadius){
explosionX=x;
explosionY=y;
explosionMaxRadius=maxRadius
explosionRadius=10;
ctxT.clearRect(0,0,canvasB.width,canvasB.height);
ctxT.beginPath();
ctxT.arc(x,y,explosionRadius,0,Math.PI*2,false)
ctxT.closePath();
ctxT.fillStyle="yellow"
ctxT.fill();
ctxT.stroke();
ctxT.fillStyle="orange";
runExplosion();
}
var fps1 = 60;
function runElevator() {
setTimeout(function() {
raf1=requestAnimFrame(runElevator);
elevatorY+=elevatorSpeed*elevatorDirection;
if(elevatorY+elevatorHeight>canvasB.height || elevatorY<30){
elevatorDirection= -elevatorDirection;
}
drawElevator(elevatorX,elevatorY,elevatorWidth,elevatorHeight)
}, 1000 / fps1);
}
var fps2 = 30;
function runExplosion() {
explosionRadius+=1.5;
if(explosionRadius<explosionMaxRadius){
drawExplosion(explosionX,explosionY,explosionRadius);
setTimeout(runExplosion, 1000/fps2);
}else{
ctxT.clearRect(0,0,canvasT.width,canvasT.width);
}
}
function drawElevator(x,y,width,height){
ctxB.clearRect(0,0,canvasB.width,canvasB.height);
ctxB.beginPath();
ctxB.moveTo(x+width/2,0);
ctxB.lineTo(x+width/2,y);
ctxB.rect(x,y,width,height);
ctxB.stroke();
ctxB.fill();
}
function drawExplosion(x,y,radius){
ctxT.beginPath();
ctxT.arc(x,y,radius,0,Math.PI*2,false);
ctxT.closePath()
ctxT.stroke();
}
$("#explode").click(function(){ explode(150,150,75); });
}); // end $(function(){});
</script>
</head>
<body>
<button id="explode">Explode</button>
<div id="container">
<canvas id="canvasTop" width=300 height=300></canvas>
<canvas id="canvasBottom" width=300 height=300></canvas>
</div>
</body>
</html>