package modes import ( "image/color" "path/filepath" "strings" "time" "github.com/hajimehoshi/ebiten/v2" "kidskeyboard/internal/ui" ) type animal struct { name string image string sound string } type AnimalMode struct { ctx Context animals []animal current *animal } func NewAnimalMode(ctx Context) *AnimalMode { return &AnimalMode{ ctx: ctx, animals: []animal{ {"dog", "assets/animals/dog.png", "assets/animals/dog.wav"}, {"cat", "assets/animals/cat.png", "assets/animals/cat.wav"}, {"cow", "assets/animals/cow.png", "assets/animals/cow.wav"}, }, } } func (m *AnimalMode) Name() string { return "CTRL+F3 Animal" } func (m *AnimalMode) OnEnter() {} func (m *AnimalMode) OnLeave() { m.ctx.Audio.StopCurrent() } func (m *AnimalMode) HandleInput() { for _, key := range justPressedKeys() { if !childKey(key) { continue } a := m.animals[m.ctx.RNG.Intn(len(m.animals))] m.current = &a if !m.ctx.Audio.PlayWAV(filepath.Clean(a.sound), true) { m.ctx.Audio.PlayToneInterrupt(330+float64(m.ctx.RNG.Intn(280)), 260*time.Millisecond, 0.26) } return } } func (m *AnimalMode) Update() {} func (m *AnimalMode) Draw(screen *ebiten.Image) { screen.Fill(color.Black) w, h := screen.Bounds().Dx(), screen.Bounds().Dy() ui.Text(screen, "CTRL+F3", 20, 20, color.White, 2) if m.current == nil { ui.CenteredText(screen, "ANIMAL", w/2, h/2, color.White, 7) return } if img, ok := m.ctx.Assets.Image(m.current.image); ok { drawImageCentered(screen, img, w/2, h/2, float64(w)*0.65, float64(h)*0.72) return } ui.CenteredText(screen, strings.ToUpper(m.current.name), w/2, h/2, color.White, 9) } func drawImageCentered(screen *ebiten.Image, img *ebiten.Image, cx, cy int, maxW, maxH float64) { iw, ih := img.Bounds().Dx(), img.Bounds().Dy() if iw <= 0 || ih <= 0 { return } scale := min(maxW/float64(iw), maxH/float64(ih)) if scale <= 0 { scale = 1 } op := &ebiten.DrawImageOptions{} op.GeoM.Scale(scale, scale) op.GeoM.Translate(float64(cx)-float64(iw)*scale/2, float64(cy)-float64(ih)*scale/2) screen.DrawImage(img, op) }