// Copyright 2016 The Ebiten Authors // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // +build example package twenty48 import ( "github.com/hajimehoshi/ebiten" "github.com/hajimehoshi/ebiten/inpututil" ) // Dir represents a direction. type Dir int const ( DirUp Dir = iota DirRight DirDown DirLeft ) type mouseState int const ( mouseStateNone mouseState = iota mouseStatePressing mouseStateSettled ) type touchState int const ( touchStateNone touchState = iota touchStatePressing touchStateSettled touchStateInvalid ) // String returns a string representing the direction. func (d Dir) String() string { switch d { case DirUp: return "Up" case DirRight: return "Right" case DirDown: return "Down" case DirLeft: return "Left" } panic("not reach") } // Vector returns a [-1, 1] value for each axis. func (d Dir) Vector() (x, y int) { switch d { case DirUp: return 0, -1 case DirRight: return 1, 0 case DirDown: return 0, 1 case DirLeft: return -1, 0 } panic("not reach") } // Input represents the current key states. type Input struct { 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. func NewInput() *Input { return &Input{} } 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() { 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 currently pressed direction. // Dir returns false if no direction key is pressed. func (i *Input) Dir() (Dir, bool) { if inpututil.IsKeyJustPressed(ebiten.KeyUp) { return DirUp, true } if inpututil.IsKeyJustPressed(ebiten.KeyLeft) { return DirLeft, true } if inpututil.IsKeyJustPressed(ebiten.KeyRight) { return DirRight, true } if inpututil.IsKeyJustPressed(ebiten.KeyDown) { return DirDown, true } if i.mouseState == mouseStateSettled { return i.mouseDir, true } if i.touchState == touchStateSettled { return i.touchDir, true } return 0, false }