在 spritesheet 上计时

Timing on a spritesheet

我制作了一个 spritesheet 并对其进行了编码,以便 运行 通过它。如何使绘制函数每秒 运行 。当我将 运行 设为更新函数中的函数时,它使 spritesheet 变得超快,因为这就是世界更新的速度,但我希望它以不同的速度更新。

(function () {
    var requestAnimationFrame = window.requestAnimationFrame || window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame || window.msRequestAnimationFrame;
    window.requestAnimationFrame = requestAnimationFrame;
})();

var canvas = document.getElementById("canvas"),
    ctx = canvas.getContext("2d"),
    width = 1000,
    height = 200,
    player = {
        x: width / 2,
        y: height - 15,
        width: 48,
        height: 64,
        speed: 3,
        velX: 0,
        velY: 0,
        jumping: false,
        grounded: false,
        count: 0,
        img: new Image()
    },
    keys = [],
    friction = 0.8,
    gravity = 0.3;
    player.img.src = "img/playersheet.png";
    player.img.onload = draw;
    var sprX;
    var sprY;
    setTimeout(draw, 3000);

var boxes = [];

// dimensions
boxes.push({
    x: 0,
    y: 0,
    width: 10,
    height: height
});
boxes.push({
    x: 0,
    y: height - 2,
    width: width,
    height: 50
});
boxes.push({
    x: width - 10,
    y: 0,
    width: 50,
    height: height
});

boxes.push({
    x: 120,
    y: 100,
    width: 80,
    height: 80
});
boxes.push({
    x: 250,
    y: 150,
    width: 80,
    height: 80
});
boxes.push({
    x: 400,
    y: 180,
    width: 80,
    height: 80
});
boxes.push({
    x: 270,
    y: 150,
    width: 40,
    height: 40
});

canvas.width = width;
canvas.height = height;

function draw() {
 requestAnimationFrame(draw);
 sprX = (player.count % 3) * 171;
     sprY = Math.floor(player.count / 9) * 351;
     ctx.drawImage(player.img, sprX, sprY, 171, 351, 50, 50, 32, 32);
     if(player.count == 2)
      player.count = 0;
     else
      player.count++;
}

function update() {
    // check keys
    if (keys[87] || keys[32]) {
        // up arrow or space
        if (!player.jumping && player.grounded) {
            player.jumping = true;
            player.grounded = false;
            player.velY = -player.speed * 2;
        }
    }
    if (keys[68]) {
        // right arrow
        if (player.velX < player.speed) {
            player.velX++;
            //player.img.src = "img/player_r.png";

        }
    }
    if (keys[65]) {
        // left arrow
        if (player.velX > -player.speed) {
            player.velX--;
            //player.img.src = "img/player.png";
        }
    }
     if (keys[83]) {
        // down arrow
            //player.img.src = "img/player_crouch.png";
    }

    player.velX *= friction;
    player.velY += gravity;

    ctx.clearRect(0, 0, width, height);
    ctx.fillStyle = "black";
    ctx.beginPath();
    
    player.grounded = false;
    for (var i = 0; i < boxes.length; i++) {
        ctx.rect(boxes[i].x, boxes[i].y, boxes[i].width, boxes[i].height);
        
        var dir = colCheck(player, boxes[i]);

        if (dir === "l" || dir === "r") {
            player.velX = 0;
            player.jumping = false;

        } else if (dir === "b") {
            player.grounded = true;
            player.jumping = false;
        } else if (dir === "t") {
            player.velY *= -1;
        }

    }
    
    if(player.grounded){
         player.velY = 0;
    }
    
    player.x += player.velX;
    player.y += player.velY;

    ctx.fill();

    requestAnimationFrame(update);
}



function colCheck(shapeA, shapeB) {
    // get the vectors to check against
    var vX = (shapeA.x + (shapeA.width / 2)) - (shapeB.x + (shapeB.width / 2)),
        vY = (shapeA.y + (shapeA.height / 2)) - (shapeB.y + (shapeB.height / 2)),
        // add the half widths and half heights of the objects
        hWidths = (shapeA.width / 2) + (shapeB.width / 2),
        hHeights = (shapeA.height / 2) + (shapeB.height / 2),
        colDir = null;

    // if the x and y vector are less than the half width or half height, they we must be inside the object, causing a collision
    if (Math.abs(vX) < hWidths && Math.abs(vY) < hHeights) {
        // figures out on which side we are colliding (top, bottom, left, or right)
        var oX = hWidths - Math.abs(vX),
            oY = hHeights - Math.abs(vY);
        if (oX >= oY) {
            if (vY > 0) {
                colDir = "t";
                shapeA.y += oY;
            } else {
                colDir = "b";
                shapeA.y -= oY;
            }
        } else {
            if (vX > 0) {
                colDir = "l";
                shapeA.x += oX;
            } else {
                colDir = "r";
                shapeA.x -= oX;
            }
        }
    }
    return colDir;
}

document.body.addEventListener("keydown", function (e) {
    keys[e.keyCode] = true;
});

document.body.addEventListener("keyup", function (e) {
    keys[e.keyCode] = false;
});


window.addEventListener("load", function () {
    update();
});
<head>
    <title>Platformer Game</title>
</head>
<body>
  <h3>Arrow keys to move, and space to jump</h3>
    <canvas id="canvas"></canvas>
    <style>
    canvas {
    border:1px solid #d3d3d3;
    background-color: #f1f1f1;
 }
 </style>
</body>

如果我理解正确的话,您的 draw 函数只是循环遍历您的 3x3 精灵并不断绘制。您可以尝试的一种方法是设置您自己的帧速率 (fps) 并检查与开始时间的偏移量:

var fps = 24;
var msPerFrame = 1000 / fps;
var startTime;

function draw() {
  if (!startTime) startTime = Date.now();
  var elapsedTime = Date.now() - startTime;
  var spriteIndex = Math.floor(elapsedTime / msPerFrame) % 9;

  requestAnimationFrame(draw);
  sprX = (spriteIndex % 3) * 171;
  sprY = Math.floor(spriteIndex / 9) * 351;
  ctx.drawImage(player.img, sprX, sprY, 171, 351, 50, 50, 32, 32);
}

我使用 4x4 的 sprite sheet 制作了一个有效的 fiddle here,并尝试重用您的大量代码,以便您了解发生了什么。