【问题标题】:SetTimeOut() in THREE JS三个 JS 中的 SetTimeOut()
【发布时间】:2015-02-18 10:02:44
【问题描述】:

我实现了一个硕士学位项目。 我必须创建一个三个js太空侵略者游戏。

该项目正在进行中,但我有一个问题。我的外星人(THREE.Mesh 对象)必须能够随机开火。 为此,我创建了一个应该绘制随机数的函数。此功能有效。 问题来自 animate() 函数。事实上,我不能将 SetTimeOut() 放在 animate() 函数中。

SetTimeOut() 在第一次调用 animate() 时起作用,但在没有计时器之后。代码不断执行,无需等待计时器。

也许问题来了,因为 requestAnimationFrame() 不断调用 animate;

我的代码:

Index.html =>

if (!init())animate();

function animate(){
   requestAnimationFrame( animate );
   level1.animate();

   render();
}

Level.js =>

Level.prototype.animate = function()
{

 //Timer doesn't work
 var that = this;

 //Just a test with a simple console.log test
 setTimeout(function() { console.log("test"); },10000);*/

this.sky.rotation.x -=0.005;

this.spaceship.fire();
for (var i=0; i<this.ducks.length;i++)
{
   this.ducks[i].move();
    if (this.ducks[i].is_ready_to_fire())
        this.ducks[i].fire_if_ready();
}

};

在这个例子中,程序将在第一次打印“test”之前等待 10 秒,在第一次调用之后,打印“test”而不等待。

你有什么想法吗?

非常感谢。

对不起,我的英语很差。

【问题讨论】:

  • 我想我明白这里发生了什么:您正在为每个 Level.prototype.animate() 调用创建一个新的计时器事件。
  • 那该如何解决呢?例如将结果放入 this.timer 中?
  • 我打印了计时器 ID,它是所有 animate() 调用中的不同 ID。所以每次我想它都是一个新的计时器。

标签: javascript three.js


【解决方案1】:

如果您需要一个计时器来达到您的目的。

如果我正确理解你的问题,你需要外星人在随机时间后开火。

如果您不关心确切的时间量,而只关心外星人在随机场合射击,我会在每个外星人上使用一个计数器来计算帧数,直到它射击为止。

所以你的代码看起来像这样:

var MAX_FRAMES_TO_WAIT = 600000;

Alien.prototype.init = function() {
 this.framesUntilFire = Math.round(Math.random() * MAX_FRAMES_TO_WAIT);
}

Alien.prototype.fireWhenReady = function() {
  if(--this.framesUntilFire === 0) {
    this.fire();
    this.framesUntilFire = Math.round(Math.random() * MAX_FRAMES_TO_WAIT);
  }
}

function animate() {
  requestAnimationFrame(animate);

  /* ... */

  for (var i=0; i<this.ducks.length;i++)
  {
    this.ducks[i].move();
    this.ducks[i].fireWhenReady();
  }

这应该可以解决问题。请注意,这意味着当帧速率较高时敌人开火速度更快,而当帧速率下降时敌人开火速度较慢。

您也可以通过计算帧速率并将其用作分隔线来平衡它。

希望对你有所帮助!

【讨论】:

    【解决方案2】:

    您可以通过在前一个计时器完成后简单地重置一个新计时器来避免每帧设置一个新计时器。一个简单的解决方案是递归:

    Level.prototype.fireDelayed = function() {
        setTimeout(function() {
            if (!this.currentLevel) {
                return;
            }
    
            this.fireDelayed();
            this.fire();
        }.bind(this), Math.random() * 1000);
    };
    

    如果关卡不再是currentLevel,它就会停止触发。

    这有意义吗?

    【讨论】:

    • 谢谢,但还是不行。这很奇怪。
    猜你喜欢
    • 1970-01-01
    • 2020-08-09
    • 1970-01-01
    • 2016-01-29
    • 2023-03-30
    • 1970-01-01
    • 2012-12-10
    • 2019-06-27
    • 1970-01-01
    相关资源
    最近更新 更多