LoginSignup
16
17

More than 1 year has passed since last update.

termbox-go の基本的な使い方

Last updated at Posted at 2017-09-11

termboxg-go および termbox は開発が終了したため、代替である tcell ライブラリを使った方が良いでしょう。


Go でTUI(Text User Interface) を作るための termbox-go の基本的な使い方のメモ

基本的な考え方

  1. メインループを作る
  2. イベントハンドリングを定義する
  3. 描画関数を定義する
  4. メインループ内で描画関数を呼び出す
package main

import (
	"math/rand"

	log "github.com/Sirupsen/logrus"
	"github.com/nsf/termbox-go"
)

const coldef = termbox.ColorDefault

// (3) 描画関数の定義
// (x, y)座標に四角を表示するだけの関数
func drawBox(x, y int) {
	termbox.Clear(coldef, coldef)
	termbox.SetCell(x, y, '┏', coldef, coldef)
	termbox.SetCell(x+1, y, '┓', coldef, coldef)
	termbox.SetCell(x, y+1, '┗', coldef, coldef)
	termbox.SetCell(x+1, y+1, '┛', coldef, coldef)
	termbox.Flush() // Flushを呼ばないと描画されない
}

func main() {
	if err := termbox.Init(); err != nil {
		log.Fatal(err)
	}
	defer termbox.Close()

	drawBox(0, 0)
	// (1) メインループ
MAINLOOP:
	for {
		w, h := termbox.Size()
		// (2) イベントハンドリング
		switch ev := termbox.PollEvent(); ev.Type {
		case termbox.EventKey:
			switch ev.Key {
			case termbox.KeyEsc:
				break MAINLOOP
			}
		}
		drawBox(rand.Intn(w), rand.Intn(h)) // (4) メインループ内で描画関数を呼び出す
	}
}
  • 描画の基本は termbox.SetCell(x座標, y座標, '表示したいrune', 前景色, 背景色) 関数
    • 指定した座標に1文字表示する関数
    • 極端な話、1座標ずつこれを呼び出せば好きな画面を構築できる

バッファを直接変更して画面に表示する方法

termbox-go はターミナル画面に表示される領域を termbox.Cell 構造体の配列として保持している。
back buffer とも呼ぶもよう。
この配列を直接指定して値を設定しても、同様に画面を操作可能。ただし、1次元配列なので画面幅と高さを取得してオフセット計算を行う必要がある。

package main

import (
	log "github.com/Sirupsen/logrus"
	"github.com/nsf/termbox-go"
)

const coldef = termbox.ColorDefault

func drawBox() {
	w, _ := termbox.Size()
	termbox.Clear(coldef, coldef)

	buf := termbox.CellBuffer()

	buf[0].Ch = '┏'
	buf[0].Bg = coldef
	buf[0].Fg = termbox.ColorRed

	buf[1].Ch = '┓'
	buf[1].Bg = termbox.ColorRed
	buf[1].Fg = coldef

	buf[w].Ch = '┗'
	buf[w].Bg = coldef
	buf[w].Fg = coldef

	buf[w+1].Ch = '┛'
	buf[w+1].Bg = coldef
	buf[w+1].Fg = coldef

	termbox.Flush() // Flushを呼ばないと描画されない
}

func main() {
	if err := termbox.Init(); err != nil {
		log.Fatal(err)
	}
	defer termbox.Close()

	drawBox()
MAINLOOP:
	for {
		switch ev := termbox.PollEvent(); ev.Type {
		case termbox.EventKey:
			switch ev.Key {
			case termbox.KeyEsc:
				break MAINLOOP
			}
		default:
			drawBox()
		}
	}
}

参考文献

16
17
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
16
17