我需要帮助实现我的事件管理器和引擎系统(SDL& C ++)

时间:2012-01-13 01:32:35

标签: c++ oop inheritance sdl

我在编写可重用的游戏引擎时需要帮助。它不是最好的引擎,但我绝对认为一旦完成它就可以重复使用。我不是要求代码或是为了勺子,但我要求一些建议: - )。

我目前的布局:

我有一个引擎类,一个游戏类和一个事件管理器类。引擎类扩展了事件管理器类,游戏类扩展了引擎类。这是我这3个类的当前代码(忽略Graphics类 - 它只是一个可重用的类,我用来避免重写全屏,初始化和调整屏幕功能)。

ENGINE.HPP

#ifndef _ENGINE_HPP
#define _ENGINE_HPP

#pragma once

#include <SDL/SDL.h>

#include "event_manager.hpp"

enum
  {
    ENGINE_SUCCESS = 0,
    ENGINE_INITIALIZATION_ERROR
  };

class Engine : public EventManager
{
public:
  Engine();
  virtual ~Engine();
  int exec();
  void handle_event(SDL_Event *);
  void update_engine();
  virtual bool init();
  virtual void render();
  virtual void update();
  virtual void clean();
  bool running_;
};

ENGINE.CPP

#include "./engine.hpp"

Engine::Engine()
{
  running_ = false;
}

Engine::~Engine()
{
}

int Engine::exec()
{
  if (!init())
    {
      clean();
      return ENGINE_INITIALIZATION_ERROR;
    }

  SDL_Event event;
  while (running_)
    {
      while (SDL_PollEvent(&event))
    handle_event(&event);

      update();
      render();
    }

  clean();
  return ENGINE_SUCCESS;
}

void update_engine()
{
}

void handle_event(SDL_Event *event)
{
  EventManager::handle_event(event);
}

bool init() {return true;}
void render() {}
void update() {}
void clean() {}

EVENT_MANAGER.HPP

#ifndef _EVENT_MANAGER_HPP
#define _EVENT_MANAGER_HPP

#pragma once

#include <SDL/SDL.h>

class EventManager
{
public:
  EventManager();
  virtual ~EventManager();
  virtual void handle_event(SDL_Event *);
  // events here
  virtual void event_exit();
};

#endif

EVENT_MANAGER.CPP

#include "./event_manager.hpp"

EventManager::EventManager() 
{
}

EventManager::~EventManager()
{
}

void EventManager::handle_event(SDL_Event *event)
{
  switch (event->type)
    {
    case SDL_QUIT:
      event_exit();
      break;
    }
}

void on_exit() {}

GAME.HPP

#ifndef _GAME_HPP
#define _GAME_HPP

#include "./engine.hpp"
#include "./entity.hpp"
#include "./graphics.hpp"

class Game : public Engine
{
public:
  Game();
  bool init();
  void render();
  void update();
  void clean();
private:
  Graphics g;
};

#endif

GAME.CPP

#include "./game.hpp"

int main(int argc, char **argv)
{
  Engine engine;
  return engine.exec();
}

Game::Game() {}

bool Game::init()
{
  if (!g.init(800, 600, 32, g.screen_flags()))
    {
      return false;
    }

  SDL_WM_SetCaption("Title", NULL);
  return true;
}

void Game::update()
{
  Engine::update_engine();
}

void Game::clean()
{
  SDL_FreeSurface(g.screen_);
  SDL_Quit();
}

void Game::render()
{
  SDL_Flip(g.screen_);
}

我收到此错误:

engine.cpp: In function ‘void handle_event(SDL_Event*)’:
engine.cpp:40: error: cannot call member function ‘virtual void
EventManager::handle_event(SDL_Event*)’ without object

为什么会这样?我不应该做EventManager ::如果我做了

class Engine : public EventManager

???

这是我得到的唯一错误,我相信这很简单。现在我需要一些建议。

而不是处理像

这样的事件
void Engine::event_exit()

在引擎中,我宁愿在游戏课程中这样做。

class Game : public Engine


void Game::event_exit()

如果没有意义,请注意我是如何使Engine扩展EventManager,而我的Game类扩展Engine

class Engine : public EventManager

class Game : public Engine
如果我在这两个片段之上调用片段,它会起作用吗?我无法测试它,因为我得到了这个错误。

1 个答案:

答案 0 :(得分:1)

发生在我们最好的人身上,但我认为这只是忘记指定名称空间的问题。当您在engine.cpp中实现这些功能时,您忘记添加Engine::,因此代码应为:

void Engine::update_engine()
{
}

void Engine::handle_event(SDL_Event *event)
{
    EventManager::handle_event(event);
}

这是C ++错误消息的经典案例,并没有真正告诉您错误的 root

一个简短的解释,以防万一:

编译器尝试编译函数 void handle_event(SDL_Event *event),并看到对方法 EventManager::handle_event(event);的调用。由于编译器认为该函数不是Engine类的一部分,因此它会期望您调用EventManager类的特定实例的方法,即

someEventManager->handle_event(event);

一旦指定您编写的实现是属于类Engine的方法的实现,编译器就会推断:

void Engine::handle_event(SDL_Event *event)
{
    this->EventManager::handle_event(event);
}

因此很开心。