【发布时间】:2019-09-05 09:56:24
【问题描述】:
我有 2 个类,一个完全是菜单设置和渲染,另一个是在 main() 中调用的主游戏类。我制作了一种获取用户鼠标位置的方法,如果它位于其中一个菜单文本上,它将“选择”菜单项并播放声音。现在的问题是,除非您将鼠标悬停在任何文本上,否则声音不会播放一次而是不断重复。
我尝试过使用我在网上找到的另一个人的时钟,但它似乎并不能完全按照预期的方式工作,因为我有他分成 2 个类的东西,而不是全部都在 1 个类中地点。
这就是我说的解决方案:https://en.sfml-dev.org/forums/index.php?topic=15297.0
这是在主类中运行程序的代码,在 main.cpp 中的 main() 中调用。
void Terraria::Run()
{
Menu Menu(mTerraria, mTerraria.getSize().x, mTerraria.getSize().y);
Menu.mMainTheme.play();
while (mTerraria.isOpen())
{
sf::Event event;
Menu.GetMousePosition(mTerraria);
while (mTerraria.pollEvent(event))
{
switch (event.type)
{
case sf::Event::MouseButtonReleased:
{
switch (event.key.code)
{
case sf::Mouse::Left:
switch (Menu.GetPressedItem())
{
case 0:
{
break;
}
case 1:
{
break;
}
case 2:
{
break;
}
case 3:
{
break;
}
case 4:
{
Menu.mMenuOpen.play();
mTerraria.close();
break;
}
}
}
}
default:
HandlePlayerInput(event.key.code);
break;
case sf::Event::Closed:
{
mTerraria.close();
}
}
mTerraria.clear();
Menu.Render(mTerraria);
mTerraria.display();
}
}
}
这是它在 while 循环的第 10 行调用的函数。它在名为 Menu 的第二个类中。
void Menu::GetMousePosition(sf::RenderWindow& mTerraria)
{
UnSelect();
if (mMenu[0].getGlobalBounds().contains(sf::Mouse::getPosition(mTerraria).x, sf::Mouse::getPosition(mTerraria).y))
{
Select(mMenu[0]);
OnSP = true;
OnMP = false;
OnAchievements = false;
OnOptions = false;
OnExit = false;
SelectedItemIndex = 0;
}
else if (mMenu[1].getGlobalBounds().contains(sf::Mouse::getPosition(mTerraria).x, sf::Mouse::getPosition(mTerraria).y))
{
Select(mMenu[1]);
OnSP = false;
OnMP = true;
OnAchievements = false;
OnOptions = false;
OnExit = false;
SelectedItemIndex = 1;
}
else if (mMenu[2].getGlobalBounds().contains(sf::Mouse::getPosition(mTerraria).x, sf::Mouse::getPosition(mTerraria).y))
{
Select(mMenu[2]);
OnSP = false;
OnMP = false;
OnAchievements = true;
OnOptions = false;
OnExit = false;
SelectedItemIndex = 2;
}
else if (mMenu[3].getGlobalBounds().contains(sf::Mouse::getPosition(mTerraria).x, sf::Mouse::getPosition(mTerraria).y))
{
Select(mMenu[3]);
OnSP = false;
OnMP = false;
OnAchievements = false;
OnOptions = true;
OnExit = false;
SelectedItemIndex = 3;
}
else if (mMenu[4].getGlobalBounds().contains(sf::Mouse::getPosition(mTerraria).x, sf::Mouse::getPosition(mTerraria).y))
{
Select(mMenu[4]);
OnSP = false;
OnMP = false;
OnAchievements = false;
OnOptions = false;
OnExit = true;
SelectedItemIndex = 4;
}
else
{
OnSP = false;
OnMP = false;
OnAchievements = false;
OnOptions = false;
OnExit = false;
}
}
这是每次鼠标悬停在任何文本上时调用的 Select() 函数。再次在 Menu 类中。
void Menu::Select(sf::Text &mMenu)
{
mMenu.setColor(sf::Color::Yellow);
mMenu.setScale(sf::Vector2f(1.1f, 1.1f));
mMenuTick.play();
}
当您将鼠标悬停在任何文本上时,我只需要播放一次声音,然后在您将鼠标悬停并悬停到下一个文本或悬停在下一个文本上之前不会播放。我知道由于 while 循环,它被调用了数百万次。
【问题讨论】:
-
使用one-shot-if :) 不是真的:您需要为相关的 ui 小部件实现(鼠标)on_enter 和 on_exit 方法
-
您可能还想考虑为您的游戏命名,而不是 terraria,该名称的游戏已经存在。
-
我知道它已经存在,我正在尝试用 c++ 重新创建整个游戏,以便以 64 位编译它。不用担心我不会分发它,它只是一个学习项目。
-
尝试使用 C++ 实现 mod 支持会很麻烦。我还认为 Terraria 长期支持 x64 位 <.>
-
唯一的 64 位启动器是与原来的 64 位 tmodloader 分开的 tmodloader (forums.terraria.org/index.php?threads/…)。原始的 tmodloader 和游戏本身都是 32 位的,除非你在 linux 或 mac 上玩,不记得哪个版本只有 64 位。