From ba86d37ce8fd362e2a0896d285e01c8686f7a7f2 Mon Sep 17 00:00:00 2001 From: Hajime Hoshi Date: Tue, 27 Jun 2017 00:36:38 +0900 Subject: [PATCH] examples/2048: Add mouse/touch feature (#370) --- examples/2048/2048/input.go | 130 ++++++++++++++++++++++++++++++++++++ 1 file changed, 130 insertions(+) diff --git a/examples/2048/2048/input.go b/examples/2048/2048/input.go index 6473e7381..3de49c0ca 100644 --- a/examples/2048/2048/input.go +++ b/examples/2048/2048/input.go @@ -30,6 +30,24 @@ const ( DirLeft ) +type mouseState int + +const ( + mouseStateNone mouseState = iota + mouseStatePressing + mouseStateSettled +) + +type touchState int + +const ( + touchStateNone touchState = iota + touchStatePressing + touchStateSettled + touchStateInvalid + n +) + // String returns a string representing the direction. func (d Dir) String() string { switch d { @@ -63,6 +81,19 @@ func (d Dir) Vector() (x, y int) { // Input represents the current key states. type Input struct { keyState map[ebiten.Key]int + + mouseState mouseState + mouseInitPosX int + mouseInitPosY int + mouseDir Dir + + touchState touchState + touchID int + touchInitPosX int + touchInitPosY int + touchLastPosX int + touchLastPosY int + touchDir Dir } // NewInput generates a new Input object. @@ -81,6 +112,30 @@ var ( } ) +func abs(x int) int { + if x < 0 { + return -x + } + return x +} + +func vecToDir(dx, dy int) (Dir, bool) { + if abs(dx) < 4 && abs(dy) < 4 { + return 0, false + } + if abs(dx) < abs(dy) { + if dy < 0 { + return DirUp, true + } + return DirDown, true + } else { + if dx < 0 { + return DirLeft, true + } + return DirRight, true + } +} + // Update updates the current input states. func (i *Input) Update() { for k := range dirKeys { @@ -90,6 +145,75 @@ func (i *Input) Update() { i.keyState[k] = 0 } } + switch i.mouseState { + case mouseStateNone: + if ebiten.IsMouseButtonPressed(ebiten.MouseButtonLeft) { + x, y := ebiten.CursorPosition() + i.mouseInitPosX = x + i.mouseInitPosY = y + i.mouseState = mouseStatePressing + } + case mouseStatePressing: + if !ebiten.IsMouseButtonPressed(ebiten.MouseButtonLeft) { + x, y := ebiten.CursorPosition() + dx := x - i.mouseInitPosX + dy := y - i.mouseInitPosY + d, ok := vecToDir(dx, dy) + if !ok { + i.mouseState = mouseStateNone + break + } + i.mouseDir = d + i.mouseState = mouseStateSettled + } + case mouseStateSettled: + i.mouseState = mouseStateNone + } + switch i.touchState { + case touchStateNone: + ts := ebiten.Touches() + if len(ts) == 1 { + i.touchID = ts[0].ID() + x, y := ts[0].Position() + i.touchInitPosX = x + i.touchInitPosY = y + i.touchLastPosX = x + i.touchLastPosX = y + i.touchState = touchStatePressing + } + case touchStatePressing: + ts := ebiten.Touches() + if len(ts) >= 2 { + break + } + if len(ts) == 1 { + if ts[0].ID() != i.touchID { + i.touchState = touchStateInvalid + } else { + x, y := ts[0].Position() + i.touchLastPosX = x + i.touchLastPosY = y + } + break + } + if len(ts) == 0 { + dx := i.touchLastPosX - i.touchInitPosX + dy := i.touchLastPosY - i.touchInitPosY + d, ok := vecToDir(dx, dy) + if !ok { + i.touchState = touchStateNone + break + } + i.touchDir = d + i.touchState = touchStateSettled + } + case touchStateSettled: + i.touchState = touchStateNone + case touchStateInvalid: + if len(ebiten.Touches()) == 0 { + i.touchState = touchStateNone + } + } } // Dir returns a currenly pressed direction. @@ -100,5 +224,11 @@ func (i *Input) Dir() (Dir, bool) { return d, true } } + if i.mouseState == mouseStateSettled { + return i.mouseDir, true + } + if i.touchState == touchStateSettled { + return i.touchDir, true + } return 0, false }