所以,我正在使用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
(因此间接来自SlimFSM
和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
中的虚拟空实现吗?
答案 0 :(得分:0)
您应该将run()方法声明为virtual,以强制将对象指针解释为PongGame对象,因为目前它不是。某些编译器可能会警告您也要覆盖run()。在这种情况下,run()的PongGame实现可以是一个简单的代码重复,大部分时间都是无害的。
void PongGame::run() {
SlimGame::run();
}