requestAnimationFrame(... paramList ...)有什么好处?

时间:2014-07-01 21:36:49

标签: javascript

问题:

为什么使用此函数调用requestAnimationFrame?例如,如果我正在构建一个游戏,那么requestAnimationFrame只会重新绘制画布的好处。

代码:

function main() {
    var now = Date.now();
    var delta = now - then;

    update(delta / 1000);
    render();

    then = now;

    // Request to do this again ASAP
    requestAnimationFrame(main);
};

以下所有代码:(您需要3个.jpg文件)

<html>
<head>
  <title>test</title>
</head>
<body>
<script>
    // Create the canvas
    var canvas = document.createElement("canvas");
    var ctx    = canvas.getContext("2d");
    canvas.width  = 512;
    canvas.height = 480;
    document.body.appendChild(canvas);

    // Background image
    var bgReady = false;
    var bgImage = new Image();
    bgImage.onload = function () {
        bgReady = true;
    };
    bgImage.src = "background.png";

    // Hero image
    var heroReady = false;
    var heroImage = new Image();
    heroImage.onload = function () {
        heroReady = true;
    };
    heroImage.src = "hero.png";

    // Monster image
    var monsterReady = false;
    var monsterImage = new Image();
    monsterImage.onload = function () {
        monsterReady = true;
    };
    monsterImage.src = "monster.png";

    // Game objects
    var hero = {
        speed: 256 // movement in pixels per second
    };

    var monster = {};
    var monstersCaught = 0;

    // Handle keyboard controls
    var keysDown = {};

    addEventListener("keydown", function (e) {
        keysDown[e.keyCode] = true;
    }, false);

    addEventListener("keyup", function (e) {
        delete keysDown[e.keyCode];
    }, false);

    // Reset the game when the player catches a monster
    var reset = function () {
        hero.x = canvas.width / 2;
        hero.y = canvas.height / 2;

        // Throw the monster somewhere on the screen randomly
        monster.x = 32 + (Math.random() * (canvas.width - 64));
        monster.y = 32 + (Math.random() * (canvas.height - 64));
    };

    // Update game objects
    var update = function (modifier) {
        if (38 in keysDown) { // Player holding up
            hero.y -= hero.speed * modifier;
        }
        if (40 in keysDown) { // Player holding down
            hero.y += hero.speed * modifier;
        }
        if (37 in keysDown) { // Player holding left
            hero.x -= hero.speed * modifier;
        }
        if (39 in keysDown) { // Player holding right
            hero.x += hero.speed * modifier;
        }

        // Are they touching?
        if (hero.x <= (monster.x + 32) && 
            monster.x <= (hero.x + 32) && 
            hero.y <= (monster.y + 32) && 
            monster.y <= (hero.y + 32)
        ) {
            ++monstersCaught;
            reset();
        }
    };

    // Draw everything
    var render = function () {
        if (bgReady) {
            ctx.drawImage(bgImage, 0, 0);
        }

        if (heroReady) {
            ctx.drawImage(heroImage, hero.x, hero.y);
        }

        if (monsterReady) {
            ctx.drawImage(monsterImage, monster.x, monster.y);
        }

        // Score
        ctx.fillStyle = "rgb(250, 250, 250)";
        ctx.font      = "24px Helvetica";
        ctx.textAlign    = "left";
        ctx.textBaseline = "top";
        ctx.fillText("Goblins caught: " + monstersCaught, 32, 32);
    };

    // The main game loop
    /*var main = function () {
        var now = Date.now();
        var delta = now - then;

        update(delta / 1000);
        render();

        then = now;

        // Request to do this again ASAP
        requestAnimationFrame(main);
    };*/

    // The main game loop -- This is the second way of doing this
    function main() {
        var now = Date.now();
        var delta = now - then;

        update(delta / 1000);
        render();

        then = now;

        // Request to do this again ASAP
        requestAnimationFrame(main);
    };

    // Cross-browser support for requestAnimationFrame
    var w = window;
    requestAnimationFrame = w.requestAnimationFrame || w.webkitRequestAnimationFrame || w.msRequestAnimationFrame || w.mozRequestAnimationFrame;

    // Let's play this game!
    var then = Date.now();
    reset();
    main();
</script>
</body>
</html>

1 个答案:

答案 0 :(得分:1)

因为反复调用main会导致浏览器挂起,直到它放弃堆栈溢出错误。

requestAnimationFrame只是说&#34;当浏览器准备好渲染另一帧时执行此操作&#34;。