Перейти к тексту

Нажимая Отправить, Вы принимаете Условия использования developerWorks.

Профиль создается, когда вы в первый раз заходите в developerWorks. Выберите данные в своем профиле (имя, страна/регион, компания) которые будут общедоступными и будут отображаться, когда вы публикуете какую-либо информацию. Вы можете изменить данные вашего ИБМ аккаунта в любое время.

Вся введенная информация защищена.

  • Закрыть [x]

При первом входе в developerWorks для Вас будет создан профиль и Вам нужно будет выбрать Отображаемое имя. Оно будет выводиться рядом с контентом, опубликованным Вами в developerWorks.

Отображаемое имя должно иметь длину от 3 символов до 31 символа. Ваше Имя в системе должно быть уникальным. В качестве имени по соображениям приватности нельзя использовать контактный e-mail.

Нажимая Отправить, Вы принимаете Условия использования developerWorks.

Вся введенная информация защищена.

  • Закрыть [x]

Разработка 2D-игр на HTML5: Игра Snail Bait

Первый опыт разработки платформера

Дэвид Гири, автор и докладчик, Clarity Training, Inc.
Дэвид Гири
Дэвид Гири (David Geary), автор книги Core HTML5 Canvas, является также сооснователем группы пользователей HTML5 Денвера и автором восьми книг по Java-программированию, в том числе бестселлеров по Swing и JavaServer Faces. Дэвид часто выступает на конференциях, в том числе JavaOne, Devoxx, Strange Loop, NDC и OSCON, и трижды заслужил титул "рок-звезды JavaOne". Для developerWorks он написал циклы статей JSF 2 fu и GWT fu. За новостями Дэвида можно следить в Twitter: @davidgeary.

Описание:  В предлагаемом цикле статей знаток HTML5 Дэвид Гири шаг за шагом демонстрирует процесс создания 2D-видеоигры на HTML5. В этой первой статье демонстрируется готовая игра, а затем начинается ее разработка с нуля. Этот цикл статей ― для тех, кто хотел бы создать игру на HTML5, но не нашел времени, чтобы разобраться во всех деталях.

Больше статей из этой серии

Дата:  08.02.2013
Уровень сложности:  средний
Активность:  3037 просмотров
Комментарии:  


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

Компьютерные игры-платформеры

Данки Конг, Братья Марио, Ежик Соник и Хитросплетение ― все эти широко известные, популярные игры представляют собой платформеры. Одно время на долю платформеров приходилось до трети всех продаж видеоигр. Сегодня их доля рынка существенно уже, но успешных платформеров все еще много.

Однако вознаграждение это дается не легко ― даже наоборот. Для создания игр, особенно видеоигр, требуется нетривиальное знание программирования, хорошее владение графикой и анимацией и недюжинные математические способности в сочетании с искусством и творчеством. И это только начало. Успешные разработчики тратят массу времени на полировку своих игр, оттачивая геймплей и графику, не говоря уже о многих аспектах игры, которые не имеют ничего общего с геймплеем, — таких как табло, инструкции, анимации в промежутках между жизнями и уровнями и последовательности эндгейма.

Цель этого цикла статей ― показать, как создать видеоигру на HTML5, чтобы читатель смог продолжать самостоятельно.

Видеоролик «Об этом цикле статей» ― вот расшифровка стенограммы.

Игра: Snail Bait

В этом цикле статей я покажу, как создать видеоигру-платформер, главным образом с помощью API Canvas HTML5. Это игра Snail Bait (средство от улиток), которая показана на рисунке 1. В нее можно поиграть в онлайне (см. ссылку в разделе Ресурсы). Убедитесь, что ваш браузер поддерживает аппаратное ускорение Canvas (оно совсем недавно реализовано в большинстве браузеров, в том числе в Chrome, начиная с версии 18); в противном случае Snail Bait будет работать крайне медленно. (См. боковик Производительность HTML5 Canvas.)


Рисунок 1. Игра Snail Bait в браузере Chrome
Игра Snail Bait в браузере Chrome

Технологии HTML5, используемые в Snail Bait

  • Canvas (2D API)
  • Управление синхронизацией в анимациях на основе сценариев
  • Звук
  • CSS3 (переходы и обращение к устройствам)

Snail Bait представляет собой классический платформер. Персонаж, которого я буду называть просто бегун, бежит и скачет между плавучих платформ, которые движутся горизонтально. Конечная цель бегуна ― добраться до пульсирующей платформы с золотой кнопкой в конце уровня. Бегун, пульсирующая платформа и золотая кнопка показаны на рисунке 1.

Игрок управляет бегуном с клавиатуры: клавиша d перемещает его влево, клавиша k ― право, клавиши j и f заставляют подпрыгнуть, а клавиша p приостанавливает игру.

В начале игры вам даются три жизни. Слева над холстом игры отображаются значки с изображением бегуна, указывающие количество оставшихся жизней, как видно на рисунке 1. На своем пути бегун должен увертываться от монстров — пчел, летучих мышей и улитки — пытаясь при этом схватить ценные предметы - монеты, рубины и сапфиры. Если бегун сталкивается с монстрами, он лопается, и вы теряете жизнь, возвращаясь в начало уровня. Когда бегун подбирает предметы, ваш счет увеличивается, и вы получаете вознаграждение в виде приятной мелодии.

WASD?

Для управления видеоиграми часто используют клавиши w, a, s и d. Это соглашение появилось главным образом потому, что оно позволяет правшам использовать мышь и клавиатуру одновременно. К тому же правая рука остается свободной для нажатия пробела или клавиш-модификаторов, таких как CTRL и ALT. Snail Bait не использует WASD, потому что не принимает сигналы от мыши и клавиш-модификаторов. Но код игры легко изменить так, чтобы использовать любую комбинацию клавиш.

Монстры в основном просто висят и ждут, пока бегун натолкнется на них. Однако улитка периодически бросается ядрами (серебряное ядро вблизи центра на рисунке 1). Эти ядра, как и монстры, взрывают бегуна, когда настигают его.

Игра заканчивается одним из двух способов: либо вы теряете все три жизни, либо достигаете пульсирующей платформы (с бонусными очками за нажатие на золотую кнопку). В любом случае игра заканчивается титрами, показанными на рисунке 2.


Рисунок 2. Сообщение об авторах игры
Сообщение об авторах игры Snail Bait

Чего не видно на рисунке 1, так это того, что всё — за исключением бегуна, чьим движением вы управляете, — постоянно движется. Это движение делает Snail Bait не просто платформером, а сайд-скроллером. Однако не только это движение в игре привело меня к спрайтам и их манипуляторам.


Спрайты: действующие лица

Производительность Canvas HTML5

Не так давно в большинстве браузеров появилось аппаратное ускорение CSS-переходов, но для Canvas это еще не сделано. Canvas всегда работал относительно быстро, особенно по сравнению с другими графическими системами, такими как Scalable Vector Graphics (SVG), но без аппаратного ускорения Canvas далеко до того, что имеет поддерживает такое ускорение.

Теперь все современные браузеры аппаратно ускоряют элементы Canvas. Это делает даже iOS 5, что означает, что видеоигры с гладкой анимацией на основе Canvas теперь возможны не только на ПК, но и на мобильных устройствах Apple.

За исключением фона, все в Snail Bait представляет собой спрайты. Спрайт — это объект, который можно нарисовать на холсте игры. Спрайты просты в реализации, хотя и не являются частью API Canvas. Вот спрайты игры:

  • платформы (неодушевленные объекты);
  • бегун (персонаж);
  • пчелы и летучие мыши (монстры);
  • кнопки (полезные предметы);
  • рубины и сапфиры (полезные предметы);
  • монеты (полезные предметы);
  • улитка (монстр);
  • ядра улитки (вредные предметы).

Помимо горизонтальных движений, почти все спрайты игры имеют собственные независимые движения. Например, рубины и сапфиры подпрыгивают с разной частотой, а кнопки и улитка снуют туда-сюда по своим платформам.

Replica Island

Идея поведения спрайтов — которая служит примером модели проектирования "Стратегия" — исходит от Replica Island, популярного платформера с открытым исходным кодом для Android. Большинство графики Snail Bait взято из Replica Island (используется с разрешения). См. в разделе Ресурсы ссылку на статью Википедии о модели проектирования "Стратегия" и на главную страницу проекта Replica Island.

Это независимое движение ― один из многих манипуляторов спрайтов. У спрайтов могут быть и другие манипуляторы, не связанные с движением; например, помимо подпрыгивания, рубины и сапфиры искрятся.

Каждый спрайт имеет свой набор манипуляторов. Манипулятор — это просто объект с методом execute(). В каждом кадре анимации игра вызывает метод execute() каждого манипулятора. В этом методе манипуляторы определенным образом управляют соответствующими спрайтами в зависимости от условий игры. Например, при нажатии клавиши k для перемещения бегуна вправо манипулятор бегуна горизонтальное перемещение последовательно перемещает бегуна вправо в каждом кадре анимации до тех пор, пока вы не измените направление. Другой манипулятор ― бег на месте ― периодически изменяет изображение бегуна, имитируя бег на месте. В совокупности эти два манипулятора производят впечатление бега влево или вправо.

В таблице 1 перечислены спрайты игры и соответствующие манипуляторы (поведение).


Таблица 1. Спрайты и манипуляторы Snail Bait
СпрайтПоведение
Платформы
  • Перемещаются горизонтально (все спрайты, за исключением бегуна и ядер улитки, движутся синхронно с платформами)
Бегун
  • Бег на месте
  • Горизонтальное перемещение
  • Прыжок
  • Падение
  • Столкновение с монстрами/вредными предметами и взрыв
  • Столкновение с полезными предметами и получение очков
Пчелы и летучие мыши (монстры)
  • Парят
  • Машут крыльями
Кнопки
  • Снуют
  • Лопаются
  • Взрывают монстров или завершают уровень.
Монеты, рубины и сапфиры
  • Сверкают
  • Подпрыгивают
  • Снуют
Улитки
  • Снуют
  • Бросают ядра
Ядра улиток
  • Движутся вправо и влево (быстрее, чем платформы)
  • Сталкиваются с бегуном и исчезают

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


Листинг 1. Создание спрайтов
var runInPlace = {  // Просто объект с методом execute
   execute: function (sprite, time, fps) {
      // Обновление атрибутов спрайта на основе времени и частоты кадров
   }
};

var runner = new Sprite('runner', // имя
                        runnerPainter, // построитель
                        [ runInPlace,... ]); // манипуляторы

Объект runInPlace определяется и передается конструктору спрайта бегуна вместе с другими манипуляторами. Пока тот бежит, игра в каждом кадре анимации вызывает метод execute() объекта runInPlace.


Практика разработки игр на HTML5

Свободно доступные ресурсы

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

В Snail Bait используются:

  • звуковые эффекты из freesound.org;
  • саундтрек из soundclick.com;
  • спрайт бегуна из panelmonkey.org (сайт взломан);
  • вся остальная графика из Replica Island.

На протяжении этого цикла статей я буду давать практические рекомендации по разработке игр и начну с пятерки, специфической для HTML5:

Я рассмотрю эту пятерку рекомендаций подробно в последующих статьях цикла; пока же вкратце пробежимся по каждому из них.

1. Приостановка игры, когда окно теряет фокус

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

2. Обратный отсчет времени, когда окно восстанавливает фокус

Когда окно игры вновь восстанавливает фокус, полезно предоставить пользователю несколько секунд на подготовку к игре. В игре Snail Bait, когда окно восстанавливает фокус, начинается обратный отсчет трех секунд, как показано на рисунке 3.


Рисунок 3. Автопауза Snail Bait
Автопауза Snail Bait

3. Использование переходов CSS3

На рисунке 4 приведен скриншот, сделанный после загрузки игры.


Рисунок 4. Эффекты CSS3
Снимок экрана CSS3-эффектов Snail Bait

На рисунке 4 надо отметить три вещи. Во-первых, это надпись Good luck! (Удачи!), которая на короткое время демонстрируется игроку. Она тускнеет в процессе загрузки игры и через пять секунд исчезает. Во-вторых, обратите внимание на флажки (для отключения звука и музыки) и инструкции (указывающие, какие клавиши какие функции выполняют) под холстом игры. Когда игра начинается, флажки и инструкции хорошо видны, как на рисунке 4; когда же игра начинается, эти элементы медленно тускнеют, пока на становятся едва заметны (как показано на рисунке 3), чтобы не отвлекать игрока.

Snail Bait затемняет элементы и гасит надписи с помощью переходов CSS3.

4. Обнаружение медленного исполнения игры и реагирование на него

В отличие от консольных игр, которые выполняются в жестко контролируемой среде, среда игр HTML5 переменчива, непредсказуема и хаотична. Нередко игра работает недопустимо медленно, так как пользователь воспроизводит видео YouTube в другой вкладке или еще как-нибудь перегружает ЦП или графический процессор. И всегда есть вероятность того, что игрок будет использовать браузер, который "не тянет".

Разработчик игр должен предвидеть эти неблагоприятные условия и соответственно реагировать на них. Snail Bait постоянно контролирует частоту кадров, и когда она опускается ниже определенного порога много раз и на много секунд, отображает сообщение о медленной работе игры, показанное на рисунке 5.


Рисунок 5. Обнаружение низкой частоты кадров
Обнаружение низкой частоты кадров

5. Включение социальных функций

Почти все популярные игры включают социальные аспекты, такие как размещение счета в Twitter или Facebook. Когда игрок Snail Bait щелкает на ссылке Tweet my score, которая появляется в конце игры (см. рисунок 2), Snail Bait открывает Twitter в отдельной вкладке и автоматически создает твит с объявлением счета, как показано на рисунке 7.


Рисунок 7. Текст твита
Текст твита

Теперь, когда у вас сложилось общее представление об игре, пришло время взглянуть на код.


Код HTML и CSS игры Snail Bait

Статистика кода Snail Bait

Число строк кода:

  • HTML: 276;
  • CSS: 410;
  • JavaScript: 3898.

Игра Snail Bait реализована на базе HTML, CSS и JavaScript; как видно из врезки Статистика кода Snail Bait, большая часть кода ― это JavaScript. Остальные статьи этого цикла посвящены главным образом JavaScript ― с отдельными вылазками в сторону HTML и CSS3.

На рисунке 8 показаны элементы HTML и соответствующие CSS для самой игры, без HTML и CSS других элементов, таких как сообщения и заключительные титры.


Рисунок 8. Код HTML и CSS игры (без объявлений и надписей)
Код HTML и CSS игры (без объявлений и надписей)

Код CSS в основном ничем не примечателен, за исключением нескольких интересных атрибутов, которые я подчеркнул на рисунке 8. Во-первых, я установил значение 0 auto атрибута margin элемента wrapper, что означает, что оболочка и все, что внутри нее, центрируется в окне по горизонтали. Во-вторых, положение элементов lives и sound-and-music имеет значение absolute. Если оставить значение по умолчанию relative, то эти элементы DIV развернутся до ширины холста и заслонят своих соседей (счет и инструкции соответственно). Наконец, классы CSS keys и explanation имеют атрибут inline, чтобы соответствующие элементы размещались в той же строке.

В листинге 2 показан код CSS, соответствующий рисунку 8.


Листинг 2. game.CSS (фрагмент)
#arena {
   text-align: center;
   padding: 5px;
   width: 805px;
   height: 445px;
}

#copyright {
   margin-top: -35px;
   float: right;
   margin-right: 12px;
   padding: 2px;
   color: blue;
   text-shadow: 1px 1px 1px rgba(255,255,255,0.7);
   font-size: 0.8em;
}

.explanation {
   color: #ff0;
   text-shadow: 1px 1px 1px rgba(0,0,0,1.0);
   display: inline;
   margin-top: 5px;
   padding-right: 5px;
   padding-left: 5px;
   padding-bottom: 2px;
}

#game-canvas {
   border: 2px inset rgba(0,0,80,0.62);
   -webkit-box-shadow: rgba(0,0,0,0.5) 8px 8px 16px;
   -moz-box-shadow: rgba(0,0,0,0.5) 8px 8px 16px;
   -o-box-shadow: rgba(0,0,0,0.5) 8px 8px 16px;
   box-shadow: rgba(0,0,0,0.5) 8px 8px 16px;
}

#instructions {
   height: 30px;
   margin-right: 8px;
   padding-top: 6px;
   padding-left: 25px;

   -webkit-transition: opacity 2s;
   -moz-transition: opacity 2s;
   -o-transition: opacity 2s;
   transition: opacity 2s;

   color: #ff0;
   font-size: 1.05em;
   opacity: 1.0;
}

.keys {
   color: blue;
   text-shadow: 1px 1px 1px rgba(255,255,0,1.0);
   background: rgba(0,0,0,0.1);
   border: thin solid rgba(0,0,0,0.20);
   border-radius: 5px;
   margin-left: 10px;
   padding-right: 10px;
   padding-left: 10px;
   padding-bottom: 5px;
   display: inline;
}

#sound-and-music {
   position: absolute;
   top: 495px;
   margin-left: 10px;
   color: #ff0;
   text-shadow: 1px 1px 1px rgba(0,0,0,0.5);
   background: rgba(0,0,0,0.1);
   border-radius: 5px;
   border: thin solid rgba(0,0,0,0.20);
   padding-top: 2px;
   padding-bottom: 2px;
   z-index: 1;
}

#wrapper {
   margin: 0 auto;
   margin-top: 20px;
   padding: 5px;
   width: 817px;
   height: 520px;
}

Как видно из листинга 3, который содержит код HTML, соответствующий рисунку 8, HTML-код игры ― это набор элементов DIV и холстов с несколькими изображениями и парой флажков.


Листинг 3. game.html (фрагмент)
<!DOCTYPE html>
<html>
   <!-- Head........................................................-->

   <head>
     <title>Snail Bait</title>
   </head>

   <!-- Body........................................................-->

   <body>
      <!-- Wrapper..................................................-->

      <div id='wrapper'>
         <!-- Header.................................................-->

         <div id='header'>
            <div id='lives'>
               <img id='life-icon-left'   src='images/runner-small.png'/>
               <img id='life-icon-middle' src='images/runner-small.png'/>
               <img id='life-icon-right'  src='images/runner-small.png'/>
            </div>

            <div id='score'>0</div>
            <div id='fps'></div>
         </div>

         <!-- Arena..................................................-->

         <div id='arena'>
            <!-- The game canvas.....................................-->

            <canvas id='game-canvas' width='800' height='400'>
               Your browser does not support HTML5 Canvas.
            </canvas>

            <!-- Sound and music.....................................-->

            <div id='sound-and-music'>
               <div class='checkbox-div'>
                  Sound <input id='sound-checkbox'
                                  type='checkbox' checked/>
               </div>

               <div class='checkbox-div'>
                  Music <input id='music-checkbox' 
                                  type='checkbox' checked/>
               </div>
            </div>

            <!-- Instructions........................................-->

            <div id='instructions'>
               <div class='keys'>
                  d / k

                  <div class='explanation'>
                     move left/right
                  </div>
               </div>

               <div class='keys'>
                  f / j

                  <div class='explanation'>
                     jump
                  </div>
               </div>

               <div class='keys'>
                  p

                  <div class='explanation'>
                     pause

                  </div>
               </div>
            </div>

            <!-- Copyright...........................................-->

            <div id='copyright'> В©2012 David Geary</div>
         </div>
      </div>

      <!-- JavaScript................................................-->

      <script src='js/stopwatch.js'></script>
      <script src='js/animationTimer.js'></script>
      <script src='js/sprites.js'></script>
      <script src='js/requestNextAnimationFrame.js'></script>
      <script src='js/behaviors/bounce.js'></script>
      <script src='js/behaviors/cycle.js'></script>
      <script src='js/behaviors/pulse.js'></script>
      <script src='game.js'></script>
  </body>
</html>

Элемент canvas ― это место, где происходит все действие. Холст содержит 2D-контекст с мощным API для реализации 2D-игр и прочих вещей. Текст внутри элемента canvas представляет собой страховочный текст, который браузер отображает только в том случае, если он не поддерживает Canvas HTML5.

Одно заключительное замечание о коде HTML и CSS игры: обратите внимание, что ширина и высота холста указывается атрибутами элемента canvas width и height. Эти атрибуты относятся как к размеру элемента canvas, так и к размеру поверхности рисунка, содержащейся в этом элементе.

С другой стороны, размер элемента canvas можно установить, только используя CSS для задания его ширины и высоты. Поле рисунка сохраняет свою ширину и высоту по умолчанию в 300 и 150 пикселей соответственно. Это означает, что соответствия между размером элемента canvas и размером поля его рисунка, скорее всего, не будет, и браузер изменит масштаб поля рисунка под размер элемента. Чаще всего это нежелательно, поэтому лучше задать размер элемента canvas с помощью CSS.

Рисовать на меньшем холсте, и пусть CSS увеличит его?

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

Итак, как в лучших кинофильмах, таких как Криминальное чтиво, конец истории вы уже знаете. Теперь обратимся к ее началу.


Непритязательное начало Snail Bait

На рисунке 9 показана отправная точка игры, где просто вырисовывается фон, платформы и бегун. Сначала платформы и бегун не являются спрайтами; игра вырисовывает их непосредственно. См. раздел Загрузка с кодом, который создает фон и бегуна.


Рисунок 9. Изображение фона и бегуна
Вырисовывание фона и бегуна

В листинге 3 приведена отправная точка HTML-кода игры, который представляет собой просто усеченную версию HTML-кода из листинга 2.


Листинг 3. game.html (начальная версия)
<!DOCTYPE html>
<html>
   <!-- Head.........................................................-->

   <head>
      <title>Snail Bait</title>
      <link rel='stylesheet' href='game.css'/>
   </head>

   <!-- Body.........................................................-->

   <body>
      <!-- Wrapper...................................................-->

      <div id='wrapper'>
         <!-- Header.................................................-->

         <div id='header'>
            <div id='score'>0</div>
         </div>

         <!-- Arena..................................................-->

         <div id='arena'>
            <!-- The game canvas.....................................-->

            <canvas id='game-canvas' width='800' height='400'>
               Your browser does not support HTML5 Canvas.
            </canvas>
         </div>
      </div>

      <!-- JavaScript................................................-->

      <script src='game.js'></script>
  </body>
</html>

В листинге 4 показан код JavaScript.


Листинг 4. game.html (начальная версия)
// --------------------------- ОБЪЯВЛЕНИЯ ----------------------------

var canvas = document.getElementById('game-canvas'),
    context = canvas.getContext('2d'),

   // Константы............................................................

   PLATFORM_HEIGHT = 8,  
   PLATFORM_STROKE_WIDTH = 2,
   PLATFORM_STROKE_STYLE = 'rgb(0,0,0)',

   STARTING_RUNNER_LEFT = 50,
   STARTING_RUNNER_TRACK = 1,

   // Проведение исходных линий
   //
   // Платформы двигаются вдоль дорожек. Следующие константы определяют координату 
   // Y каждой дорожки (от верхней границы холста).

   TRACK_1_BASELINE = 323,
   TRACK_2_BASELINE = 223,
   TRACK_3_BASELINE = 123,

   // Изображения

   background  = new Image(),
   runnerImage = new Image(),

   // Платформы
   //
   // У каждой платформы свой собственный стиль заливки, но стиль контура одинаков.

   platformData = [  // Экран пока один
      // Экран 1.......................................................
      {
         left:      10,
         width:     230,
         height:    PLATFORM_HEIGHT,
         fillStyle: 'rgb(255,255,0)',
         opacity:   0.5,
         track:     1,
         pulsate:   false,
      },

      {  left:      250,
         width:     100,
         height:    PLATFORM_HEIGHT,
         fillStyle: 'rgb(150,190,255)',
         opacity:   1.0,
         track:     2,
         pulsate:   false,
      },

      {  left:      400,
         width:     125,
         height:    PLATFORM_HEIGHT,
         fillStyle: 'rgb(250,0,0)',
         opacity:   1.0,
         track:     3,
         pulsate:   false
      },

      {  left:      633,
         width:     100,
         height:    PLATFORM_HEIGHT,
         fillStyle: 'rgb(255,255,0)',
         opacity:   1.0,
         track:     1,
         pulsate:   false,
      },
   ];

// ------------------------- ИНИЦИАЛИЗАЦИЯ ----------------------------

function initializeImages() {
   background.src = 'images/background_level_one_dark_red.png';
   runnerImage.src = 'images/runner.png';

   background.onload = function (e) {
      startGame();
   };
}

function drawBackground() {
   context.drawImage(background, 0, 0);
}

function calculatePlatformTop(track) {
   var top;

   if      (track === 1) { top = TRACK_1_BASELINE; }
   else if (track === 2) { top = TRACK_2_BASELINE; }
   else if (track === 3) { top = TRACK_3_BASELINE; }

   return top;
}

function drawPlatforms() {
   var pd, top;

   context.save(); // Сохранение атрибутов контекста в стеке

   for (var i=0; i < platformData.length; ++i) {
      pd = platformData[i];
      top = calculatePlatformTop(pd.track);

      context.lineWidth = PLATFORM_STROKE_WIDTH;
      context.strokeStyle = PLATFORM_STROKE_STYLE;
      context.fillStyle = pd.fillStyle;
      context.globalAlpha = pd.opacity;

      // Если изменить порядок следующих двух вызовов, то контур будет казаться толще.

      context.strokeRect(pd.left, top, pd.width, pd.height);
      context.fillRect  (pd.left, top, pd.width, pd.height);
   }

   context.restore(); // Восстановление атрибутов контекста
}

function drawRunner() {
   context.drawImage(runnerImage,
      STARTING_RUNNER_LEFT,
      calculatePlatformTop(STARTING_RUNNER_TRACK) - runnerImage.height);
}

function draw(now) {
   drawBackground();
   drawPlatforms();
   drawRunner();
}

function startGame() {
   draw();
}

// Запуск игры

initializeImages();

Сценарий JavaScript обращается к элементу canvas и получает ссылку на 2D-контекст холста. Затем код использует метод контекста drawImage() для рисования фона и бегуна. В данном случае я использую вариант с тремя аргументами метода drawImage(), чтобы нарисовать изображения в определенном месте холста (x, y).

Функция drawPlatforms() изображает платформы, вырисовывая и заполняя прямоугольные контуры после установки ширины линии, стиля обводки, стиля заливки и глобального альфа-атрибута контекста. Обратите внимание на вызовы методов context.save() и context.restore(): настройки атрибутов между этими вызовами ― временные. Мы поговорим об этих методах в следующей статье.

Игра начинается, когда загружается фоновое изображение. Пока запуск влечет за собой только вырисовывание фона, спрайтов и бегуна. Следующая задача ― вызвать эти статические изображения к жизни.


В следующей статье

Следующую статью этого цикла я начну с обзора 2D-API контекста холста, а затем расскажу об анимации и приведении предметов в движение при помощи прокрутки фона. Вы увидите, как реализовать параллакс, чтобы платформа казалась ближе, чем фон, и как сделать так, чтобы спрайты двигались с постоянной скоростью независимо от частоты кадров анимации. До скорой встречи.



Загрузка

ОписаниеИмяРазмерМетод загрузки
Код фона и персонажа Snail Baitj-html5-game1.zip718 КБHTTP

Информация о методах загрузки


Ресурсы

Об авторе

Дэвид Гири

Дэвид Гири (David Geary), автор книги Core HTML5 Canvas, является также сооснователем группы пользователей HTML5 Денвера и автором восьми книг по Java-программированию, в том числе бестселлеров по Swing и JavaServer Faces. Дэвид часто выступает на конференциях, в том числе JavaOne, Devoxx, Strange Loop, NDC и OSCON, и трижды заслужил титул "рок-звезды JavaOne". Для developerWorks он написал циклы статей JSF 2 fu и GWT fu. За новостями Дэвида можно следить в Twitter: @davidgeary.

Помощь по сообщениям о нарушениях

Сообщение о нарушениях

Спасибо. Эта запись была помечена для модератора.


Помощь по сообщениям о нарушениях

Сообщение о нарушениях

Сообщение о нарушении не было отправлено. Попробуйте, пожалуйста, позже.


developerWorks: вход


Нужен IBM ID?
Забыли Ваш IBM ID?


Забыли Ваш пароль?
Изменить пароль

Нажимая Отправить, Вы принимаете Условия использования developerWorks.

 


При первом входе в developerWorks для Вас будет создан профиль. Выберите информацию отображаемую в Вашем профиле — скрыть или отобразить поля можно в любой момент.

Выберите ваше отображаемое имя

При первом входе в developerWorks для Вас будет создан профиль и Вам нужно будет выбрать Отображаемое имя. Оно будет выводиться рядом с контентом, опубликованным Вами в developerWorks.

Отображаемое имя должно иметь длину от 3 символов до 31 символа. Ваше Имя в системе должно быть уникальным. В качестве имени по соображениям приватности нельзя использовать контактный e-mail.

(Должно содержать от 3 до 31 символа.)


Нажимая Отправить, Вы принимаете Условия использования developerWorks.

 


Оценить эту статью

Комментарии

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=40
Zone=Технология Java, Open source, Web-архитектура
ArticleID=857614
ArticleTitle=Разработка 2D-игр на HTML5: Игра Snail Bait
publish-date=02082013