Браузерная игра на HTML и JS


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

Создадим файл с именем tetris.html, откроем его в любом текстовом редакторе, желательно Блокноте Windows, а лучше чем-то с подсветкой кода HTML/JavaScript, например Dreamweaver. Вставим туда следующий код HTML: Открыв tetris.html, вот что мы увидим в браузере:
0 - отображает кол-во набранных очков.
level 1 - уровень игрока (начинаем с первого).
New game - кнопка, нажав на которую начинается новая игра.
Pause - пауза в игре.
Внутри дива с id="htmlgame" и будут происходить основные игровые действия.
А внутри дива с id="nextelm" будет показываться следующий в очереди элемент.
Класс .physx будет задавать нужные параметры блокам, которые образуют фигурку элемента для тетриса; высота и ширина такого блока будет одинаковой, 32 пикселя.
Впечатляет? Пока сказать сложно... Сам по себе код HTML статичен и не интерактивен (будущую его версию - HTML5 - в расчёт не берём, да и ждать его выхода и полной поддержки всеми браузерами мы не хотим). Вот тут-то и придёт на помощь JavaScript. JavaScript — объектно-ориентированный скриптовый язык программирования. Обычно используется в браузерах как язык сценариев для придания интерактивности веб-страницам. Дабы свести объём кода к минимуму мы воспользуемся библиотекой jQuery, в которой уже есть все часто используемые функции JavaScript. Писать их ещё раз нам не придётся - просто берём и используем их.

Для начала подключим эту библиотеку к себе на страницу. Скачивать её с официального сайта не обязательно: достаточно будет использовать ссылку до неё, которую, кстати, может предоставить Google.

Вставляем этот код: между тегами head нашей страницы, после тега . Всё, теперь мы можем использовать функции jQuery, к примеру, для того, что бы получить какой-то элемент, вместо длинного document.getElementById(eid) достаточно писать просто $('#'+eid). А обращаться к элементам нам придётся часто. Очень часто.

Как известно, любая игра на компьютере имеет частоту кадров. Т.е. каждый кадр (обычно 60-100 раз в секунду) компьютер выполняет некоторый код игры и выводит результат на экран. Значит, в нашем коде должна быть функция, которая выполняется с некоторым интервалом несколько раз в секунду. Сделаем это. Сразу после кода подключения jQuery добавьте этот код:

Каждый элемент тетриса (т.е. фигуру) образуют 4 квадрата, переменные cubeW и cubeH задают их размеры (ширину и высоту, соответственно) в пикселях.
Переменные tetW и tetH определяют размеры непосредственно игрового окна (меню справа не в счёт!), в пикселях. Если будете менять эти значения, то не забудьте их изменить и в стилях вот в этой части: pause и gOver - эти переменные определяют паузу в игре и конец игры.
lower - эта переменная определяет скорость игры, чем она больше, тем больше будет пропущено кадров и, следовательно, тем медленнее будут движения в игре (в тетрисе - это движение элемента вниз).
e - эта переменная будет указывать на элемент тетриса, с которым мы в данный момент работаем, т.е. его мы будем перемещать стрелочками, вращать и вставлять куда захотим.
ste - здесь будет список всех «складированных» элементов тетриса.
lvl - переменная содержит текущий уровень игрока.
scr - переменная содержит текущее кол-во очков игрока.

Теперь перейдём непосредственно к элементам тетриса. У них может быть разные фигуры. Зададим различные варианты через этот массив: Вставьте его перед setInterval. Думаю, понять массив несложно: то место, где имеется единица, будет «замещено» «кубиком».
И сразу же, ниже, вставим функцию создания элемента (т.е. фигуры) для тетриса: Перед вызовом функции createElm выбирается случайный элемент и записывается в переменную ri (точнее, записывается ИНДЕКС этого элемента в массиве arr).
После каждого вызова функции createElm (кроме некоторых, см. ниже) в переменную ri каждый раз записывается новый случайно выбранный индекс элемента в массиве arr.
Функция может принимать параметр ret, имеющий одно из трёх значений: true, false, array (массив).
Если true, то созданный элемент будет помещён в игровое поле, а указатель на него будет возвращён (return); согласно ранее сгенерированному ri будет выбран элемент из массива arr и записан в переменную size, после чего ri будет сгенерирован ещё раз на будущий вызов функции создания элемента (это нужно, что бы заранее уже знать, каким будет следующий элемент). Если false, то новый созданный элемент будет помещён в ячейку следующего элемента в очереди, при этом переменные ri и size НЕ будeт изменены.
Если array, то параметр будет воспринят как указание на форму для нового элемента. Будут совершены почти те же действия, что и при true. Зачем это нужно - узнаете ниже, при рассмотрении функции вращения фигуры.
Переменная x содержит смещение от левой границы тетриса до центра игрового поля. Нужно для того, чтобы размещать созданый элемент «красиво» и по центру в игровом поле.

Элемент тетриса должен реагировать на столкновения со стенами и другими элементами, которые лежат внизу. Для этого создадим функцию collisionDetect. Вставьте перед функций createElm этот код: Функция принимает параметр a, который определяет, как проверять столкновения.
Если left, то функция проверяет, свободно ли пространство слева.
Если right, то функция проверяет, свободно ли пространство справа.
Если bottom, то функция проверяет, свободно ли пространство внизу.
Если top, то функция проверяет, свободно ли пространство сверху.
P.S. Все столкновения проверяются в рамках размеров одного блока, составляющего фигурку для тетриса.
Учитываются границы окна тетриса, за них элемент двигать нельзя.
Если произошло столкновение, возвращается true. В иных случаях - false.
gameOver() происходит в тот самый момент, когда элементов уже так много, что новый созданный элемент поместить уже не куда (он размещается прямо внутри других элементов).

В JavaScript нет методов, позволяющий как-то вращать элементы HTML. Для этих целей нам придётся создать свою функцию. Вставьте ещё ниже этот код: Каждый раз при создании элемента (createElm) в глобальную переменную size заносится элемент массива arr, описывающий форму этого элемента; в функции transElm мы её используем, чтобы знать, как перевернуть текущий элемент.
Код переворачивает size следующим образом:
- было: - стало:

Ещё ниже добавим события на нужные кнопки для управления элементом тетриса: Код выше работает так: пока мы не «врезались» в препятствие, делать движение. Так же надо не забыть повесить событие и на отпускание клавиши «стрелка вниз» (её код - 40), дабы вернуть значение переменной lower в нормальное:

Повесим события на клики по двум ссылкам справа, в меню: Добавим события при конце игры. Вставьте в див с id="htmlgame" этот код: А в стиль добавьте ещё это: Перед функцией collisionDetect добавьте этот код: Теперь при конце игры у нас будет плавно появляться сообщение вида

GAME OVER!
You gained 9000 scored!

Перейдём к нашей основной функции. Помните, та самая, которая была задана при setInterval? Внутри неё заменяем это: на следующий код: Код хорошо прокомментирован. Думаю, дополнительные пояснения будут лишними.

Вот что у нас получилось (можете начать играть прямо в браузере):
http://www.cybernova.net/games/tetris.html (посмотрите и изучите исходный HTML-код страницы).

Кстати, вы можете скачать первую версию тетриса здесь:
http://www.cybernova.net/games/tetris.zip (16bit, DOS).