package screens import ( "image/color" "github.com/hajimehoshi/ebiten/v2" "github.com/hajimehoshi/ebiten/v2/inpututil" "github.com/hajimehoshi/ebiten/v2/text/v2" ) // Settings interface type FPSCapSetting interface { String() string Cycle() } type SettingsScreen struct { selectedIndex int fpsMonitorValue *bool fpsCapValue FPSCapSetting } func NewSettingsScreen() *SettingsScreen { return &SettingsScreen{ selectedIndex: 0, } } func (s *SettingsScreen) SetFPSMonitor(enabled *bool) { s.fpsMonitorValue = enabled } func (s *SettingsScreen) SetFPSCap(cap FPSCapSetting) { s.fpsCapValue = cap } func (s *SettingsScreen) Update() bool { if inpututil.IsKeyJustPressed(ebiten.KeyEscape) { return true } settingsCount := 2 if inpututil.IsKeyJustPressed(ebiten.KeyArrowUp) || inpututil.IsKeyJustPressed(ebiten.KeyW) { s.selectedIndex-- if s.selectedIndex < 0 { s.selectedIndex = 0 } } if inpututil.IsKeyJustPressed(ebiten.KeyArrowDown) || inpututil.IsKeyJustPressed(ebiten.KeyS) { s.selectedIndex++ if s.selectedIndex >= settingsCount { s.selectedIndex = settingsCount - 1 } } if inpututil.IsKeyJustPressed(ebiten.KeyEnter) || inpututil.IsKeyJustPressed(ebiten.KeySpace) { if s.selectedIndex == 0 && s.fpsMonitorValue != nil { *s.fpsMonitorValue = !*s.fpsMonitorValue } else if s.selectedIndex == 1 && s.fpsCapValue != nil { s.fpsCapValue.Cycle() } } return false } // Rendering func (s *SettingsScreen) Draw(screen *ebiten.Image, screenWidth, screenHeight int, title string) { screen.Fill(color.RGBA{R: 20, G: 20, B: 30, A: 255}) titleX := (screenWidth / 2) - (len(title) * 7 / 2) titleY := screenHeight/3 - 50 s.drawText(screen, title, color.White, titleX, titleY) startY := screenHeight/2 - 20 leftMargin := screenWidth/2 - 120 // FPS monitor toggle fpsMonitorText := "FPS Monitor: " if s.fpsMonitorValue != nil && *s.fpsMonitorValue { fpsMonitorText += "ON" } else { fpsMonitorText += "OFF" } if s.selectedIndex == 0 { indicatorX := leftMargin - 20 s.drawText(screen, ">", color.RGBA{R: 255, G: 200, B: 0, A: 255}, indicatorX, startY) s.drawText(screen, fpsMonitorText, color.RGBA{R: 255, G: 255, B: 100, A: 255}, leftMargin, startY) } else { s.drawText(screen, fpsMonitorText, color.RGBA{R: 180, G: 180, B: 200, A: 255}, leftMargin, startY) } // FPS cap setting fpsCapText := "FPS Cap: " if s.fpsCapValue != nil { fpsCapText += s.fpsCapValue.String() } else { fpsCapText += "60 FPS" } capY := startY + 40 if s.selectedIndex == 1 { indicatorX := leftMargin - 20 s.drawText(screen, ">", color.RGBA{R: 255, G: 200, B: 0, A: 255}, indicatorX, capY) s.drawText(screen, fpsCapText, color.RGBA{R: 255, G: 255, B: 100, A: 255}, leftMargin, capY) } else { s.drawText(screen, fpsCapText, color.RGBA{R: 180, G: 180, B: 200, A: 255}, leftMargin, capY) } // Instructions hintText := "Enter/Space to toggle, ESC to go back" hintX := (screenWidth / 2) - (len(hintText) * 7 / 2) hintY := screenHeight - 50 s.drawText(screen, hintText, color.RGBA{R: 120, G: 120, B: 150, A: 255}, hintX, hintY) } func (s *SettingsScreen) drawText(screen *ebiten.Image, txt string, clr color.Color, x, y int) { op := &text.DrawOptions{} op.GeoM.Translate(float64(x), float64(y)-basicFaceAscent) op.ColorScale.ScaleWithColor(clr) text.Draw(screen, txt, basicFace, op) } func (s *SettingsScreen) Reset() { s.selectedIndex = 0 }