JS + Phaser пишем игру с Дино (часть 4) 🦖
В прошлой части мы с вами добавили противников для нашего Дино, а так же разобрались с тем, как делать респаун объектов по своему желанию, если вы это пропустили, то советую вернуться к части 3.
Код, который уже готов живет тут.
Противников мы с вами добавили в предыдущей части, а сегодня займемся тем, чтобы эти противники могли нанести нам урон...
А именно научимся обрабатывать коллизии и определять конец нашей игры)
Начнем отслеживать коллизии
И так, для начала нам нужно как-то определить, что Дино столкнулся с другими объектами, для этого в конструкторе добавим строчку с инициализацией функции, которая будет за это отвечать:
create() { // Остальной код функции this.initAnims(); // Добавим еще одну функцию илициализатов this.initColliders(); this.createControll(); this.initStartTrigger(); }
Теперь давайте начнем создавать объявленную функцию:
initColliders() { this.physics.add.collider(this.dino, this.obsticles, () => { // 1 this.physics.pause(); // 2 this.isGameRunning = false; // 3 this.anims.pauseAll(); // 4 this.dino.setTexture('dino-hurt'); // 5 this.respawnTime = 0; // 6 this.gameSpeed = 10; // 7 }, null, this); }
collider
- функция, которая позволяет нам добавить функцию обработчик на ситуации коллизии объектов.- Для начала при столкновении мы с вами остановим всю физику в игре
- Скажем что сейчас игра не идет
- Остановим все анимации, которые у нас сейчас играют
- Навесим на динозавра погибающего спрайта
- Откатим време респауна
- И откатим скорость игры к дефолтному значению
Немного оптимизации
После того как препятствия пропадают из нашей области видимости обработчик этой функции на них сохраняется и код продолжает жить в памяти, из-за того что мы никак ее не высвобождаем. Давайте исправим это!
Для этого нам нужно добавить убийство этих объектов в нашу функцию update()
:
update(time, delta) { // Остальной код функции this.obsticles.getChildren().forEach(obsticle => { // Если препятствие вышло за границы if (obsticle.getBounds().right < 0) { // Метод для вызова деструктора obsticle.destroy(); } }); }
Добавим перезапуск игры
После того как произошла коллизия нам бы как-то игру перезапустить, для этого давайте в конструкторе создадим еще несколько объектов:
create() { // Остальной код функции this.gameOverScreen = this.add.container(width / 2, height / 2 - 50); this.gameOverText = this.add.image(0, 0, 'game-over'); this.restart = this.add.image(0, 80, 'restart').setInteractive(); this.gameOverScreen.add([ this.gameOverText, this.restart ]); }
Метод setInteractive()
- дает нам возможность потом взаимодействовать с объектом, а в нашем случае - обрабатывать нажатия.
Если открыть браузер, то мы сразу увидем наш экран для конца игры:
Это не совсем то что мы хотим, поэтому давайте на момент начала игры спрячем этот экран, установив ему .setAlpha(0)
:
create() { // Остальной код функции this.gameOverScreen = this.add.container(width / 2, height / 2 - 50).setAlpha(0); this.gameOverText = this.add.image(0, 0, 'game-over'); this.restart = this.add.image(0, 80, 'restart').setInteractive(); this.gameOverScreen.add([ this.gameOverText, this.restart ]); }
А вот когда игра заканчивается - в функции обработки коллизии, нам нужно наоборот показать этот экран:
initColliders() { this.physics.add.collider(this.dino, this.obsticles, () => { this.physics.pause(); this.isGameRunning = false; this.anims.pauseAll(); this.dino.setTexture('dino-hurt'); this.respawnTime = 0; this.gameSpeed = 20; // Показываем экран this.gameOverScreen.setAlpha(1); }, null, this); }
Сейчас у нас выходит следующее:
Обрабатываем нажатие на кнопку
Ну что же, для полноценного рестарта не хватает только перезапуска по кнопке, поэтому давайте добавим этот обработчик в функции createControll()
:
createControll() { // Остальной код функции this.restart.on('pointerdown', () => { // 1 this.dino.setVelocityY(0); // 2 this.dino.body.height = 92; // 3 this.dino.body.offset.y = 0; // 4 this.physics.resume(); // 5 this.obsticles.clear(true, true); // 6 this.isGameRunning = true; // 7 this.gameOverScreen.setAlpha(0); // 8 this.anims.resumeAll(); // 9 }); }
- Функция обработчик нажатия на кнопку
- Если наш Дино прыгал - вернем его на землю
- Если он пригибался - вернем исходную высоту
- Так же нужно просто откатить к состоянию, которое у нас было на начало игры
- Возобновим всю физику в игре
- Уберем всех врагов со сцены
- Запустим игру
- Спрячем экран конца игры
- Возобновим анимацию
На этом я закончу четвертую часть из цикла статей по созданию игры с Дино, надеюсь вам было интересно и вы попробовали сами с нуля создать свою игру!
Вы можете найти код для этого урока тут