我正在尝试做一个小游戏,在我的游戏中我有一些方 block ,当用户点击这些方 block 时,它们会突出显示。为实现此效果,我将 glutMouseFunc
与 glutTimerFunc
结合使用。
当用户点击屏幕时,我选择像素并确定我需要突出显示的正方形。确定正方形后,我调用 glutTimerFunc
。 glutTimerFunc
注册的函数将颜色的每个分量的值增加 0.01,直到它们达到我定义的一个最大值,然后这个值回到最小值。
glutTimerFunc
在 60 毫秒内执行,我得到了几乎平滑的发光效果。
我的问题是,如果我快速点击两个方 block ,效果会从第一个方 block 开始,但不会结束,所以方 block 仍然突出显示,第二个方 block 完成整个效果。如果我疯狂地点击每个方 block ,所有方 block 都会突出显示。
即使我点击其他方 block ,如何使这种发光效果终止?
这是一段代码
void Memoria::shineEffect(GLint value) {
if(value == 1) {
for(GLint i = 0; i < 3; i++) {
if(colors[selectedSquare][i] > 0) {
colors[selectedSquare][i] += COLOR_INCREASE;
if(colors[selectedSquare][i] >= MAX) {
colors[selectedSquare][i] = MAX;
value = -1;
}
}
}
glutTimerFunc(FPS, timeWrapper, value);
}
else {
if(value == -1) {
for(GLint i = 0; i < 3; i++) {
if(colors[selectedSquare][i] > 0) {
colors[selectedSquare][i] -= COLOR_INCREASE;
if(colors[selectedSquare][i] <= MIN) {
value = 0;
colors[selectedSquare][i] = MIN;
}
}
}
glutTimerFunc(FPS, timeWrapper, value);
}
}
}
timeWrapper
如果传入参数的值为 1 或 -1,则调用 shineEffect
。
最佳答案
您希望 shineEffect
函数至少经过一个高亮循环,然后在高亮项发生变化时停止。它更像是一个 UI 代码设计问题,而不是 OpenGL 或 GLUT 问题。
您需要实现的机制非常简单:
- 使用
glutTimerFunc
一次性安装一个updateHighlights
函数:这个函数将负责更新所有点击元素的高亮显示, - 创建一个元素队列:每次点击一个元素时,将其添加到队列中,
updateHighLights
函数执行的任务应该如下所示:
- 如果队列包含一个元素,就像您在程序中所做的那样,继续循环其突出显示
- 如果队列包含多个元素,对于队列中的每个元素,
- 步入亮点循环
- 如果循环结束,且该元素不是最后一个,则将该元素从队列中移除
这是解决您的问题的另一种可能更灵活的方法。
Glut 事件循环机制的设计非常简单:只有一个钩子(Hook)可以放置您的“空闲工作”代码,因此在其中安装一个调用其他函数列表的函数可能更灵活。然后可以使用 set 原语修改该列表,以安装或删除要在空闲时间执行的特定任务。这可能比 GLUT 的“单一功能”方法灵活得多。
例如,您可以将当前的高亮显示代码隔离在一个函数中,该函数包含一个包含要高亮显示的元素的结构,并在其元素通过高亮循环完成并且不再处于事件状态时让该函数将其自身从列表中删除。
由于您使用的是 C++,因此将所有这些功能捆绑在类中应该很容易:
- 空闲任务列表的一个类
- 一个用于空闲任务的基类
- 一个派生的空闲任务类,用于突出显示一个方 block (带有方 block 和事件状态的字段)
- 一个类来跟踪事件方 block ,以便它可以很容易地停用并由新的事件方 block 替换。这将由
glutMouseFunc
函数访问。
关于c++ - 将 glutTimerFunc 与 glutMouseFunc 一起使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13920095/