文章原文:https://github.com/okamstudio/godot/wiki/tutorial_gui
Introduction
展示给用户的图形界面的开发令程序员头大,图形界面是用来与用户进行交互的,这样的界面开发起来是枯燥的,乏味和没有挑战性的。更糟糕的是这几个方面:
- UI元素的对齐是困难的在不同分辨率的屏幕下
- 在测试阶段需因为设计和可用性的问题需要不断修改界面
- 需要适配不同分辨率的屏幕
- 动画也会受一些屏幕组件的影响
GUI编程会令程序员感觉不爽,在godot开发期间,一些技术性的和概念性的东西被加入到了用户界面的开发中,例如 immediate mode ,容器,锚点,脚本,等等。之所以这样做,就是为了减少程序员在拼接用户界面的工作量。
godot的UI子系统是一个高效的解决上述问题的方案,是融合了几种不同的解决方案之后的产物,学习难度要高于对godot其他工具的学习,开发人员可以在很短的时间内整合复杂的用户界面,通过在设计师和动画师之间分享相同的工具集。
Control
在godot的UI元素中最基本的node是Control(在其他的工具集中被称为"Widget" or "Box"),每一个节点都自带用户界面的函数,当Control节点作为其他Control的子节点放入到scene tree中,则放入的Control的坐标(position, size)一直相对于父节点的,这使godot能够快速而直观的编辑复杂用户界面。
Input and Drawing
Control 通过_input_event()回调函数来接收事件输入,如果Control获得焦点,使用grab_focus()函数来接收事件输入,鼠标运动事件直接被鼠标选中的control接收。当一个control接收了鼠标按键按下的事件,随后所有的运动事件,都被这个control接收直到松开按下的鼠标,即使鼠标在control的边界外的运动也会被这个control接收。
就像继承了CanvasItem的类那样(Control已经继承了),从开始起每一次control的重新绘制事件都会被_draw()回调函数接收(程序员需要调用update()函数将每一次重绘事件加入到CanvasItem的重绘事件的队列中)。如果control节点是不可见的(这是canvasitem类的另一个属性),那么这个control节点不会接收任何输入。
通常,使用godot的程序员在构建游戏界面时不需要关注绘图处理和事件输入的细节。而是专注于,动作发生时control发出的各种不同的信息信号。例如,一个按钮被按下时发出一个"pressed"信号,一个滑块被拖动时会发出一个"value_changed"信号,等等。
Custom Control Mini Tutorial
在继续深入之前,通过在godot中创建一个控件来实践下,是理解控件工作流程的好方法,因为它们不像理论那样枯燥。此外,虽然godot中有许多功能各异的控件,创建一个空的control然后将这个空的control设置为具有特定功能的control,会更有助于帮助理解control的工作方式。
那么开始吧,创建一个只有一个control节点的场景,如图:
接下来给这个control添加脚本,代码如下:
extends Control
var tapped=false
func _draw():
var r = Rect2( Vector2(), get_size() )
if (tapped):
draw_rect(r, Color(1,0,0) )
else:
draw_rect(r, Color(0,0,1) )
func _input_event(ev):
if (ev.type==InputEvent.MOUSE_BUTTON and ev.pressed):
tapped=true
update()
然后运行,如果蓝色矩形被点击,就会将事件信号发送给 _input_event()回调函数,然后确定事件的信号后,update()函数将重绘事件
添加到重绘事件的队列中,_draw()回调函数来处理队列中的重绘事件,最终矩形会被重绘为红色,如图:
UI Complexity(复杂的用户界面)
如前所述,godot中包含了数十种control(控件),用来组建用户界面,这些控件分为2类,第一种是一个控件小集合,用来拼接游戏中的大部分用户界面,第二类(大部分control属于这一类)用来组建复杂用户界面和界面皮肤的。下面的描述将有助于理解这2种类型的使用场合。
Simplified UI Controls(简单界面控件)
这个控件集合足以满足大部分游戏,它们可以很容易的成为带有纹理皮肤的控件。
- Lable:用来显示文本信息。
- TextureFrame:显示一个单一的纹理,可缩放也可固定。
- TextureButton:显示一个简单的带纹理的按钮,可以设置pressed,hover,disabled等状态。
- TextureProgress:显示一个带单一纹理的进度条。
此外,控件可以用锚点重新定位。
在任何情况下,即使是简单的游戏,也会有复杂的界面交互。例如一个滚动的高分排行的列表,需要一个ScrollContainer控件和一个VBOXContainer控件。这些高级控件可以无缝的和普通控件一起构建需要的界面。
Complex UI Controls
其余的控件,最常见的使用场合:
- 满足构建复杂界面的需求
- 创建自定义的开发工具加快内容的创建
- 创建godot编辑器插件,扩展引擎的功能函数
通常使用containers重定位类控件。