package modes import ( "image/color" "time" "github.com/hajimehoshi/ebiten/v2" "kidskeyboard/internal/ui" ) type KeyboardMode struct { ctx Context highlight map[ebiten.Key]float64 layout [][]ebiten.Key } func NewKeyboardMode(ctx Context) *KeyboardMode { return &KeyboardMode{ ctx: ctx, highlight: map[ebiten.Key]float64{}, layout: [][]ebiten.Key{ {ebiten.KeyDigit1, ebiten.KeyDigit2, ebiten.KeyDigit3, ebiten.KeyDigit4, ebiten.KeyDigit5, ebiten.KeyDigit6, ebiten.KeyDigit7, ebiten.KeyDigit8, ebiten.KeyDigit9, ebiten.KeyDigit0}, {ebiten.KeyQ, ebiten.KeyW, ebiten.KeyE, ebiten.KeyR, ebiten.KeyT, ebiten.KeyY, ebiten.KeyU, ebiten.KeyI, ebiten.KeyO, ebiten.KeyP}, {ebiten.KeyA, ebiten.KeyS, ebiten.KeyD, ebiten.KeyF, ebiten.KeyG, ebiten.KeyH, ebiten.KeyJ, ebiten.KeyK, ebiten.KeyL}, {ebiten.KeyZ, ebiten.KeyX, ebiten.KeyC, ebiten.KeyV, ebiten.KeyB, ebiten.KeyN, ebiten.KeyM}, {ebiten.KeySpace, ebiten.KeyEnter, ebiten.KeyBackspace}, }, } } func (m *KeyboardMode) Name() string { return "CTRL+F1 Keyboard" } func (m *KeyboardMode) OnEnter() {} func (m *KeyboardMode) OnLeave() {} func (m *KeyboardMode) HandleInput() { for _, key := range justPressedKeys() { if !childKey(key) { continue } m.highlight[key] = 1 freq := 220 + float64(int(key)%48)*18 m.ctx.Audio.PlayTone(freq, 120*time.Millisecond, 0.22) } } func (m *KeyboardMode) Update() { for key, v := range m.highlight { v -= 0.035 if v <= 0 { delete(m.highlight, key) continue } m.highlight[key] = v } } func (m *KeyboardMode) Draw(screen *ebiten.Image) { screen.Fill(color.Black) w, h := screen.Bounds().Dx(), screen.Bounds().Dy() keyW := float32(w) / 13 keyH := float32(h) / 10 gap := float32(8) startY := float32(h)/2 - keyH*2.7 for rowIndex, row := range m.layout { rowWidth := float32(len(row))*(keyW+gap) - gap if rowIndex == 4 { rowWidth = keyW*7 + gap*2 } x := (float32(w) - rowWidth) / 2 y := startY + float32(rowIndex)*(keyH+gap) for _, key := range row { drawW := keyW if key == ebiten.KeySpace { drawW = keyW * 3 } if key == ebiten.KeyEnter || key == ebiten.KeyBackspace { drawW = keyW * 2 } m.drawKey(screen, key, x, y, drawW, keyH) x += drawW + gap } } ui.CenteredText(screen, "CTRL+F1", w/2, 48, color.White, 2) } func (m *KeyboardMode) drawKey(screen *ebiten.Image, key ebiten.Key, x, y, w, h float32) { base := color.NRGBA{R: 18, G: 18, B: 18, A: 255} if v := m.highlight[key]; v > 0 { base = color.NRGBA{R: uint8(60 + 180*v), G: uint8(80 + 160*v), B: 255, A: 255} } ui.Rect(screen, x, y, w, h, base) ui.RectOutline(screen, x, y, w, h, 2, color.White) ui.CenteredText(screen, keyLabel(key), int(x+w/2), int(y+h/2), color.White, 2) }