2016-11-17 62 views
0

我製作了一個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() { 
 
\t requestAnimationFrame(draw); 
 
\t sprX = (player.count % 3) * 171; 
 
    \t sprY = Math.floor(player.count/9) * 351; 
 
    \t ctx.drawImage(player.img, sprX, sprY, 171, 351, 50, 50, 32, 32); 
 
    \t if(player.count == 2) 
 
    \t \t player.count = 0; 
 
    \t else 
 
    \t \t 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; 
 
\t } 
 
\t </style> 
 
</body>

+0

就像一個評論,而不是一個答案,但是你檢查過'phaser.js',它是基於畫布的,它已經有一些你試圖實現的方法。缺點是,上次我使用它有點沉重,但它可以爲您的動畫提供很多額外的功能。 https://phaser.io/ –

回答

3

如果我理解正確的話你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); 
} 

我做了一個工作小提琴here使用精靈表是4×4,並試圖重新使用了大量的你的代碼,以便你可以看到發生了什麼。