101 lines
2.0 KiB
Go
101 lines
2.0 KiB
Go
package modes
|
|
|
|
import (
|
|
"image/color"
|
|
"path/filepath"
|
|
"time"
|
|
|
|
"github.com/hajimehoshi/ebiten/v2"
|
|
|
|
"kidskeyboard/internal/ui"
|
|
)
|
|
|
|
type FindKeyMode struct {
|
|
ctx Context
|
|
target rune
|
|
successTicks int
|
|
errorTicks int
|
|
lastJingle int
|
|
}
|
|
|
|
const findChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
|
|
|
|
func NewFindKeyMode(ctx Context) *FindKeyMode {
|
|
m := &FindKeyMode{ctx: ctx, lastJingle: -1}
|
|
m.pickNext()
|
|
return m
|
|
}
|
|
|
|
func (m *FindKeyMode) Name() string { return "CTRL+F5 Find Key" }
|
|
func (m *FindKeyMode) OnEnter() {}
|
|
func (m *FindKeyMode) OnLeave() {}
|
|
|
|
func (m *FindKeyMode) HandleInput() {
|
|
if m.successTicks > 0 {
|
|
return
|
|
}
|
|
for _, key := range justPressedKeys() {
|
|
if !childKey(key) {
|
|
continue
|
|
}
|
|
r, ok := keyRune(key)
|
|
if ok && r == m.target {
|
|
m.successTicks = 180
|
|
m.errorTicks = 0
|
|
m.playJingle()
|
|
return
|
|
}
|
|
m.errorTicks = 18
|
|
m.ctx.Audio.PlayError()
|
|
return
|
|
}
|
|
}
|
|
|
|
func (m *FindKeyMode) Update() {
|
|
if m.errorTicks > 0 {
|
|
m.errorTicks--
|
|
}
|
|
if m.successTicks > 0 {
|
|
m.successTicks--
|
|
if m.successTicks == 0 {
|
|
m.pickNext()
|
|
}
|
|
}
|
|
}
|
|
|
|
func (m *FindKeyMode) Draw(screen *ebiten.Image) {
|
|
screen.Fill(color.Black)
|
|
w, h := screen.Bounds().Dx(), screen.Bounds().Dy()
|
|
ui.Text(screen, "CTRL+F5", 20, 20, color.White, 2)
|
|
|
|
var clr color.Color = color.White
|
|
if m.errorTicks > 0 {
|
|
clr = color.NRGBA{R: 255, A: 255}
|
|
}
|
|
if m.successTicks > 0 {
|
|
clr = color.NRGBA{G: 255, A: 255}
|
|
}
|
|
ui.CenteredText(screen, string(m.target), w/2, h/2, clr, 18)
|
|
}
|
|
|
|
func (m *FindKeyMode) pickNext() {
|
|
m.target = rune(findChars[m.ctx.RNG.Intn(len(findChars))])
|
|
}
|
|
|
|
func (m *FindKeyMode) playJingle() {
|
|
const count = 4
|
|
next := m.ctx.RNG.Intn(count)
|
|
if count > 1 {
|
|
for next == m.lastJingle {
|
|
next = m.ctx.RNG.Intn(count)
|
|
}
|
|
}
|
|
m.lastJingle = next
|
|
path := filepath.Join("assets", "sounds", "jingle"+string(rune('1'+next))+".wav")
|
|
if m.ctx.Audio.PlayWAV(path, true) {
|
|
return
|
|
}
|
|
freq := 520 + float64(next)*120
|
|
m.ctx.Audio.PlayToneInterrupt(freq, 180*time.Millisecond, 0.28)
|
|
}
|