3

それで、私は SDL を使用して小さな Pong ゲームのクローンを書いています。次のセットアップがあります。

SlimGameFSM クラスとイベント ハンドラ クラスから継承する一般的なゲーム クラスがあります。

// 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あります(したがって、 and から間接的SlimFSMSlimEventHandler):

// 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

オブジェクト ポインタを強制的に PongGame オブジェクトとして解釈するには、run() メソッドを virtual として宣言する必要があります。現在はそうではないためです。一部のコンパイラは、run() もオーバーライドするように警告する場合があります。その場合、run() の PongGame 実装は、ほとんどの場合無害な単純なコードの繰り返しである可能性があります。

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