nirasan's tech blog

趣味や仕事の覚え書きです。Linux, Perl, PHP, Ruby, Javascript, Android, Cocos2d-x, Unity などに興味があります。

termbox-go 使い方まとめ

はじめに

https://github.com/kurehajime/pong-command とかみたいな感じでターミナル上で任意の座標に任意の文字を表示できる termbox-go の使い方まとめ。

概要としては termbox の内部でターミナル上の座標に対応した文字のバッファを持っているので、SetCell で座標と文字などを指定して、Flush で表示するという感じ。

使い方

インストール

go get github.com/mattn/go-runewidth // termbox-go が参照している
go get github.com/nsf/termbox-go

初期化

err := termbox.Init()
if err != nil {
        panic(err)
}
defer termbox.Close()

バッファのクリア

文字色と背景色を指定してバッファをクリアする

色の一覧は https://godoc.org/github.com/nsf/termbox-go#Attribute

termbox.Clear(termbox.ColorDefault, termbox.ColorDefault)

文字のセット

https://godoc.org/github.com/nsf/termbox-go#SetCell

termbox.SetCell(1, 2, rune("a"), termbox.ColorDefault, termbox.ColorDefault)

文字の取得

termbox 内部のバッファから文字を取得する。

表示済みの文字の色だけ変える場合などに使用できる。

以下は2行目の3文字目を取得する。

width, _ := termbox.Size()
row := 1
col := 2
cell := termbox.CellBuffer()[(width*row)+col]
var char rune = cell.Ch
var fg termbox.Attribute = cell.Fg
var bg termbox.Attribute = cell.Bg

バッファの表示

termbox.Flush()

キーボード入力の受付

mainloop:
for {
  switch ev := termbox.PollEvent(); ev.Type {
  case termbox.EventKey:
    if ev.Key == termbox.KeyEsc {
      break mainloop // Esc で実行終了
    }
  case termbox.EventResize:
    // 画面のリサイズが発生したので再描画などをする
  }
}

マウス入力の受付

mac の Terminal.app や iTerm2.app では現状バグが有って正常に動かない様子(マウス入力時に Esc など他のキー押下イベントが発生してしまう)

https://github.com/nsf/termbox-go/issues/120

termbox.SetInputMode(termbox.InputEsc | termbox.InputMouse)
mainloop:
for {
  switch ev := termbox.PollEvent(); ev.Type {
  case termbox.EventMouse:
    if ev.Key == termbox.MouseLeft {
      mx := ev.MouseX
      my := ev.MouseY
    }
}

キーボードのアルファベットキーを取得する

  • termbox のデフォルトのキーイベントではアルファベットキーをそのままは受け取れないので github.com/jteeuwen/keyboard/termbox を使う
import keyboard "github.com/jteeuwen/keyboard/termbox"

func main() {
  // termbox の初期化などは省略
  pollEvent()
}

func pollEvent() {
    running := true

    kb := keyboard.New()
    kb.Bind(func() { running = false }, "escape", "q")
    kb.Bind(func() { /* do up */ }, "up", "k")
    kb.Bind(func() { /* do down */ }, "down", "j")
    kb.Bind(func() { /* do left */  }, "left", "h")
    kb.Bind(func() { /* do right */  }, "right", "l")

    for running {
        kb.Poll(termbox.PollEvent())
    }
}

文字色を数字で指定する

// 256色表示(デフォルトは8色)
termbox.SetOutputMode(termbox.Output256)
// 文字色を背景色を数字で指定(内部で-1されているので+1する)
termbox.SetCell(0, 0, "a", termbox.Attribute(100+1), termbox.Attribute(200+1))

参考アプリケーション