1

我一直在为我的游戏编写服务器代码。它工作得非常好,但 90% 的功能都属于 1 类。

通常我发现很容易知道如何划分事物。每个对象都是一个类,或者每个对话框都是一个类并为其子级处理逻辑。

在这种情况下,服务器收到一个请求,然后要么告诉其他玩家,要么处理并通知适当的玩家。

这是头文件:

    class ServerCore : public ServerHost, public NetEventListener,
        public ServerEventProvider
    {
        NetEventDecoder m_dec;
        NetEventEncoder m_enc;
        LoginManager m_login;

        ServerPlayerManager m_playerMan;
        ServerTableManager m_tableMan;

        void sendToTarget();
        void sendToAllActive();
        void sendToActiveNotTarget();
        void sendToTable(int tableNo);



    public:
        ServerCore();
        virtual void onConnect (Lacewing::Server::Client &client);
        virtual void onDisconnect (Lacewing::Server::Client &client);
        virtual void onError (Lacewing::Error &error);
        virtual void onReceive (Lacewing::Server::Client &client, char * data, int size);
        virtual void sendChatMessageC(const std::string& message,ChatAreaEnum area);
        virtual void requestTableC(int tableNo, int seatNo);
        virtual void playerRequestSitC(int tableNumber, int seatNumber);
        virtual void playerStoodUpC();
        virtual void hostGameC(const SpadesGameInfo& info);
        virtual void gameMessageC(SpadesCSMessageEnum message, const std::vector<int>& params);
        virtual void modifyListC(const std::string& player, GroupTypeEnum group, bool add);
        virtual void canceledHostingRequestC();
        virtual void sendInviteC(int tableNo, const std::string& player);

        virtual void loginResult(const std::string& name, ServerPlayer* player,
            const std::string& sessionID, bool success, bool newSession);
        virtual void readyToReceiveLobbyDataC();

        virtual void playerAbandonedGameC();
        virtual void watchTableC(int tableNo);

        virtual void gameCompleted(int tableId);

        virtual void playerWantsPlayAgainC();
        virtual ~ServerCore(void);
    };
}

我真的不知道如何将其分解为较小的班级。他们执行的任务被交给其他对象,例如身份验证和从数据库中检索数据,但所有事件当前都在这个 1 文件中处理。

网络事件解码器在从通过网络接收的字符串转换之后调用适当的方法。

这样做效果很好,但游戏会变得更大,我想保持干净和模块化。

这个设计是个好主意吗?如果不是,那么在游戏服务器开发中通常使用什么类型的模式来使事情更加面向对象?

谢谢

4

1 回答 1

1

看着你的课,我想到了命令模式。事实上,以结尾的方法C看起来很像命令。如果你有一个命令界面:

class Command {
  virtual void execute() = 0;
}

以及每个命令的单独子类,然后NetEventDecoder可以将接收到的字符串解码为特定命令。

此外,每当您发现自己将相同的数据传递给多个方法时,这都暗示着其中隐藏着一个类。例如,您可以将所有采用 a 的方法拉tableNumber入一个Table类。我还将摆脱Manager类并更直接地对关联进行建模。

例如:

// A game server contains players and tables
class GameServer {
  map<string, Player *> players;
  map<int, Table *> tables;

  Player *findPlayer(const string &name);
  Table *findTable(int tableNumber);
  ...
}

// A player can perform various actions
class Player {
  string name;

  bool requestSeat(Table *table);
  void standUp();
  ...
}

// A table maintains the status of seats
class Table {
  int tableNumber;

  bool requestSeat(int seatNumber);
  ...
}

上面的GameServer类只是简单地模拟游戏,根本不处理网络。然后可以协调以提供网络功能并NetEventDecoder在. 示例命令可能如下所示:ServerCoreGameServer

class PlayerStandUpCommand : public Command {
  GameServer *server;
  string playerName;

  void execute() {
    Player *player = server->findPlayer(playerName);
    player->standUp();
  }
}
于 2012-07-24T05:31:49.430 回答