97 lines
2.7 KiB
Go
97 lines
2.7 KiB
Go
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)
|
|
}
|