Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #1 (permalink)  
Старый 12.05.2013, 03:56
Аватар для Daiver
Интересующийся
Отправить личное сообщение для Daiver Посмотреть профиль Найти все сообщения от Daiver
 
Регистрация: 12.05.2013
Сообщений: 14

Таймер для игры
Делаю игру судоку на javascript. Нужно исправить/переделать таймер, чтобы он смог:
а) Ставиться/сниматься с паузы без глюков. В нынешнем состоянии если несколько раз часто пощелкать на кнопку паузы запускается парралельно несколько setTimeout()-ов параллельно и таймер скачет не соответствуя реальности.
б) Останавливаться окончательно и безповоротно из отдельной функции. Возможно сама дойду до этого пункта при полном решении всех проблем из остальных пунктов.
в) Имея не законченную игру и запущенный таймер при запуске новой игры чтобы не было глюка из пункта (а).

На данный момент таймер реализован через рекурсивную функцию с использованием setTimeout(). О наличии метода setInterval() знаю, но как-то не совсем мне удалось понять как с ним работать. Ссылка на подробное описание, с примерами, работы с ним приветствуются.
Готового решения не ищу и даже отвергаю.
Нужны подсказки в каком направлении мыслить + минимальные опорные точки для направления. Хочу все написать сама.
Заранее всем благодарна.
P.S. Сильно не бейте за кривой код. Я самоучка. Все писала сама. Сейчас перерабатываю тонну HTML в циклы с объектно ориентированной генерацией через DOM.

Последний раз редактировалось Daiver, 12.05.2013 в 04:10.
Ответить с цитированием
  #2 (permalink)  
Старый 12.05.2013, 07:04
Аспирант
Отправить личное сообщение для edison Посмотреть профиль Найти все сообщения от edison
 
Регистрация: 01.04.2013
Сообщений: 58

var timerID=null; // global
timerID=setTimeout(.....);
clearTimeout(timerID);
timerID=null;
Цитата:
не совсем мне удалось понять как с ним работать
ммм так-же как и с сеттаймаут , один в один)) только будет вызов не 1 раз а много раз пока не сделать clearInterval(intervalID) где intervalID это переменная куда положен сет интервал )
В общем таймер(-ы) в переменную(-ые) и все 3 пункта решатся ) б) - clearTimeout clearInterval ( правда с вызовом функции из самой себя, можно проскочить момент с clearTimeout , так-что лучше переделывать под clearInterval )
Ответить с цитированием
  #3 (permalink)  
Старый 12.05.2013, 07:05
Аватар для Aetae
Тлен
Отправить личное сообщение для Aetae Посмотреть профиль Найти все сообщения от Aetae
 
Регистрация: 02.01.2010
Сообщений: 6,505

Таймер так и делается, там всё просто:
var timeout;
function timer(){
    //действия
    timeout = setTimeout(timer, 1000);
}

//запуск
timer();

//остановка
clearTimeout(timeout);


С clearTimeout'ом ничего проскочить нельзя, т.к. если clearTimeout произведён то никаких вызовов точно не будет. Главное правило чтоб не накосячить - одновременно на одну задачу должен существовать только один таймер, следующий не должен вызываться пока предыдущий не закончится.
А вот как раз таки setInterval использовать не рекомендуется(только в особых случаях), т.к. он имеет свойство в случае лагов накапливаться, и может случиться так, что он уже очищен, а функция продолжает вызываться.)
__________________
29375, 35

Последний раз редактировалось Aetae, 12.05.2013 в 07:14.
Ответить с цитированием
  #4 (permalink)  
Старый 12.05.2013, 14:27
Аватар для Daiver
Интересующийся
Отправить личное сообщение для Daiver Посмотреть профиль Найти все сообщения от Daiver
 
Регистрация: 12.05.2013
Сообщений: 14

Сообщение от edison Посмотреть сообщение
В общем таймер(-ы) в переменную(-ые) и все 3 пункта решатся
Замечание понято. Буду исправляться.

Из всего сказанного возникает вопрос - а можно ли как-то исправить следующее: когда ставится пауза, то обнуляется таймер, а когда игра снимается с паузы, то таймер опять ждет 1000 мс чтобы переключить на табло еще одну секунду. Получается накапливание времени зазоров. Хотелось бы, к примеру - если табло было переключено пол секунды назад, то чтобы после паузы таймер отсчитывал уже пол секунды, а не целую. Так вот как можно выцепить сколько времени прошло с запуска таймера до обрывания, чтобы потом таймер можно было поставить не на 1000 мс, а на (1000-(столько, сколько прошло перед обрывом отсчета))мс.?
Ответить с цитированием
  #5 (permalink)  
Старый 12.05.2013, 15:16
Аватар для Aetae
Тлен
Отправить личное сообщение для Aetae Посмотреть профиль Найти все сообщения от Aetae
 
Регистрация: 02.01.2010
Сообщений: 6,505

Date.now() вам в помощь.
Однако не вижу особого смысла именно в секундной задержке. Обычно с этим не заморачиваются и выводят время с интервалом в 100мс. Никаких задержек тогда не заметно.
Ну и плюс обратите внимание на мой пример: в нём сначала выполняется код, а потом уже запускается таймер следующего вызова. Т.е. при нажатии на кнопку обновление происходит сразу.
__________________
29375, 35
Ответить с цитированием
  #6 (permalink)  
Старый 12.05.2013, 20:36
Аспирант
Отправить личное сообщение для edison Посмотреть профиль Найти все сообщения от edison
 
Регистрация: 01.04.2013
Сообщений: 58

Aetae
Про проскочить, имелось в виду не существование 2х таймеров, а когда идет вызов таймера на функцию из самой себя, то может наступить тот момент, когда мы во время выполнения этой функции жмем стоп, но функция вешает опять таймер, т.к. выполняется все асинхронно.

Понятно, что в вашем примере вероятность попадания clearTimeout(timeout);
в момент выполнения функции timer стремится к нулю, но чем больше функция, тем выше шанс. Вообще можно вводить дополнительную переменную для проверки в обоих случаях.

Последний раз редактировалось edison, 12.05.2013 в 20:39.
Ответить с цитированием
  #7 (permalink)  
Старый 12.05.2013, 20:59
Аватар для 9xakep
сегодня в 12:34|Комментир
Отправить личное сообщение для 9xakep Посмотреть профиль Найти все сообщения от 9xakep
 
Регистрация: 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.
Ответить с цитированием
  #8 (permalink)  
Старый 12.05.2013, 21:11
Аватар для Daiver
Интересующийся
Отправить личное сообщение для Daiver Посмотреть профиль Найти все сообщения от Daiver
 
Регистрация: 12.05.2013
Сообщений: 14

В коде по выше приведенной ссылке вероятно сложно найти нужную часть кода. Привожу пример отдельно взятого табло с таймером.
После вставления таймера в переменную как предложил edison проблема не решилась. Попробуйте часто пощелкать по кнопке пауза при запущеном таймере и вы увидите удивительный глюк. За одну секунду реального времени перескакивает сразу несколько секунд на табло. Что не так?
Ответить с цитированием
  #9 (permalink)  
Старый 12.05.2013, 21:18
Аватар для 9xakep
сегодня в 12:34|Комментир
Отправить личное сообщение для 9xakep Посмотреть профиль Найти все сообщения от 9xakep
 
Регистрация: 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.
Ответить с цитированием
  #10 (permalink)  
Старый 12.05.2013, 22:01
Аватар для Daiver
Интересующийся
Отправить личное сообщение для Daiver Посмотреть профиль Найти все сообщения от Daiver
 
Регистрация: 12.05.2013
Сообщений: 14

Спасибо, 9xakep, принцип поняла, сейчас попробую переделать. Но у меня все на много проще - мне надо просто реализовать обновление табло через каждую секунду. Просто чтобы пользователь видел сколько времени прошло с момента начала игры, с возможностью поставить на паузу.
Ответить с цитированием
Ответ



Опции темы Искать в теме
Искать в теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Установка цвета через функцию .css() сбрасывает цвет для :hover xintrea jQuery 4 18.08.2012 15:38
Некорректная работа get(set)Attribute в IE для элементов img back to back Internet Explorer 15 09.06.2012 16:52
Удалению метаданных в JPEG lorents Библиотеки/Тулкиты/Фреймворки 2 22.04.2012 21:02
Реализация игрового поля для игры "Точки" last-art Events/DOM/Window 7 22.04.2012 03:18
Переодическое обновление значений для графика, функция для обновления значений yupa87 Общие вопросы Javascript 0 09.07.2009 14:48