开发针对游戏的图形用户界面(GUI)

3

我已经想要在C++和DirectX 9中创建自己的GUI库一段时间了。我看到了很多关于GUI的问题,但是我想要一个适用于游戏的GUI。大多数库非常复杂并且过于通用,它们提供了命令行解析和窗口创建等支持。这些库不适合我的需求,所以我想写自己的库。唯一的问题是我不知道从哪里开始。

我不知道如何建立库的框架/基础。我不知道如何使GUI元素/对象彼此通信以及如何处理事件。我也不知道如何管理GUI的图形。例如,我应该让程序员完全负责GUI的外观,还是创建默认设计?然后我存储一个单独的文件来设计按钮、文本框、标签、组合框等吗?

我还想指出,我计划只在全屏模式下使用我的GUI,并且我只想支持基本元素,如按钮、文本框、静态标签等。我希望能够使用该库创建HUD。我知道我问了很多问题,但我从未尝试过创建如此复杂的东西。


你想创建一个GUI或者像DirectX和OpenGL那样的图形库来构建游戏而不是GUI吗?如果是后者,我认为你不能这样做,除非你使用基于DirectX的XNA,它对特定的游戏有很好的支持,最适合使用C#,但也可以在.net框架中通用。 - Tamer Shlash
4个回答

5
如果你对这些完全没有头绪,我建议你不要从头开始编写自己的GUI。(实际上我确实从头编写了自己的游戏GUI,但我有点后悔——最终得到的结果有些不成熟,我相信有更好的选择。) 但我理解你的意思:你不想使用标准GUI工具包,因为那样不会“感觉”像一个游戏。好消息是,已经有专门为游戏设计的现有GUI工具包了。最受欢迎的一个似乎是CEGUI(Crazy Eddie's GUI System)。正如你可以从他们的网站看到的那样,它看起来非常可定制,并且一点也不像Windows应用程序。我没有使用过它,但在你设计自己的GUI之前,我建议你先研究一下它。

CeGUI的第二个优点是它有很多工具可以自定义UI的视觉表现,这是赋予游戏独特视觉风格最重要的部分。 - Nicol Bolas
1
同意这个观点。有很多其他的游戏GUI库,我也建议不要自己编写。其他例子包括libRocket(http://librocket.com/)和Awesomium(http://awesomium.com/)。除非你有大量时间并且出于“教育目的”,否则没有必要重新发明轮子 :) - LiMuBei
好的,谢谢。我会看一下CEGUI。我想自己编写库没有意义了。 - Zayats

3
我尊重其他人在这里表达的意见。(背景:我在大学学习计算机科学,并且已经编程30年了。)你可以编写自己的GUI系统,如果你知道你在做什么,你可以在不到两周的时间内完成。即使是编程方面的初学者也能够做到。我认为“如何编写GUI系统”是失传的知识,导致了一种认为编写GUI系统需要多年时间的观念。
我建议(我认识到这是少数派的报告)在您的努力中遵循以下策略要点:
  • 忘记设计模式、架构、总线通信系统、可扩展性等等。 对于这样一个简单的问题,你绝对不需要它们。 如果你追求这些东西,你的头脑将陷入你甚至没有的问题中。 不要做任何面向对象的事情。 对于你正在做的事情来说,完全是错误的。
  • 走极简主义;在这里,你真的不能太极端了。 避免任何不绝对必要的抽象。考虑你设计中的每一根电线,思考“什么需要与什么交流”的绝对最小值。 你真的需要一个总线系统吗? 还是可以添加一个执行通知的单条线路? 想想看,你能否使得完全不需要通知?从另一个角度来看:你真的需要为你的游戏创建可点击和拖动的窗口吗?等等。 十有八九,“你不需要它”,还有另外一种更简单的方法来实现它。找到这些更简单的方法就像找到GUI设计的秘籍。
  • 从最终用户界面出发思考。在纸上设计你的GUI系统需要支持的最终用户界面。看看你说的话:“只有全屏模式,按钮,文本框,静态标签等。...一个带有库的HUD。” 这非常简单。 你完全可以以低成本实现这一点,并且你会更加快乐,因为你将拥有完美的控制。
  • 使用数据。让数据告诉你用户界面的外观和工作方式。你能否在代码中用可打印的ASCII字符绘制窗口和布局,并从中呈现?
  • 控制API到绘图系统(即DirectX)的符号表示法。使用“ESC”来表示退出键的键码,“SPC”来表示空格键。使用你的包装器使API方便。将它映射到你正在做的基本操作:flip(),line(x,y,x2,y2),color(BLACK)等。
  • 使用位图并使其易于在API中访问。 stamp(iconid,x,y)是你想要使其变得非常简单的方式,以在某个位置绘制图标。请注意,这不是:window.stamp(icon.imgdata,translated_coordinate(cursorpos))。
  • 注意你的输入轮询和绘制翻转系统。那是你引擎的核心。如果你有交互模式,那也是核心。
  • 考虑使用元/信息平面来表示位置和坐标以及点击穿透。你可以使用网格来表示布局,从而大大简化GUI处理。当用户点击空间时,信息平面可以有关于被点击内容的信息。

我仅使用500行Python(使用pysdl2)编写了非常复杂的GUI环境。这包括我的包装器。我还用C++编写过GUI系统 - 需要更多的代码行,但真的不需要太多。

我强烈推荐你为自己的工作编写自己的GUI系统。虽然这需要你跳出当今主流编程思维模式的“盒子”,但你可以获得非常自由的控制水平,不仅在游戏开发中,在所有需要与用户交互的编程领域中也是如此。

如果你想跳出主流思维模式,考虑阅读Alan Kay、Chuck Moore或其他年长的程序员的著作。他们并没有被感染上这种观念:“你必须使用其他人在你之前写过的东西,因为其他人比你更明智,知道你需要什么,并且知道如何制作,如果你沿着他们的路走下去,你只会重蹈覆辙。”他们对“有效”的理解与当代的理解非常不同。我鼓励你进行探索。


3
编写自己的GUI是一个很好的教育任务,因为您很快就必须学习用于使其可扩展的设计模式。如果您有兴趣,GoF book使用GUI作为许多模式的示例。
然而,要正确地完成这项任务需要大量(非常多-我指的是几年时间)的工作。
然而,可能会引起您兴趣的一个项目是cIMG库。这是一个图像处理库,而不是GUI库。它不支持按钮或类似的东西,但它确实进行了相当低级别的绘图,这可能更接近您的最终目标(它没有将其成像外包给GUI /图形库)。它还是一个仅有头文件的库,所有代码都在单个头文件中,因此相当容易查看。

你有没有其他关于设计模式的好书? - Tamer Shlash
@Mr.TAMER:我使用的是GoF书籍,但你可能会对http://stackoverflow.com/questions/105049/what-are-the-best-design-patterns-books-you-have-read感兴趣。 - Tom
1
@Mr.TAMER,由于我们正在讨论C++,因此重要的是要记住可以使用模板来代替一些“面向对象”的模式,例如模板表达式(boost proto库)以满足解释器模式的需求。 - Tom

2
这个问题已经有很多成熟的解决方案,例如针对自定义游戏的Scaleform和集成gui API的游戏引擎,如Unity,更不用说那些经验丰富的开发人员所留下的各种经验之谈了: http://www.google.com/search?q=game+gui+library 考虑到你承认自己缺乏经验,同时你提出的建议也有些重复,我认为你最好选择一些更小而实用的东西来练手。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接