95 lines
2.7 KiB
Go
95 lines
2.7 KiB
Go
//go:build gl
|
||
|
||
// 界面屏幕:主菜单(中文标题「年糕历险记」)与暂停菜单(UI还原.md §2)。
|
||
package ui
|
||
|
||
import (
|
||
"image"
|
||
)
|
||
|
||
// TitleScreen 主菜单屏幕(UI还原.md §2:标题 + 按钮 + 背景)。
|
||
type TitleScreen struct {
|
||
// 标题与按钮为预光栅化纹理(中文用 cjkfont、ASCII 用位图字体)
|
||
TitleTex uint32
|
||
TitleW float32
|
||
TitleH float32
|
||
Buttons []Button
|
||
}
|
||
|
||
// Button 一个按钮(点击区域 + 纹理)。
|
||
type Button struct {
|
||
X, Y, W, H float32
|
||
Tex uint32
|
||
Action string // "play" / "quit" / "resume"
|
||
}
|
||
|
||
// NewTitleScreen 创建主菜单(textures 由调用方预上传:标题与按钮标签)。
|
||
func NewTitleScreen(titleTex uint32, titleW, titleH float32, buttons []Button) *TitleScreen {
|
||
return &TitleScreen{TitleTex: titleTex, TitleW: titleW, TitleH: titleH, Buttons: buttons}
|
||
}
|
||
|
||
// HitTest 命中检测:返回点击的按钮动作。
|
||
func (s *TitleScreen) HitTest(mx, my float32) string {
|
||
for _, b := range s.Buttons {
|
||
if mx >= b.X && mx <= b.X+b.W && my >= b.Y && my <= b.Y+b.H {
|
||
return b.Action
|
||
}
|
||
}
|
||
return ""
|
||
}
|
||
|
||
// Draw 绘制主菜单(暗背景 + 标题 + 按钮,UI还原.md §2)。
|
||
func (s *TitleScreen) Draw(r *Renderer) {
|
||
w, h := float32(r.w), float32(r.h)
|
||
// 背景(暗色遮罩)
|
||
r.DrawRect(0, 0, w, h, [4]float32{0.08, 0.10, 0.12, 1})
|
||
// 标题(居中偏上)
|
||
if s.TitleTex != 0 {
|
||
r.pushQuad(quad{x: w/2 - s.TitleW/2, y: h * 0.2, w: s.TitleW, h: s.TitleH,
|
||
u0: 0, v0: 0, u1: 1, v1: 1, r: 1, g: 1, b: 1, a: 1, tex: s.TitleTex})
|
||
}
|
||
// 按钮
|
||
for _, b := range s.Buttons {
|
||
if b.Tex != 0 {
|
||
r.pushQuad(quad{x: b.X, y: b.Y, w: b.W, h: b.H,
|
||
u0: 0, v0: 0, u1: 1, v1: 1, r: 1, g: 1, b: 1, a: 1, tex: b.Tex})
|
||
}
|
||
}
|
||
}
|
||
|
||
// PauseScreen 暂停菜单(UI还原.md §2)。
|
||
type PauseScreen struct {
|
||
TitleTex uint32
|
||
TitleW float32
|
||
TitleH float32
|
||
Buttons []Button
|
||
}
|
||
|
||
// HitTest 命中检测。
|
||
func (s *PauseScreen) HitTest(mx, my float32) string {
|
||
for _, b := range s.Buttons {
|
||
if mx >= b.X && mx <= b.X+b.W && my >= b.Y && my <= b.Y+b.H {
|
||
return b.Action
|
||
}
|
||
}
|
||
return ""
|
||
}
|
||
|
||
// Draw 绘制暂停菜单(半透明遮罩 + 标题 + 按钮)。
|
||
func (s *PauseScreen) Draw(r *Renderer) {
|
||
w, h := float32(r.w), float32(r.h)
|
||
r.DrawRect(0, 0, w, h, [4]float32{0, 0, 0, 0.6})
|
||
if s.TitleTex != 0 {
|
||
r.pushQuad(quad{x: w/2 - s.TitleW/2, y: h * 0.15, w: s.TitleW, h: s.TitleH,
|
||
u0: 0, v0: 0, u1: 1, v1: 1, r: 1, g: 1, b: 1, a: 1, tex: s.TitleTex})
|
||
}
|
||
for _, b := range s.Buttons {
|
||
if b.Tex != 0 {
|
||
r.pushQuad(quad{x: b.X, y: b.Y, w: b.W, h: b.H,
|
||
u0: 0, v0: 0, u1: 1, v1: 1, r: 1, g: 1, b: 1, a: 1, tex: b.Tex})
|
||
}
|
||
}
|
||
}
|
||
|
||
var _ image.Image // 保持 image 引用
|