12.05.2013, 03:56
|
|
Интересующийся
|
|
Регистрация: 12.05.2013
Сообщений: 14
|
|
Таймер для игры
Делаю игру судоку на javascript. Нужно исправить/переделать таймер, чтобы он смог:
а) Ставиться/сниматься с паузы без глюков. В нынешнем состоянии если несколько раз часто пощелкать на кнопку паузы запускается парралельно несколько setTimeout()-ов параллельно и таймер скачет не соответствуя реальности.
б) Останавливаться окончательно и безповоротно из отдельной функции. Возможно сама дойду до этого пункта при полном решении всех проблем из остальных пунктов.
в) Имея не законченную игру и запущенный таймер при запуске новой игры чтобы не было глюка из пункта (а).
На данный момент таймер реализован через рекурсивную функцию с использованием setTimeout(). О наличии метода setInterval() знаю, но как-то не совсем мне удалось понять как с ним работать. Ссылка на подробное описание, с примерами, работы с ним приветствуются.
Готового решения не ищу и даже отвергаю.
Нужны подсказки в каком направлении мыслить + минимальные опорные точки для направления. Хочу все написать сама.
Заранее всем благодарна.
P.S. Сильно не бейте за кривой код. Я самоучка. Все писала сама. Сейчас перерабатываю тонну HTML в циклы с объектно ориентированной генерацией через DOM.
Последний раз редактировалось Daiver, 12.05.2013 в 04:10.
|
|
12.05.2013, 07:04
|
Аспирант
|
|
Регистрация: 01.04.2013
Сообщений: 58
|
|
var timerID=null; // global
timerID=setTimeout(.....);
clearTimeout(timerID);
timerID=null;
Цитата:
|
не совсем мне удалось понять как с ним работать
|
ммм так-же как и с сеттаймаут , один в один)) только будет вызов не 1 раз а много раз пока не сделать clearInterval(intervalID) где intervalID это переменная куда положен сет интервал )
В общем таймер(-ы) в переменную(-ые) и все 3 пункта решатся ) б) - clearTimeout clearInterval ( правда с вызовом функции из самой себя, можно проскочить момент с clearTimeout , так-что лучше переделывать под clearInterval )
|
|
12.05.2013, 07:05
|
|
Тлен
|
|
Регистрация: 02.01.2010
Сообщений: 6,584
|
|
Таймер так и делается, там всё просто:
var timeout;
function timer(){
//действия
timeout = setTimeout(timer, 1000);
}
//запуск
timer();
//остановка
clearTimeout(timeout);
С clearTimeout'ом ничего проскочить нельзя, т.к. если clearTimeout произведён то никаких вызовов точно не будет. Главное правило чтоб не накосячить - одновременно на одну задачу должен существовать только один таймер, следующий не должен вызываться пока предыдущий не закончится.
А вот как раз таки setInterval использовать не рекомендуется(только в особых случаях), т.к. он имеет свойство в случае лагов накапливаться, и может случиться так, что он уже очищен, а функция продолжает вызываться.)
__________________
29375, 35
Последний раз редактировалось Aetae, 12.05.2013 в 07:14.
|
|
12.05.2013, 14:27
|
|
Интересующийся
|
|
Регистрация: 12.05.2013
Сообщений: 14
|
|
Сообщение от edison
|
В общем таймер(-ы) в переменную(-ые) и все 3 пункта решатся
|
Замечание понято. Буду исправляться.
Из всего сказанного возникает вопрос - а можно ли как-то исправить следующее: когда ставится пауза, то обнуляется таймер, а когда игра снимается с паузы, то таймер опять ждет 1000 мс чтобы переключить на табло еще одну секунду. Получается накапливание времени зазоров. Хотелось бы, к примеру - если табло было переключено пол секунды назад, то чтобы после паузы таймер отсчитывал уже пол секунды, а не целую. Так вот как можно выцепить сколько времени прошло с запуска таймера до обрывания, чтобы потом таймер можно было поставить не на 1000 мс, а на (1000-(столько, сколько прошло перед обрывом отсчета))мс.?
|
|
12.05.2013, 15:16
|
|
Тлен
|
|
Регистрация: 02.01.2010
Сообщений: 6,584
|
|
Date.now() вам в помощь.
Однако не вижу особого смысла именно в секундной задержке. Обычно с этим не заморачиваются и выводят время с интервалом в 100мс. Никаких задержек тогда не заметно.
Ну и плюс обратите внимание на мой пример: в нём сначала выполняется код, а потом уже запускается таймер следующего вызова. Т.е. при нажатии на кнопку обновление происходит сразу.
__________________
29375, 35
|
|
12.05.2013, 20:36
|
Аспирант
|
|
Регистрация: 01.04.2013
Сообщений: 58
|
|
Aetae
Про проскочить, имелось в виду не существование 2х таймеров, а когда идет вызов таймера на функцию из самой себя, то может наступить тот момент, когда мы во время выполнения этой функции жмем стоп, но функция вешает опять таймер, т.к. выполняется все асинхронно.
Понятно, что в вашем примере вероятность попадания clearTimeout(timeout);
в момент выполнения функции timer стремится к нулю, но чем больше функция, тем выше шанс. Вообще можно вводить дополнительную переменную для проверки в обоих случаях.
Последний раз редактировалось edison, 12.05.2013 в 20:39.
|
|
12.05.2013, 20:59
|
|
сегодня в 12:34|Комментир
|
|
Регистрация: 12.04.2011
Сообщений: 1,180
|
|
1) Ну я хз зачем вам интервал в судоку
function Game() {
var interval, self = this;
this.count = 0;
this.start = function () {
interval = setInterval(function () {
self.count++;
}, 1000)
}
this.pause = function () {
clearInterval(interval);
}
}
var snake = new Game();
snake.start();
setTimeout(function () { alert(snake.count); snake.pause(); }, 3000) // Берем результаты через 3 секунды
setTimeout(function () { alert(snake.count+' Результат тот же, значит пауза сработала'); snake.start()}, 5000) // Проверяем, что пауза сработала
setTimeout(function () { alert(snake.count+' Результат изменился, значит работа продолжилась');snake.pause(); }, 7000) // Проверяем, что мы продолжили работу
__________________
оляля, ололо
Последний раз редактировалось 9xakep, 12.05.2013 в 21:05.
|
|
12.05.2013, 21:11
|
|
Интересующийся
|
|
Регистрация: 12.05.2013
Сообщений: 14
|
|
В коде по выше приведенной ссылке вероятно сложно найти нужную часть кода. Привожу пример отдельно взятого табло с таймером.
После вставления таймера в переменную как предложил edison проблема не решилась. Попробуйте часто пощелкать по кнопке пауза при запущеном таймере и вы увидите удивительный глюк. За одну секунду реального времени перескакивает сразу несколько секунд на табло. Что не так?
|
|
12.05.2013, 21:18
|
|
сегодня в 12:34|Комментир
|
|
Регистрация: 12.04.2011
Сообщений: 1,180
|
|
<div id='timer'></div><br />
<script>
function Game() {
var interval, self = this, isStart = false;
this.count = 0;
this.start = function () {
if (!isStart) {
isStart = true;
interval = setInterval(function () {
/* Тут вы пишете код, который будет выполнятся */
self.count++;
self.log();
}, 1000)
}
}
this.pause = function () {
isStart = false;
/* Тут просто останавливаете выполнение кода */
clearInterval(interval);
}
this.stop = function () {
/* А тут останавливаете, плюс восстанавливаете изначальные значения (count = 0) */
self.pause();
self.count = 0;
self.log()
}
this.log = function () {
// Этот метод просто обновляет div
timer.innerHTML = self.count;
}
}
var snake = new Game();
</script>
<input type='button' value='start' onclick='snake.start()' /><br />
<input type='button' value='pause' onclick='snake.pause()' /><br />
<input type='button' value='stop' onclick='snake.stop()' />
__________________
оляля, ололо
Последний раз редактировалось 9xakep, 12.05.2013 в 21:22.
|
|
12.05.2013, 22:01
|
|
Интересующийся
|
|
Регистрация: 12.05.2013
Сообщений: 14
|
|
Спасибо, 9xakep, принцип поняла, сейчас попробую переделать. Но у меня все на много проще - мне надо просто реализовать обновление табло через каждую секунду. Просто чтобы пользователь видел сколько времени прошло с момента начала игры, с возможностью поставить на паузу.
|
|
|
|