Skip to content
Topic 4 of 5
Theory

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

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

В прошлой теме 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 + запас.

Монетка

Easy+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

Connect the connector to solve tasks

Task code runs on your own computer — faster and more reliable than in the browser. This needs the free CodeWithMe connector app. You only connect it once.

Looking for the connector on this computer…

  1. 1
    Download the connector for your system (Windows, macOS or Linux).Download the connectorOn the download page pick the file with your system in its name, e.g. windows-amd64.
  2. 2Run it and choose a folder for your solutions. It will install Python and Node.js there by itself when needed.
  3. 3
    Enter below the 6-digit code shown in the connector window (“Code for CodeWithMe”). If the browser asks about local network access — allow it.

The connector is open source (on GitHub), works only on your computer and runs code only after you enter the pairing code.