2015-04-24 2 views
2

Я пишу игру с использованием холста HTML5 и Javascript. Я использую setInterval для анимирования игры и проверки событий с регулярными интервалами. Я написал несколько уровней для игры, но я не могу убежать от setInterval, когда данный уровень заканчивается, чтобы начать следующий. Код точно обнаруживает, когда уровень выигран или потерян, и успешно очищает интервал и отображает кнопку, но кнопка не срабатывает.побег из setInterval в конце игрового уровня

Добавление кнопки было моей последней идеей. Я также попытался удалить холст с помощью jQuery и вставить новый. Я также попытался использовать clearRect на холсте, но он тоже не срабатывает.

Учитывая, что я не могу вернуть значение из setInterval, какие у меня параметры, если они есть? Есть ли другой способ сделать то же самое? Есть ли отдельная ошибка с моим кодом, который я забыл? Благодаря!

Game.prototype.win = function(int) { 
    clearInterval(int); 
    var content = "<p style='color:white;'>You win</p><br><button id='next-level'>Next Level</button></menu>" 
    $('#controls').append(content) 
}; 

Game.prototype.lose = function(int) { 
    clearInterval(int); 
    var content = "<p style='color:white;'>You Lose</p><br><button id='next-level'>Start Over?</button></menu>" 
    $('#controls').append(content) 
}; 

Game.prototype.run = funtion() {  
    $('#start').click(function() { 
     $('#controls').empty(); 
     var waveOne = new window.CrystalQuest.Wave(this.X_DIM, this.Y_DIM, this, Game.WAVE_ONE) 
     var game = this 

     var int = setInterval(function() { 
     if (waveOne.step() === "lost") { 
      game.lose(int); 
     } else if (waveOne.step() === "won") { 
      game.win(int); 
     } 
     waveOne.draw(this.ctx) 
     }, 20) 
     this.bindKeyHandlers(waveOne); 
    }.bind(this)); 

    $('#next-level').click(function() { 
     $('#controls').empty(); 
     ...more code... 
    }); 
}; 

ответ

1

Чтобы остановить setInterval() вы должны хранить возвращенное значение от первоначального вызова setInterval() в каком-то месте постоянного, а затем вызвать clearInterval() по этому значению.

Поскольку вы указали свой интервал var, как в var int, он был локальным только для этого метода и не был доступен нигде в коде.

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

Game.prototype.run = funtion() {  
    $('#start').click(function() { 
     $('#controls').empty(); 
     var waveOne = new window.CrystalQuest.Wave(this.X_DIM, this.Y_DIM, this, Game.WAVE_ONE) 
     var game = this; 

     this.stop(); 
     this.interval = setInterval(function() { 
     if (waveOne.step() === "lost") { 
      game.lose(int); 
     } else if (waveOne.step() === "won") { 
      game.win(int); 
     } 
     waveOne.draw(this.ctx) 
     }, 20) 
     this.bindKeyHandlers(waveOne); 
    }.bind(this)); 

    $('#next-level').click(function() { 
     $('#controls').empty(); 
     ...more code... 
    }); 
}; 

Затем вы можете сделать метод, который остановит интервал, как это:

Game.prototype.stop = function() { 
     if (this.interval) { 
      clearInterval(this.interval); 
      this.interval = null; 
     } 
} 

И изменить другие методы, как это :

Game.prototype.win = function(int) { 
    this.stop(); 
    var content = "<p style='color:white;'>You win</p><br><button id='next-level'>Next Level</button></menu>" 
    $('#controls').append(content) 
}; 

Game.prototype.lose = function(int) { 
    this.stop(); 
    var content = "<p style='color:white;'>You Lose</p><br><button id='next-level'>Start Over?</button></menu>" 
    $('#controls').append(content) 
}; 

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

У вас есть два варианта, как это исправить:

  1. После создания новых элементов DOM, вы можете снова установить обработчик событий на новых элементах DOM.
  2. Вы можете использовать «делегированное управление событиями». Это привязывает обработчики событий к родительскому объекту DOM, который сам не заменяется. Событие щелчка пузырится до родителя и обрабатывается там. Ребенок может быть заменен столько раз, сколько вы хотите, и обработчик событий все равно будет работать.

Смотрите эти ссылки для того, как использовать делегированные обработку событий с JQuery:

Does jQuery.on() work for elements that are added after the event handler is created?

jQuery .live() vs .on() method for adding a click event after loading dynamic html

JQuery Event Handlers - What's the "Best" method

+0

Спасибо! Я попробую. – hmt

+0

Hm. Этот метод, похоже, не делает код выполненным иначе, чем с локальной переменной.Интервал все еще останавливается, но я не могу ничего сделать за пределами интервала (нажмите кнопку и т. Д.). – hmt

+0

@hmt - Что значит «ничего не может сделать за пределами интервала»? Я не понимаю эту часть проблемы. Если вы уничтожаете элементы DOM, на которых есть обработчики событий с кодом типа '$ ('# controls'). Empty();', то эти обработчики событий также уничтожаются. Вам придется либо привязать обработчики событий к вновь созданным элементам DOM, либо использовать делегированную обработку событий для присоединения обработчиков событий к элементам DOM более высокого уровня, которые не будут заменены. – jfriend00

Смежные вопросы