问题描述
|
我在JS中有一个由16个台球组成的数组,想以其方向和速度平稳地移动每个球。
为此,我设置了一个计时器,每42毫秒调用一次“ 0”(24 fps)。
问题在于“ 0”需要53毫秒作为萤火虫状态。
现在,
UpdateThis
遍历每个球并调用calls3ѭ。
我认为问题就在这里.UpdateBall看起来像这样:
function UpdateBall(ball)
{
if(ball.direction.x != 0 && ball.direction.y != 0) {
//ball moving!
for(var i = 0; i < balls.length; i++) {
//CheckCollision(ball,balls[i]); //even without this it takes 53 ms!
}
var ps = VAdd(ball.position,VMul(ball.direction,ball.speed)); //Multiply Direction with speed and add to position!
if(ps.x < Bx || ps.y < By || ps.x > Bw || ps.y > Bh) { //Bounce off the wall!
ball.direction = VMul(ball.direction,-1); //Invert direction
ball.speed *= 1;
ps = VAdd(ball.position,ball.speed)); //Calc new position!
}
ball.position = ps;
ball.MoveTo(); //See explanation at the bottom.
ball.speed *= GRK; //Gravity
if(ball.speed < 0.05) {
ball.speed = 0;
}
}
}
似乎大部分时间都花在ѭ5中,看起来像这样:
function()
{
this.image.style.left = this.position.x + \"px\";
this.image.style.top = this.position.y + \"px\";
}
-更新-
function UpdateThis() {
for(var i = 0; i < balls.length; i++) {
var cur = balls[i];
UpdateBall(cur);
balls[i] = cur;
}
}
和加载看起来像
nx = setInterval(function() { UpdateThis(); },42);
有人对如何加快速度有任何想法吗?
-更新2-
您可以在此处下载带有HTML文件的文件夹(密码为password)
解决方法
如何从图形中分离位置更新呢?所以有这样的东西(未经测试的代码):
function DrawBall(ball)
{
ball.MoveTo(); //Take this line out of UpdateBall
}
--
function UpdateThis() {
for(var i = 0; i < balls.length; i++) {
var cur = balls[i];
UpdateBall(cur);
balls[i] = cur;
}
}
--
function DrawThis() {
for(var i = 0; i < balls.length; i++) {
DrawBall(balls[i]);
}
setTimeout(function() { DrawThis(); },42);
}
--
nx = setInterval(function() { UpdateThis(); },42);
setTimeout(function() { DrawThis(); },42);
如果确实是位置移动缓慢,则这种逻辑更新仍会在42ms处发生,并且帧速率不会比42ms快,但是它可以跳过帧。 (我实际上没有尝试过,因此这只是理论上的,您可能需要调整一些内容)
, 为什么移动可能(并且很可能是)缓慢?
移动功能可能很慢,因为它比简单的变量赋值还有更多的事情要做。它实际上必须将某些元素渲染到其他地方。如果您在IE9上运行它,则可以进行测试。我预计它会运行得更快,因为它使用了硬件视频加速。
至于其他常规程序,我希望其他人可以对其进行剖析。 :)
给你的问题
你能描述一下球如何运动吗?偶尔地?您如何称呼每个球13英镑?你把那些电话排队吗?
提供VMul
和VAdd
功能
你玩过造型吗?球的直接父对象的相对位置可能会加快渲染速度。然后在其上设置overflow:hidden
。我不知道。取决于您的操作方式。因此,JSFiddle将非常有帮助。
一条建议
而不是使用setInterval
调用您的函数,您应该只是将它们排队并让它们尽快执行。并且仅出于此目的,请向中央setInterval
提供一些观察者,以确保它们的运行速度不会太快。
但是我想它仍然会以100%的利用率使用您的处理器,这还是不好的。
非常重要的注意事项:启用Firebug时不要运行您的应用程序,因为众所周知,Firebug运行时Javascript的执行速度要慢得多。
, 这很难,如果MoveTo()实际上是您的瓶颈,因为那里没有很多事情要做。我唯一能想到的就是
1)缓存图像的样式属性和位置,以加快查找速度。每当您在对象链中看到一个点时,都需要逐步遍历作用域链。理想情况下,您可以在构造MoveTo()的父级时缓存此属性。
2)是否需要\'px \'字符串?它可能会导致无效的CSS规范,但仍然可以使用。我很难相信2串concat确实会改变所有的东西。
这里的主要问题可能是这样的事实,即您每次更改DOM时,浏览器都会重新处理整个页面。您唯一的其他选择可能是进行重构,以便实际上不删除样式,而是删除先前的内容,并用描述新状态的文档片段替换它。这将导致整个步骤仅进行2次回流(1次用于移除,1次用于添加),而不是每个球2次。
编辑:关于上面的#1,当我说缓存时,我的意思并不只是在函数调用中本地。但也许作为父对象的闭包。例如:
var Ball = function(img){
var style = img.style;
var posX;
var posY;
function MoveTo(){
style.left = posX + \"px\";
style.right = posY + \"px\";
}
};