86 lines
2.1 KiB
Go
86 lines
2.1 KiB
Go
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)
|
|
}
|