Строим космический корабль

Догонять

Привет всем! Эта статья - вторая часть моего руководства по созданию небольшой игры с Javascript. Вы можете прочитать часть 1 здесь.

Полный исходный код этого руководства можно найти здесь.

Создание космического корабля

Теперь, когда фон готов, мы можем наконец приступить к настройке нашего космического корабля!

Давайте создадим Player.js файл и добавим его в index.html как сценарий (такой же, как CloudManager).

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

По сути, мы хотим, чтобы этот корабль появлялся у левой границы экрана. Нам также нужно, чтобы его якорь (точка положения объекта) находился в центре спрайта, и, поскольку он может быть слишком большим, мы можем изменить его масштаб:

Конечно, мы должны объявить этот объект как глобальную переменную файла main.js , чтобы его можно было создать в игре:

… И в функции init того же файла (сразу после CloudManager):

Теперь вы должны увидеть сияющий космический корабль.

Однако если вы подождете несколько секунд, у вас должны возникнуть проблемы:

Космический корабль летит за облаками!

Да, потому что на самом деле последний созданный объект движется за предыдущим. Облака появляются после создания экземпляра космического корабля, поэтому нам нужен облачный менеджер, создающий облака, в нижней части списка объектов. Для этого нам просто нужно немного обновить addChild в CloudManager класс:

addChildAt позволяет нам передавать второй параметр, который является позицией в списке объектов рабочей области. Чем дальше он будет, тем дальше будет спрайт на экране.

«0» означает первый индекс в списке объектов, поэтому каждый раз, когда мы создаем новое облако, мы добавляем его в первую позицию списка, гарантируя, что он появится за космическим кораблем.

Теперь, когда это сделано, мы можем приступить к управлению космическим кораблем.

Перемещение космического корабля

Вернемся к классу Player.js и добавим несколько строк в конструктор:

Это позволяет игре улавливать события клавиатуры (когда клавиша нажимается и отпускается). Когда происходит одно из этих событий, выполняется метод в конце каждой строки.

Примечание. Добавляя «.bind (this)» в конце функции, мы передаем в нее контекст объекта, что означает, что мы все еще можем получить доступ к его свойствам, вызвав «this» ». Если мы не напишем это таким образом, функция обратного вызова не сможет определить, с каким объектом мы работаем. Просто помните, что если одна из ваших функций обратного вызова выдает ошибку «undefined this», возможно, вам придется привязать свой объект следующим образом.

Давайте определим 2 пустых метода в одном классе (мы заполним их через некоторое время):

Нам также нужны 3 переменные для перемещения космического корабля: его горизонтальное и вертикальное направления (X и Y) и скорость (все они в конструкторе):

Этот объект в основном представляет собой ассоциацию кодов клавиш и значений направления:

  • 37 - это клавиша со стрелкой влево, чтобы переместить космический корабль влево, нам нужно уменьшить его положение по оси X.
  • 38 - это клавиша со стрелкой вверх, чтобы переместить наш космический корабль наверх, нам нужно уменьшить его положение по оси Y.
  • 39 - это клавиша со стрелкой вправо, чтобы переместить наш космический корабль вправо, нам нужно увеличить его положение по оси X.
  • 40 - это клавиша со стрелкой вниз, чтобы переместить космический корабль вниз, нам нужно увеличить его положение по оси Y.

Каждый раз, когда нажимается клавиша, мы получаем соответствующее направление:

Это выглядит довольно странно, но давайте объясним следующее: если код клавиши 37 или 39 (что означает клавишу со стрелкой влево или вправо), мы просто устанавливаем направление X. Если это 38 или 40, вы можете догадаться, что происходит (да, на самом деле это вертикальное направление). Это все!

Давайте добавим метод обновления плеера (например, Cloud Manager, помните?):

… И, конечно же, не забудьте вызвать его в функции цикла в main.js!

Если вы сохраните и перезагрузите игру, она (должна) работать нормально, за исключением того, что корабль продолжает движение, когда мы отпускаем клавиши направления. Это очевидно, потому что мы не выполнили функцию onKeyUp, которая перехватывает только что отпущенную клавишу. Таким образом, мы можем остановить его, установив для directionX или directionY значение 0.

Здесь есть только одна небольшая проблема: что произойдет, если мы установим направление на 0, потому что мы отпустили левую клавишу, но правая клавиша все еще нажата?

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

Так почему бы не проверить, нажата ли правая или левая клавиша, чтобы мы могли сбросить направление на эту предыдущую нажатую клавишу?

Вот что мы собираемся делать. И для этого нам нужно сохранить состояние каждой клавиши в виде логического, нажатого или отпущенного (true или false). Давайте поместим все эти состояния в объектную переменную в конструкторе Player:

Если нажата клавиша (идентифицируемая собственным кодом), то мы просто меняем ее состояние на true, а если она отпускается, мы устанавливаем его на false . Легко, правда?

Давайте добавим эту строку в начало onKeyDown:

… И этот в onKeyUp:

Теперь мы можем продолжить работу с логикой onKeyUp: если одна из горизонтальных или вертикальных клавиш отпущена, но противоположная все еще нажата, мы меняем направление на последнюю. Если они оба будут выпущены, мы остановим корабль:

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

Все готово, сохраните, перезагрузите и наслаждайтесь!

Обновление: космический корабль может выйти за пределы экрана! Попробуйте проверить его положение перед обновлением. Проверить результат можно здесь.

Стрельба ракетами

Теперь, когда мы можем управлять кораблем, мы хотим, чтобы он стрелял ракетами.

Начнем с добавления спрайта в папку assets :

… И добавьте его в загрузчик ресурсов как обычно:

Создайте новый файл с именем Rocket.js в папке src и добавьте его в index.html. с остальными ребятами:

Вернемся к классу Player. Мы хотим, чтобы он мог стрелять ракетой, если он нажимает кнопку пробела. Функция onKeyDown уже перехватывает такие события, поэтому нам просто нужно создать условие с нужным кодом клавиши (пробел в этом примере):

Мы задаем позицию космического корабля в конструкторе Rocket, поэтому внутри мы просто устанавливаем его позицию на позицию космического корабля (со смещением, чтобы он появлялся перед кораблем, а не в середине).

Итак, приступим, инициализируем Rocket.js с помощью конструктора:

Хорошо, если вы сохраните и перезагрузите, вы сможете запускать (статические) ракеты, нажав клавишу пробела!

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

Переменная _list находится за пределами класса, поскольку она статична, что означает, что ее значение уникально и не является свойством только одного объекта (в отличие от this ). Однако мы можем получить его и установить по своему усмотрению (с двумя первыми строками класса).

Мы можем поместить текущий объект в этот список (в конструкторе) и объявить скорость переменную в том же время:

… А также добавьте update метод:

Это в основном то же самое, что и раньше, мы обновляем x положение ракеты (а не y, потому что она не движется вертикально) и т. Д. облака, мы удаляем их, когда они выходят за пределы экрана, за исключением того, что на этот раз это правый край.

После этого в цикле main.js нам просто нужно проанализировать список ракет и вызвать update функция для каждого элемента:

Сохраните и перезагрузите, и попробуйте!

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

Давайте определим две новые переменные в Player конструкторе: скорость стрельбы (которую можно изменить) и время восстановления, которое будет значение таймера:

Нам также необходимо обновить keyState, чтобы добавить клавишу пробела, потому что мы хотим знать, нажата она или нет:

Вот функция, которую мы используем для стрельбы (нам нужно вызвать ее в обновлении плеера):

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

Эта функция постоянно выполняется в цикле update проигрывателя:

Работа сделана! Если вы хотите быстрее, просто уменьшите переменную скорости огня (и увеличьте ее для более медленной скорости).

Скоро следующий пост: мы добавляем врагов!

Спасибо за чтение!

Если у вас есть вопросы или предложения, дайте мне знать, и я смогу улучшить следующее!