UI系统:用Control节点制作游戏菜单(适配鸿蒙折叠屏)
本文通过“创建菜单场景→绑定按钮事件→适配折叠屏”三个步骤,带你掌握了用Control节点制作游戏菜单的核心技能。Control节点的布局系统(锚点、容器)是UI自适应的基础;鸿蒙折叠屏适配的核心是动态检测屏幕尺寸并调整布局参数;新手应多利用Godot的可视化编辑器(拖拽调整节点)和信号系统(简化事件处理)。
对于游戏开发者来说,UI(用户界面)是玩家与游戏交互的第一扇门。而Godot的Control
节点作为UI系统的核心,能轻松实现按钮、菜单、对话框等交互组件。本文将以鸿蒙折叠屏适配为目标,带你用Control
节点制作一个基础游戏菜单,并解决折叠屏下的布局难题。
一、为什么选择Control节点做UI?
在Godot中,Control
节点是所有UI元素的基类(如按钮Button
、标签Label
、面板Panel
),它天生支持:
- 布局系统:通过锚点(Anchor)、边距(Margin)自动对齐父节点;
- 输入响应:内置点击、悬停等事件,无需手动检测触摸位置;
- 样式自定义:支持主题(Theme)全局配置字体、颜色、圆角等;
- 折叠屏适配:通过动态调整尺寸和位置,适配不同屏幕形态。
对于新手来说,Control
节点的可视化编辑(在Godot编辑器中拖拽调整)和简洁的API(如position
、size
、anchor_left
)能大幅降低UI开发门槛。
二、实战准备:创建菜单场景
1. 新建鸿蒙适配项目
- 打开Godot 4.2+版本,创建新项目(选择2D模板);
- 配置鸿蒙SDK路径(参考前文《鸿蒙适配:Godot项目初始化》);
- 导出设置中勾选“鸿蒙(HarmonyOS)”导出模板。
2. 构建菜单场景结构
我们需要一个主菜单,包含“开始游戏”“设置”“退出”三个按钮,以及顶部标题。场景结构如下:
MainMenu (Control) # 主菜单面板
├── Title (Label) # 游戏标题
├── ButtonContainer (VBoxContainer) # 按钮容器(垂直排列)
│ ├── StartBtn (Button) # 开始按钮
│ ├── SettingsBtn (Button) # 设置按钮
│ └── ExitBtn (Button) # 退出按钮
└── Version (Label) # 版本号(底部)
操作步骤:
- 在根节点(默认
Node2D
)下添加MainMenu
(Control
类型),命名为MainMenu
; - 调整
MainMenu
的锚点(anchor_left
、anchor_right
、anchor_top
、anchor_bottom
)为0,1,0,1
(占满整个屏幕); - 添加
Title
(Label
)作为子节点,设置文本为“我的游戏”,字体大小48
,锚点center_x=0.5, top=0.1
(水平居中,顶部距离屏幕10%); - 添加
ButtonContainer
(VBoxContainer
,垂直布局容器),锚点center_x=0.5, center_y=0.5
(水平居中,垂直居中); - 在
ButtonContainer
中添加三个Button
节点(StartBtn
、SettingsBtn
、ExitBtn
),设置文本分别为“开始游戏”“设置”“退出”,调整custom_minimum_size
为200x60
(最小尺寸); - 添加
Version
(Label
),文本为“v1.0.0”,锚点center_x=0.5, bottom=0.1
(水平居中,底部距离屏幕10%)。
三、基础菜单功能:按钮交互与事件
Control
节点的核心优势是内置事件系统。我们可以通过_on_Button_pressed()
等回调函数,快速实现按钮点击逻辑。
1. 编写菜单脚本
为MainMenu
节点添加脚本(main_menu.gd
):
extends Control
# 按钮点击事件(自动绑定同名信号)
func _on_StartBtn_pressed():
print("开始游戏!")
# 这里可以跳转到游戏场景:get_tree().change_scene("res://game.tscn")
func _on_SettingsBtn_pressed():
print("打开设置!")
# 打开设置弹窗(后续扩展)
func _on_ExitBtn_pressed():
print("退出游戏!")
get_tree().quit() # 退出游戏
2. 绑定按钮信号
在Godot编辑器中:
- 选中
StartBtn
,点击右侧“节点”面板的“信号”按钮; - 搜索
pressed
信号(按钮按下时触发),点击“连接”; - 选择目标节点为
MainMenu
,方法名为_on_StartBtn_pressed
; - 重复步骤为
SettingsBtn
和ExitBtn
绑定对应事件。
新手提示:Godot支持自动重命名信号处理函数(如按钮命名为StartBtn
,自动生成_on_StartBtn_pressed
函数),无需手动输入。
四、鸿蒙折叠屏适配:动态调整布局
鸿蒙折叠屏的核心特性是屏幕形态可变(折叠时为小屏,展开时为大屏)。为了让菜单在不同形态下都能良好显示,需要实现响应式布局。
1. 检测屏幕形态
通过get_viewport_rect()
获取当前可用屏幕区域(排除系统导航栏等),判断是否为折叠状态:
# 在MainMenu.gd中添加以下代码
var is_folded = false # 折叠状态标志
func _ready():
# 初始检测屏幕尺寸(假设折叠屏展开宽度≥1200vp,折叠宽度≤800vp)
check_screen_size()
# 监听窗口尺寸变化(折叠屏切换时触发)
get_window().connect("size_changed", self, "_on_window_size_changed")
func check_screen_size():
var screen_size = get_viewport_rect().size # 获取当前可用屏幕尺寸(Vector2)
is_folded = screen_size.x < 1200 # 假设宽度<1200为折叠状态
adjust_layout(is_folded)
func _on_window_size_changed(new_size):
# 窗口尺寸变化时重新检测
check_screen_size()
2. 动态调整布局
根据折叠状态,调整菜单的间距、字体大小和按钮尺寸:
func adjust_layout(is_folded: bool):
# 调整标题字体大小
var title = $Title
title.font_size = 36 if is_folded else 48
# 调整按钮容器间距
var button_container = $ButtonContainer
button_container.spacing = 20 if is_folded else 30 # 折叠时按钮间距更小
# 调整按钮最小尺寸
for btn in button_container.get_children():
if btn is Button:
btn.custom_minimum_size = Vector2(150, 50) if is_folded else Vector2(200, 60)
# 调整版本号字体大小
var version = $Version
version.font_size = 24 if is_folded else 32
3. 锚点与百分比布局(进阶)
为了进一步适配不同屏幕比例,可使用@export
声明变量,结合百分比设置位置:
@export var title_top_margin: float = 0.1 # 标题顶部边距(屏幕高度的10%)
@export var button_width_percent: float = 0.4 # 按钮宽度占屏幕的40%
func _ready():
# 使用百分比设置标题位置
$Title.position.y = -get_viewport_rect().size.y * title_top_margin
# 使用百分比设置按钮宽度
for btn in $ButtonContainer.get_children():
if btn is Button:
btn.custom_minimum_size.x = get_viewport_rect().size.x * button_width_percent
五、常见问题与解决方案
问题1:折叠屏切换时,菜单元素错位
解决方案:
- 确保所有
Control
节点的锚点设置为百分比(如anchor_left=0.5
表示水平居中); - 使用
get_viewport_rect().size
动态计算位置,而非固定数值; - 在
_ready()
和size_changed
信号中调用布局调整函数。
问题2:按钮点击区域过小(折叠屏上难以点击)
解决方案:
- 增大按钮的
custom_minimum_size
(最小尺寸); - 启用按钮的“扩大点击区域”属性(在编辑器中勾选
Button
的expand_click_area
); - 为按钮添加
Area2D
子节点,扩大碰撞检测范围:# 在Button节点下添加Area2D(命名为ButtonArea) # 设置Area2D的size比按钮大20vp func _ready(): var area = $ButtonArea area.size = Vector2(240, 80) # 比按钮大40vp(20vp*2)
问题3:鸿蒙设备字体显示异常
解决方案:
- 使用鸿蒙系统默认字体(避免自定义字体兼容性问题);
- 在
Project Settings > General > Text Editor
中设置Font Antialiasing
为2x
(提升小字体清晰度); - 为
Label
和Button
启用clip_text
属性(超出部分裁剪,避免文字溢出)。
总结:从基础到适配的UI开发流程
本文通过“创建菜单场景→绑定按钮事件→适配折叠屏”三个步骤,带你掌握了用Control
节点制作游戏菜单的核心技能。关键是要理解:
Control
节点的布局系统(锚点、容器)是UI自适应的基础;- 鸿蒙折叠屏适配的核心是动态检测屏幕尺寸并调整布局参数;
- 新手应多利用Godot的可视化编辑器(拖拽调整节点)和信号系统(简化事件处理)。
更多推荐
所有评论(0)