2015-02-16 3 views
0

Я реализую проект для магистерской степени. Я должен создать игру для захватчиков трех js.SetTimeOut() в THREE JS

Проект идет полным ходом, но у меня есть проблема. Мои инопланетяне (объект THREE.Mesh) должны иметь возможность стрелять случайным образом. Чтобы выполнить это, я создал функцию, которая должна нарисовать случайное число. Эта функция работает. Проблема заключается в функции animate(). На самом деле я не могу поставить функцию SetTimeOut() animate().

SetTimeOut() работает при первом вызове анимации(), но после того, как нет таймера. Кодирование выполняется непрерывно, не дожидаясь таймера.

Возможно, проблема возникает из-за того, что анимация постоянно вызывается requestAnimationFrame();

Мой код:

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(); 
} 

};

В этом примере программа будет ждать 10 секунд в первый раз перед печатью «тест» и после первого вызова распечатать «тест» без ожидания.

У вас есть идеи?

спасибо.

Извините за мой плохой английский.

+0

Я думаю, что я вижу, что здесь происходит: вы создаете новое событие таймера на каждом вызове 'Level.prototype.animate()'. – Phylogenesis

+0

Как решить это? Поместите результат в этот. Timer например? – merinid

+0

И я напечатал идентификатор таймера, и это другой идентификатор во всем вызове animate(). Поэтому его новый таймер каждый раз, когда я думаю. – merinid

ответ

0

Вы можете избежать установки нового таймера каждый кадр простым сбросом нового таймера после завершения предыдущего. Простое решение для этого является рекурсивным:

Level.prototype.fireDelayed = function() { 
    setTimeout(function() { 
     if (!this.currentLevel) { 
      return; 
     } 

     this.fireDelayed(); 
     this.fire(); 
    }.bind(this), Math.random() * 1000); 
}; 

Он просто не перестает стрелять, если уровень больше не currentLevel.

Это имеет смысл?

+0

Спасибо, но все еще не работает. Это очень странно. – merinid

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(); 
    } 

Это должно сделать трюк. Имейте в виду, что это будет означать, что враги быстрее стреляют, когда частота кадров выше и медленнее, когда частота кадров должна упасть.

Вы можете встретить это с подсчетом частоты кадров и использовать его в качестве разделителя, чтобы выровнять его.

Я надеюсь, что это помогло вам!