在 Allegro 5 中使用多个定时器

Using multiple timers in Allegro 5

我看了很多关于在 Allegro 中使用多个定时器的教程,但这种编程方式对我不起作用。 问题是源地址与我想看的定时器地址不匹配。

我用多个classes/instances来封装我的代码,因为以后会很复杂。我游戏的主循环位于游戏 class/instance 中。计时器和事件封装在 Engine class/instance 中,它是 Game 实例的成员。

Game.cpp:

void Game::GameLoop() {   
  al_wait_for_event(GameEngine.LoopTimerEvent_queue, &GameEngine.LoopTimerEvent);

  if (GameEngine.LoopTimerEvent.type == ALLEGRO_EVENT_TIMER)
  {
    // DEBUG: EVENT SOURCE ADRESSES DON'T MATCH TO THE TIMER ADRESSES
    std::cout << "TimerEvent: " << GameEngine.LoopTimerEvent.timer.source << " " << GameEngine.VSyncTimer << " " << GameEngine.LoopTimer << " " << GameEngine.InGameTimer << "\n";

    if (GameEngine.LoopTimerEvent.timer.source == GameEngine.InGameTimer) 
    { 
        std::cout << "InGameTimerEvent"; 
    }
    if (GameEngine.LoopTimerEvent.timer.source == GameEngine.VSyncTimer) 
    { 
        std::cout << "VSyncTimerEvent"; 
    }
    if (GameEngine.LoopTimerEvent.timer.source == GameEngine.LoopTimer) 
    { 
        std::cout << "LoopTimerEvent"; 
    }
  }  
}

Engine.cpp:

Engine::Engine() {
  if (al_init()) std::cout << "allegro initialized\n";
  else std::cout << "failed to initialize allegro!\n";

  if (InitTimer()) std::cout << "Timer initialized\n";
  else std::cout << "failed to initialize timer!\n";

  LoopTimerEvent_queue = al_create_event_queue();

  al_register_event_source(LoopTimerEvent_queue, al_get_timer_event_source(LoopTimer));
  al_register_event_source(LoopTimerEvent_queue, al_get_timer_event_source(VSyncTimer));
  al_register_event_source(LoopTimerEvent_queue, al_get_timer_event_source(InGameTimer));
  std::cout << "Event queues initialized\n"; 
}


bool Engine::InitTimer() {
  LoopTimer = al_create_timer(1.0);
  if (!LoopTimer) 
  {
    std::cout << "failed to initialize LoopTimer!\n";
    return false;
  }

  InGameTimer = al_create_timer(1.0 / m_iTimeScale);
  if (!InGameTimer)
  {
    std::cout << "failed to initialize InGameTimer!\n";
    return false;
  }

  VSyncTimer = al_create_timer(1.0 / FPS);
  if (!VSyncTimer)
  {
    std::cout << "failed to initialize VSyncTimer!\n";
    return false;
  }

  al_start_timer(LoopTimer);
  al_start_timer(VSyncTimer);
  al_start_timer(InGameTimer);
  std::cout << "Timers started\n";

  return true;
}

Engine.h:

class Engine {
public:
  ALLEGRO_DISPLAY* pDisplay = NULL;
  ALLEGRO_TIMER* VSyncTimer = NULL;
  ALLEGRO_TIMER* LoopTimer = NULL;
  ALLEGRO_TIMER* InGameTimer = NULL;
  ALLEGRO_EVENT LoopTimerEvent;
  ALLEGRO_EVENT_QUEUE* LoopTimerEvent_queue = NULL;

  Logger EngineLogger;
  EventHandler GameEvents;

  private:
  double m_iTimeScale = 2.0;

public:
  Engine();
  ~Engine();

  bool InitEngine();
  bool InitTimer();
  bool InitDisplay();

  void UpdateDisplay();

  float GetTimeScale();
  void SetTimeScale(float timescale);
};

输出
TimerEvent: 031A0D80 0326AF30 0326A380 0326B090

"TimerEvent: " [实际事件地址] [VSyncTimer 地址] [LoopTimer 地址] [InGameTimer 地址]

这些地址哪里有问题?

我不小心将计时器实例初始化了两次,这创建了具有(当然)不同地址的新计时器。但是在事件队列中旧的被注册了,因为我愚蠢的组织。我通过将队列注册放入 InitTimer 函数来解决这个问题,并修复了双计时器初始化的错误。 现在一切正常!