Гузариш ба мундариҷа
Мавзӯи 4 аз 5
Назария

Сбор предметов, враги и счёт

Столкнуться или пересечься

В прошлой теме collider не давал телам войти друг в друга. Но монету не нужно «отталкивать» — её нужно подобрать. Для этого есть overlap: тела проходят друг сквозь друга, а Phaser вызывает функцию, когда они пересеклись.

this.physics.add.overlap(this.player, this.coin, this.collect, null, this);

collect(player, coin) {
  coin.destroy();
  this.score += 10;
  this.scoreText.setText(`Score: ${this.score}`);
}

Аргументы overlap (и collider тоже):

  1. первый объект или группа;
  2. второй объект или группа;
  3. функция-обработчик — получит два столкнувшихся объекта;
  4. функция-фильтр (null, если не нужна) — может вернуть false, чтобы пропустить столкновение;
  5. контекст — что будет this внутри обработчика. Передаём this (сцену), иначе внутри метода this.score не найдётся.

Можно и стрелкой — тогда this берётся из create сам:

this.physics.add.overlap(this.player, this.coins, (player, coin) => {
  coin.destroy();
  this.score += 10;
});

Группы предметов

Монет, врагов, пуль много, и все ведут себя одинаково. Их собирают в группу и проверяют столкновения сразу со всей группой:

this.coins = this.physics.add.group({ allowGravity: false });
for (let i = 0; i < 6; i++) {
  this.coins.add(this.add.circle(50 + i * 60, 250, 8, 0xffd54f));
}
this.physics.add.overlap(this.player, this.coins, this.collect, null, this);

Обработчик получит конкретную монету из группы, которую задел игрок. Полезные методы групп:

this.coins.getChildren();       // массив объектов
this.coins.countActive();       // сколько ещё активных
this.coins.clear(true, true);   // удалить все

Победа и поражение

Условия конца игры проверяют там, где меняется состояние, — прямо в обработчике:

if (this.coins.countActive() === 0) {
  this.win = true;
  this.add.text(200, 150, "You win!").setOrigin(0.5);
}

Остановить игру можно, поставив физику на паузу: this.physics.pause() — все тела замрут. Перезапуск сцены — this.scene.restart() (подробнее в следующей теме).

Враги: сверху или сбоку

Классика платформеров: прыгнул врагу на голову — он побеждён, врезался сбоку — теряешь жизнь. Отличить одно от другого помогают свойства тела:

  • body.velocity.y > 0 — игрок падает (а не взлетает);
  • body.bottom — нижний край тела игрока, body.top — верхний край врага.
hitEnemy(player, enemy) {
  const stomp = player.body.velocity.y > 0 && player.body.bottom <= enemy.body.top + 8;
  if (stomp) {
    enemy.destroy();
    player.body.setVelocityY(-250);   // отскок от врага
    this.score += 50;
  } else {
    this.lives -= 1;
    player.body.reset(50, 200);        // на старт с нулевой скоростью
  }
}

Запас в 8 пикселей нужен потому, что за один кадр игрок успевает немного «войти» во врага, — без запаса прыжок сверху иногда засчитывался бы как удар сбоку.

Враги ходят сами

Самый простой враг ходит туда-сюда: скорость по x и полный отскок от стен.

const enemy = this.add.rectangle(200, 265, 30, 30, 0xe53935);
this.enemies.add(enemy);
enemy.body.setVelocityX(-60).setBounce(1, 0).setCollideWorldBounds(true);

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

Итог

  • overlap(a, b, обработчик, null, this) — пересечение без отталкивания; collider — с отталкиванием.
  • Группы: одна проверка столкновений на все объекты, countActive() — сколько осталось.
  • Конец игры — флаг + this.physics.pause().
  • Прыжок на врага: velocity.y > 0 и body.bottom <= enemy.body.top + запас.

Монетка

Осон+10 XP

В сцене есть игрок this.player, монета this.coin (обе с телами), счёт this.score = 0 и текст this.scoreText. Допиши:

  • метод collect(player, coin): монета исчезает (coin.destroy()), счёт растёт на 10, текст — Score: N;
  • в create — overlap между игроком и монетой, который вызывает this.collect.
игрок дошёл до монеты  →  монета исчезла, Score: 10

Барои ҳал кардани масъалаҳо коннекторро пайваст кун

Коди масъалаҳо дар компютери худат иҷро мешавад — ин аз браузер тезтар ва боэътимодтар аст. Барои ин барномаи ройгони коннектори CodeWithMe лозим аст. Онро як бор пайваст кардан кифоя аст.

Коннекторро дар ин компютер ҷустуҷӯ мекунем…

  1. 1
    Коннекторро барои системаи худ (Windows, macOS ё Linux) зеркашӣ кун.Зеркашии коннекторДар саҳифаи зеркашӣ файлеро интихоб кун, ки дар номаш системаи ту ҳаст, масалан windows-amd64.
  2. 2Онро иҷро кун ва ҷузвдонеро интихоб кун, ки ҳалҳоят дар он ҷо меистанд. Python ва Node.js-ро ӯ худаш ҳангоми зарурат ба он ҷо мегузорад.
  3. 3
    Дар поён рамзи 6-рақамаро ворид кун — он дар равзанаи коннектор навишта шудааст («Рамз барои сайти CodeWithMe»). Агар браузер дар бораи дастрасӣ ба шабакаи маҳаллӣ пурсад — иҷозат деҳ.

Коннектор кушода аст (рамзи манбаъ дар GitHub), танҳо дар компютери ту кор мекунад ва кодро танҳо пас аз ворид кардани рамзи пайвастшавӣ иҷро мекунад.