go-tetris/key_input.go

119 lines
1.9 KiB
Go

package main
import (
"github.com/nsf/termbox-go"
"runtime"
)
type KeyInput struct {
stopped bool
chanStop chan struct{}
chanKeyInput chan *termbox.Event
}
func NewKeyInput() *KeyInput {
return &KeyInput{
chanStop: make(chan struct{}, 1),
chanKeyInput: make(chan *termbox.Event, 8),
}
}
func (keyInput *KeyInput) Run() {
logger.Info("KeyInput Run start")
loop:
for {
select {
case <-keyInput.chanStop:
break loop
default:
}
event := termbox.PollEvent()
if event.Type == termbox.EventKey {
select {
case <-keyInput.chanStop:
break loop
default:
select {
case keyInput.chanKeyInput <- &event:
case <-keyInput.chanStop:
break loop
}
}
}
}
logger.Info("KeyInput Run end")
}
func (keyInput *KeyInput) ProcessEvent(event *termbox.Event) {
if event.Key == termbox.KeyCtrlI {
// ctrl i to log stack trace
buffer := make([]byte, 1<<16)
length := runtime.Stack(buffer, true)
logger.Debug("Stack trace", "buffer", string(buffer[:length]))
return
}
if event.Ch == 'q' || event.Key == termbox.KeyCtrlC {
if !keyInput.stopped {
keyInput.stopped = true
close(keyInput.chanStop)
}
engine.Stop()
return
}
if engine.gameOver {
if event.Key == termbox.KeySpace {
engine.NewGame()
}
return
}
if engine.paused {
if event.Ch == 'p' {
engine.UnPause()
}
return
}
if engine.aiEnabled {
switch event.Ch {
case 'p':
engine.Pause()
case 'i':
engine.DisableAi()
}
return
}
if event.Ch == 0 {
switch event.Key {
case termbox.KeySpace:
board.MinoDrop()
case termbox.KeyArrowUp:
board.MinoDrop()
case termbox.KeyArrowDown:
board.MinoMoveDown()
case termbox.KeyArrowLeft:
board.MinoMoveLeft()
case termbox.KeyArrowRight:
board.MinoMoveRight()
}
} else {
switch event.Ch {
case 'z':
board.MinoRotateLeft()
case 'x':
board.MinoRotateRight()
case 'p':
engine.Pause()
case 'i':
engine.EnabledAi()
}
}
}