Создание игры на HTML5. Часть 1.

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

В этой части расскажу немного теории об устройстве игр и покажу небольшой пример работы с canvas.

Алгоритм практически каждой игры состоит из стандартной последовательности действий. Сначала происходит подготовка, настройка параметров игры (уровня), затем запускается повторяющийся игровой цикл, ну а после выхода из него (game over/переход на след. уровень) освобождаются выделенные ресурсы.

Самое интересное находится внутри цикла. Тут у нас происходит следующее:

  1. Опрос клавиатуры/мыши/итд — управление.
  2. Глобальные события (например, перемещение камеры).
  3. Обновление состояния игровых объектов  (координаты, скорости, поведение: столкновение, умирание, появление, превращение и т.п.).
  4. Отрисовка игровых объектов и всего остального (задний фон, набранные очки и др.).

Вообще, слово «объект» слишком общее, им можно назвать что угодно. Но не придумал пока что ничего лучше (если есть идеи — сообщите ;) ). Поэтому уточню.

Игровым объектом будем считать элемент игры, обладающий своим поведением; с этим элементом игрок (или другие объекты) может взаимодействовать.

Определеие пока не идеальное, возможно позже появится лучший вариант) Другими словами, это враги/союзники/пули/ящики, которые можно разрушить или сдвинуть. В то же время, ящики, которые являются частью декораций, частью карты не будут игровыми объектами — их не надо обновлять, их надо просто нарисовать. Хотя взаимодествие игрока с ними возможно: они могут загораживать путь например.

Я не случайно эти игровые объекты придумываю. Они будут реализованы как наследники одного базового класса, в котором как раз все необходимые свойства и методы будут готовы.

Но это позже, пока сделаем заготовку будущей игры. Итак, html файл:

<!DOCTYPE HTML>
<html>
<head>
  <title>Mind Defender</title>
  <style type="text/css">
    #canvas {margin:0 auto; width:320px; height:480px; border:1px solid #000; image-rendering:optimizeSpeed}
  </style>
  <script type="text/javascript" src="minddef/game.js"></script>
</head>
<body>
  <canvas id="canvas">
    <div id="noCanvas">
      Ваш браузер не поддерживает canvas, попробуйте более современный ;)
    </div>
  </canvas>
</body>
</html>

Тут всё просто: настраиваем стили для canvas, подгружаем заготовку игры (game.js) и размещаем canvas на странице. Если браузер его не поддерживает, то будет показано соответствующее сообщение.

Код самой игры находится в minddef/game.js:

var MindDefGame = {
//подготовка
  initialize: function() {
     this.cnv = document.getElementById('canvas');
     this.ctx = this.cnv.getContext('2d');
     this.x = 0;
  },
//завершение
  stop: function() {
     //пока пусто
  },
//повторяющийся цикл
  loop: function() {
     //input.update();    // управление
     //global.update();   // "глобальные события"
     //objs.update();     // обновление
     //objs.render();     // отрисовка
     // "затухание" экрана
     this.ctx.globalAlpha = .017;
     this.ctx.fillStyle = "#000";
     this.ctx.fillRect(0,0,this.cnv.width,this.cnv.height);
     this.ctx.globalAlpha = 1;
     // изображение новой полоски
     var clr = 'rgb(' + Math.round(Math.random()*255) + ',' + Math.round(Math.random()*255) + ',' + Math.round(Math.random()*255) + ')';
     this.ctx.fillStyle = clr;
     this.ctx.fillRect(this.x, 0, 1, this.cnv.height);
     this.x++;
     this.x &= 0xFF;
  }
};

Function.prototype.bind = function(bind) {
  var me = this;
  return function() {
    var args = Array.prototype.slice.call(arguments);
    return me.apply(bind || null, args);
  };
};
window.addEventListener(
  "load",
  function() {
    MindDefGame.initialize();
    var fps = 25;
    MindDefGame._interval = setInterval(MindDefGame.loop.bind(MindDefGame), 1000/fps);
  },
  false);

Тут тоже всё просто. Игра у нас расположена в глобальной переменной MindDefGame. Внутри описаны методы инициализации, остановки а также игровой цикл. Сейчас здесь не совсем игровой цикл, а скорее проверка «холста» (canvas): мы просто заполняем экран разноцветными полосками.

Есть пара моментов, которые необходимо учесть.

1. Чтобы быть уверенным, что игра запустится после загрузки документа, добавляем обработчик события onload. Как раз он и подготовит игру к запуску(MindDefGame.initialize) и настроит повторение цикла (setInterval) в соответствии со значением FPS. Если например мы хотим получить 25 кадров в секунду, то интервал между вызовами loop должен быть 1000/25=40 миллисекунд.

2. Т.к. setInterval вызовет MindDefGame.loop в контексте window (this будет указывать на window, а не на MindDefGame, как бы нам хотелось), используем метод bind. Подробнее о bind вы можете узнать из документации к prototype

На этом пока что всё. Продолжение следует.

P.S.: исходники в архиве выложу чуть позже (тут wordpress не позволяет этого сделать). Также будут рабочие страницы с примерами. Пока что это не критично, с помощью copy&paste вполне можно два этих файла создать, посмотреть ;)

комментария 2 (+добавить свой?)

  1. StaruhaMt
    Янв 29, 2017 @ 01:26:40

    Всем Привет!

  2. KirilMt
    Янв 30, 2017 @ 12:26:48

    Доброго времени суток