玩家退出提示

目前游戏开始之后,对于玩家退出是没有做任何处理的,也就导致了当我方玩家退出之后,对手玩家还在地图里瞎转悠,游戏体验不太好,本章我们就来解决这个问题。

15 玩家退出提示 - 图1

解决方法其实也很简单,当WebSocket连接断开时会触发SwooleonClose()方法,我们只需要在这里新增一些逻辑,通知一下对手就能比较简单的解决这个问题。

做题时间

  1. Logic类中新增方法closeRoom()并在Server类的onClose()方法中调用。
  2. closeRoom()方法判断退出玩家是否存在比赛中的房间,存在的话则通知对手玩家并关闭游戏房间。
  3. Sender类中新增一种消息类型:玩家退出。

Server类:

  1. <?php
  2. ...
  3. class Server
  4. {
  5. ...
  6. public function onClose($server, $fd)
  7. {
  8. ...
  9. $this->logic->closeRoom(DataCenter::getPlayerId($fd));
  10. ...
  11. }
  12. ...
  13. }
  14. ...

Logic类:

  1. <?php
  2. ...
  3. class Logic
  4. {
  5. ...
  6. public function closeRoom($closerId)
  7. {
  8. $roomId = DataCenter::getPlayerRoomId($closerId);
  9. if (!empty($roomId)) {
  10. /**
  11. * @var Game $gameManager
  12. * @var Player $player
  13. */
  14. $gameManager = DataCenter::$global['rooms'][$roomId]['manager'];
  15. $players = $gameManager->getPlayers();
  16. foreach ($players as $player) {
  17. if ($player->getId() != $closerId) {
  18. Sender::sendMessage($player->getId(), Sender::MSG_OTHER_CLOSE);
  19. }
  20. DataCenter::delPlayerRoomId($player->getId());
  21. }
  22. unset(DataCenter::$global['rooms'][$roomId]);
  23. }
  24. }
  25. ...
  26. }

Sender类:

  1. <?php
  2. ...
  3. class Sender
  4. {
  5. ...
  6. const MSG_OTHER_CLOSE = 1006;
  7. const CODE_MSG = [
  8. ...
  9. self::MSG_OTHER_CLOSE => '你的敌人跑路了',
  10. ];
  11. ...
  12. }

以上代码写完后,我们重启一下服务器并测试退出提示功能。

15 玩家退出提示 - 图2

Chrome的调试窗口里可以看到,前端已经接收到code1006的消息了,那么接下来我们就来实现前端逻辑。

做题时间

  1. 前端接收到1006消息后,弹窗提示玩家对手已退出。

index.html

  1. ...
  2. <script>
  3. var app = new Vue({
  4. ...
  5. websocketonmessage(e) { //数据接收
  6. ...
  7. switch (message.code) {
  8. ...
  9. case 1006:
  10. alert('你的敌人跑路了')
  11. break;
  12. }
  13. },
  14. ...
  15. }
  16. })
  17. </script>
  18. ...

15 玩家退出提示 - 图3

本章对应Github Commit扩展五:玩家退出提示