👾
Ebitengine モバイル : TouchID で座標を取ろう!
モバイルといえば入力はタッチ!
Ebitengine で TouchID から座標を取得してみました。
公式のサンプルはこちら
タッチされた最後の座標だけを覚えておくシンプルバージョン
使用するAPI
値を保持する箇所を定義
type Game struct {
touchIds []ebiten.TouchID
touchPositionX int
touchPositionY int
}
座標を取得
func (g *Game) Update() error {
g.touchIds = ebiten.AppendTouchIDs(g.touchIds[:0]) // タッチされてる箇所を全て取得
for _, id := range g.touchIds {
x, y := ebiten.TouchPosition(id) // 順番にIDから座標を取得
g.touchPositionX = x
g.touchPositionY = y
}
}
マルチタッチで複数本の指でタッチしてたりすると、一番最後判定になった座標が touchPositionX
, touchPositionY
に入る。
指一本でタッチしてる座標を単純に取りたい、のであればこれで良さそう。
デバッグ情報を画面に表示
func (g *Game) Draw(screen *ebiten.Image) {
msg := fmt.Sprintf("position x=%d,y=%d", g.touchPositionX, g.touchPositionY)
ebitenutil.DebugPrint(screen, msg)
}
マルチタッチ対応
先ほどのバージョンだと、ループしてるくせに一番最後の値しか保持してないので、TouchID
をキーにした map に保存してみる。
(しれっと言ってるけどここで盛大にハマりました・・)
値を保持する箇所を定義
type Game struct {
touchIds []ebiten.TouchID
touchIdsPosition map[ebiten.TouchID]PositionXY
}
type PositionXY {
x, y int
}
座標を取得し、map に保存
func (g *Game) Update() error {
g.touchIds = ebiten.AppendTouchIDs(g.touchIds[:0])
g.touchIdsPosition = map[ebiten.TouchID]PositionXY{} // ここ重要!
for _, id := range g.touchIds {
x, y := ebiten.TouchPosition(id) // 順番にIDから座標を取得
g.touchIdsPosition[id] = PositionXY{x: x, y: y}
}
}
↑ここ重要!のコメント箇所が map を初期化してる(はず・・)
これがないと値を入れようとしても何も表示されない。
デバッグ情報を画面に表示
func (g *Game) Draw(screen *ebiten.Image) {
var msg = "TouchIDs : "
for _, id := range g.touchIds {
pos := g.touchIdsPosition[id]
msg += fmt.Sprintf("ID=%d (%d,%d)", id, pos.x, pos.y)
}
ebitenutil.DebugPrint(screen, msg)
}
これがないと値を入れようとしても何も表示されない について
何が起きているのかしっくりこなかったので、A Tour of Go の実行環境で試してみた。
package main
import "fmt"
type Position struct {
x, y int
}
type Game struct {
title string
touchIdPositionMap map[int]Position
}
func main() {
g := &Game{ title: "New Game" }
fmt.Printf("title %s\n", g.title)
//g.touchIdPositionMap = map[int]Position{} // 大事の行
g.touchIdPositionMap[0] = Position{x:10,y:20}
fmt.Printf("map %q\n", g.touchIdPositionMap)
}
map初期化部分をコメントアウトすると
resultに
title New Game
panic: assignment to entry in nil map
goroutine 1 [running]:
main.main()
/tmp/sandbox3778988721/prog.go:20 +0xa5
と出てきた。
普通に panic 起きてたのか・・・
Goでビルドした aar を Android プロジェクト側で読み込んでいると、この辺のエラーがどこにも出てこないっぽいので何が起きてるのかわからなかった・・・
なるほどスッキリ!
モバイル組み込みしてたからこその罠という感じがしますね・・
どこかにログ出てくれたらいいんだけど・・
Discussion