存储布尔值以确定是否持有某个键的常见做法是什么?

问题描述 投票:0回答:1

我是 OpenGL 新手,使用 GLFW 进行输入。我最近一直在开发一个简单的程序,通过单击鼠标左键来创建形状。如果按住鼠标左键,形状将跟随鼠标移动,直到释放鼠标左键。我目前有一个全局布尔变量,用于跟踪何时按住或释放密钥。鼠标单击回调分别将布尔值从 true 更改为 false。我知道使用全局变量是不好的做法,因此,更好的方法是什么?我读过,通常使用单独的缓冲区对象来跟踪这一点,但我想使用哪种缓冲区?还是有我不知道的更好的方法来解决这个问题?

// Globals
// -------
bool keyHeld = false;

int main() {


   while (!glfwWindowShouldClose(window)) {
      if (keyHeld) {
      
         // Get screen coordinates
         // Get Cursor Position
         // Convert position to clip. coords. 
         // Create transformation matrix

      }
   }
      // Send matrix to uniform in shader
      // Render shape

   return 0;
}

void mouse_callback(GLFWwindow* window, int button, int action, int mods) {

   if (button == GLFW_MOUSE_BUTTON_LEFT && action == GLFW_PRESS) 
      keyHeld = true;

   if (button == GLFW_MOUSE_BUTTON_LEFT && action == GLFW_RELEASE)
      keyHeld = false;

}
c++ opengl graphics glfw
1个回答
0
投票
组织状态(例如按键和鼠标按钮的输入状态)的一个好方法是将它们放入一个公共命名空间中,在其中存储每个输入的布尔值。该命名空间应该有一个输入函数,用于访问输入 API(在本例中为 GLFW),并更新每个按键和按钮的状态。然后,您可以通过返回特定输入状态的函数来允许访问按钮。

以下是此输入命名空间的示例:

namespace Input { bool _mouseDown = false; void Update(GLFWwindow *window) { int state = glfwGetMouseButton(window, GLFW_MOUSE_BUTTON_LEFT); if(state == GLFW_PRESS) { _mouseDown = true; } else if(state == GLFW_RELEASE) { _mouseDown = false; } } bool MouseDown() { return _mouseDown; } }
获取鼠标按钮状态的确切示例位于回调示例下方的 glfw api 文档中:

GLFW 鼠标按钮输入

这也可以针对按键输入完成,并且在回调示例下方也可以找到访问 glfw 状态的类似方法:

GLFW 按键输入

您还必须确保让 glfw 更新其输入值。为此,您必须添加 glfwPollEvents();在更新输入命名空间之前进入主循环。

有关输入事件处理的更多文档请查看

此处

那么你的主要功能将如下所示:

int main() { while (!glfwWindowShouldClose(window)) { glfwPollEvents(); // makes GLFW check for changes in input state Input::Update(window); // updates our input booleans stored in our Input namespace if (Input::MouseDown()) { // returns current state of left mouse button // Get screen coordinates // Get Cursor Position // Convert position to clip. coords. // Create transformation matrix } } // Send matrix to uniform in shader // Render shape return 0; }
还要确保,如果将此输入命名空间存储在头文件中,则将其包含在渲染循环文件的顶部。

这种抽象方式的好处是:

  1. 可读性:使用 MouseDown() 的函数名称,或者任何你想调用的名称,其他人甚至你自己都可以轻松地知道代码中发生了什么。

  2. 面向未来:如果您更改底层输入 API,您所要做的就是更改输入命名空间中的函数,而不必遍历并找到检查鼠标输入的每个位置。因此您只需更改一处代码即可。

如果您想要额外的安全性,您可以将此名称空间放入一个类中并将成员变量保留为私有,这样它们就不会被意外访问。

这是我在 Stack Overflow 上的第一个回答,所以我希望我做得不错!

© www.soinside.com 2019 - 2024. All rights reserved.