(C++) 在游戏循环中执行一次指令 (SFML)
(C++) Executing an instruction inside a game loop once (SFML)
这个问题的答案是我写到一半的时候想到的,老实说,我觉得我应该完成我开始的工作并记录下来,因为我整天都被这个错误困住了,而且它以后可能会派上用场。
我正在使用 SFML 并且我有很多按钮,我想在鼠标光标悬停在其中一个按钮上时播放 blip 音效...
这是按钮 class 中的方法,用于测试鼠标光标与按钮之间的碰撞:
bool menu_button::button_collision() {
if ((cursor.getPosition().x <= (text_box.getPosition().x)+text_box.getSize().x/2)
&& (cursor.getPosition().x >= (text_box.getPosition().x) - text_box.getSize().x / 2)
&&(cursor.getPosition().y <= (text_box.getPosition().y) + text_box.getSize().y / 2)
&& (cursor.getPosition().y >= (text_box.getPosition().y) - text_box.getSize().y / 2)) {
text.setFillColor(sf::Color(sf::Color::Yellow));
coll = true;
}
else { text.setFillColor(sf::Color(sf::Color::White)); coll = false; }
return coll;
}
这是当光标悬停在按钮上时播放音效的代码:
for (int j = init; j < limit; j++) { //This is a loop that tests every button.
collision = buttons[j].button_collision();// 'collision' is a boolean that stores the value returned by the collision function.
if (collision == true) {
m_hover.play();
}
//Other instructions go here...
}
现在这段代码工作得很好,但由于它在游戏循环中,每帧重复,声音将每秒播放 'x' 次('x' 是每秒帧数)这不是我想要的,所以我将代码修改为如下所示:
for (int j = init; j < limit; j++) {
collision = buttons[j].button_collision();
if (collision == true) {
if (collision2 == false) { // 'collision2' is another boolean, that becomes true AFTER the sound-effect have already played.
m_hover.play();
collision2 = true;
}
}
//Other instructions go here...
}
现在,当光标第一次悬停在按钮上时会播放音效,但只是第一次,然后就完全没有声音了,很明显我们还有另一个问题...
所以我在父条件下添加了这一行(测试collision
的那个):
else { collision2 = false; }
我认为这行得通,但现在我又回到了第一个问题,在光标悬停在按钮上的每一帧中,音效都会不断播放...
经过一番修改后,我开始意识到 collision
每帧都会重置为 false
,这就是音效最终会在每一帧播放的原因,但我不是确定发生这种情况的原因和 where/when,或者如何解决它。
事实证明,collision
每帧重置为 false
的原因是因为我忘记了这整组指令包含在一个 for
循环中,该循环测试每个按钮,因此每个按钮每一帧都会进行碰撞测试,并且每次返回值存储在 collision
中时,这意味着 collision
将其值重置 'y' 次每帧('y' 是当时屏幕上的按钮数量),并且由于所有其他没有光标悬停在其上的按钮的碰撞值将是 false
, 碰撞值每帧重置为 false 是非常有意义的。
现在这个问题的解决方案很清楚了,我所要做的就是用一个布尔值数组替换 collision2
布尔值,这个数组的每个元素对应于其中一个的碰撞值按钮,这意味着这个数组的大小将等于我正在使用的按钮总数...
所以现在代码应该是这样的:
for (int j = init; j < limit; j++) {
collision = buttons[j].button_collision();
if (collision == true) {
if (collision2[j] == false) {// 'collision2' is an array that stores the collision values for each button.
m_hover.play();
collision2[j] = true;
}
}
else { collision2[j] = false; }
//Other instructions go here...
}
现在可以了!我对这整件事感到沮丧,同时也感到宽慰...
这个问题的答案是我写到一半的时候想到的,老实说,我觉得我应该完成我开始的工作并记录下来,因为我整天都被这个错误困住了,而且它以后可能会派上用场。
我正在使用 SFML 并且我有很多按钮,我想在鼠标光标悬停在其中一个按钮上时播放 blip 音效...
这是按钮 class 中的方法,用于测试鼠标光标与按钮之间的碰撞:
bool menu_button::button_collision() {
if ((cursor.getPosition().x <= (text_box.getPosition().x)+text_box.getSize().x/2)
&& (cursor.getPosition().x >= (text_box.getPosition().x) - text_box.getSize().x / 2)
&&(cursor.getPosition().y <= (text_box.getPosition().y) + text_box.getSize().y / 2)
&& (cursor.getPosition().y >= (text_box.getPosition().y) - text_box.getSize().y / 2)) {
text.setFillColor(sf::Color(sf::Color::Yellow));
coll = true;
}
else { text.setFillColor(sf::Color(sf::Color::White)); coll = false; }
return coll;
}
这是当光标悬停在按钮上时播放音效的代码:
for (int j = init; j < limit; j++) { //This is a loop that tests every button.
collision = buttons[j].button_collision();// 'collision' is a boolean that stores the value returned by the collision function.
if (collision == true) {
m_hover.play();
}
//Other instructions go here...
}
现在这段代码工作得很好,但由于它在游戏循环中,每帧重复,声音将每秒播放 'x' 次('x' 是每秒帧数)这不是我想要的,所以我将代码修改为如下所示:
for (int j = init; j < limit; j++) {
collision = buttons[j].button_collision();
if (collision == true) {
if (collision2 == false) { // 'collision2' is another boolean, that becomes true AFTER the sound-effect have already played.
m_hover.play();
collision2 = true;
}
}
//Other instructions go here...
}
现在,当光标第一次悬停在按钮上时会播放音效,但只是第一次,然后就完全没有声音了,很明显我们还有另一个问题...
所以我在父条件下添加了这一行(测试collision
的那个):
else { collision2 = false; }
我认为这行得通,但现在我又回到了第一个问题,在光标悬停在按钮上的每一帧中,音效都会不断播放...
经过一番修改后,我开始意识到 collision
每帧都会重置为 false
,这就是音效最终会在每一帧播放的原因,但我不是确定发生这种情况的原因和 where/when,或者如何解决它。
事实证明,collision
每帧重置为 false
的原因是因为我忘记了这整组指令包含在一个 for
循环中,该循环测试每个按钮,因此每个按钮每一帧都会进行碰撞测试,并且每次返回值存储在 collision
中时,这意味着 collision
将其值重置 'y' 次每帧('y' 是当时屏幕上的按钮数量),并且由于所有其他没有光标悬停在其上的按钮的碰撞值将是 false
, 碰撞值每帧重置为 false 是非常有意义的。
现在这个问题的解决方案很清楚了,我所要做的就是用一个布尔值数组替换 collision2
布尔值,这个数组的每个元素对应于其中一个的碰撞值按钮,这意味着这个数组的大小将等于我正在使用的按钮总数...
所以现在代码应该是这样的:
for (int j = init; j < limit; j++) {
collision = buttons[j].button_collision();
if (collision == true) {
if (collision2[j] == false) {// 'collision2' is an array that stores the collision values for each button.
m_hover.play();
collision2[j] = true;
}
}
else { collision2[j] = false; }
//Other instructions go here...
}
现在可以了!我对这整件事感到沮丧,同时也感到宽慰...