Статьи

Создание простой игры для Windows 8 с JavaScript: игровая логика

Это третья в серии из четырех публикаций за четыре недели, в которой показано, как создать простую игру для Windows 8 с использованием HTML5, JavaScript, WinJS и CreateJS .

Игра основана на образце игры XNA «Catapult Wars Lab» . Мы будем использовать ресурсы этой игры, когда будем разрабатывать новую версию для Windows 8, основанную на веб-технологиях.

В этом посте мы познакомим вас с игровой логикой и JavaScript.

Игровой цикл

Сердцебиение любой игры — игровой цикл. Это функция, которая запускается много раз в секунду и имеет два основных задания: обновить происходящее и нарисовать новую сцену.

Во второй части мы уже наметили схему:

code sample 1

Теперь вопрос в том, как gameLoop() функцию gameLoop() и поддерживать ее выполнение много раз в секунду?

EaselJS Ticker Class

К счастью, EaselJS имеет класс Ticker, который имеет некоторые функции, которые мы будем использовать:

  • Управление временем игрового цикла
  • Приостановить / возобновить игровой цикл
  • Измерьте прошедшее время

Это статический класс, поэтому мы можем просто начать его использовать. В default.js добавьте новую startGame() и вызовите ее в конце prepareGame() :

code sample 2

Здесь мы говорим Ticker использовать window.requestAnimationFrame чтобы контролировать, как часто вызывается функция gameLoop.

requestAnimationFrame — это относительно новый API для веб-приложений, который помогает избежать ненужной работы. Чтобы понять, почему это может быть лучше, чем установка фиксированного таймера (например, с помощью setTimeout() ), см. Пример requestAnimationFrame на сайте IE Test Drive .

RequestAnimationFrame

Каждый раз, когда requestAnimationFrame готов, наш игровой цикл запускается.

«Готов, цель, огонь!»

Хорошо, теперь у нас есть игра с запущенным игровым циклом, так что пришло время добавить немного веселья!

Каждый игрок / катапульта будет стрелять боеприпасами / камнем в сторону другого. Нам нужно знать, летит ли сейчас выстрел, кто его поворачивает и как движется выстрел.

Во-первых, давайте добавим больше переменных в default.js :

code sample 3

Теперь давайте воспользуемся некоторыми из них, добавив следующее в функцию update() :

code sample 4

На данный момент оба игрока автоматически стреляют (со случайной скоростью) на своих ходах. ammoBitma p перемещается в верхний центр катапульты стрельбы, а shotVelocity получает случайное значение в ограниченном диапазоне (с поправкой на разрешение экрана).

Мы также добавим функцию fireShot() чтобы показать выстрел и сообщить игре, что он в эфире:

code sample 5

Обновление дисплея

Прежде чем мы переместим выстрел по воздуху, давайте сосредоточимся на 2-й половине уравнения игрового цикла — рисовании на экране. Часто это может быть очень сложным, но EaselJS Stage заботится о том, чтобы нарисовать наш контент (все дочерние элементы — растровые изображения, текст и т. Д., Которые мы добавили в Stage) на холст, поэтому это все, что нам нужно:

code sample 6

Это оно! Если вы запустите игру, игрок 1 автоматически выстрелит, и выстрел появится над красной катапультой …

non-moving shot

… но это не сдвинется с места. Давайте заставим вещи двигаться.

Перемещение выстрела

Давайте вернемся к функции update() и добавим логику в оператор if (shotIsFlying) :

code sample 7

Пока не запускайте, нам все еще нужны две функции, но вот что происходит:

  • Линии 149 и 150 — переместить выстрел, добавив скорость (которая может быть отрицательной, чтобы идти вверх и / или влево)
  • Линия 151 — Применить гравитацию к медленной скорости
  • Линии 153-155. Удар по земле или ушел с левого или правого края экрана?
  • Линии 157-160 — Пропущенные — конец броска и смена игроков
  • Линии 162-168 — выстрел игрока 1 — посмотрите, попал ли он в игрока 2. Если это так, обновите жизни игрока 2.
  • Линии 169-175 — выстрел игрока 2 — посмотрите, попал ли он в игрока 1. Если это так, обновите жизни игрока 1.

Давайте добавим checkHit(Bitmap) :

code sample 8

Что это за разговор о hitTest? EaselJS DisplayObject s (на котором основан Bitmap ) поддерживает метод hitTest() , который позволяет очень легко увидеть, находится ли точка над позицией текущего объекта. К сожалению, мы масштабируем объекты, и hitTest работает только с исходными размерами, поэтому нам нужно самим проверять наличие попаданий. Немного математики, и все готово.

Обработка хитов

Теперь добавьте функцию processHit () :

code sample 9

Это просто заканчивает выстрел, меняет игроков и гарантирует, что игра не окончена.

Завершение игры

Давайте закончим этот пост, закончив игру. Добавьте функцию endgame(Image) :

code sample 10

Это оно! Теперь вы можете запустить игру и посмотреть, кто победит.

victorydefeat

Что дальше?

В этой части мы многое добавили — вещи рисуют, двигаются, ударяются, заканчиваются … но есть две зияющие дыры. Во-первых, игрок на самом деле не играет , поэтому мы добавим обработку ввода далее. Во-вторых, все очень тихо, особенно для войны, поэтому мы также добавим некоторые звуки.

На части 4: на следующей неделе!