Support moving checkers on Android devices by tapping instead of dragging
This commit is contained in:
parent
f42ee3f497
commit
975da1f1f9
6 changed files with 49 additions and 71 deletions
|
@ -1,6 +1,7 @@
|
|||
1.1.4:
|
||||
- Display player "off" spaces
|
||||
- Allow bearing off by moving checkers to the "off" spaces
|
||||
- Support moving checkers on Android devices by tapping instead of dragging
|
||||
|
||||
1.1.3:
|
||||
- Support spectating matches
|
||||
|
|
108
game/board.go
108
game/board.go
|
@ -43,8 +43,7 @@ type board struct {
|
|||
lastDragClick time.Time
|
||||
moving *Sprite // Moving automatically
|
||||
|
||||
dragTouchId ebiten.TouchID
|
||||
touchIDs []ebiten.TouchID
|
||||
touchIDs []ebiten.TouchID
|
||||
|
||||
spaceWidth float64
|
||||
barWidth float64
|
||||
|
@ -339,8 +338,6 @@ func NewBoard() *board {
|
|||
b.Sprites.sprites[i] = b.newSprite(i >= 15)
|
||||
}
|
||||
|
||||
b.dragTouchId = -1
|
||||
|
||||
return b
|
||||
}
|
||||
|
||||
|
@ -812,7 +809,14 @@ func (b *board) updateBackgroundImage() {
|
|||
|
||||
func (b *board) drawSprite(target *ebiten.Image, sprite *Sprite) {
|
||||
x, y := float64(sprite.x), float64(sprite.y)
|
||||
if !sprite.toStart.IsZero() {
|
||||
if sprite == b.dragging {
|
||||
cx, cy := ebiten.CursorPosition()
|
||||
if cx != 0 || cy != 0 {
|
||||
x, y = float64(cx-sprite.w/2), float64(cy-sprite.h/2)
|
||||
} else {
|
||||
x, y = float64(b.dragX), float64(b.dragY)
|
||||
}
|
||||
} else if !sprite.toStart.IsZero() {
|
||||
progress := float64(time.Since(sprite.toStart)) / float64(sprite.toTime)
|
||||
if x == float64(sprite.toX) && y == float64(sprite.toY) {
|
||||
sprite.toStart = time.Time{}
|
||||
|
@ -986,6 +990,8 @@ func (b *board) Draw(screen *ebiten.Image) {
|
|||
|
||||
playerRoll := b.gameState.Roll1
|
||||
opponentRoll := b.gameState.Roll2
|
||||
roll1 := b.gameState.Roll1
|
||||
roll2 := b.gameState.Roll2
|
||||
if b.gameState.PlayerNumber == 2 {
|
||||
playerRoll, opponentRoll = opponentRoll, playerRoll
|
||||
}
|
||||
|
@ -1013,17 +1019,17 @@ func (b *board) Draw(screen *ebiten.Image) {
|
|||
op.GeoM.Translate(float64(innerCenter-diceSize/2), float64(b.y+(b.innerH/2))-diceGap-float64(diceSize))
|
||||
screen.DrawImage(diceImage(opponentRoll), op)
|
||||
}
|
||||
} else if b.gameState.Turn != b.gameState.PlayerNumber && b.gameState.Roll1 != 0 {
|
||||
} else if b.gameState.Turn != b.gameState.PlayerNumber && roll1 != 0 {
|
||||
{
|
||||
op := &ebiten.DrawImageOptions{}
|
||||
op.GeoM.Translate(float64(innerCenter-diceSize)-diceGap, float64(b.y+(b.innerH/2))-diceGap-float64(diceSize))
|
||||
screen.DrawImage(diceImage(b.gameState.Roll1), op)
|
||||
screen.DrawImage(diceImage(roll1), op)
|
||||
}
|
||||
|
||||
{
|
||||
op := &ebiten.DrawImageOptions{}
|
||||
op.GeoM.Translate(float64(innerCenter)+diceGap, float64(b.y+(b.innerH/2))-diceGap-float64(diceSize))
|
||||
screen.DrawImage(diceImage(b.gameState.Roll2), op)
|
||||
screen.DrawImage(diceImage(roll2), op)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1039,17 +1045,17 @@ func (b *board) Draw(screen *ebiten.Image) {
|
|||
op.GeoM.Translate(float64(innerCenter-diceSize/2), float64(b.y+(b.innerH/2))-diceGap-float64(diceSize))
|
||||
screen.DrawImage(diceImage(playerRoll), op)
|
||||
}
|
||||
} else if b.gameState.Turn == b.gameState.PlayerNumber && b.gameState.Roll1 != 0 {
|
||||
} else if b.gameState.Turn == b.gameState.PlayerNumber && roll1 != 0 {
|
||||
{
|
||||
op := &ebiten.DrawImageOptions{}
|
||||
op.GeoM.Translate(float64(innerCenter-diceSize)-diceGap, float64(b.y+(b.innerH/2))-diceGap-float64(diceSize))
|
||||
screen.DrawImage(diceImage(b.gameState.Roll1), op)
|
||||
screen.DrawImage(diceImage(roll1), op)
|
||||
}
|
||||
|
||||
{
|
||||
op := &ebiten.DrawImageOptions{}
|
||||
op.GeoM.Translate(float64(innerCenter)+diceGap, float64(b.y+(b.innerH/2))-diceGap-float64(diceSize))
|
||||
screen.DrawImage(diceImage(b.gameState.Roll2), op)
|
||||
screen.DrawImage(diceImage(roll2), op)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1386,7 +1392,7 @@ func (b *board) spaceAt(x, y int) int {
|
|||
for i := 0; i < bgammon.BoardSpaces; i++ {
|
||||
sx, sy, sw, sh := b.spaceRect(i)
|
||||
sx, sy = b.offsetPosition(i, sx, sy)
|
||||
if x >= sx && x <= sx+sw && y >= sy && y <= sy+sh {
|
||||
if x >= sx && x < sx+sw && y >= sy && y < sy+sh {
|
||||
return i
|
||||
}
|
||||
}
|
||||
|
@ -1687,32 +1693,21 @@ func (b *board) startDrag(s *Sprite, space int, click bool) {
|
|||
}
|
||||
|
||||
// finishDrag calls processState. It does not need to be locked.
|
||||
func (b *board) finishDrag(x int, y int) {
|
||||
func (b *board) finishDrag(x int, y int, click bool) {
|
||||
if b.dragging == nil {
|
||||
return
|
||||
} else if b.draggingClick && !click {
|
||||
return
|
||||
}
|
||||
|
||||
if x != 0 || y != 0 { // 0,0 is returned when the touch is released
|
||||
b.dragX, b.dragY = x, y
|
||||
}
|
||||
|
||||
var dropped *Sprite
|
||||
if b.draggingClick {
|
||||
if b.dragTouchId == -1 {
|
||||
if inpututil.IsMouseButtonJustReleased(ebiten.MouseButtonLeft) && time.Since(b.lastDragClick) >= 50*time.Millisecond {
|
||||
dropped = b.dragging
|
||||
b.dragging = nil
|
||||
}
|
||||
} else if inpututil.IsTouchJustReleased(b.dragTouchId) {
|
||||
dropped = b.dragging
|
||||
b.dragging = nil
|
||||
}
|
||||
} else {
|
||||
if b.dragTouchId == -1 {
|
||||
if inpututil.IsMouseButtonJustReleased(ebiten.MouseButtonLeft) {
|
||||
dropped = b.dragging
|
||||
b.dragging = nil
|
||||
}
|
||||
} else if inpututil.IsTouchJustReleased(b.dragTouchId) {
|
||||
dropped = b.dragging
|
||||
b.dragging = nil
|
||||
}
|
||||
if ((b.draggingClick && click) || (!b.draggingClick && len(ebiten.AppendTouchIDs(b.touchIDs[:0])) == 0 && !ebiten.IsMouseButtonPressed(ebiten.MouseButtonLeft))) && time.Since(b.lastDragClick) >= 50*time.Millisecond {
|
||||
dropped = b.dragging
|
||||
b.dragging = nil
|
||||
}
|
||||
if dropped != nil {
|
||||
if x == 0 && y == 0 {
|
||||
|
@ -1728,8 +1723,20 @@ func (b *board) finishDrag(x int, y int) {
|
|||
index = bgammon.SpaceHomePlayer
|
||||
}
|
||||
|
||||
if !b.draggingClick && index == b.draggingSpace && b.dragTouchId == -1 && !b.lastDragClick.IsZero() && time.Since(b.lastDragClick) < 500*time.Millisecond {
|
||||
if !b.draggingClick && index == b.draggingSpace && !b.lastDragClick.IsZero() && time.Since(b.lastDragClick) < 500*time.Millisecond {
|
||||
b.startDrag(dropped, index, true)
|
||||
if game.TouchInput {
|
||||
r := b.spaceRects[index]
|
||||
offset := int(b.spaceWidth) + int(b.overlapSize)*4
|
||||
if !b.bottomRow(index) {
|
||||
b.dragX, b.dragY = int(b.horizontalBorderSize)+r[0], r[1]+offset
|
||||
} else {
|
||||
b.dragX, b.dragY = int(b.horizontalBorderSize)+r[0], r[1]+r[3]-offset
|
||||
}
|
||||
if index == bgammon.SpaceBarPlayer || index == bgammon.SpaceBarOpponent {
|
||||
b.dragX += int(b.horizontalBorderSize / 2)
|
||||
}
|
||||
}
|
||||
b.processState()
|
||||
scheduleFrame()
|
||||
b.lastDragClick = time.Now()
|
||||
|
@ -1764,7 +1771,7 @@ func (b *board) finishDrag(x int, y int) {
|
|||
}
|
||||
|
||||
func (b *board) Update() {
|
||||
b.finishDrag(0, 0)
|
||||
b.finishDrag(0, 0, inpututil.IsMouseButtonJustPressed(ebiten.MouseButtonLeft))
|
||||
if b.dragging != nil && b.draggingClick {
|
||||
x, y := ebiten.CursorPosition()
|
||||
if x != 0 || y != 0 {
|
||||
|
@ -1896,44 +1903,17 @@ func (bw *BoardWidget) HandleMouse(cursor image.Point, pressed bool, clicked boo
|
|||
|
||||
if b.dragging == nil {
|
||||
// TODO allow grabbing multiple pieces by grabbing further down the stack
|
||||
|
||||
if !handled && b.playerTurn() && inpututil.IsMouseButtonJustPressed(ebiten.MouseButtonLeft) {
|
||||
if !handled && b.playerTurn() && clicked && (b.lastDragClick.IsZero() || time.Since(b.lastDragClick) >= 50*time.Millisecond) {
|
||||
s, space := b.spriteAt(cx, cy)
|
||||
if s != nil && s.colorWhite == (b.gameState.PlayerNumber == 2) && space != bgammon.SpaceHomePlayer && space != bgammon.SpaceHomeOpponent {
|
||||
b.startDrag(s, space, false)
|
||||
handled = true
|
||||
}
|
||||
}
|
||||
|
||||
b.touchIDs = inpututil.AppendJustPressedTouchIDs(b.touchIDs[:0])
|
||||
for _, id := range b.touchIDs {
|
||||
game.EnableTouchInput()
|
||||
x, y := ebiten.TouchPosition(id)
|
||||
if b.playerTurn() {
|
||||
b.dragX, b.dragY = x, y
|
||||
|
||||
s, space := b.spriteAt(x, y)
|
||||
if s != nil && s.colorWhite == (b.gameState.PlayerNumber == 2) && space != bgammon.SpaceHomePlayer && space != bgammon.SpaceHomeOpponent {
|
||||
b.startDrag(s, space, false)
|
||||
b.dragTouchId = id
|
||||
handled = true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
x, y := cx, cy
|
||||
if b.dragTouchId != -1 {
|
||||
x, y = ebiten.TouchPosition(b.dragTouchId)
|
||||
|
||||
if x != 0 || y != 0 { // 0,0 is returned when the touch is released
|
||||
b.dragX, b.dragY = x, y
|
||||
} else {
|
||||
x, y = b.dragX, b.dragY
|
||||
}
|
||||
}
|
||||
|
||||
b.finishDrag(x, y)
|
||||
b.finishDrag(x, y, clicked)
|
||||
|
||||
if b.dragging != nil {
|
||||
sprite := b.dragging
|
||||
|
|
|
@ -36,7 +36,7 @@ import (
|
|||
"golang.org/x/text/language"
|
||||
)
|
||||
|
||||
const version = "v1.1.3p1"
|
||||
const version = "v1.1.4"
|
||||
|
||||
const MaxDebug = 2
|
||||
|
||||
|
|
|
@ -46,9 +46,6 @@ msgstr ""
|
|||
msgid "Double"
|
||||
msgstr ""
|
||||
|
||||
msgid "Drag here to bear off"
|
||||
msgstr ""
|
||||
|
||||
msgid "Failed to join match: %s"
|
||||
msgstr ""
|
||||
|
||||
|
|
2
go.mod
2
go.mod
|
@ -3,7 +3,7 @@ module code.rocket9labs.com/tslocum/boxcars
|
|||
go 1.17
|
||||
|
||||
require (
|
||||
code.rocket9labs.com/tslocum/bgammon v0.0.0-20231118004131-667d0e9ba037
|
||||
code.rocket9labs.com/tslocum/bgammon v0.0.0-20231120015537-44b1eb1fd379
|
||||
code.rocket9labs.com/tslocum/etk v0.0.0-20231111061733-ffdef73ac8fb
|
||||
code.rocketnine.space/tslocum/kibodo v1.0.2
|
||||
code.rocketnine.space/tslocum/messeji v1.0.6-0.20231118073151-fee1357e1e9b
|
||||
|
|
4
go.sum
4
go.sum
|
@ -1,5 +1,5 @@
|
|||
code.rocket9labs.com/tslocum/bgammon v0.0.0-20231118004131-667d0e9ba037 h1:A9FnU3fiR2F8UqzJiKDIn7zyOBCqwz8j+1v4pMPMmDg=
|
||||
code.rocket9labs.com/tslocum/bgammon v0.0.0-20231118004131-667d0e9ba037/go.mod h1:NIwLSiHvXFJPJ6loPWJWb3esPaZT8Qk27hO6Tzassb4=
|
||||
code.rocket9labs.com/tslocum/bgammon v0.0.0-20231120015537-44b1eb1fd379 h1:7V0qBPP8IEVOxNKisVP8EM25YtbBhBFfUbq2vJ0vRaQ=
|
||||
code.rocket9labs.com/tslocum/bgammon v0.0.0-20231120015537-44b1eb1fd379/go.mod h1:NIwLSiHvXFJPJ6loPWJWb3esPaZT8Qk27hO6Tzassb4=
|
||||
code.rocket9labs.com/tslocum/etk v0.0.0-20231111061733-ffdef73ac8fb h1:CJgcS7SZi9ICZNCs1Hz6+YpajvCHmzyqY38xl+2z8h8=
|
||||
code.rocket9labs.com/tslocum/etk v0.0.0-20231111061733-ffdef73ac8fb/go.mod h1:mwrZqZLdxJhtbWKcuX3Ym06fFr1yqWH8FMXG5wHJ/KU=
|
||||
code.rocketnine.space/tslocum/kibodo v1.0.2 h1:0RfvVz+IUku8MFx9wvDb+p8byns5gAjQLUo4ZenWP44=
|
||||
|
|
Loading…
Reference in a new issue