处理好来自用户的事件是一个很重要的话题。php
首先咱们来认识一下什么是事件?函数
通常来讲,事件是在某些状况下被触发的对象。它们依赖于操做系统,可是 SFML 为咱们提供了一个很好的对象来处理事件,它是独立于操做系统的方式。sf::Event 类,这个类包含了各类事件。学习
建议阅读 SFML 官方文档去好好了解 SFML 事件的类型,地址是https://www.sfml-dev.org/tutorials/2.5/window-events.php。 注意 sf::Event 是一个联合体(union),使用的时候要恰当的选择咱们须要的事件类型。编码
逻辑上,咱们能够将事件分红四种类型:spa
类型 | 相关成员 | 描述 |
---|---|---|
Event::Closed | None | 当操做系统检测单用户想要关闭窗口时触发 |
Event::Resized | Event::size 表示新窗口的大小 | 当操做系统检测单用户想要改变窗口大小时触发,或者调用Window::setSize() |
Event::LostFocus Event::GainedFocus | None | 当窗口失去/获得焦点时触发,失去焦点的窗口不会收到键盘事件 |
类型 | 相关成员 | 描述 |
---|---|---|
Event::KeyPressed Event::KeyReleased | Event::key 表示的事当前按住/松开的按键 | 在获得焦点的窗口中,当一个按钮被按下或者松开的时候触发 |
Event::TextEntered | Event::text 表示的是一个字符的UTF-32 unicode | 任什么时候候一个字符输入的时候触发 |
类型 | 相关成员 | 描述 |
---|---|---|
Event::MouseMoved | Event::mouseMove 表示鼠标新位置 | 当鼠标在窗口内移动时触发 |
Event::MouseButtonPressed Event::MouseButtonReleased | Event::mouseButton 表示的是按下/松开的鼠标按钮以及它的位置 | 当鼠标上的按钮按下/松开的时候触发。目前支持5种类型的按钮:左、中、右、额外的按钮1和按钮2 |
Event::MouseWheelMoved | Event::mouseWheel 表示的是滚轮以及鼠标位置 | 当鼠标上的滚轮滚动时触发 |
类型 | 相关成员 | 描述 |
---|---|---|
Event::JoystickConnected Event::JoystickDisconnected | Event::joystickConnect 表示的是手柄链接/断开链接时的ID | 当手柄链接或者断开链接时触发 |
Event::JoystickButtonPressed Event::JoystickButtonReleased | Event::joystickButton 表示的是手柄上按钮按下的数量以及手柄ID | 当手柄上的按钮按下时触发,SFML为咱们提供了最多8个手柄,每一个手柄32个按钮的支持 |
Event::JoystickMoved | Event::joystickMove 表示的是移动操纵杆的轴,操纵杆轴的位置以及手柄ID | 移动操纵杆的轴时会触发此操做 |
对于窗口事件来讲,咱们一般用 bool Window::pollEvent(sf::Event& event)
函数,若是有事件将要被使用的话,函数会返回 true
, event
参数会对应某个具体事件。==须要注意的是,同一时间下可能会有多个事件须要被处理,所以咱们须要确保捕获到每个事件。==代码以下:操作系统
while (window.isOpen()) {
sf::Event event;
while (window.pollEvent(event)) {
}
// 刷新帧
// 绘制帧
}
复制代码
运行上面这份代码以后,咱们能够作出移动窗口,改变窗口大小或者是最小化窗口这些操做,可是有一个问题,那就是咱们没法关闭窗口。当咱们点击窗口的关闭按钮时,SFML 不会去关闭窗口,这一操做须要咱们去实现。code
经过 Window::pollEvent()
捕获事件以后,咱们能够经过 Event::type
检查事件类型。事件类型是 Event::EventTyp
,它是 Event
类中的一个枚举类型。使用方法以下对象
sf::Event event;
while (window.pollEvent(event)) {
if (event.type == sf::Event::EventType::Closed) {
window.close();
}
}
复制代码
调用 Window::close()
能够关闭窗口。事件
若是咱们想要使用更多的事件,咱们的可使用 switch
语法。以下:unicode
sf::Event event;
while (window.pollEvent(event)) {
switch (event.type) {
case sf::Event::EventType::Closed:
window.close();
break;
case sf::Event::EventType::KeyPressed:
// 改变窗口标题当空格键按下的时候
if (event.key.code == sf::Keyboard::Key::Space)
window.setTitle("Space Pressed");
break;
case sf::Event::EventType::KeyReleased:
// 再次改变窗口标题当空格键松开的时候
if (event.key.code == sf::Keyboard::Key::Space)
window.setTitle("Space Released");
// 当 Esc 键松开的时候关闭窗口
else if (event.key.code == sf::Keyboard::Key::Escape)
window.close();
break;
default:
break;
}
}
复制代码
上面这份代码的意思很容易理解,经过空格键能够改变窗口的标题,松开 Esc 键时关闭窗口。注意到 Event::key
包含了 code
成员,它是 Keyboard::Key
类型中的一个枚举类型。用上面这种方法能够处理其余事件类型。
然而,Event::EventType::TextEntered
的使用有点意思。按键被按下/松开的时候能够被检测到且可使用一种相对简单的方式去处理。可是当键入一些特殊字符的时候,事情变得有点复杂起来。例如,输入 !
号的时候在大多数键盘中是使用 shift+1
的。幸亏 SFML 为咱们提供了一个简单的方式去处理,仅当按下表示字符的组合键时才会发生事件,这意味着按下一个键(例如 shift
)时不会触发事件。
下面这个例子使用了 TextEntered
事件组合了一个字符串,而后按下 Enter
键时这个字符串会显示在窗口标题中。
sf::String buffer;
while (window.isOpen()) {
sf::Event event;
while (window.pollEvent(event)) {
switch (event.type) {
case sf::Event::EventType::Closed:
window.close();
break;
case sf::Event::EventType::TextEntered:
buffer += event.text.unicode;
break;
case sf::Event::EventType::KeyReleased:
if (event.key.code == sf::Keyboard::Key::Return) {
window.setTitle(buffer);
buffer.clear();
}
break;
default:
break;
}
}
}
复制代码
这里使用 sf::String
类型可以避免不一样语言之间的字符编码转换。
这一节简单介绍了 SFML 中的事件处理,下一节将会学习图像以及精灵(sprite)的简单使用。😃