0

在玩家移动和电梯移动的主要底层上,我使用以下帧速率:

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
}

我的问题是如何阻止这种故障?即使正在播放动画,如何使电梯和其他东西在循环中同时运行?

4

2 回答 2

1

这是一个同时使用 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);
}

setTimeout 动画循环运行你的爆炸,看起来像这样:

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);
    }

}

这是代码和小提琴:http: //jsfiddle.net/m1erickson/YzqUF/

<!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>
于 2013-07-05T21:21:44.893 回答
0

听起来您正试图通过控制帧速率来控制动画的速度。我建议重构,使帧率独立于动画速度。

换句话说,不要通过降低帧速率来减慢爆炸速度。您应该通过减少每帧之间的火焰/碎片移动来减慢速度。

就是说,当你死时放慢整个关卡(电梯和所有)听起来像是一种巧妙的效果;)

于 2013-07-05T20:10:58.893 回答