refactor: move ui code from game/state/handlers/menu.go to its own package in game/ui
This commit is contained in:
parent
190c6ad914
commit
bcd6025aa3
5 changed files with 118 additions and 45 deletions
|
|
@ -2,59 +2,39 @@ package handlers
|
|||
|
||||
import (
|
||||
"tetris/assets"
|
||||
"tetris/engine/audio"
|
||||
"tetris/engine/render"
|
||||
"tetris/game"
|
||||
"tetris/game/state"
|
||||
"tetris/game/ui"
|
||||
|
||||
rl "github.com/gen2brain/raylib-go/raylib"
|
||||
)
|
||||
|
||||
type entry struct {
|
||||
label string
|
||||
state string
|
||||
type MainMenu struct {
|
||||
menu ui.Menu
|
||||
}
|
||||
|
||||
type Menu struct {
|
||||
selected int
|
||||
entries []entry
|
||||
}
|
||||
|
||||
func NewMenu() *Menu {
|
||||
return &Menu{
|
||||
selected: 0,
|
||||
entries: []entry{
|
||||
{"Start", "gameplay"},
|
||||
{"Quit", "quit"},
|
||||
},
|
||||
func NewMainMenu(fsm state.Transitioner) *MainMenu {
|
||||
return &MainMenu{
|
||||
menu: ui.NewMenu([]ui.Widget{
|
||||
ui.NewButton("Start", func() { fsm.Switch("gameplay") }),
|
||||
ui.NewButton("Quit", func() { fsm.Switch("quit") }),
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
||||
func (menu *Menu) Enter() {
|
||||
menu.selected = 0
|
||||
func (main *MainMenu) Enter() {
|
||||
main.menu.Select(0)
|
||||
}
|
||||
|
||||
func (Menu) Exit() {
|
||||
func (MainMenu) Exit() {
|
||||
}
|
||||
|
||||
func (menu *Menu) Update(fsm state.Transitioner, delta float32) {
|
||||
if rl.IsKeyPressed(rl.KeyEnter) {
|
||||
fsm.Switch(menu.entries[menu.selected].state)
|
||||
audio.Play(assets.SFX_MENU_ENTER)
|
||||
} else if rl.IsKeyPressed(rl.KeyDown) {
|
||||
if menu.selected+1 < len(menu.entries) {
|
||||
menu.selected = menu.selected + 1
|
||||
audio.Play(assets.SFX_MENU_SELECT)
|
||||
}
|
||||
} else if rl.IsKeyPressed(rl.KeyUp) {
|
||||
if menu.selected-1 >= 0 {
|
||||
menu.selected = menu.selected - 1
|
||||
audio.Play(assets.SFX_MENU_SELECT)
|
||||
}
|
||||
}
|
||||
func (menu *MainMenu) Update(fsm state.Transitioner, delta float32) {
|
||||
menu.menu.HandleInput()
|
||||
}
|
||||
|
||||
func (Menu) renderLogo(offset_x, offset_y int32) {
|
||||
func (MainMenu) renderLogo(offset_x, offset_y int32) {
|
||||
for y := range assets.LOGO_HEIGHT {
|
||||
for x := range assets.LOGO_STRIDE {
|
||||
index := assets.Logo[x+(y*assets.LOGO_STRIDE)]
|
||||
|
|
@ -76,20 +56,15 @@ func (Menu) renderLogo(offset_x, offset_y int32) {
|
|||
}
|
||||
}
|
||||
|
||||
func (menu Menu) renderEntries(offset_x, offset_y int32) {
|
||||
func (menu MainMenu) renderEntries(offset_x, offset_y int32) {
|
||||
y := offset_y
|
||||
for i, entry := range menu.entries {
|
||||
|
||||
col := rl.White
|
||||
if i == menu.selected {
|
||||
col = rl.Red
|
||||
}
|
||||
render.DrawTextCenter(offset_x, y, 32, entry.label, col)
|
||||
for i, entry := range menu.menu.Entries() {
|
||||
entry.Draw(offset_x, y, menu.menu.IsSelected(i))
|
||||
y += 40
|
||||
}
|
||||
}
|
||||
|
||||
func (menu Menu) Render() {
|
||||
func (menu MainMenu) Render() {
|
||||
render.Begin(rl.Black)
|
||||
|
||||
menu.renderLogo(20, 150)
|
||||
|
|
|
|||
33
game/ui/button.go
Normal file
33
game/ui/button.go
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
package ui
|
||||
|
||||
import (
|
||||
"tetris/engine/render"
|
||||
|
||||
rl "github.com/gen2brain/raylib-go/raylib"
|
||||
)
|
||||
|
||||
type Button struct {
|
||||
Text string
|
||||
Action func()
|
||||
}
|
||||
|
||||
func NewButton(text string, action func()) Button {
|
||||
return Button{
|
||||
Text: text,
|
||||
Action: action,
|
||||
}
|
||||
}
|
||||
|
||||
func (b Button) HandleInput() {
|
||||
if rl.IsKeyPressed(rl.KeyEnter) {
|
||||
b.Action()
|
||||
}
|
||||
}
|
||||
|
||||
func (b Button) Draw(x, y int32, selected bool) {
|
||||
col := rl.White
|
||||
if selected {
|
||||
col = rl.Red
|
||||
}
|
||||
render.DrawTextCenter(x, y, 32, b.Text, col)
|
||||
}
|
||||
59
game/ui/menu.go
Normal file
59
game/ui/menu.go
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
package ui
|
||||
|
||||
import (
|
||||
"tetris/assets"
|
||||
"tetris/engine/audio"
|
||||
|
||||
rl "github.com/gen2brain/raylib-go/raylib"
|
||||
)
|
||||
|
||||
type Menu struct {
|
||||
selected int
|
||||
entries []Widget
|
||||
}
|
||||
|
||||
func NewMenu(entries []Widget) Menu {
|
||||
return Menu{
|
||||
entries: entries,
|
||||
}
|
||||
}
|
||||
|
||||
func (menu Menu) Entries() []Widget {
|
||||
return menu.entries
|
||||
}
|
||||
|
||||
func (menu *Menu) Select(index int) {
|
||||
menu.selected = min(index, len(menu.entries)-1)
|
||||
}
|
||||
|
||||
func (menu Menu) Selected() Widget {
|
||||
return menu.entries[menu.selected]
|
||||
}
|
||||
|
||||
func (menu Menu) IsSelected(index int) bool {
|
||||
return menu.selected == index
|
||||
}
|
||||
|
||||
func (menu *Menu) Next() {
|
||||
if menu.selected+1 < len(menu.entries) {
|
||||
menu.selected = menu.selected + 1
|
||||
audio.Play(assets.SFX_MENU_SELECT)
|
||||
}
|
||||
}
|
||||
|
||||
func (menu *Menu) Previous() {
|
||||
if menu.selected-1 >= 0 {
|
||||
menu.selected = menu.selected - 1
|
||||
audio.Play(assets.SFX_MENU_SELECT)
|
||||
}
|
||||
}
|
||||
|
||||
func (menu *Menu) HandleInput() {
|
||||
if rl.IsKeyPressed(rl.KeyDown) {
|
||||
menu.Next()
|
||||
} else if rl.IsKeyPressed(rl.KeyUp) {
|
||||
menu.Previous()
|
||||
} else {
|
||||
menu.Selected().HandleInput()
|
||||
}
|
||||
}
|
||||
6
game/ui/widget.go
Normal file
6
game/ui/widget.go
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
package ui
|
||||
|
||||
type Widget interface {
|
||||
HandleInput()
|
||||
Draw(x, y int32, selected bool)
|
||||
}
|
||||
|
|
@ -41,7 +41,7 @@ func main() {
|
|||
|
||||
// Setup state machine.
|
||||
fsm := machine.New()
|
||||
fsm.Register("menu", handlers.NewMenu())
|
||||
fsm.Register("menu", handlers.NewMainMenu(fsm))
|
||||
fsm.Register("gameover", &handlers.GameOver{})
|
||||
fsm.Register("gameplay", handlers.NewGamePlay())
|
||||
fsm.Start("menu")
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue