如何防止如此频繁地调用更新?

how to prevent update from being called so frequently?

我正在使用 ThreeJs 制作俄罗斯方块类型的演示。对于渲染,我使用 requestAnimationFrame。片段:

game.prototype.render = function(){
 var thisObj = this;

 requestAnimationFrame( function() {thisObj.render();} );

 var now = new Date().getTime();
 var dt = now - (time || now);
 time = now;

 this.update(dt);

 this.boardMgr.render(dt);
 this.renderer.render(this.scene, this.camera);
};

this.update(dt) - 调用 boardMgr.update(dt)

BoardMgr.prototype.update = function(dt) {
 if(this.activeBlock == null){
  this.activeBlock = this.getNextBlock();
  //console.log("letter: " + this.activeBlock.letter);
 }

 // update active block as per keyboard input
 // left/right/falldown
 // else
 {
  this.move(this.activeBlock, DIRECTION.DOWN);
 }
};

当我 运行 这样做时,方块下落的速度太快(如果我理解正确的话,更新被调用的次数太多了,因此方块的更新速度也很快)。

如何控制方块掉落的速度?或者我不应该经常调用 update 吗?正确的处理方式是什么?

代码可以在这里看到: https://github.com/brainydexter/PublicCode/tree/master/graphics

运动:我有一个 5x5 的网格板,我保持一个板的位置。所以,如果一个方块can向下移动,新的位置就是:(x,y+1)。在渲染时,我根据棋盘位置更新方块在世界坐标系中的位置。所以,我总是以 BLOCK_WIDTH:

的增量移动块

BoardMgr.prototype.render = function(dt) {
 for (var i = 0; i < this.blocks.length; i++) {
  if(this.blocks[i].visible)
  {
   this.blocks[i].position.x = (this.BLOCK_WIDTH/2) + ( this.blocks[i].boardPosition.x * this.BLOCK_WIDTH);
   this.blocks[i].position.y = (this.BLOCK_WIDTH/2) + ( this.blocks[i].boardPosition.y * this.BLOCK_WIDTH);
  }
 };
};

编辑

啊。所以我猜你想让方块吸附到一个网格上,并让经典的跳动在屏幕上向下移动。最简单的方法是保留自上次更新以来的时间,并且只有在超过某个限制(例如 500 毫秒)时才再次移动块。

// Wait times between each step
sidestep = 240;
downstep = 500;
fallstep = 80;

BoardMgr.prototype.update = function(dt) {
    this.vtimer += dt;
    this.htimer += dt;
    ...

    if ( left && this.htimer > sidestep ) {
        this.move(this.activeBlock, DIRECTION.LEFT);
        this.htimer = 0;
    }
    if ( right && this.htimer > sidestep ) {
        this.move(this.activeBlock, DIRECTION.RIGHT);
        this.htimer = 0;
    }

    if ( ( fall && this.vtimer > fallstep ) || ( this.vtimer > downstep ) ) {
        this.vtimer = 0;
        this.move(this.activeBlock, DIRECTION.DOWN);
}
};

如果你想让它对左右更敏感,并且不限制横向速度,你可以这样做:

BoardMgr.prototype.update = function(dt) {
    this.vtimer += dt;
    ...

    if ( left )
        this.move(this.activeBlock, DIRECTION.LEFT);
    if ( right )
        this.move(this.activeBlock, DIRECTION.RIGHT);

    if ( ( fall && this.vtimer > fallstep ) || ( this.vtimer > downstep ) ) {
        this.vtimer = 0;
        this.move(this.activeBlock, DIRECTION.DOWN);
}
};

通常,您需要在 boardManager.update 内缩放 activity 以实际考虑自上次 运行 以来的时间增量。看起来你已经把其中的大部分连接起来了。

值得查看有关游戏循环的一般主题http://gameprogrammingpatterns.com/game-loop.html

简而言之,您不一定需要 update 被调用的频率降低,您只需要考虑到这一点并根据更新频率改变您所做的事情。

编辑 您的渲染不一定要考虑时间增量,它应该只渲染 update 更新您的游戏状态后的状态,除非除了平滑之外您还想要平滑的外观运行 运动状态更新。

但在 update 作为重力移动方块的一部分,也许作为 move 的参数,您需要计算出移动的幅度。您已经提供了方向,DOWN,因此您需要计算出方块每毫秒掉落的速率,并将其乘以您的时间增量中的毫秒数,或者以您想要的方式影响运动你想要的效果。

用户输入,例如向左或向右移动一个方块,可能不会受到时间增量的影响,但在那个地方,移动的渲染可能被视为渲染的一部分,以平滑movement.Otherwise,您可以简单地在输入时立即更新块的位置。

这是您要查找的 aesthetics/behavior/difficulty 的问题。但是你拥有所有你需要的旋钮,可以按照你想要的方式进行拨号。