Support connecting to FIBS via WebSocket proxy
parent
0c1c6ea6c3
commit
8618f9e674
|
@ -23,10 +23,14 @@ Run the following command to build a `boxcars` executable:
|
|||
|
||||
Run `~/go/bin/boxcars` to play.
|
||||
|
||||
## Android
|
||||
### Android
|
||||
|
||||
*Coming soon*
|
||||
|
||||
## Gameplay notes
|
||||
|
||||
- To bear off a piece, drag it from your home on to the bar.
|
||||
|
||||
## Support
|
||||
|
||||
Please share issues and suggestions [here](https://code.rocketnine.space/tslocum/boxcars/issues).
|
||||
|
@ -35,4 +39,5 @@ Please share issues and suggestions [here](https://code.rocketnine.space/tslocum
|
|||
|
||||
- [ebiten](https://github.com/hajimehoshi/ebiten) - 2D game engine
|
||||
- [draw2d](https://github.com/llgcode/draw2d) - 2D shape drawing
|
||||
- [kibodo](https://code.rocketnine.space/tslocum/kibodo) - On-screen keyboard
|
||||
- [resize](https://github.com/nfnt/resize) - Image resizing
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
// +build js,wasm
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"code.rocketnine.space/tslocum/fibs"
|
||||
)
|
||||
|
||||
func init() {
|
||||
fibs.DefaultProxyAddress = "wss://fibsproxy.rocketnine.space"
|
||||
|
||||
AutoWatch = true
|
||||
}
|
376
game/board.go
376
game/board.go
|
@ -17,6 +17,7 @@ import (
|
|||
type stateUpdate struct {
|
||||
from int
|
||||
to int
|
||||
s []string
|
||||
v []int
|
||||
}
|
||||
|
||||
|
@ -24,6 +25,8 @@ type board struct {
|
|||
x, y int
|
||||
w, h int
|
||||
|
||||
innerW, innerH int
|
||||
|
||||
op *ebiten.DrawImageOptions
|
||||
|
||||
backgroundImage *ebiten.Image
|
||||
|
@ -47,13 +50,19 @@ type board struct {
|
|||
overlapSize int
|
||||
|
||||
lastDirection int
|
||||
V []int
|
||||
|
||||
s []string
|
||||
v []int
|
||||
|
||||
moveQueue chan *stateUpdate
|
||||
|
||||
drawFrame chan bool
|
||||
|
||||
debug int // Print and draw debug information
|
||||
|
||||
Client *fibs.Client
|
||||
|
||||
dragX, dragY int
|
||||
}
|
||||
|
||||
func NewBoard() *board {
|
||||
|
@ -69,7 +78,8 @@ func NewBoard() *board {
|
|||
},
|
||||
spaces: make([][]*Sprite, 26),
|
||||
spaceRects: make([][4]int, 26),
|
||||
V: make([]int, 42),
|
||||
s: make([]string, 2),
|
||||
v: make([]int, 42),
|
||||
moveQueue: make(chan *stateUpdate, 10),
|
||||
drawFrame: make(chan bool, 10),
|
||||
}
|
||||
|
@ -270,9 +280,60 @@ func (b *board) draw(screen *ebiten.Image) {
|
|||
b.op.GeoM.Translate(float64(b.x), float64(b.y))
|
||||
screen.DrawImage(b.backgroundImage, b.op)
|
||||
|
||||
if b.debug == 2 {
|
||||
b.iterateSpaces(func(space int) {
|
||||
x, y, w, h := b.spaceRect(space)
|
||||
spaceImage := ebiten.NewImage(w, h)
|
||||
if space%2 == 0 {
|
||||
spaceImage.Fill(color.RGBA{50, 50, 50, 150})
|
||||
} else {
|
||||
spaceImage.Fill(color.RGBA{255, 255, 255, 150})
|
||||
}
|
||||
x, y = b.offsetPosition(x, y)
|
||||
b.op.GeoM.Reset()
|
||||
b.op.GeoM.Translate(float64(x), float64(y))
|
||||
screen.DrawImage(spaceImage, b.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
|
||||
ebiten.ScheduleFrame()
|
||||
}
|
||||
b.op.GeoM.Reset()
|
||||
b.op.GeoM.Translate(float64(sprite.x), float64(sprite.y))
|
||||
b.op.GeoM.Translate(x, y)
|
||||
|
||||
if sprite.colorWhite {
|
||||
screen.DrawImage(imgCheckerWhite, b.op)
|
||||
|
@ -314,6 +375,63 @@ func (b *board) draw(screen *ebiten.Image) {
|
|||
}
|
||||
})
|
||||
|
||||
// Draw opponent name and dice
|
||||
|
||||
borderSize := b.horizontalBorderSize
|
||||
if borderSize > b.barWidth/2 {
|
||||
borderSize = b.barWidth / 2
|
||||
}
|
||||
|
||||
playerColor := color.White
|
||||
opponentColor := color.Black
|
||||
if b.v[fibs.StatePlayerColor] == -1 {
|
||||
playerColor = color.Black
|
||||
opponentColor = color.White
|
||||
}
|
||||
|
||||
if b.v[fibs.StateOpponentDice1] > 0 {
|
||||
label := fmt.Sprintf("%s %d %d", b.s[fibs.StateOpponentName], b.v[fibs.StateOpponentDice1], b.v[fibs.StateOpponentDice2])
|
||||
|
||||
bounds := text.BoundString(mplusNormalFont, label)
|
||||
img := ebiten.NewImage(bounds.Dx()*2, bounds.Dy()*2)
|
||||
text.Draw(img, label, mplusNormalFont, 0, bounds.Dy(), opponentColor)
|
||||
|
||||
x := ((b.innerW - borderSize) / 4) - (bounds.Dx() / 2)
|
||||
y := (b.innerH / 2) - (bounds.Dy() / 2)
|
||||
x, y = b.offsetPosition(x, y)
|
||||
b.op.GeoM.Reset()
|
||||
b.op.GeoM.Translate(float64(x), float64(y))
|
||||
screen.DrawImage(img, b.op)
|
||||
}
|
||||
|
||||
// Draw player name and dice
|
||||
|
||||
if b.v[fibs.StatePlayerDice1] > 0 {
|
||||
label := fmt.Sprintf("%s %d %d", b.s[fibs.StatePlayerName], b.v[fibs.StatePlayerDice1], b.v[fibs.StatePlayerDice2])
|
||||
|
||||
bounds := text.BoundString(mplusNormalFont, label)
|
||||
img := ebiten.NewImage(bounds.Dx()*2, bounds.Dy()*2)
|
||||
text.Draw(img, label, mplusNormalFont, 0, bounds.Dy(), playerColor)
|
||||
|
||||
x := ((b.innerW / 4) * 3) - (bounds.Dx() / 2)
|
||||
y := (b.innerH / 2) - (bounds.Dy() / 2)
|
||||
x, y = b.offsetPosition(x, y)
|
||||
b.op.GeoM.Reset()
|
||||
b.op.GeoM.Translate(float64(x), float64(y))
|
||||
screen.DrawImage(img, b.op)
|
||||
}
|
||||
|
||||
/* TODO centering issue
|
||||
img := ebiten.NewImage(115, 20)
|
||||
img.Fill(color.White)
|
||||
x := (((b.innerW - borderSize) / 2) / 2) - (115 / 2)
|
||||
y := (b.innerH / 2) - (20 / 2)
|
||||
x = (b.innerW - borderSize) / 4
|
||||
x, y = b.offsetPosition(x, y)
|
||||
b.op.GeoM.Reset()
|
||||
b.op.GeoM.Translate(float64(x), float64(y))
|
||||
screen.DrawImage(img, b.op)*/
|
||||
|
||||
// Draw moving sprite
|
||||
if b.moving != nil {
|
||||
drawSprite(b.moving)
|
||||
|
@ -328,22 +446,14 @@ func (b *board) draw(screen *ebiten.Image) {
|
|||
b.iterateSpaces(func(space int) {
|
||||
x, y, w, h := b.spaceRect(space)
|
||||
spaceImage := ebiten.NewImage(w, h)
|
||||
if space%2 == 0 {
|
||||
spaceImage.Fill(color.RGBA{0, 0, 0, 150})
|
||||
} else {
|
||||
spaceImage.Fill(color.RGBA{255, 255, 255, 150})
|
||||
}
|
||||
|
||||
br := ""
|
||||
if b.bottomRow(space) {
|
||||
br = "B"
|
||||
}
|
||||
|
||||
ebitenutil.DebugPrint(spaceImage, fmt.Sprintf(" %d %s", space, br))
|
||||
|
||||
x, y = b.offsetPosition(x, y)
|
||||
|
||||
b.op.GeoM.Reset()
|
||||
b.op.GeoM.Scale(2, 2)
|
||||
b.op.GeoM.Translate(float64(x), float64(y))
|
||||
screen.DrawImage(spaceImage, b.op)
|
||||
})
|
||||
|
@ -390,6 +500,13 @@ func (b *board) setRect(x, y, w, h int) {
|
|||
b.horizontalBorderSize = 0
|
||||
}
|
||||
|
||||
borderSize := b.horizontalBorderSize
|
||||
if borderSize > b.barWidth/2 {
|
||||
borderSize = b.barWidth / 2
|
||||
}
|
||||
b.innerW = b.w - (b.horizontalBorderSize * 2)
|
||||
b.innerH = b.h - (b.verticalBorderSize * 2)
|
||||
|
||||
loadAssets(b.spaceWidth)
|
||||
|
||||
for i := 0; i < b.Sprites.num; i++ {
|
||||
|
@ -422,6 +539,8 @@ func (b *board) positionCheckers() {
|
|||
s.x += (w - s.w) / 2
|
||||
}
|
||||
}
|
||||
|
||||
b.ScheduleFrame()
|
||||
}
|
||||
|
||||
func (b *board) spriteAt(x, y int) *Sprite {
|
||||
|
@ -447,21 +566,14 @@ func (b *board) spaceAt(x, y int) int {
|
|||
return -1
|
||||
}
|
||||
|
||||
// TODO move to fibs library
|
||||
func (b *board) iterateSpaces(f func(space int)) {
|
||||
if b.V[fibs.StateDirection] == 1 {
|
||||
for space := 0; space <= 25; space++ {
|
||||
f(space)
|
||||
}
|
||||
return
|
||||
}
|
||||
for space := 25; space >= 0; space-- {
|
||||
for space := 0; space <= 25; space++ {
|
||||
f(space)
|
||||
}
|
||||
}
|
||||
|
||||
func (b *board) translateSpace(space int) int {
|
||||
if b.V[fibs.StateDirection] == -1 {
|
||||
if b.v[fibs.StateDirection] == -1 {
|
||||
// Spaces range from 24 - 1.
|
||||
if space == 0 || space == 25 {
|
||||
space = 25 - space
|
||||
|
@ -526,7 +638,7 @@ func (b *board) bottomRow(space int) bool {
|
|||
bottomStart := 1
|
||||
bottomEnd := 12
|
||||
bottomBar := 25
|
||||
if b.V[fibs.StateDirection] == 1 {
|
||||
if b.v[fibs.StateDirection] == 1 {
|
||||
bottomStart = 13
|
||||
bottomEnd = 24
|
||||
bottomBar = 0
|
||||
|
@ -562,12 +674,13 @@ func (b *board) stackSpaceRect(space int, stack int) (x, y, w, h int) {
|
|||
return x, y, w, h
|
||||
}
|
||||
|
||||
func (b *board) SetState(v []int) {
|
||||
b.moveQueue <- &stateUpdate{-1, -1, v}
|
||||
func (b *board) SetState(s []string, v []int) {
|
||||
// TODO setstate include playernames, use string?
|
||||
b.moveQueue <- &stateUpdate{-1, -1, s, v}
|
||||
}
|
||||
|
||||
func (b *board) ProcessState() {
|
||||
v := b.V
|
||||
v := b.v
|
||||
|
||||
if b.lastDirection != v[fibs.StateDirection] {
|
||||
b.setSpaceRects()
|
||||
|
@ -578,21 +691,26 @@ func (b *board) ProcessState() {
|
|||
b.spaces = make([][]*Sprite, 26)
|
||||
for space := 0; space < 26; space++ {
|
||||
spaceValue := v[fibs.StateBoardSpace0+space]
|
||||
if spaceValue == 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
white := spaceValue > 0
|
||||
// TODO reverse bar spaces - always?
|
||||
// TODO take direction into account
|
||||
if spaceValue == 0 {
|
||||
white = v[fibs.StatePlayerColor] == 1
|
||||
}
|
||||
|
||||
abs := spaceValue
|
||||
if abs < 0 {
|
||||
abs *= -1
|
||||
}
|
||||
|
||||
for i := 0; i < abs; i++ {
|
||||
var preMovesTo = b.Client.Board.Premoveto[space]
|
||||
var preMovesFrom = b.Client.Board.Premovefrom[space]
|
||||
|
||||
for i := 0; i < (abs+preMovesTo)-preMovesFrom; i++ {
|
||||
s := b.newSprite(white)
|
||||
if i >= abs {
|
||||
s.colorWhite = v[fibs.StatePlayerColor] == 1
|
||||
// TODO draw special premove overlay?
|
||||
}
|
||||
b.spaces[space] = append(b.spaces[space], s)
|
||||
b.Sprites.sprites = append(b.Sprites.sprites, s)
|
||||
}
|
||||
|
@ -602,9 +720,13 @@ func (b *board) ProcessState() {
|
|||
b.positionCheckers()
|
||||
}
|
||||
|
||||
func (b *board) _movePiece(sprite *Sprite, from int, to int, speed int) {
|
||||
moveSize := 1
|
||||
moveDelay := time.Duration(1/speed) * time.Millisecond
|
||||
func (b *board) _movePiece(sprite *Sprite, from int, to int, speed int, pause bool) {
|
||||
//moveSize := 1
|
||||
//moveDelay := time.Duration(1/speed) * time.Millisecond
|
||||
moveTime := time.Second / time.Duration(speed)
|
||||
pauseTime := 750 * time.Millisecond
|
||||
|
||||
b.moving = sprite
|
||||
|
||||
space := from
|
||||
for {
|
||||
|
@ -616,95 +738,76 @@ func (b *board) _movePiece(sprite *Sprite, from int, to int, speed int) {
|
|||
space--
|
||||
}
|
||||
|
||||
var diag bool
|
||||
|
||||
// Go to bar or home immediately
|
||||
if from == 0 || from == 25 || to == 0 || to == 25 {
|
||||
// TODO always enabled
|
||||
if true || from == 0 || from == 25 || to == 0 || to == 25 {
|
||||
space = to
|
||||
diag = true
|
||||
}
|
||||
|
||||
stack := len(b.spaces[space])
|
||||
if stack == 1 && sprite.colorWhite != b.spaces[space][0].colorWhite {
|
||||
stack = 0 // Hit
|
||||
} else if space != to {
|
||||
stack++
|
||||
}
|
||||
|
||||
x, y, _, _ := b.stackSpaceRect(space, stack)
|
||||
x, y = b.offsetPosition(x, y)
|
||||
|
||||
cy := y
|
||||
if cy > sprite.y == b.bottomRow(space) {
|
||||
if cy > sprite.y == b.bottomRow(space) && !diag {
|
||||
cy = sprite.y
|
||||
}
|
||||
|
||||
if sprite.x != x {
|
||||
// Center
|
||||
for {
|
||||
if sprite.y == cy {
|
||||
break
|
||||
}
|
||||
if sprite.y < cy {
|
||||
sprite.y += moveSize
|
||||
if sprite.y > cy {
|
||||
sprite.y = cy
|
||||
}
|
||||
} else if sprite.y > cy {
|
||||
sprite.y -= moveSize
|
||||
if sprite.y < cy {
|
||||
sprite.y = cy
|
||||
}
|
||||
}
|
||||
b.ScheduleFrame()
|
||||
time.Sleep(moveDelay)
|
||||
if diag {
|
||||
sprite.toX = x
|
||||
sprite.toY = y
|
||||
sprite.toTime = moveTime
|
||||
sprite.toStart = time.Now()
|
||||
ebiten.ScheduleFrame()
|
||||
time.Sleep(sprite.toTime)
|
||||
sprite.x = x
|
||||
sprite.y = y
|
||||
} else {
|
||||
if sprite.y != cy {
|
||||
sprite.toX = sprite.x
|
||||
sprite.toY = cy
|
||||
sprite.toTime = moveTime / 4
|
||||
sprite.toStart = time.Now()
|
||||
ebiten.ScheduleFrame()
|
||||
time.Sleep(sprite.toTime)
|
||||
sprite.toStart = time.Time{}
|
||||
sprite.y = cy
|
||||
}
|
||||
for {
|
||||
if sprite.x == x {
|
||||
break
|
||||
}
|
||||
if sprite.x < x {
|
||||
sprite.x += moveSize
|
||||
if sprite.x > x {
|
||||
sprite.x = x
|
||||
}
|
||||
} else if sprite.x > x {
|
||||
sprite.x -= moveSize
|
||||
if sprite.x < x {
|
||||
sprite.x = x
|
||||
}
|
||||
}
|
||||
b.ScheduleFrame()
|
||||
time.Sleep(moveDelay / 2)
|
||||
|
||||
if sprite.x != x {
|
||||
sprite.toX = x
|
||||
sprite.toY = sprite.y
|
||||
sprite.toTime = moveTime / 4
|
||||
sprite.toStart = time.Now()
|
||||
ebiten.ScheduleFrame()
|
||||
time.Sleep(sprite.toTime)
|
||||
sprite.toStart = time.Time{}
|
||||
sprite.x = x
|
||||
}
|
||||
}
|
||||
for {
|
||||
if sprite.x == x && sprite.y == y {
|
||||
break
|
||||
|
||||
if sprite.x != x || sprite.y != y {
|
||||
sprite.toX = x
|
||||
sprite.toY = y
|
||||
sprite.toTime = moveTime / 4
|
||||
sprite.toStart = time.Now()
|
||||
ebiten.ScheduleFrame()
|
||||
time.Sleep(sprite.toTime)
|
||||
sprite.toStart = time.Time{}
|
||||
sprite.x = x
|
||||
sprite.y = y
|
||||
}
|
||||
if sprite.x < x {
|
||||
sprite.x += moveSize
|
||||
if sprite.x > x {
|
||||
sprite.x = x
|
||||
}
|
||||
} else if sprite.x > x {
|
||||
sprite.x -= moveSize
|
||||
if sprite.x < x {
|
||||
sprite.x = x
|
||||
}
|
||||
}
|
||||
if sprite.y < y {
|
||||
sprite.y += moveSize
|
||||
if sprite.y > y {
|
||||
sprite.y = y
|
||||
}
|
||||
} else if sprite.y > y {
|
||||
sprite.y -= moveSize
|
||||
if sprite.y < y {
|
||||
sprite.y = y
|
||||
}
|
||||
}
|
||||
b.ScheduleFrame()
|
||||
time.Sleep(moveDelay)
|
||||
}
|
||||
}
|
||||
|
||||
// TODO do not add bear off pieces
|
||||
b.spaces[to] = append(b.spaces[to], sprite)
|
||||
for i, s := range b.spaces[from] {
|
||||
if s == sprite {
|
||||
|
@ -716,13 +819,41 @@ func (b *board) _movePiece(sprite *Sprite, from int, to int, speed int) {
|
|||
|
||||
b.ScheduleFrame()
|
||||
|
||||
time.Sleep(time.Second)
|
||||
if !pause {
|
||||
return
|
||||
}
|
||||
time.Sleep(pauseTime)
|
||||
}
|
||||
|
||||
func (b *board) handlePieceMoves() {
|
||||
for u := range b.moveQueue {
|
||||
if u.from == -1 || u.to == -1 {
|
||||
b.V = u.v
|
||||
same := true
|
||||
if len(b.s) == len(u.s) {
|
||||
for i := range b.s {
|
||||
if b.s[i] != u.s[i] {
|
||||
same = false
|
||||
break
|
||||
}
|
||||
}
|
||||
} else {
|
||||
same = false
|
||||
}
|
||||
if len(b.v) == len(u.v) {
|
||||
for i := range b.v {
|
||||
if b.v[i] != u.v[i] {
|
||||
same = false
|
||||
break
|
||||
}
|
||||
}
|
||||
} else {
|
||||
same = false
|
||||
}
|
||||
if same {
|
||||
continue
|
||||
}
|
||||
b.s = u.s
|
||||
b.v = u.v
|
||||
b.ProcessState()
|
||||
continue
|
||||
}
|
||||
|
@ -743,16 +874,16 @@ func (b *board) handlePieceMoves() {
|
|||
}
|
||||
}
|
||||
|
||||
b._movePiece(sprite, from, to, 1)
|
||||
b._movePiece(sprite, from, to, 1, moveAfter == nil)
|
||||
if moveAfter != nil {
|
||||
toBar := 0
|
||||
if b.V[fibs.StateTurn] == b.V[fibs.StatePlayerColor] {
|
||||
toBar = 25 // TODO how is this determined?
|
||||
if b.v[fibs.StateDirection] == -1 {
|
||||
toBar = 25
|
||||
}
|
||||
if b.V[fibs.StateDirection] == -1 {
|
||||
toBar = 25 - toBar
|
||||
if b.v[fibs.StateTurn] != b.v[fibs.StatePlayerColor] {
|
||||
toBar = 25 - toBar // TODO how is this determined?
|
||||
}
|
||||
b._movePiece(moveAfter, to, toBar, 2)
|
||||
b._movePiece(moveAfter, to, toBar, 1, true)
|
||||
}
|
||||
|
||||
b.positionCheckers()
|
||||
|
@ -761,7 +892,7 @@ func (b *board) handlePieceMoves() {
|
|||
|
||||
// Do not call directly
|
||||
func (b *board) movePiece(from int, to int) {
|
||||
b.moveQueue <- &stateUpdate{from, to, nil}
|
||||
b.moveQueue <- &stateUpdate{from, to, nil, nil}
|
||||
}
|
||||
|
||||
func (b *board) update() {
|
||||
|
@ -781,6 +912,9 @@ func (b *board) update() {
|
|||
b.touchIDs = inpututil.AppendJustPressedTouchIDs(b.touchIDs[:0])
|
||||
for _, id := range b.touchIDs {
|
||||
x, y := ebiten.TouchPosition(id)
|
||||
|
||||
b.dragX, b.dragY = x, y
|
||||
|
||||
s := b.spriteAt(x, y)
|
||||
if s != nil {
|
||||
b.dragging = s
|
||||
|
@ -792,6 +926,12 @@ func (b *board) update() {
|
|||
x, y := ebiten.CursorPosition()
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
var dropped *Sprite
|
||||
|
@ -810,12 +950,16 @@ func (b *board) update() {
|
|||
|
||||
index := b.spaceAt(x, y)
|
||||
if index >= 0 {
|
||||
for space, pieces := range b.spaces {
|
||||
for stackIndex, piece := range pieces {
|
||||
if piece == dropped {
|
||||
b.spaces[space] = append(b.spaces[space][:stackIndex], b.spaces[space][stackIndex+1:]...)
|
||||
b.spaces[index] = append(b.spaces[index], dropped)
|
||||
break
|
||||
if b.Client != nil {
|
||||
for space, pieces := range b.spaces {
|
||||
for _, piece := range pieces {
|
||||
if piece == dropped {
|
||||
if space != index {
|
||||
b.Client.Board.AddPreMove(space, index)
|
||||
b.ProcessState()
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
45
game/game.go
45
game/game.go
|
@ -113,6 +113,10 @@ type Sprite struct {
|
|||
h int
|
||||
x int
|
||||
y int
|
||||
toStart time.Time
|
||||
toTime time.Duration
|
||||
toX int
|
||||
toY int
|
||||
colorWhite bool
|
||||
}
|
||||
|
||||
|
@ -147,6 +151,7 @@ type Game struct {
|
|||
screenW, screenH int
|
||||
|
||||
drawBuffer bytes.Buffer
|
||||
lastDraw time.Time
|
||||
|
||||
spinnerIndex int
|
||||
|
||||
|
@ -157,6 +162,7 @@ type Game struct {
|
|||
usernameConfirmed bool
|
||||
|
||||
Watch bool
|
||||
TV bool
|
||||
|
||||
Client *fibs.Client
|
||||
|
||||
|
@ -200,8 +206,12 @@ func NewGame() *Game {
|
|||
func (g *Game) handleEvents() {
|
||||
for e := range g.Client.Event {
|
||||
switch event := e.(type) {
|
||||
case *fibs.EventBoardState:
|
||||
g.Board.SetState(event.S, event.V)
|
||||
case *fibs.EventMove:
|
||||
g.Board.movePiece(event.From, event.To)
|
||||
case *fibs.EventDraw:
|
||||
g.Board.ProcessState()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -214,17 +224,21 @@ func (g *Game) Connect() {
|
|||
address = defaultServerAddress
|
||||
}
|
||||
g.Client = fibs.NewClient(address, g.Username, g.Password)
|
||||
g.Board.Client = g.Client
|
||||
|
||||
go g.handleEvents()
|
||||
|
||||
c := g.Client
|
||||
|
||||
if g.Watch {
|
||||
if g.TV {
|
||||
go func() {
|
||||
time.Sleep(1 * time.Second)
|
||||
c.WatchRandomGame()
|
||||
|
||||
go g.renderLoop()
|
||||
time.Sleep(time.Second)
|
||||
c.Out <- []byte("tv")
|
||||
}()
|
||||
} else if g.Watch {
|
||||
go func() {
|
||||
time.Sleep(time.Second)
|
||||
c.Out <- []byte("watch")
|
||||
}()
|
||||
}
|
||||
|
||||
|
@ -236,15 +250,6 @@ func (g *Game) Connect() {
|
|||
}()
|
||||
}
|
||||
|
||||
func (g *Game) renderLoop() {
|
||||
t := time.NewTicker(time.Second)
|
||||
for range t.C {
|
||||
gameBoard := g.Board
|
||||
v := g.Client.Board.GetIntState()
|
||||
gameBoard.SetState(v)
|
||||
}
|
||||
}
|
||||
|
||||
func (g *Game) leftTouched() bool {
|
||||
for _, id := range g.touchIDs {
|
||||
x, _ := ebiten.TouchPosition(id)
|
||||
|
@ -322,7 +327,11 @@ func (g *Game) Update() error { // Called by ebiten only when input occurs
|
|||
g.inputBuffer += string(input.Rune)
|
||||
continue
|
||||
}
|
||||
if input.Key == ebiten.KeyEnter {
|
||||
if input.Key == ebiten.KeyBackspace {
|
||||
if len(g.inputBuffer) > 0 {
|
||||
g.inputBuffer = g.inputBuffer[:len(g.inputBuffer)-1]
|
||||
}
|
||||
} else if input.Key == ebiten.KeyEnter {
|
||||
g.inputBuffer += "\n"
|
||||
}
|
||||
}
|
||||
|
@ -381,6 +390,12 @@ func (g *Game) Update() error { // Called by ebiten only when input occurs
|
|||
}
|
||||
|
||||
func (g *Game) Draw(screen *ebiten.Image) {
|
||||
frameTime := time.Second / 175
|
||||
if time.Since(g.lastDraw) < frameTime {
|
||||
time.Sleep(time.Until(g.lastDraw.Add(frameTime)))
|
||||
}
|
||||
g.lastDraw = time.Now()
|
||||
|
||||
screen.Fill(color.RGBA{0, 102, 51, 255})
|
||||
|
||||
// Log in screen
|
||||
|
|
14
go.mod
14
go.mod
|
@ -3,24 +3,24 @@ module code.rocketnine.space/tslocum/boxcars
|
|||
go 1.17
|
||||
|
||||
require (
|
||||
code.rocketnine.space/tslocum/fibs v0.0.0-00010101000000-000000000000
|
||||
code.rocketnine.space/tslocum/kibodo v0.0.0-20210830194839-05789279ce56
|
||||
github.com/hajimehoshi/ebiten/v2 v2.2.0-alpha.12.0.20210828073710-0e5dca9453a5
|
||||
github.com/llgcode/draw2d v0.0.0-20210313082411-577c1ead272a
|
||||
code.rocketnine.space/tslocum/kibodo v0.0.0-20210908010225-5e1a355e9061
|
||||
github.com/hajimehoshi/ebiten/v2 v2.2.0-alpha.13
|
||||
github.com/llgcode/draw2d v0.0.0-20210904075650-80aa0a2a901d
|
||||
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646
|
||||
golang.org/x/image v0.0.0-20210628002857-a66eb6448b8d
|
||||
)
|
||||
|
||||
require (
|
||||
code.rocketnine.space/tslocum/fibs v0.0.0-20210908010953-ee35198ae238 // indirect
|
||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20210727001814-0db043d8d5be // indirect
|
||||
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 // indirect
|
||||
github.com/klauspost/compress v1.13.5 // indirect
|
||||
github.com/reiver/go-oi v1.0.0 // indirect
|
||||
github.com/reiver/go-telnet v0.0.0-20180421082511-9ff0b2ab096e // indirect
|
||||
golang.org/x/exp v0.0.0-20190731235908-ec7cb31e5a56 // indirect
|
||||
golang.org/x/mobile v0.0.0-20210716004757-34ab1303b554 // indirect
|
||||
golang.org/x/mobile v0.0.0-20210902104108-5d9a33257ab5 // indirect
|
||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c // indirect
|
||||
golang.org/x/sys v0.0.0-20210820121016-41cdb8703e55 // indirect
|
||||
golang.org/x/text v0.3.7 // indirect
|
||||
nhooyr.io/websocket v1.8.7 // indirect
|
||||
)
|
||||
|
||||
replace code.rocketnine.space/tslocum/fibs => /home/trevor/programming/fibs
|
||||
|
|
63
go.sum
63
go.sum
|
@ -1,17 +1,29 @@
|
|||
code.rocketnine.space/tslocum/kibodo v0.0.0-20210830194839-05789279ce56 h1:+KVT4Zw9CEQkxdNP81wuTvX3EHRPpPUQFwn6UVLoMFY=
|
||||
code.rocketnine.space/tslocum/kibodo v0.0.0-20210830194839-05789279ce56/go.mod h1:nWGK8LvmYgMZQcwGMYOOuZ19VsVYL5E1hREEJ2gV46M=
|
||||
code.rocketnine.space/tslocum/fibs v0.0.0-20210908010953-ee35198ae238 h1:l6mAo+aReaHfL07SF+MWxOAmNVl1ShXhoWTe8HqI/+c=
|
||||
code.rocketnine.space/tslocum/fibs v0.0.0-20210908010953-ee35198ae238/go.mod h1:f7Cz0zJWOnJ9DW7R/GTuE8z5XWQtkbXkKpksW9SDu2c=
|
||||
code.rocketnine.space/tslocum/kibodo v0.0.0-20210908010225-5e1a355e9061/go.mod h1:AWfFB/VvYWk+Lugwdpsko9hq8eMmJIgJx2JFSpVewNw=
|
||||
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
|
||||
github.com/gin-gonic/gin v1.6.3/go.mod h1:75u5sXoLsGZoRN5Sgbi1eraJ4GU3++wFwWzhwvtwp4M=
|
||||
github.com/go-gl/gl v0.0.0-20180407155706-68e253793080/go.mod h1:482civXOzJJCPzJ4ZOX/pwvXBWSnzD4OKMdH4ClKGbk=
|
||||
github.com/go-gl/glfw v0.0.0-20180426074136-46a8d530c326 h1:QqWaXlVeUGwSH7hO8giZP2Y06Qjl1LWR+FWC22YQsU8=
|
||||
github.com/go-gl/glfw v0.0.0-20180426074136-46a8d530c326/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
|
||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20210727001814-0db043d8d5be h1:vEIVIuBApEBQTEJt19GfhoU+zFSV+sNTa9E9FdnRYfk=
|
||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20210727001814-0db043d8d5be/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
||||
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 h1:DACJavvAHhabrF08vX0COfcOBJRhZ8lUbR+ZWIs0Y5g=
|
||||
github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
|
||||
github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8=
|
||||
github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA=
|
||||
github.com/go-playground/validator/v10 v10.2.0/go.mod h1:uOYAAleCW8F/7oMFd6aG0GOhaH6EGOAJShg8Id5JGkI=
|
||||
github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee/go.mod h1:L0fX3K22YWvt/FAX9NnzrNzcI4wNYi9Yku4O0LKYflo=
|
||||
github.com/gobwas/pool v0.2.0/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw=
|
||||
github.com/gobwas/ws v1.0.2/go.mod h1:szmBTxLgaFppYjEmNtny/v3w89xOydFnnZMcgRRu/EM=
|
||||
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k=
|
||||
github.com/hajimehoshi/bitmapfont/v2 v2.1.3 h1:JefUkL0M4nrdVwVq7MMZxSTh6mSxOylm+C4Anoucbb0=
|
||||
github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
|
||||
github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk=
|
||||
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||
github.com/hajimehoshi/bitmapfont/v2 v2.1.3/go.mod h1:2BnYrkTQGThpr/CY6LorYtt/zEPNzvE/ND69CRTaHMs=
|
||||
github.com/hajimehoshi/ebiten/v2 v2.2.0-alpha.12.0.20210828073710-0e5dca9453a5 h1:fUSKz2wvklV02UTmBXXDlNKc6molRGUu5O8b80AvEa4=
|
||||
github.com/hajimehoshi/ebiten/v2 v2.2.0-alpha.12.0.20210828073710-0e5dca9453a5/go.mod h1:B4Cje+Kb1ZjztrKFPaiMWOGXO3Vp8u+zIBdxkZqkyD4=
|
||||
github.com/hajimehoshi/ebiten/v2 v2.2.0-alpha.13/go.mod h1:44O6eBPGyRv8YctRbfzaqUH2sek5UdXh0aLWOP02ELI=
|
||||
github.com/hajimehoshi/file2byteslice v0.0.0-20200812174855-0e5e8a80490e/go.mod h1:CqqAHp7Dk/AqQiwuhV1yT2334qbA/tFWQW0MD2dGqUE=
|
||||
github.com/hajimehoshi/go-mp3 v0.3.2/go.mod h1:qMJj/CSDxx6CGHiZeCgbiq2DSUkbK0UbtXShQcnfyMM=
|
||||
github.com/hajimehoshi/oto v0.6.1/go.mod h1:0QXGEkbuJRohbJaxr7ZQSxnju7hEhseiPx2hrh6raOI=
|
||||
|
@ -19,35 +31,43 @@ github.com/hajimehoshi/oto/v2 v2.0.0-alpha.2/go.mod h1:rUKQmwMkqmRxe+IAof9+tuYA2
|
|||
github.com/jakecoffman/cp v1.1.0/go.mod h1:JjY/Fp6d8E1CHnu74gWNnU0+b9VzEdUVPoJxg2PsTQg=
|
||||
github.com/jfreymuth/oggvorbis v1.0.3/go.mod h1:1U4pqWmghcoVsCJJ4fRBKv9peUJMBHixthRlBeD6uII=
|
||||
github.com/jfreymuth/vorbis v1.0.2/go.mod h1:DoftRo4AznKnShRl1GxiTFCseHr4zR9BN3TWXyuzrqQ=
|
||||
github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||
github.com/jung-kurt/gofpdf v1.0.0/go.mod h1:7Id9E/uU8ce6rXgefFLlgrJj/GYY22cpxn+r32jIOes=
|
||||
github.com/llgcode/draw2d v0.0.0-20210313082411-577c1ead272a h1:gl2CmDrcVtYJY4YBKfNdpa4Igj3iNIBsaC3m8TQipYw=
|
||||
github.com/llgcode/draw2d v0.0.0-20210313082411-577c1ead272a/go.mod h1:mVa0dA29Db2S4LVqDYLlsePDzRJLDfdhVZiI15uY0FA=
|
||||
github.com/llgcode/ps v0.0.0-20150911083025-f1443b32eedb h1:61ndUreYSlWFeCY44JxDDkngVoI7/1MVhEl98Nm0KOk=
|
||||
github.com/klauspost/compress v1.10.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
|
||||
github.com/klauspost/compress v1.13.5 h1:9O69jUPDcsT9fEm74W92rZL9FQY7rCdaXVneq+yyzl4=
|
||||
github.com/klauspost/compress v1.13.5/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk=
|
||||
github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII=
|
||||
github.com/llgcode/draw2d v0.0.0-20210904075650-80aa0a2a901d/go.mod h1:mVa0dA29Db2S4LVqDYLlsePDzRJLDfdhVZiI15uY0FA=
|
||||
github.com/llgcode/ps v0.0.0-20150911083025-f1443b32eedb/go.mod h1:1l8ky+Ew27CMX29uG+a2hNOKpeNYEQjjtiALiBlFQbY=
|
||||
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 h1:zYyBkD/k9seD2A7fsi6Oo2LfFZAehjjQMERAvZLEDnQ=
|
||||
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
|
||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
||||
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646/go.mod h1:jpp1/29i3P1S/RLdc7JQKbRpFeM1dOBd8T9ki5s+AY8=
|
||||
github.com/pkg/browser v0.0.0-20180916011732-0a3d74bf9ce4/go.mod h1:4OwLy04Bl9Ef3GJJCoec+30X3LQs/0/m4HFRt/2LUSA=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/reiver/go-oi v1.0.0 h1:nvECWD7LF+vOs8leNGV/ww+F2iZKf3EYjYZ527turzM=
|
||||
github.com/reiver/go-oi v1.0.0/go.mod h1:RrDBct90BAhoDTxB1fenZwfykqeGvhI6LsNfStJoEkI=
|
||||
github.com/reiver/go-telnet v0.0.0-20180421082511-9ff0b2ab096e h1:quuzZLi72kkJjl+f5AQ93FMcadG19WkS7MO6TXFOSas=
|
||||
github.com/reiver/go-telnet v0.0.0-20180421082511-9ff0b2ab096e/go.mod h1:+5vNVvEWwEIx86DB9Ke/+a5wBI464eDRo3eF0LcfpWg=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||
github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw=
|
||||
github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY=
|
||||
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20190731235908-ec7cb31e5a56 h1:estk1glOnSVeJ9tdEZZc5mAMDZk5lNJNyJ6DvrBkTEU=
|
||||
golang.org/x/exp v0.0.0-20190731235908-ec7cb31e5a56/go.mod h1:JhuoJpWY28nO4Vef9tZUw9qufEGTyX1+7lmHxV5q5G4=
|
||||
golang.org/x/image v0.0.0-20180708004352-c73c2afc3b81/go.mod h1:ux5Hcp/YLpHSI86hEcLt0YII63i6oz57MZXIpbrjZUs=
|
||||
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
|
||||
golang.org/x/image v0.0.0-20190703141733-d6a02ce849c9/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
||||
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
||||
golang.org/x/image v0.0.0-20210628002857-a66eb6448b8d h1:RNPAfi2nHY7C2srAV8A49jpsYr0ADedCk1wq6fTMTvs=
|
||||
golang.org/x/image v0.0.0-20210628002857-a66eb6448b8d/go.mod h1:023OzeP/+EPmXeapQh35lcL3II3LrY8Ic+EFFKVhULM=
|
||||
golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=
|
||||
golang.org/x/mobile v0.0.0-20190415191353-3e0bab5405d6/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o=
|
||||
golang.org/x/mobile v0.0.0-20210716004757-34ab1303b554 h1:3In5TnfvnuXTF/uflgpYxSCEGP2NdYT37KsPh3VjZYU=
|
||||
golang.org/x/mobile v0.0.0-20210716004757-34ab1303b554/go.mod h1:jFTmtFYCV0MFtXBU+J5V/+5AUeVS0ON/0WkE/KSrl6E=
|
||||
golang.org/x/mobile v0.0.0-20210902104108-5d9a33257ab5/go.mod h1:c4YKU3ZylDmvbw+H/PSvm42vhdWbuxCzbonauEAP9B8=
|
||||
golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY=
|
||||
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
|
@ -55,27 +75,34 @@ golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn
|
|||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c h1:5KslGYwFpkhGh+Q16bwMP3cOontH8FOep7tGV86Y7SQ=
|
||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190429190828-d89cdac9e872/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210820121016-41cdb8703e55 h1:rw6UNGRMfarCepjI8qOepea/SXwIBVfTKjztZ5gBbq4=
|
||||
golang.org/x/sys v0.0.0-20210820121016-41cdb8703e55/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk=
|
||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
nhooyr.io/websocket v1.8.7 h1:usjR2uOr/zjjkVMy0lW+PPohFok7PCow5sDjLgX4P4g=
|
||||
nhooyr.io/websocket v1.8.7/go.mod h1:B70DZP8IakI65RVQ51MsWP/8jndNma26DVA/nFSCgW0=
|
||||
|
|
11
main.go
11
main.go
|
@ -18,6 +18,8 @@ const (
|
|||
screenHeight = 768
|
||||
)
|
||||
|
||||
var AutoWatch bool // WASM only
|
||||
|
||||
func main() {
|
||||
ebiten.SetWindowTitle("Boxcars")
|
||||
ebiten.SetWindowSize(screenWidth, screenHeight)
|
||||
|
@ -38,8 +40,13 @@ func main() {
|
|||
flag.StringVar(&g.Password, "password", "", "Password")
|
||||
flag.StringVar(&g.ServerAddress, "address", "fibs.com:4321", "Server address")
|
||||
flag.BoolVar(&g.Watch, "watch", false, "Watch random game")
|
||||
flag.BoolVar(&g.TV, "tv", false, "Watch random games continuously")
|
||||
flag.Parse()
|
||||
|
||||
if AutoWatch {
|
||||
g.Watch = true
|
||||
}
|
||||
|
||||
// Auto-connect
|
||||
if g.Username != "" && g.Password != "" {
|
||||
g.Connect()
|
||||
|
@ -60,10 +67,6 @@ func main() {
|
|||
|
||||
g.Client.Out <- append(scanner.Bytes())
|
||||
}
|
||||
|
||||
if scanner.Err() != nil {
|
||||
// TODO
|
||||
}
|
||||
}()
|
||||
|
||||
sigc := make(chan os.Signal, 1)
|
||||
|
|
Loading…
Reference in New Issue