2014-08-31 84 views
1

我一直在为这一段时间打破了我的头。我使用画布在javascript中编写了一个空间游戏。我使用分辨率为16x16的800x600分辨率,并且在任何时候在视口中都有大约200-300个图块。html canvas平滑运动

Ofcourse当然,这会太慢,不能重绘每一帧因此,我把它渲染到一个屏幕外的画布上,每个边上都有1个大的图块。移动时,我只需移动屏幕外的画布,然后只重新绘制新的图块。这在60fps下完美运行,即使有1000多个瓷砖。只有轻微的故障,四处走动并不是100%顺畅。

我无法解释发生了什么,它是某种跳动/屏幕撕裂。 我虽然是我的代码中的一些错误,但是当我用1个瓷砖创建了一个简单的测试时,我有完全相同的错误。

这里是我的测试:http://jsfiddle.net/da7g9khj/1/

var prevTime = new Date().getTime(); 
function loop(time) { 
    requestAnimationFrame(loop); 

    var curTime = new Date().getTime(); 
    var dt = (curTime - prevTime)/1000; 
    prevTime = curTime; 


    var speed = 6; 
    if(keys.up) camera.y -= speed * dt; 
    if(keys.down) camera.y += speed * dt; 
    if(keys.left) camera.x -= speed * dt; 
    if(keys.right) camera.x += speed * dt; 

    var leftMost = (camera.x - scn.width/2); 
    var topMost = (camera.y - scn.height/2); 
    var screenCoordinates = { 
     x: (300 - leftMost) * 16, 
     y: (250 - topMost) * 16 
    }; 

    rsc.ctx.clearRect(0, 0, scn.width * 16, scn.height * 16); 

    rsc.ctx.fillStyle = "black"; 
    rsc.ctx.beginPath(); 

    rsc.ctx.rect(Math.round(screenCoordinates.x), Math.round(screenCoordinates.y), 16, 16); 

    rsc.ctx.fill(); 
    rsc.ctx.closePath();   
} 

var camera = {x: 300, y: 250} 
var rsc = {}; 
var scn = { 
    width: 50, 
    height: 37.5 
}; 
var keys = { 
    up: false, 
    down: false, 
    right: false, 
    left: false 
}; 

rsc.canvas = document.getElementById("canvas"); 
rsc.canvas.width = 16 * scn.width; 
rsc.canvas.height = 16 * scn.height; 
rsc.ctx = rsc.canvas.getContext("2d"); 

window.onkeydown = function(e) { 
    switch(e.keyCode) { 
     case 40: 
      keys.down = true; 
      return false; 
     case 38: 
      keys.up = true; 
      return false; 
     case 37: 
      keys.left = true; 
      return false; 
     case 39: 
      keys.right = true; 
      return false; 
    } 
}; 

window.onkeyup = function(e) { 
    switch(e.keyCode) { 
     case 40: 
      keys.down = false; 
      return false; 
     case 38: 
      keys.up = false; 
      return false; 
     case 37: 
      keys.left = false; 
      return false; 
     case 39: 
      keys.right = false; 
      return false; 
    } 
}; 

requestAnimationFrame(loop); 

尝试使用箭头键移动相机。按住一个键,你有时会看到跳动的动作。

我真的很希望有人能帮助我,因为我一直在试图找出为什么这会发生一段时间。

回答

0

在我的桌面上,我得到矩形的正常半平滑运动,但没有跳跃或撕裂。我猜这个问题发生在比一个好的桌面资源少的设备上。

你的代码看起来效率很高,但我确实在你的动画循环中看到了相当多的东西 - 但那不会引起你的跳跃和流泪。

这里有一个不太这些混沌重构(不会解决你的问题):http://jsfiddle.net/m1erickson/0k2Ljth5/

什么是可能导致你的跳跃是var dt = (curTime - prevTime)/1000;。如果requestAnimationFrame由于某种原因无法执行循环(通常会导致一些其他系统任务需要时间),那么您的dt将比预期的更大,并且您的矩形将在预期位置“跳”到较大的dt所指定的位置。

另一方面,眼泪是由以前的图画引起的,而这些图画在新的循环框架开始时是不完整的。您要求的绘图数量并不总是适合循环。撕裂的治疗方法是减少帆布在循环过程中必须完成的工作。

+0

嗯,它的古怪的寿,我有我的上网本和我相当强大的桌面相同的生涩运动。我的一个朋友在mac pro上也遇到了同样的问题,这个问题更加强大:p。 我正在使用Linux寿,虐待它尝试在Windows上。 – 2014-09-01 07:44:35