Godot游戏练习01-第14节-Theme,字体,游戏UI

今天来学习游戏中的主题(Theme)和字体调整, 并添加一个能显示轮次和倒计时的游戏UI

看看效果

像素字体加上, 瞬间有那感觉了! 有点那么回事了, 哈哈

实现过程

主题和字体设置

字体我是直接在网上找了一个开源字体, 觉得好看就用了: https://github.com/TakWolf/fusion-pixel-font

下载otf格式, 不带woff/woff2后缀的字体, 导入Godot, 关闭抗锯齿(Antialiasing), Hinting, Subpixel Positioning后重新导入, 像素游戏不需要抗锯齿/高清/子像素等设置, 导入zh_hans(简体中文版本)

新建一个Theme资源, 命名为default.tres, 将Default Font设置为导入的字体, 调整字号为20 (自己在预览中觉得合适的大小)

设置默认主题: Project -> Project Settings -> GUI -> Theme -> Custom, 设置为刚刚新建的Theme资源, 并且可以调整默认字体导入选项

这样, 默认字体和主题都设置完毕

轮次数和轮次倒计时显示

新建一个CanvasLayer为根节点的场景, UI节点树如下

gdscript 复制代码
RoundTimerUI (CanvasLayer)
└── MarginContainer
    └── VBoxContainer
        ├── RoundLabel
        └── TimerLabel

调整对齐, Margin等属性, 让UI在靠顶居中的位置显示

RoundTimerUI脚本如下

gdscript 复制代码
extends CanvasLayer

@export var enemy_spawn_component: EnemySpawnComponent

@onready var round_label: Label = %RoundLabel
@onready var timer_label: Label = %TimerLabel

func _ready() -> void:
	enemy_spawn_component.round_changed.connect(_on_round_changed)


func _process(_delta: float) -> void:
	var time_left := enemy_spawn_component.get_round_time_left()
	timer_label.text = str(ceili(time_left))


func _on_round_changed(round_count: int) -> void:
	round_label.text = "Round %s" % round_count

它监听外部EnemySpawnComponent组件的轮次变化事件, 以及实时获取EnemySpawnComponent组件中的当前轮次剩余时间, 转换为整数显示, 更新UI

之后就是数据的通知与同步, 在这个场景中, 数据的同步显得稍微复杂一点, 它涉及到跨组件的Timer处理

主要把握好两个同步时间点:

  • Round变化
  • 新的Peer加入

同步内容: 主要同步Round计数, 以及当前剩余时间, 倒计时让每个Peer自己的Timer执行, 服务器只在关键点同步, 避免不必要的宽带浪费

这里主要看一下EnemySpawnComponent组件中提供的"同步"接口

gdscript 复制代码
func synchronize(peer_id: int = -1) -> void:
	if not is_multiplayer_authority():
		return
	var data = {
		"round_count": round_count,
		"round_timer_time_left": round_timer.time_left,
		"round_timer_running": not round_timer.is_stopped()
	}
	if peer_id < 0:
		_synchronize.rpc(data)
	elif peer_id > 1:
		_synchronize.rpc_id(peer_id, data)


@rpc("authority", "call_remote", "reliable")
func _synchronize(data: Dictionary) -> void:
	round_count = data.round_count
	round_timer.wait_time = data.round_timer_time_left
	if data.round_timer_running:
		round_timer.start()

同步接口synchronize收集服务端信息, 并同步给其他的peer, 所以peer_id中过滤自身id(1)

synchronize在Round发生变化时与所有peer进行RPC同步; 在新peer加入时, 仅与新peer同步(传入peer_id)

对round_count字段添加getter和setter

gdscript 复制代码
var round_count: int = 0:
	get:
		return round_count
	set(value):
		round_count = value
		round_changed.emit(value)

当每个peer上的round_count发生变化时, 都会触发各自的round_changed信号, 同步到UI界面, 保持数据与UI显示一致

相关推荐
传奇开心果编程14 小时前
【Compose Multiplatform 跨端开发学与练】第7课 平台适配与互操作
android·windows·学习·ui·ios·kotlin·composer
传奇开心果编程19 小时前
【现代声明式UI学与练】第4课 列表渲染与 key——如何高效渲染列表、key 的作用、列表重排时的状态保持
学习·flutter·react native·ui·swiftui·android jetpack
传奇开心果编程19 小时前
【Compose Multiplatform 跨端开发学与练】第5课 网络与数据层
android·网络·学习·ui·ios·kotlin·composer
Martina_032119 小时前
AI生成3D场景导入 Unity/Unreal 后,NPC 总串层?用6步检查导航高度与跨层连接
人工智能·游戏·数学建模·3d·unity·自然语言处理·aigc
Nil20820 小时前
leetcode 55跳跃游戏
算法·leetcode·游戏
Nil2081 天前
leetcode 45跳跃游戏Ⅱ
算法·leetcode·游戏
传奇开心果编程1 天前
【SwiftUI提高练中学】第8课 网络层架构:拦截器、重试、缓存与离线优先
学习·macos·ui·ios·swiftui
传奇开心果编程1 天前
【现代声明式UI学与练】第7课 组件通信——父传子、子传父、跨层级通信、状态提升与 Context
学习·flutter·react native·ui·swiftui·android jetpack
大圣编蚕2 天前
Rancher证书轮换过期导致不能访问UI问题处理
ui·rancher
可乐ea2 天前
Agent 评测换判据:用终态数据库状态判定任务是否完成
数据库·ui·oracle·mcp工具·agent评测·终态断言·智能体可靠性