Monogame/XNA 中的下拉菜单
Dropdown Menu in Monogame/XNA
我正在开发一款游戏并开发主菜单,其中有一个设置场景。这个场景包含几个选项卡,对于视频选项卡,我想要一个允许切换分辨率的下拉菜单。现在,我理解后一部分的逻辑,但是使用 XNA 框架我无法理解下拉菜单的逻辑。感谢您的帮助:)
我建议使用现有的 UI 库。而不是尝试从头开始实施高级 UI 系统。
不错UI图书馆:Empty Keys
我实际上为我的游戏制作了一个 DropDown,当你考虑它时,它真的没有那么难。首先,您需要一个 DropDownContainer
class 和一个 DropDownElement
。 DropDownContainer
是 DropDown 的顶部,您可以在其中看到当前选定的选项。 DropDownElement
是用户单击 DropDownContainer
时显示的可选选项。
代码的工作原理如下:
- 在您的
DropDownContainer
class 中创建一个 DropDownElement
数组。
- 在
DropDownContainer
的构造函数中,传递DropDownElement
的数量和一个字符串数组,其中每个字符串是特定DropDownElement
的文本。
- 使
DropDownElement
的构造函数接受一个字符串,并在其 Draw(spriteBatch)
方法中将该字符串绘制在 DropDownElement
的纹理上。
传入一个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
}
- 确保在两个 classes 的构造函数中都传入了
ContentManager content
,以便加载资源。
- 对这两个 class 都有一个边界
Rectangle
,其中 X
和 Y
是 (int)containerPosition.X, (int)containerPosition.Y
和 Width
并且Height
是 Texture2D
的维度。
- 在
DropDownContainer
的 Update(gameTime)
方法中,检查光标是否在 bounds
内,如果用户单击,则像这样更改标志:clicked = !clicked;
- 在
DropDownContainer
的Draw(spriteBatch)
方法中,选中if (clicked)
并通过循环绘制elements
数组。
- 像这样实例化 DropDown:
private DropDownContainer dropDown = new DropDownContainer(...);
并调用它的相应方法。
- 要检查选择了哪个选项,只需公开
DropDownElement
的 Text
属性。
- 完成后,您可以使用线性插值添加鼠标悬停效果和文本颜色淡化等内容in/out。
我还为我的 XNA 游戏制作了一个文本框,但它处理了一些繁重的事情 P/Invokes,并且由于您不知道如何制作基本的下拉菜单,所以解释起来太复杂了。
编辑以解决以下评论:
你的逻辑有一些问题,我会强调它们:
- 如果没有
string
属性 即 gets/sets 元素的文本,您将如何检查选择了哪个元素?例如。 if (container.Text == "text of first element") { /* user chose the lowest resolution */ }
- 除非您将文本传递给构造函数,否则无法设置
Element
的文本,如果没有 Text
属性.
- 如何将值
1600x900
直接添加到 enum
?除非我误解了你,否则你无法将 string
(1600x900 是一个字符串)放入 enum
...
即使你要这样做:
enum resOptions
{
_800x600 = 0,
_1280x1024 = 1,
_1920x1080 = 2,
// etc.
}
也许让它们在 DropDownElement
数组中以相同的方式排序,但是,您仍然必须实现自己的方式来查看用户点击了哪个选项...这最终会引导您检查 DropDownContainer
.
的 Text
属性
所以我强烈建议不要在这里使用 enum
,因为它只会使已经足够复杂的 DropDown 算法过于复杂。编写一种检查选择了哪个选项的方法将花费您更多时间。
我会在用户点击时将 Container
的 Text
设置为点击的 Element
的 Text
,这就是我检查所选选项的方式。如果你仍然愿意用 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回到上一级菜单。
我正在开发一款游戏并开发主菜单,其中有一个设置场景。这个场景包含几个选项卡,对于视频选项卡,我想要一个允许切换分辨率的下拉菜单。现在,我理解后一部分的逻辑,但是使用 XNA 框架我无法理解下拉菜单的逻辑。感谢您的帮助:)
我建议使用现有的 UI 库。而不是尝试从头开始实施高级 UI 系统。
不错UI图书馆:Empty Keys
我实际上为我的游戏制作了一个 DropDown,当你考虑它时,它真的没有那么难。首先,您需要一个 DropDownContainer
class 和一个 DropDownElement
。 DropDownContainer
是 DropDown 的顶部,您可以在其中看到当前选定的选项。 DropDownElement
是用户单击 DropDownContainer
时显示的可选选项。
代码的工作原理如下:
- 在您的
DropDownContainer
class 中创建一个DropDownElement
数组。 - 在
DropDownContainer
的构造函数中,传递DropDownElement
的数量和一个字符串数组,其中每个字符串是特定DropDownElement
的文本。 - 使
DropDownElement
的构造函数接受一个字符串,并在其Draw(spriteBatch)
方法中将该字符串绘制在DropDownElement
的纹理上。 传入一个
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 }
- 确保在两个 classes 的构造函数中都传入了
ContentManager content
,以便加载资源。 - 对这两个 class 都有一个边界
Rectangle
,其中X
和Y
是(int)containerPosition.X, (int)containerPosition.Y
和Width
并且Height
是Texture2D
的维度。 - 在
DropDownContainer
的Update(gameTime)
方法中,检查光标是否在bounds
内,如果用户单击,则像这样更改标志:clicked = !clicked;
- 在
DropDownContainer
的Draw(spriteBatch)
方法中,选中if (clicked)
并通过循环绘制elements
数组。 - 像这样实例化 DropDown:
private DropDownContainer dropDown = new DropDownContainer(...);
并调用它的相应方法。 - 要检查选择了哪个选项,只需公开
DropDownElement
的Text
属性。 - 完成后,您可以使用线性插值添加鼠标悬停效果和文本颜色淡化等内容in/out。
我还为我的 XNA 游戏制作了一个文本框,但它处理了一些繁重的事情 P/Invokes,并且由于您不知道如何制作基本的下拉菜单,所以解释起来太复杂了。
编辑以解决以下评论:
你的逻辑有一些问题,我会强调它们:
- 如果没有
string
属性 即 gets/sets 元素的文本,您将如何检查选择了哪个元素?例如。if (container.Text == "text of first element") { /* user chose the lowest resolution */ }
- 除非您将文本传递给构造函数,否则无法设置
Element
的文本,如果没有Text
属性. - 如何将值
1600x900
直接添加到enum
?除非我误解了你,否则你无法将string
(1600x900 是一个字符串)放入enum
...
即使你要这样做:
enum resOptions
{
_800x600 = 0,
_1280x1024 = 1,
_1920x1080 = 2,
// etc.
}
也许让它们在 DropDownElement
数组中以相同的方式排序,但是,您仍然必须实现自己的方式来查看用户点击了哪个选项...这最终会引导您检查 DropDownContainer
.
Text
属性
所以我强烈建议不要在这里使用 enum
,因为它只会使已经足够复杂的 DropDown 算法过于复杂。编写一种检查选择了哪个选项的方法将花费您更多时间。
我会在用户点击时将 Container
的 Text
设置为点击的 Element
的 Text
,这就是我检查所选选项的方式。如果你仍然愿意用 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回到上一级菜单。