【问题标题】:how to prevent update from being called so frequently?如何防止更新被如此频繁地调用?
【发布时间】:2016-01-22 04:16:08
【问题描述】:

我正在使用 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);
	}
};

当我运行它时,块下降得太快(如果我理解正确,更新被调用太多次,因此块被更新得很快)。

如何控制下落方块的速度?或者我不应该经常调用更新?正确的处理方法是什么?

代码可以在这里看到: 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);
		}
	};
};

【问题讨论】:

    标签: javascript 3d three.js 2d


    【解决方案1】:

    编辑

    啊。所以我猜你想让块对齐到一个网格,并让经典的生涩步骤从屏幕上下来。最简单的方法是保持自上次更新以来的时间,并且仅在超过某个限制(例如 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);
    }
    };
    

    【讨论】:

    • 更新了帖子,提供了更多关于运动的细节。如果我想以BLOCK_WIDTH 的块移动块,我如何考虑dt
    • 但如果我在move() 本地执行此操作,我认为它会与游戏的其他部分不同步。例如,我正在轮询输入,并且在 500 毫秒内,用户按了 LEFT 两次,我只会更新块一次。这将是一个问题
    • 是的,轮询总是有可能错过一个事件。由于这是俄罗斯方块,您可以为左右移动提供相同的对齐网格行为,并只给它一个更小的时间步长,因此它横向移动比向下移动更快。
    • 对于大多数其他游戏,我同意@mczepiel,但这是俄罗斯方块,当游戏应该是生涩的时候,使用 dt 进行时间平滑似乎有点过分了。
    • 是的,都是合理的。 OOC,您如何轮询用户输入以使您“错过”用户输入? (当然这有点题外话了)
    【解决方案2】:

    通常,您需要扩展 boardManager.update 内的活动,以实际考虑自上次运行以来的时间增量。看起来您已经完成了大部分工作。

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

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

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

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

    例如,向左或向右移动块等用户输入可能不会受到时间增量的影响,但这可能是将运动的渲染视为渲染的一部分,以平滑运动。否则,您可以简单地在输入时立即更新块的位置。

    这是您正在寻找的美学/行为/难度的问题。但是你有所有你需要的旋钮来按你想要的方式拨号。

    【讨论】:

    • 感谢您的详细回复。我了解渲染使用dt 制作动画。在boardMgr.update 中,我希望块以经典的生涩风格移动并对齐网格。因此,移动是从一个网格块到另一个网格块,而不是网格块之间的流动。移动幅度始终是固定的 (BLOCK_WIDTH)
    • 是的,如果您想要步进动画,您只需按照@andrew-williamson 的回答中的详细说明限制更新。这就是我关于您如何计算时间增量以及它如何影响您对它的计算的观点,这取决于您出于各种原因。希望你有一些工作。干杯!
    猜你喜欢
    • 2012-04-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-17
    • 1970-01-01
    • 2012-08-08
    • 1970-01-01
    • 2013-11-03
    相关资源
    最近更新 更多