From e4ca01db31ce07602e0df0f4d43f18ff9fba9873 Mon Sep 17 00:00:00 2001 From: Hajime Hoshi Date: Sat, 28 May 2016 23:15:28 +0900 Subject: [PATCH] mobile: Multitouches (#101) --- examples/mobile/mobile/update.go | 6 ++-- internal/ui/input_mobile.go | 24 +++++--------- internal/ui/ui_mobile.go | 15 ++------- mobile/run.go | 55 ++++++++++++++++++++++++++------ 4 files changed, 58 insertions(+), 42 deletions(-) diff --git a/examples/mobile/mobile/update.go b/examples/mobile/mobile/update.go index 71d28d5a1..688ba7c5c 100644 --- a/examples/mobile/mobile/update.go +++ b/examples/mobile/mobile/update.go @@ -131,9 +131,9 @@ func Update(screen *ebiten.Image) error { return err } msg := "" - if ebiten.IsMouseButtonPressed(ebiten.MouseButtonLeft) { - x, y := ebiten.CursorPosition() - msg = fmt.Sprintf("(%d, %d)", x, y) + for _, t := range ebiten.Touches() { + x, y := t.Position() + msg += fmt.Sprintf("ID: %d, (%d, %d)\n", t.ID(), x, y) } ebitenutil.DebugPrint(screen, msg) return nil diff --git a/internal/ui/input_mobile.go b/internal/ui/input_mobile.go index dde327561..fc7799951 100644 --- a/internal/ui/input_mobile.go +++ b/internal/ui/input_mobile.go @@ -16,22 +16,14 @@ package ui -func (i *input) touchDown(x, y int) { +func (i *input) updateTouches(touches []Touch) { i.m.Lock() defer i.m.Unlock() - i.mouseButtonPressed[MouseButtonLeft] = true - i.cursorX, i.cursorY = x, y -} - -func (i *input) touchUp(x, y int) { - i.m.Lock() - defer i.m.Unlock() - i.mouseButtonPressed[MouseButtonLeft] = false - i.cursorX, i.cursorY = x, y -} - -func (i *input) touchMove(x, y int) { - i.m.Lock() - defer i.m.Unlock() - i.cursorX, i.cursorY = x, y + ts := make([]touch, len(touches)) + for i := 0; i < len(ts); i++ { + ts[i].id = touches[i].ID() + x, y := touches[i].Position() + ts[i].x, ts[i].y = x, y + } + i.touches = ts } diff --git a/internal/ui/ui_mobile.go b/internal/ui/ui_mobile.go index 35ed487dc..eeb448f48 100644 --- a/internal/ui/ui_mobile.go +++ b/internal/ui/ui_mobile.go @@ -149,17 +149,6 @@ func Resume() { }() } -func TouchDown(x, y int) { - s := currentUI.actualScreenScale() - currentInput.touchDown(x/s, y/s) -} - -func TouchUp(x, y int) { - s := currentUI.actualScreenScale() - currentInput.touchUp(x/s, y/s) -} - -func TouchMove(x, y int) { - s := currentUI.actualScreenScale() - currentInput.touchMove(x/s, y/s) +func UpdateTouches(touches []Touch) { + currentInput.updateTouches(touches) } diff --git a/mobile/run.go b/mobile/run.go index 4f69c66d7..adfc961bd 100644 --- a/mobile/run.go +++ b/mobile/run.go @@ -32,9 +32,9 @@ type EventDispatcher interface { Render() error Pause() Resume() - TouchDown(x, y int) - TouchUp(x, y int) - TouchMove(x, y int) + TouchDown(id int, x, y int) + TouchMove(id int, x, y int) + TouchUp(id int) } // Start starts the game and returns immediately. @@ -42,10 +42,18 @@ type EventDispatcher interface { // Different from ebiten.Run, this invokes only the game loop and not the main (UI) loop. func Start(f func(*ebiten.Image) error, width, height, scale int, title string) (EventDispatcher, error) { chError = ebiten.RunWithoutMainLoop(f, width, height, scale, title) - return &eventDispatcher{}, nil + return &eventDispatcher{ + touches: map[int]position{}, + }, nil +} + +type position struct { + x int + y int } type eventDispatcher struct { + touches map[int]position } func (e *eventDispatcher) SetScreenSize(width, height int) { @@ -74,14 +82,41 @@ func (e *eventDispatcher) Resume() { ui.Resume() } -func (e *eventDispatcher) TouchDown(x, y int) { - ui.TouchDown(x, y) +// touch implements ui.Touch. +type touch struct { + id int + position position } -func (e *eventDispatcher) TouchUp(x, y int) { - ui.TouchUp(x, y) +func (t touch) ID() int { + return t.id } -func (e *eventDispatcher) TouchMove(x, y int) { - ui.TouchMove(x, y) +func (t touch) Position() (int, int) { + // TODO: Is this OK to adjust the position here? + return t.position.x / ui.CurrentUI().ScreenScale(), + t.position.y / ui.CurrentUI().ScreenScale() +} + +func (e *eventDispatcher) TouchDown(id int, x, y int) { + e.touches[id] = position{x, y} + e.updateTouches() +} + +func (e *eventDispatcher) TouchMove(id int, x, y int) { + e.touches[id] = position{x, y} + e.updateTouches() +} + +func (e *eventDispatcher) TouchUp(id int) { + delete(e.touches, id) + e.updateTouches() +} + +func (e *eventDispatcher) updateTouches() { + ts := []ui.Touch{} + for id, position := range e.touches { + ts = append(ts, touch{id, position}) + } + ui.UpdateTouches(ts) }