在 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 函数来解决这个问题,并修复了双计时器初始化的错误。
现在一切正常!
我看了很多关于在 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 函数来解决这个问题,并修复了双计时器初始化的错误。 现在一切正常!