feat(ui): 主菜单/暂停菜单屏幕状态机——中文标题「年糕历险记」、按钮点击、Esc 暂停(烟雾测试 10 秒无崩溃)
This commit is contained in:
@@ -45,6 +45,11 @@ type clientApp struct {
|
||||
uiR *ui.Renderer
|
||||
hud *ui.HUD
|
||||
|
||||
// 屏幕状态机:0 主菜单 / 1 游戏中 / 2 暂停(UI还原.md §2)
|
||||
screen int
|
||||
titleScreen *ui.TitleScreen
|
||||
pauseScreen *ui.PauseScreen
|
||||
|
||||
meshBuilder *mesh.Builder
|
||||
|
||||
mu sync.Mutex
|
||||
@@ -62,7 +67,46 @@ type worldMeshJob struct {
|
||||
|
||||
// Tick 每 tick(20Hz):输入 → 玩家 → 会话 → 网格构建(渲染.md §3.3 dirty 重建)。
|
||||
func (a *clientApp) Tick(dt float64) {
|
||||
// 输入 → 玩家速度(UI与输入.md §6 动作映射)
|
||||
// 屏幕状态机(UI还原.md §2:主菜单/暂停不处理游戏输入)
|
||||
switch a.screen {
|
||||
case 0: // 主菜单
|
||||
if a.in.clicked {
|
||||
switch a.titleScreen.HitTest(a.in.clickX, a.in.clickY) {
|
||||
case "play":
|
||||
a.screen = 1
|
||||
a.rend.SetCursorMode(true)
|
||||
case "quit":
|
||||
a.rend.Window().SetShouldClose(true)
|
||||
}
|
||||
a.in.clicked = false
|
||||
}
|
||||
a.in.dyaw, a.in.dpitch = 0, 0
|
||||
return
|
||||
case 2: // 暂停
|
||||
if a.in.escPressed {
|
||||
a.screen = 1
|
||||
a.rend.SetCursorMode(true)
|
||||
}
|
||||
if a.in.clicked {
|
||||
switch a.pauseScreen.HitTest(a.in.clickX, a.in.clickY) {
|
||||
case "resume":
|
||||
a.screen = 1
|
||||
a.rend.SetCursorMode(true)
|
||||
case "quit":
|
||||
a.rend.Window().SetShouldClose(true)
|
||||
}
|
||||
a.in.clicked = false
|
||||
}
|
||||
a.in.escPressed = false
|
||||
return
|
||||
}
|
||||
// 游戏中
|
||||
if a.in.escPressed {
|
||||
a.screen = 2
|
||||
a.rend.SetCursorMode(false)
|
||||
a.in.escPressed = false
|
||||
return
|
||||
}
|
||||
a.in.apply(a.sess)
|
||||
a.sess.Tick(dt)
|
||||
|
||||
@@ -107,7 +151,15 @@ func (a *clientApp) Render() {
|
||||
a.rend.DrawChunks(func(i int) (int32, int32) { return chunks[i].CX, chunks[i].CZ }, len(chunks))
|
||||
// UI pass(UI与输入.md §2:3D 之后、状态隔离)
|
||||
a.uiR.Begin()
|
||||
a.hud.Draw(a.uiR)
|
||||
switch a.screen {
|
||||
case 0:
|
||||
a.titleScreen.Draw(a.uiR)
|
||||
case 1:
|
||||
a.hud.Draw(a.uiR)
|
||||
case 2:
|
||||
a.hud.Draw(a.uiR) // 暂停时世界仍可见(UI还原.md §2)
|
||||
a.pauseScreen.Draw(a.uiR)
|
||||
}
|
||||
a.uiR.Flush()
|
||||
a.rend.EndFrame()
|
||||
}
|
||||
@@ -250,6 +302,13 @@ func main() {
|
||||
hud.SetItemAtlas(itemTex, itemUV)
|
||||
}
|
||||
|
||||
// 界面屏幕(中文标题「年糕历险记」+ 按钮,UI还原.md §2)
|
||||
lang, err := am.LoadLang(cfg.Client.Language)
|
||||
if err != nil {
|
||||
log.Warnf("语言加载失败: %v", err)
|
||||
}
|
||||
titleScreen, pauseScreen := buildScreens(uiR, lang)
|
||||
|
||||
// 6) 输入(鼠标捕获 + 键鼠回调)
|
||||
in := newInputState(rend.Window())
|
||||
|
||||
@@ -260,6 +319,8 @@ func main() {
|
||||
in: in,
|
||||
uiR: uiR,
|
||||
hud: hud,
|
||||
titleScreen: titleScreen,
|
||||
pauseScreen: pauseScreen,
|
||||
meshBuilder: mesh.NewBuilder(reg, uvFn),
|
||||
winW: cfg.Client.WindowWidth,
|
||||
winH: cfg.Client.WindowHeight,
|
||||
|
||||
Reference in New Issue
Block a user