Monogame/XNA 中的下拉菜单

Dropdown Menu in Monogame/XNA

我正在开发一款游戏并开发主菜单,其中有一个设置场景。这个场景包含几个选项卡,对于视频选项卡,我想要一个允许切换分辨率的下拉菜单。现在,我理解后一部分的逻辑,但是使用 XNA 框架我无法理解下拉菜单的逻辑。感谢您的帮助:)

我建议使用现有的 UI 库。而不是尝试从头开始实施高级 UI 系统。

不错UI图书馆:Empty Keys

我实际上为我的游戏制作了一个 DropDown,当你考虑它时,它真的没有那么难。首先,您需要一个 DropDownContainer class 和一个 DropDownElementDropDownContainer 是 DropDown 的顶部,您可以在其中看到当前选定的选项。 DropDownElement 是用户单击 DropDownContainer 时显示的可选选项。

代码的工作原理如下:

  1. 在您的 DropDownContainer class 中创建一个 DropDownElement 数组。
  2. DropDownContainer的构造函数中,传递DropDownElement的数量和一个字符串数组,其中每个字符串是特定DropDownElement的文本。
  3. 使 DropDownElement 的构造函数接受一个字符串,并在其 Draw(spriteBatch) 方法中将该字符串绘制在 DropDownElement 的纹理上。
  4. 传入一个Vector2作为容器的位置,它也将用作定位元素的基础。 DropDownContainer 的构造函数中的示例循环:

    for (int i = 0; i < elements.Count; i++)
    {
        elements[i] = new DropDownElement(spriteFont, textArray[i], new Vector2(containerPosition.X, (containerPosition.Y + (34 * (i + 1))) + 2), this.textColor, content); // 34 = DropDownElement's Texture height
    }
    
  5. 确保在两个 classes 的构造函数中都传入了 ContentManager content,以便加载资源。
  6. 对这两个 class 都有一个边界 Rectangle,其中 XY(int)containerPosition.X, (int)containerPosition.YWidth 并且HeightTexture2D 的维度。
  7. DropDownContainerUpdate(gameTime) 方法中,检查光标是否在 bounds 内,如果用户单击,则像这样更改标志:clicked = !clicked;
  8. DropDownContainerDraw(spriteBatch)方法中,选中if (clicked)并通过循环绘制elements数组。
  9. 像这样实例化 DropDown:private DropDownContainer dropDown = new DropDownContainer(...); 并调用它的相应方法。
  10. 要检查选择了哪个选项,只需公开 DropDownElementText 属性。
  11. 完成后,您可以使用线性插值添加鼠标悬停效果和文本颜色淡化等内容in/out。

我还为我的 XNA 游戏制作了一个文本框,但它处理了一些繁重的事情 P/Invokes,并且由于您不知道如何制作基本的下拉菜单,所以解释起来太复杂了。

编辑以解决以下评论:

你的逻辑有一些问题,我会强调它们:

  1. 如果没有 string 属性 即 gets/sets 元素的文本,您将如何检查选择了哪个元素?例如。 if (container.Text == "text of first element") { /* user chose the lowest resolution */ }
  2. 除非您将文本传递给构造函数,否则无法设置 Element 的文本,如果没有 Text 属性.
  3. 如何将值 1600x900 直接添加到 enum?除非我误解了你,否则你无法将 string (1600x900 是一个字符串)放入 enum...

即使你要这样做:

enum resOptions
{
    _800x600 = 0,
    _1280x1024 = 1,
    _1920x1080 = 2,
    // etc.
}

也许让它们在 DropDownElement 数组中以相同的方式排序,但是,您仍然必须实现自己的方式来查看用户点击了哪个选项...这最终会引导您检查 DropDownContainer.

Text 属性

所以我强烈建议不要在这里使用 enum,因为它只会使已经足够复杂的 DropDown 算法过于复杂。编写一种检查选择了哪个选项的方法将花费您更多时间。

我会在用户点击时将 ContainerText 设置为点击的 ElementText,这就是我检查所选选项的方式。如果你仍然愿意用 enum 来做这件事,我恐怕帮不上什么忙,因为我已经给了你一个简单方法的提示。如果您想以其他方式进行,则必须自己编写代码。毕竟这个网站的想法不是 "Write my code for me" 而是 "Give me a good idea how to properly write it myself".

当你可以用更少的努力和更少的代码来完成时,过于复杂的事情是糟糕的编程习惯。仅当您计划扩展 DropDown 的功能时,将其复杂化才是好的。但在你的情况下,老实说,我没有看到像这样设置 Text 的意义。为什么您会放弃简单而有效的解决方案并追求您不确定的事情?

如果您还有其他问题,请随时发表评论。

我不会将此作为下拉菜单。

这是一个非常 mouse/keyboard 中心的 ui 元素。考虑如果使用控制器,用户将如何与之交互。

即使您不打算使用控制器玩这款游戏,您也可能会发现避免复杂的 ui 元素(例如下拉菜单)可以让您更轻松地继续制作原型而不是分心通过 UI。

建议的解决方案: 选择代表 "change resolution from NxM" 的菜单项后,用新的子菜单替换或覆盖当前菜单,以便从垂直列表中选择特定的分辨率。关闭时,return回到上一级菜单。