diff --git a/assets/sound.go b/assets/sound.go index 09503d4..9bc2365 100644 --- a/assets/sound.go +++ b/assets/sound.go @@ -5,11 +5,12 @@ import ( ) const ( - SFX_SHAPE_LOCKED audio.SoundID = 0 - SFX_ROW_CLEARED audio.SoundID = 1 - SFX_MENU_SELECT audio.SoundID = 0 - SFX_MENU_ENTER audio.SoundID = 1 - SFX_GAME_OVER audio.SoundID = 2 + SFX_SHAPE_LOCKED audio.SoundID = 0 + SFX_ROW_CLEARED audio.SoundID = 1 + SFX_MENU_SELECT audio.SoundID = 0 + SFX_MENU_ENTER audio.SoundID = 1 + SFX_MENU_SOUND_VOLUME_SELECT audio.SoundID = 1 + SFX_GAME_OVER audio.SoundID = 2 ) func LoadSound() *audio.Library { diff --git a/game/state/handlers/options.go b/game/state/handlers/options.go new file mode 100644 index 0000000..7627964 --- /dev/null +++ b/game/state/handlers/options.go @@ -0,0 +1,62 @@ +package handlers + +import ( + "tetris/assets" + "tetris/engine/audio" + "tetris/engine/core" + "tetris/engine/render" + "tetris/game/state" + "tetris/game/ui" + "tetris/game/ui/layouts" + "tetris/game/ui/widgets" + "tetris/game/uievents" + + rl "github.com/gen2brain/raylib-go/raylib" +) + +type OptionsMenu struct { + sndVolume *widgets.Slider + list *layouts.ListBox +} + +func soundVolumeChanged(widget *widgets.Slider) { + value := core.ByteToClampedFloat32(byte(widget.Value)) + + audio.SetVolume(value) + audio.Play(assets.SFX_MENU_SOUND_VOLUME_SELECT) +} + +func NewOptionsMenu() *OptionsMenu { + sndVolume := widgets.NewSlider(0, 255, 10).WithOnChange(soundVolumeChanged) + return &OptionsMenu{ + sndVolume: sndVolume, + list: layouts.NewListBox([]ui.InputWidget{ + layouts.NewInputControl(widgets.NewLabel("Sound Volume", 16), sndVolume), + }).Spacing(10).OnSelect(uievents.MenuSelect), + } +} + +func (menu *OptionsMenu) Enter() { + vol := core.ClampedFloat32ToByte(audio.Volume()) + menu.sndVolume.SetValue(int(vol)) +} + +func (OptionsMenu) Exit() { +} + +func (menu *OptionsMenu) Update(fsm state.Transitioner, delta float32) { + if rl.IsKeyPressed(rl.KeyEscape) { + fsm.Switch("menu") + } else { + menu.list.HandleInput() + } +} + +func (opt OptionsMenu) Render() { + render.Begin(rl.Black) + + render.DrawTextCenter(340, 100, 32, "Options", rl.White) + opt.list.Draw(150, 200) + + render.End() +} diff --git a/tetris.go b/tetris.go index 3cb4040..40ae3eb 100644 --- a/tetris.go +++ b/tetris.go @@ -45,6 +45,7 @@ func main() { // Setup state machine. fsm := machine.New() fsm.Register("menu", handlers.NewMainMenu(fsm)) + fsm.Register("options", handlers.NewOptionsMenu()) fsm.Register("gameover", &handlers.GameOver{}) fsm.Register("gameplay", handlers.NewGamePlay()) fsm.Start("menu")