3

因此,我正在使用 SDL 编写一个小型 Pong 游戏克隆,并且我有以下设置。

有一个SlimGame从 FSM 类和事件处理程序类继承的通用游戏类:

// DEFINITION
class SlimGame : public SlimFSM, public SlimEventHandler {
protected:
  bool    running;        // indicates if the game is running

public:
  bool isRunning() { return this->running; }
  void setRunning(bool r) { this->running = r; }

  void run();                         // encapsulates the game loop
};

// IMPLEMENTATION
void SlimGame::run() {
  SDL_Event event;

  this->setRunning(true);

  while(this->isRunning()) {
      while(SDL_PollEvent(&event)) {
          this->handleEvent(&event);
          std::cout << "MAIN LOOP Running: " << this->isRunning(); << endl;
      }

      // ...
  }
}

FSM 类与奇怪的行为无关,但事件处理程序类如下所示:

// DEFINITION
class SlimEventHandler {
public:
  SlimEventHandler() { }
  virtual ~SlimEventHandler() { }

  void handleEvent(SDL_Event *event);

  virtual void onExit();
};

// IMPLEMENTATION
void SlimEventHandler::handleEvent(SDL_Event *event) {
  switch(event->type) {
    case SDL_QUIT:
      this->onExit();
      break;
  }
}

void SlimEventHandler::onExit() {
  std::cout << "PARENT onExit!" << std::endl;
}

然后我的PongGame类本身继承自SlimGame(因此间接继承自SlimFSMand SlimEventHandler):

// DEFINITION
class PongGame : public SlimGame {
public:
  PongGame();
  ~PongGame();

  void onExit();
};

// IMPLEMENTATION
void PongGame::onExit() {
  this->setRunning(false);

  std::cout << "CHILD onExit!" << std::endl;
}

所以通过这个设置,我像这样运行我的游戏,它很好地启动了:

int main(int argc, char **argv) {
  PongGame game;

  // setup

  game.run();

  // tear down

  return 0;
}

然而,事件处理并没有按照它应该的方式工作。如果我单击窗口关闭按钮,SDL_QUIT则会触发事件并handleEvent调用该方法。这很好,但方法本身调用onExit它自己,而不是PongGame类的继承方法,所以我看到:

PARENT onExit!

在控制台而不是

CHILD onExit!

不应该调用中的派生方法PongGame,而不是调用中的虚拟空实现SlimEventHandler吗?

4

1 回答 1

0

您应该将您的 run() 方法声明为虚拟,以强制将您的对象指针解释为 PongGame 对象,因为目前它不是。一些编译器也可能会警告您重写 run()。在这种情况下,run() 的 PongGame 实现可以是一个简单的代码重复,在大多数情况下是无害的。

void PongGame::run() {
    SlimGame::run();
}
于 2012-11-28T14:14:54.150 回答