【发布时间】:2014-03-19 03:26:42
【问题描述】:
我正在用 SDL 编写一个用于游戏编程的小型库。该库负责游戏循环、键盘和鼠标输入。我已将库分成 3 个小文件:
- ./gamelibrary.h
- ./Input/Keyboard.h
- ./Input/Mouse.h
现在,在主游戏循环中,我检查 SDL_Quit 事件(这样我可以提供一个可以默认关闭的窗口)以及键盘和鼠标事件。键盘和鼠标类是静态类,可以随时访问以获得键盘/鼠标状态(就像 XNA 一样)。我写的键盘类如下:
#ifndef KEYBOARD_INPUT
#define KEYBOARD_INPUT
#include <set>
namespace DGL
{
struct KeyboardState {
std::set<Uint8> keys;
bool isKeyDown(Uint8 key)
{
return keys.find(key) != keys.end();
}
bool isKeyUp(Uint8 key)
{
return !isKeyDown(key);
}
};
class Keyboard {
/**
* This class handles keyboard input game-like
*/
private:
static std::queue<SDL_Event> events;
public:
void insertEvent(SDL_Event event)
{
events.push(event);
}
void eraseEvents()
{
std::queue<SDL_Event> empty;
swap(events, empty);
}
static KeyboardState getKeyBoardState()
{
KeyboardState state;
while ( !Keyboard::events.empty() )
{
SDL_Event event = events.front();
Keyboard::events.pop();
state.keys.insert(event.key.keysym.sym);
}
return state;
}
};
std::queue<SDL_Event> Keyboard::events;
}
#endif
如您所见,用户可以使用方法Keyboard::getKeyboardState() 来获取具有键盘当前状态的结构。像这样:
...
...
KeyboardState state = Keyboard::getKeyboardState()
if ( state.isKeyDown(SDLK_w) )
{
....
}
....
当事件不是 SDL_Quit 而是 SDL_KEYDOWN 时,使用 'events' 静态 std::queue 中的事件填充结构,它从游戏循环接收其值。
我想找到一种方法来调用 Keyboard::insertEvent()(来自游戏循环),前提是用户包含库本身 (Keyboard.h)。
如您所见,我尝试使用 include-guards 解决我的问题,但它在运行时不起作用。
我希望我正确地解释了我的问题。最好的问候。
【问题讨论】:
-
仅当用户包含库本身时是什么意思?在一个翻译单元中?在所有翻译单元中?当包含后者时,在其他一些包含文件之前?
-
@DavidRodríguez-dribeas 我有一个用于键盘和鼠标的静态类,主循环将按下的键和按钮的状态保存到每个相应的类。如果用户包含键盘和鼠标文件,我希望我的主循环仅执行此操作,因为这意味着用户将想要读取输入。附言即使用户在主循环文件之后包含键盘和鼠标文件,我也希望它能够工作,仅当用户包含之前的文件时,包含保护才有效。
标签: c++ input keyboard include sdl