Add indicator showing where to drag when bearing off
This commit is contained in:
parent
272cf442df
commit
c888fbff06
6 changed files with 119 additions and 87 deletions
|
@ -1,4 +1,5 @@
|
|||
1.0.6:
|
||||
- Add indicator showing where to drag when bearing off
|
||||
- Optimize drawing board
|
||||
|
||||
1.0.5:
|
||||
|
|
181
game/board.go
181
game/board.go
|
@ -76,6 +76,8 @@ type board struct {
|
|||
uiGrid *etk.Grid
|
||||
frame *etk.Frame
|
||||
|
||||
bearOffOverlay *etk.Button
|
||||
|
||||
leaveGameGrid *etk.Grid
|
||||
confirmLeaveGameFrame *etk.Frame
|
||||
|
||||
|
@ -111,6 +113,11 @@ func NewBoard() *board {
|
|||
}
|
||||
b.fontUpdated()
|
||||
|
||||
b.bearOffOverlay = etk.NewButton(fmt.Sprintf("%s", gotext.Get("Drag here to bear off")), func() error {
|
||||
return nil
|
||||
})
|
||||
b.bearOffOverlay.SetVisible(false)
|
||||
|
||||
{
|
||||
leaveGameLabel := etk.NewText(gotext.Get("Leave match?"))
|
||||
leaveGameLabel.SetHorizontal(messeji.AlignCenter)
|
||||
|
@ -133,6 +140,7 @@ func NewBoard() *board {
|
|||
b.uiGrid.AddChildAt(b.inputGrid, 0, 4, 1, 1)
|
||||
|
||||
b.frame.AddChild(b.uiGrid)
|
||||
b.frame.AddChild(b.bearOffOverlay)
|
||||
b.frame.AddChild(b.leaveGameGrid)
|
||||
|
||||
b.buttons = []*boardButton{
|
||||
|
@ -458,6 +466,76 @@ func (b *board) drawButtons(screen *ebiten.Image) {
|
|||
}
|
||||
}
|
||||
|
||||
func (b *board) drawSprite(target *ebiten.Image, sprite *Sprite) {
|
||||
x, y := float64(sprite.x), float64(sprite.y)
|
||||
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{}
|
||||
sprite.x = sprite.toX
|
||||
sprite.y = sprite.toY
|
||||
} else {
|
||||
if x < float64(sprite.toX) {
|
||||
x += (float64(sprite.toX) - x) * progress
|
||||
if x > float64(sprite.toX) {
|
||||
x = float64(sprite.toX)
|
||||
}
|
||||
} else if x > float64(sprite.toX) {
|
||||
x -= (x - float64(sprite.toX)) * progress
|
||||
if x < float64(sprite.toX) {
|
||||
x = float64(sprite.toX)
|
||||
}
|
||||
}
|
||||
|
||||
if y < float64(sprite.toY) {
|
||||
y += (float64(sprite.toY) - y) * progress
|
||||
if y > float64(sprite.toY) {
|
||||
y = float64(sprite.toY)
|
||||
}
|
||||
} else if y > float64(sprite.toY) {
|
||||
y -= (y - float64(sprite.toY)) * progress
|
||||
if y < float64(sprite.toY) {
|
||||
y = float64(sprite.toY)
|
||||
}
|
||||
}
|
||||
}
|
||||
// Schedule another frame
|
||||
scheduleFrame()
|
||||
}
|
||||
|
||||
// Draw shadow.
|
||||
{
|
||||
op := &ebiten.DrawImageOptions{}
|
||||
op.Filter = ebiten.FilterLinear
|
||||
op.GeoM.Translate(x, y)
|
||||
op.ColorScale.Scale(0, 0, 0, 1)
|
||||
target.DrawImage(imgCheckerLight, op)
|
||||
}
|
||||
|
||||
// Draw checker.
|
||||
|
||||
checkerScale := 0.94
|
||||
|
||||
op := &ebiten.DrawImageOptions{}
|
||||
op.Filter = ebiten.FilterLinear
|
||||
op.GeoM.Translate(-b.spaceWidth/2, -b.spaceWidth/2)
|
||||
op.GeoM.Scale(checkerScale, checkerScale)
|
||||
op.GeoM.Translate((b.spaceWidth/2)+x, (b.spaceWidth/2)+y)
|
||||
|
||||
c := lightCheckerColor
|
||||
if !sprite.colorWhite {
|
||||
c = darkCheckerColor
|
||||
}
|
||||
op.ColorScale.Scale(0, 0, 0, 1)
|
||||
r := float32(c.R) / 0xff
|
||||
g := float32(c.G) / 0xff
|
||||
bl := float32(c.B) / 0xff
|
||||
op.ColorScale.SetR(r)
|
||||
op.ColorScale.SetG(g)
|
||||
op.ColorScale.SetB(bl)
|
||||
|
||||
target.DrawImage(imgCheckerLight, op)
|
||||
}
|
||||
func (b *board) Draw(screen *ebiten.Image) {
|
||||
{
|
||||
op := &ebiten.DrawImageOptions{}
|
||||
|
@ -465,77 +543,6 @@ func (b *board) Draw(screen *ebiten.Image) {
|
|||
screen.DrawImage(b.backgroundImage, op)
|
||||
}
|
||||
|
||||
drawSprite := func(sprite *Sprite) {
|
||||
x, y := float64(sprite.x), float64(sprite.y)
|
||||
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{}
|
||||
sprite.x = sprite.toX
|
||||
sprite.y = sprite.toY
|
||||
} else {
|
||||
if x < float64(sprite.toX) {
|
||||
x += (float64(sprite.toX) - x) * progress
|
||||
if x > float64(sprite.toX) {
|
||||
x = float64(sprite.toX)
|
||||
}
|
||||
} else if x > float64(sprite.toX) {
|
||||
x -= (x - float64(sprite.toX)) * progress
|
||||
if x < float64(sprite.toX) {
|
||||
x = float64(sprite.toX)
|
||||
}
|
||||
}
|
||||
|
||||
if y < float64(sprite.toY) {
|
||||
y += (float64(sprite.toY) - y) * progress
|
||||
if y > float64(sprite.toY) {
|
||||
y = float64(sprite.toY)
|
||||
}
|
||||
} else if y > float64(sprite.toY) {
|
||||
y -= (y - float64(sprite.toY)) * progress
|
||||
if y < float64(sprite.toY) {
|
||||
y = float64(sprite.toY)
|
||||
}
|
||||
}
|
||||
}
|
||||
// Schedule another frame
|
||||
scheduleFrame()
|
||||
}
|
||||
|
||||
// Draw shadow.
|
||||
{
|
||||
op := &ebiten.DrawImageOptions{}
|
||||
op.Filter = ebiten.FilterLinear
|
||||
op.GeoM.Translate(x, y)
|
||||
op.ColorScale.Scale(0, 0, 0, 1)
|
||||
screen.DrawImage(imgCheckerLight, op)
|
||||
}
|
||||
|
||||
// Draw checker.
|
||||
|
||||
checkerScale := 0.94
|
||||
|
||||
op := &ebiten.DrawImageOptions{}
|
||||
op.Filter = ebiten.FilterLinear
|
||||
op.GeoM.Translate(-b.spaceWidth/2, -b.spaceWidth/2)
|
||||
op.GeoM.Scale(checkerScale, checkerScale)
|
||||
op.GeoM.Translate((b.spaceWidth/2)+x, (b.spaceWidth/2)+y)
|
||||
|
||||
c := lightCheckerColor
|
||||
if !sprite.colorWhite {
|
||||
c = darkCheckerColor
|
||||
}
|
||||
op.ColorScale.Scale(0, 0, 0, 1)
|
||||
r := float32(c.R) / 0xff
|
||||
g := float32(c.G) / 0xff
|
||||
bl := float32(c.B) / 0xff
|
||||
op.ColorScale.SetR(r)
|
||||
op.ColorScale.SetG(g)
|
||||
op.ColorScale.SetB(bl)
|
||||
|
||||
screen.DrawImage(imgCheckerLight, op)
|
||||
}
|
||||
|
||||
for space := 0; space < bgammon.BoardSpaces; space++ {
|
||||
var numPieces int
|
||||
for i, sprite := range b.spaceSprites[space] {
|
||||
|
@ -544,7 +551,7 @@ func (b *board) Draw(screen *ebiten.Image) {
|
|||
}
|
||||
numPieces++
|
||||
|
||||
drawSprite(sprite)
|
||||
b.drawSprite(screen, sprite)
|
||||
|
||||
var overlayText string
|
||||
if i > 5 {
|
||||
|
@ -729,19 +736,16 @@ func (b *board) Draw(screen *ebiten.Image) {
|
|||
}
|
||||
}
|
||||
|
||||
// Draw moving sprite
|
||||
if b.moving != nil {
|
||||
drawSprite(b.moving)
|
||||
}
|
||||
|
||||
// Draw dragged sprite
|
||||
if b.dragging != nil {
|
||||
drawSprite(b.dragging)
|
||||
}
|
||||
|
||||
b.drawButtons(screen)
|
||||
}
|
||||
|
||||
func (b *board) drawDraggedChecker(screen *ebiten.Image) {
|
||||
if b.dragging == nil {
|
||||
return
|
||||
}
|
||||
b.drawSprite(screen, b.dragging)
|
||||
}
|
||||
|
||||
func (b *board) updateButtonRects() {
|
||||
btnRoll := b.buttons[0]
|
||||
btnReset := b.buttons[1]
|
||||
|
@ -1172,6 +1176,13 @@ func (b *board) handleClick(x int, y int) bool {
|
|||
return false
|
||||
}
|
||||
|
||||
func (b *board) startDrag(s *Sprite) {
|
||||
b.dragging = s
|
||||
if bgammon.CanBearOff(b.gameState.Board, b.gameState.PlayerNumber, true) && b.gameState.Board[bgammon.SpaceHomePlayer] == 0 {
|
||||
b.bearOffOverlay.SetVisible(true)
|
||||
}
|
||||
}
|
||||
|
||||
func (b *board) Update() {
|
||||
if b.Client == nil {
|
||||
return
|
||||
|
@ -1196,7 +1207,7 @@ func (b *board) Update() {
|
|||
if b.playerTurn() && inpututil.IsMouseButtonJustPressed(ebiten.MouseButtonLeft) && !handled && len(b.gameState.Available) > 0 {
|
||||
s := b.spriteAt(cx, cy)
|
||||
if s != nil && s.colorWhite == (b.gameState.PlayerNumber == 2) {
|
||||
b.dragging = s
|
||||
b.startDrag(s)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1210,7 +1221,7 @@ func (b *board) Update() {
|
|||
|
||||
s := b.spriteAt(x, y)
|
||||
if s != nil && s.colorWhite == (b.gameState.PlayerNumber == 2) {
|
||||
b.dragging = s
|
||||
b.startDrag(s)
|
||||
b.dragTouchId = id
|
||||
}
|
||||
}
|
||||
|
@ -1233,10 +1244,12 @@ func (b *board) Update() {
|
|||
if inpututil.IsMouseButtonJustReleased(ebiten.MouseButtonLeft) {
|
||||
dropped = b.dragging
|
||||
b.dragging = nil
|
||||
b.bearOffOverlay.SetVisible(false)
|
||||
}
|
||||
} else if inpututil.IsTouchJustReleased(b.dragTouchId) {
|
||||
dropped = b.dragging
|
||||
b.dragging = nil
|
||||
b.bearOffOverlay.SetVisible(false)
|
||||
}
|
||||
if dropped != nil {
|
||||
index := b.spaceAt(x, y)
|
||||
|
|
15
game/game.go
15
game/game.go
|
@ -451,6 +451,7 @@ func setViewBoard(view bool) {
|
|||
etk.SetFocus(inputBuffer)
|
||||
|
||||
game.Board.uiGrid.SetRect(game.Board.uiGrid.Rect())
|
||||
game.Board.bearOffOverlay.SetRect(game.Board.bearOffOverlay.Rect())
|
||||
} else {
|
||||
if !game.loggedIn {
|
||||
game.setRoot(connectGrid)
|
||||
|
@ -1244,6 +1245,8 @@ func (g *Game) Draw(screen *ebiten.Image) {
|
|||
log.Fatal(err)
|
||||
}
|
||||
|
||||
g.Board.drawDraggedChecker(screen)
|
||||
|
||||
game.keyboard.Draw(screen)
|
||||
|
||||
if Debug > 0 {
|
||||
|
@ -1337,6 +1340,12 @@ func (g *Game) Layout(outsideWidth, outsideHeight int) (int, int) {
|
|||
bufferPaddingX := int(g.Board.horizontalBorderSize / 2)
|
||||
g.Board.uiGrid.SetRect(image.Rect(bufferPaddingX, g.Board.h+bufferPaddingX, g.screenW-bufferPaddingX, g.screenH-bufferPaddingX))
|
||||
|
||||
w := g.screenW / 2
|
||||
h := (g.screenH - g.Board.h) / 2
|
||||
x := w / 2
|
||||
y := g.Board.h + h/2
|
||||
g.Board.bearOffOverlay.SetRect(image.Rect(x, y, x+w, y+h))
|
||||
|
||||
g.lobby.fullscreen = true
|
||||
g.lobby.setRect(0, 0, g.screenW, g.screenH-lobbyStatusBufferHeight)
|
||||
} else { // Landscape view.
|
||||
|
@ -1361,6 +1370,12 @@ func (g *Game) Layout(outsideWidth, outsideHeight int) (int, int) {
|
|||
bufferPaddingX := int(g.Board.horizontalBorderSize / 2)
|
||||
g.Board.uiGrid.SetRect(image.Rect(g.Board.w+bufferPaddingX, bufferPaddingX, g.screenW-bufferPaddingX, g.screenH-bufferPaddingX))
|
||||
|
||||
w := (g.screenW - bufferPaddingX - g.Board.w) / 2
|
||||
h := (g.screenH) / 4
|
||||
x := g.Board.w + bufferPaddingX + w/2
|
||||
y := g.screenH/2 - h/2
|
||||
g.Board.bearOffOverlay.SetRect(image.Rect(x, y, x+w, y+h))
|
||||
|
||||
g.lobby.fullscreen = true
|
||||
g.lobby.setRect(0, 0, g.screenW, g.screenH-lobbyStatusBufferHeight)
|
||||
}
|
||||
|
|
|
@ -37,6 +37,9 @@ 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-20231027191341-991fd6d481ca
|
||||
code.rocket9labs.com/tslocum/bgammon v0.0.0-20231031041258-b89776c323ab
|
||||
code.rocket9labs.com/tslocum/etk v0.0.0-20231029060740-36965d0b795c
|
||||
code.rocketnine.space/tslocum/kibodo v1.0.2-0.20231024233002-77bb43ba6fe8
|
||||
code.rocketnine.space/tslocum/messeji v1.0.5-0.20231028192343-ebfed687fb71
|
||||
|
|
4
go.sum
4
go.sum
|
@ -1,5 +1,5 @@
|
|||
code.rocket9labs.com/tslocum/bgammon v0.0.0-20231027191341-991fd6d481ca h1:JClRU4ONLpMiyW/BoI3O8Sb9yiYcySTZjcUfQ48GWvw=
|
||||
code.rocket9labs.com/tslocum/bgammon v0.0.0-20231027191341-991fd6d481ca/go.mod h1:U8qo60VHGzKFUHLZZJcvT0yDzwWybJBabsCw3Lyqx4s=
|
||||
code.rocket9labs.com/tslocum/bgammon v0.0.0-20231031041258-b89776c323ab h1:FH0ZI82dOOFv34Ywwxy2TDN34/MIs1dDEu4VI1tokTQ=
|
||||
code.rocket9labs.com/tslocum/bgammon v0.0.0-20231031041258-b89776c323ab/go.mod h1:U8qo60VHGzKFUHLZZJcvT0yDzwWybJBabsCw3Lyqx4s=
|
||||
code.rocket9labs.com/tslocum/etk v0.0.0-20231029060740-36965d0b795c h1:tupDtvsfZAGs9aruB5z4d+PesDFAZ7W2Q9+HQc/s3kk=
|
||||
code.rocket9labs.com/tslocum/etk v0.0.0-20231029060740-36965d0b795c/go.mod h1:C+pdWMPmOOPGk6adunX6PxE40F8CSg0h8LLwWIO2qeM=
|
||||
code.rocketnine.space/tslocum/kibodo v1.0.2-0.20231024233002-77bb43ba6fe8 h1:i1NzTMQA1DAAUIpFh2bnHVnH5j9hUkG6F3tqzsdD16Y=
|
||||
|
|
Loading…
Reference in a new issue