音效 SoundManager
May 12
游戏没声音就像炒菜没盐 — 没那个味儿。这一章加上:
- 🪶 翅膀扇动声(小鸟跳跃时)
- ⭐ 得分声(穿过水管时)
- 💥 碰撞声(撞死时)
准备音效文件
我用的音效来源:TODO 素材链接
免费音效推荐:
- freesound.org(CC 许可)
- zapsplat.com
- sfxr — 在线生成复古 8-bit 音效,超适合 Flappy Bird
需要 3 个文件,放到 audio/ 目录下:
wing.wav— 扑翅膀score.wav— 得分strike.wav— 撞击

💡 推荐用
.wav而不是.mp3:体积大一点,但延迟低、循环不卡顿。短音效用 wav 是标配。
SoundManager 是个场景,不是脚本
和 GameManager 不一样,SoundManager 我们用 场景(.tscn) 来做,而不是单纯的脚本。
为什么? 因为每个音效都需要一个 AudioStreamPlayer 节点 — 与其在脚本里 new AudioStreamPlayer(),不如直接在场景里把所有 player 节点摆好,音效文件也提前在 Inspector 里预设好,调用时直接 .play() 就行。
创建 SoundManager 场景
新建场景,保存为 scenes/autoload/sound_manager.tscn。
使用到的节点:
Node(重命名SoundManager)— 根节点Node(重命名SFX)— 音效组AudioStreamPlayer(重命名wing_sfx)AudioStreamPlayer(重命名score_sfx)AudioStreamPlayer(重命名strike_sfx)

每个 AudioStreamPlayer 的设置
选中每个 player,在右侧 Inspector 里:
- Stream:拖入对应的音效文件(如
wing.wav拖到wing_sfx的 Stream 槽) - Volume dB:根据音量调整(-6 dB 是温和的衰减,-12 dB 是明显的降低)

SoundManager 脚本
给根节点挂脚本 sound_manager.gd:
extends Node
# 在检查器里预载好你的音效文件
@onready var score_sfx: AudioStreamPlayer = $SFX/score_sfx
@onready var strike_sfx: AudioStreamPlayer = $SFX/strike_sfx
@onready var wing_sfx: AudioStreamPlayer = $SFX/wing_sfx
func play_score():
score_sfx.play()
func play_die():
strike_sfx.play()
func play_wing():
wing_sfx.play()
@onready var xxx = $SFX/xxx— 拿到子节点的引用- 方法本身就一行:调用对应 player 的
play()即可
注册为 Autoload
和 GameManager 一样,项目 → 项目设置 → 全局 → 自动加载:
| 路径 | 节点名称 |
|---|---|
res://scenes/autoload/sound_manager.tscn | SoundManager |

⚠️ 注意这里加载的是 场景文件 (.tscn),不是脚本 (.gd)。Godot 的 Autoload 同时支持两者。
在游戏里调用
现在任何节点都能直接喊 SoundManager 一声 — 在合适的位置加上音效调用:
小鸟跳跃时(bird.gd)
if Input.is_action_just_pressed("fly"):
velocity.y = jump_force
SoundManager.play_wing() # 👈 加这一行
穿过水管得分时(pillar_pair.gd)
func _on_goal_body_entered(body: Node2D) -> void:
if body.name == "Bird":
SoundManager.play_score() # 👈 加这一行
if GameManager.has_method("add_score"):
GameManager.add_score(1)
goal.set_deferred("monitoring", false)
撞死时(killzone.gd)
func _on_body_entered(body: Node2D) -> void:
if body.name == "Bird" and GameManager.current_state == GameManager.GameState.PLAYING:
SoundManager.play_die() # 👈 加这一行
GameManager.game_over()
测试运行
戴上耳机,应该能听到:
- ✅ 按 fly → 翅膀扇动声
- ✅ 穿过水管 → 清脆的得分音
- ✅ 撞死 → 一声闷响
如果声音太大/太小,去 sound_manager.tscn 里调 Volume dB,不用改代码。
(可选)背景音乐 BGM
你可以再加一个 AudioStreamPlayer(命名 BGM),在 Inspector 里:
- Stream:拖入背景音乐
- Autoplay:✅ 勾选(场景一加载就播放)
- Loop:在 Stream 的导入设置里勾选
Loop
这样游戏一开始就有背景音乐。
下一章我们打包导出游戏,发布到 itch.io!🚀