Наверх

Урок 3. Запускаем таймер хода. Области видимости

Тетрис — это такая игра, где процесс идет сам собой — не важно, играет человек или нет. Как только игру запустили, фигуры начинают падать с определенной скоростью (частотой кадров).

Мы будем использовать функцию setInterval. Для начала немного теории. Я так предполагаю, что у нас будет функция tick, которая будет запускаться с помощью setInterval, например, 1 раз в секунду.

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

Итак, создаем метод tick у объекта Tetris
var Tetris = {
  // ...
  init: function() {
    for (var i = 0; i < Tetris.pitch.height; i++) {
      Tetris.pitch.bricks[i] = [];
      for (var j = 0; j < Tetris.pitch.width; j++) {
        Tetris.pitch.bricks[i][j] = 0;
      }
    }
    Tetris.startBtn.onclick = function () {
        // Заменяем вызов метода draw на вызов метода tick
        Tetris.tick();
    }
  },
  tick: function() {
    Tetris.draw();
  },
  // ...
}
Теперь в коде метода tick добавляем запуск метода tick раз в секунду. Вот такая тавталогия получилась. На самом деле такая ситуация, когда внутри функции вызывается эта же функция, называется рекурсией.
tick: function() {
    Tetris.draw();
    console.log('tick');
    setInterval(function(){
        Tetris.tick();
    }, 1000);
  }
Если мы запустим этот скрипт, нажмем на кнопку старт, то в консоли браузера начнут появляться надписи tick раз в секунду.

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

Для этого нужно присвоить вывод функции setInterval переменной. Чтобы потом можно было прервать работу этой функции.

Однако, мы не можем просто написать
var tickHandler = setInterval(function(){
   Tetris.tick();
}, 1000);
Потому что существует такое понятие как «область видимости переменных». В этом случае, переменная каждый раз будет пересоздаваться, а мы не сможем обратиться к ней из любой другой точки.

Поэтому нам нужно переменную tickHandler сделать свойством объекта Tetris:
// Проверяем, не было ли свойство объявлено ранее
if (Tetris.tickHandler === undefined) {
  // и создаем его
  Tetris.tickHandler = setInterval(function(){
    Tetris.tick();
  }, 1000);
}
Теперь мы можем прервать игру в любой момент.
var Tetris = {
  // ...
  tick: function() {
    Tetris.draw();
    Tetris.i = Tetris.i || 0;
    Tetris.i++;
    alert(Tetris.i);
    if (Tetris.i >= 3) {
    	clearInterval(Tetris.tickHandler);
    }
    if (Tetris.tickHandler === undefined) {
      Tetris.tickHandler = setInterval(function(){
        Tetris.tick();
      }, 1000);
    }
  },
  // ...
};
Tetris.init();
У меня при клике на кнопку старт появляются окна 1, 2 и 3. После чего игра останавливается: http://jsfiddle.net/ilyautkin/aavju3jd/4/


2 комментария

  1. Станислав Морозов 11 января 2016, 11:10 # 0
    Используй лучше requestAnimationFrame
    learn.javascript.ru/js-animation — вот ссылка, там объясняют почему лучше его использовать
    1. Илья Уткин 11 января 2016, 12:11 # 0
      Отлично, спасибо, почитаю)

    Авторизация

    через сервис Loginza:


    Шаблоны MODX

    1 2 Дальше »

    Объектная
    модель
    MODX