RU

Урок 7 — Мультиплеер по сети

JumPHP соединяет игроков через сервер-ретранслятор (WebSocket): один и тот же код работает по сети на компьютере и в браузере. Игра Pong — полный пример (src/Scene/PlayScene.php).

Лобби

$this->scenes()->switchTo(LobbyScene::class, [
    'next' => PlayScene::class,             // сцена игры, когда игроки собрались
    'nextParams' => ['mode' => 'online'],
    'back' => TitleScene::class,
    'players' => 2,
]);

Лобби создаёт комнату (4-буквенный код, которым можно поделиться), заходит в существующую или находит соперника. Затем оно открывает сцену игры с параметрами ['online' => true, 'net' => NetSession, 'host' => bool, 'peer' => int].

Сообщения

$net = $params['net'];
$net->removeAllListeners();
$net->on('message', fn (int $from, int $type, string $payload) => $this->receive($from, $type, $payload));
$net->on('peerLeave', fn (int $peer) => $this->scenes()->switchTo(TitleScene::class));

$net->send(self::MSG_STATE, pack('gg', $this->x, $this->y), reliable: false);   // часто: может потеряться
$net->sendJson(self::MSG_EVENT, ['goal' => 1]);                                   // редко: доходит всегда

Правильная организация

  • Решает хост: он симулирует партию, считает очки и отправляет состояние ~20 раз в секунду;
  • остальные отправляют свои команды ~30 раз в секунду;
  • объекты других игроков рисуются с небольшой сглаженной задержкой: SnapshotBuffer (push($this->engine->time(), $state), затем sample($this->engine->time())).

Сервер-ретранслятор запускается у вас командой bin/jumphp relay up; игра указывает свой через net_url в game.yaml (или ?net=wss://… в адресе страницы).