Add game status buffer
parent
a061c032c6
commit
57f265acf3
128
game/board.go
128
game/board.go
|
@ -37,12 +37,12 @@ type board struct {
|
|||
dragTouchId ebiten.TouchID
|
||||
touchIDs []ebiten.TouchID
|
||||
|
||||
spaceWidth int
|
||||
barWidth int
|
||||
spaceWidth float64
|
||||
barWidth float64
|
||||
triangleOffset float64
|
||||
horizontalBorderSize int
|
||||
verticalBorderSize int
|
||||
overlapSize int
|
||||
horizontalBorderSize float64
|
||||
verticalBorderSize float64
|
||||
overlapSize float64
|
||||
|
||||
lastDirection int
|
||||
|
||||
|
@ -62,8 +62,8 @@ func NewBoard() *board {
|
|||
b := &board{
|
||||
barWidth: 100,
|
||||
triangleOffset: float64(50),
|
||||
horizontalBorderSize: 50,
|
||||
verticalBorderSize: 25,
|
||||
horizontalBorderSize: 20,
|
||||
verticalBorderSize: 10,
|
||||
overlapSize: 97,
|
||||
Sprites: &Sprites{
|
||||
sprites: make([]*Sprite, 30),
|
||||
|
@ -139,8 +139,8 @@ func (b *board) updateBackgroundImage() {
|
|||
if borderSize > b.barWidth/2 {
|
||||
borderSize = b.barWidth / 2
|
||||
}
|
||||
frameW := b.w - ((b.horizontalBorderSize - borderSize) * 2)
|
||||
innerW := b.w - (b.horizontalBorderSize * 2) // Outer board width (including frame)
|
||||
frameW := b.w - int((b.horizontalBorderSize-borderSize)*2)
|
||||
innerW := float64(b.w) - b.horizontalBorderSize*2 // Outer board width (including frame)
|
||||
|
||||
// Table
|
||||
box := image.NewRGBA(image.Rect(0, 0, b.w, b.h))
|
||||
|
@ -157,7 +157,7 @@ func (b *board) updateBackgroundImage() {
|
|||
b.backgroundImage.DrawImage(img, b.op)
|
||||
|
||||
// Face
|
||||
box = image.NewRGBA(image.Rect(0, 0, innerW, b.h-(b.verticalBorderSize*2)))
|
||||
box = image.NewRGBA(image.Rect(0, 0, int(innerW), b.h-int(b.verticalBorderSize*2)))
|
||||
img = ebiten.NewImageFromImage(box)
|
||||
img.Fill(faceColor)
|
||||
b.op.GeoM.Reset()
|
||||
|
@ -165,18 +165,18 @@ func (b *board) updateBackgroundImage() {
|
|||
b.backgroundImage.DrawImage(img, b.op)
|
||||
|
||||
// Bar
|
||||
box = image.NewRGBA(image.Rect(0, 0, b.barWidth, b.h))
|
||||
box = image.NewRGBA(image.Rect(0, 0, int(b.barWidth), b.h))
|
||||
img = ebiten.NewImageFromImage(box)
|
||||
img.Fill(frameColor)
|
||||
b.op.GeoM.Reset()
|
||||
b.op.GeoM.Translate(float64((b.w/2)-(b.barWidth/2)), 0)
|
||||
b.op.GeoM.Translate(float64((b.w/2)-int(b.barWidth/2)), 0)
|
||||
b.backgroundImage.DrawImage(img, b.op)
|
||||
|
||||
// Draw triangles
|
||||
baseImg := image.NewRGBA(image.Rect(0, 0, b.w-(b.horizontalBorderSize*2), b.h-(b.verticalBorderSize*2)))
|
||||
baseImg := image.NewRGBA(image.Rect(0, 0, b.w-int(b.horizontalBorderSize*2), b.h-int(b.verticalBorderSize*2)))
|
||||
gc := draw2dimg.NewGraphicContext(baseImg)
|
||||
for i := 0; i < 2; i++ {
|
||||
triangleTip := float64((b.h - (b.verticalBorderSize * 2)) / 2)
|
||||
triangleTip := (float64(b.h) - (b.verticalBorderSize * 2)) / 2
|
||||
if i == 0 {
|
||||
triangleTip -= b.triangleOffset
|
||||
} else {
|
||||
|
@ -194,7 +194,7 @@ func (b *board) updateBackgroundImage() {
|
|||
gc.SetFillColor(triangleB)
|
||||
}
|
||||
|
||||
tx := b.spaceWidth * j
|
||||
tx := b.spaceWidth * float64(j)
|
||||
ty := b.h * i
|
||||
if j >= 6 {
|
||||
tx += b.barWidth
|
||||
|
@ -233,8 +233,8 @@ func (b *board) updateBackgroundImage() {
|
|||
edge := float64((((innerW) - b.barWidth) / 2) + borderSize)
|
||||
gc.MoveTo(float64(borderSize), float64(b.verticalBorderSize))
|
||||
gc.LineTo(edge, float64(b.verticalBorderSize))
|
||||
gc.LineTo(edge, float64(b.h-b.verticalBorderSize))
|
||||
gc.LineTo(float64(borderSize), float64(b.h-b.verticalBorderSize))
|
||||
gc.LineTo(edge, float64(b.h-int(b.verticalBorderSize)))
|
||||
gc.LineTo(float64(borderSize), float64(b.h-int(b.verticalBorderSize)))
|
||||
gc.LineTo(float64(borderSize), float64(b.verticalBorderSize))
|
||||
gc.Close()
|
||||
gc.Stroke()
|
||||
|
@ -243,14 +243,14 @@ func (b *board) updateBackgroundImage() {
|
|||
edgeEnd := float64(innerW + borderSize)
|
||||
gc.MoveTo(float64(edgeStart), float64(b.verticalBorderSize))
|
||||
gc.LineTo(edgeEnd, float64(b.verticalBorderSize))
|
||||
gc.LineTo(edgeEnd, float64(b.h-b.verticalBorderSize))
|
||||
gc.LineTo(float64(edgeStart), float64(b.h-b.verticalBorderSize))
|
||||
gc.LineTo(edgeEnd, float64(b.h-int(b.verticalBorderSize)))
|
||||
gc.LineTo(float64(edgeStart), float64(b.h-int(b.verticalBorderSize)))
|
||||
gc.LineTo(float64(edgeStart), float64(b.verticalBorderSize))
|
||||
gc.Close()
|
||||
gc.Stroke()
|
||||
img = ebiten.NewImageFromImage(borderImage)
|
||||
b.op.GeoM.Reset()
|
||||
b.op.GeoM.Translate(float64(b.horizontalBorderSize-borderSize), 0)
|
||||
b.op.GeoM.Translate(b.horizontalBorderSize-borderSize, 0)
|
||||
b.backgroundImage.DrawImage(img, b.op)
|
||||
}
|
||||
|
||||
|
@ -360,9 +360,9 @@ func (b *board) draw(screen *ebiten.Image) {
|
|||
labelColor = color.RGBA{0, 0, 0, 255}
|
||||
}
|
||||
|
||||
bounds := text.BoundString(mplusNormalFont, overlayText)
|
||||
bounds := text.BoundString(normalFont, overlayText)
|
||||
overlayImage := ebiten.NewImage(bounds.Dx()*2, bounds.Dy()*2)
|
||||
text.Draw(overlayImage, overlayText, mplusNormalFont, 0, bounds.Dy(), labelColor)
|
||||
text.Draw(overlayImage, overlayText, normalFont, 0, bounds.Dy(), labelColor)
|
||||
|
||||
x, y, w, h := b.stackSpaceRect(space, numPieces-1)
|
||||
x += (w / 2) - (bounds.Dx() / 2)
|
||||
|
@ -412,7 +412,7 @@ func (b *board) draw(screen *ebiten.Image) {
|
|||
}
|
||||
|
||||
drawLabel := func(label string, labelColor color.Color, border bool, borderColor color.Color) *ebiten.Image {
|
||||
bounds := text.BoundString(mplusNormalFont, label)
|
||||
bounds := text.BoundString(normalFont, label)
|
||||
|
||||
w := int(float64(bounds.Dx()) * 1.5)
|
||||
h := int(float64(bounds.Dy()) * 2)
|
||||
|
@ -432,7 +432,7 @@ func (b *board) draw(screen *ebiten.Image) {
|
|||
}
|
||||
|
||||
img := ebiten.NewImageFromImage(baseImg)
|
||||
text.Draw(img, label, mplusNormalFont, (w-bounds.Dx())/2, int(float64(h-(bounds.Max.Y/2))*0.75), labelColor)
|
||||
text.Draw(img, label, normalFont, (w-bounds.Dx())/2, int(float64(h-(bounds.Max.Y/2))*0.75), labelColor)
|
||||
|
||||
return img
|
||||
}
|
||||
|
@ -443,7 +443,7 @@ func (b *board) draw(screen *ebiten.Image) {
|
|||
img := drawLabel(label, opponentColor, b.v[fibs.StateTurn] != b.v[fibs.StatePlayerColor], opponentColor)
|
||||
bounds := img.Bounds()
|
||||
|
||||
x := ((b.innerW - borderSize) / 4) - (bounds.Dx() / 2)
|
||||
x := int(((float64(b.innerW) - borderSize) / 4) - (float64(bounds.Dx()) / 2))
|
||||
y := (b.innerH / 2) - (bounds.Dy() / 2)
|
||||
x, y = b.offsetPosition(x, y)
|
||||
b.op.GeoM.Reset()
|
||||
|
@ -486,8 +486,8 @@ func (b *board) draw(screen *ebiten.Image) {
|
|||
img.DrawImage(ebiten.NewImageFromImage(baseImg), nil)
|
||||
|
||||
label := "Reset"
|
||||
bounds := text.BoundString(mplusNormalFont, label)
|
||||
text.Draw(img, label, mplusNormalFont, (w-bounds.Dx())/2, (h+(bounds.Dy()/2))/2, color.Black)
|
||||
bounds := text.BoundString(normalFont, label)
|
||||
text.Draw(img, label, normalFont, (w-bounds.Dx())/2, (h+(bounds.Dy()/2))/2, color.Black)
|
||||
|
||||
b.op.GeoM.Reset()
|
||||
b.op.GeoM.Translate(float64(x), float64(y))
|
||||
|
@ -532,50 +532,34 @@ func (b *board) setRect(x, y, w, h int) {
|
|||
if b.x == x && b.y == y && b.w == w && b.h == h {
|
||||
return
|
||||
}
|
||||
const stackAllowance = 0.97 // TODO configurable
|
||||
|
||||
b.x, b.y, b.w, b.h = x, y, w, h
|
||||
|
||||
b.horizontalBorderSize = 0
|
||||
b.triangleOffset = (float64(b.h) - (b.verticalBorderSize * 2)) / 15
|
||||
|
||||
b.triangleOffset = float64(b.h-(b.verticalBorderSize*2)) / 15
|
||||
b.spaceWidth = (float64(b.w) - (b.horizontalBorderSize * 2)) / 13
|
||||
b.barWidth = b.spaceWidth
|
||||
|
||||
for {
|
||||
b.verticalBorderSize = 7 // TODO configurable
|
||||
|
||||
b.spaceWidth = (b.w - (b.horizontalBorderSize * 2)) / 13
|
||||
|
||||
b.barWidth = b.spaceWidth
|
||||
|
||||
b.overlapSize = (((b.h - (b.verticalBorderSize * 2)) - (int(b.triangleOffset) * 2)) / 2) / 5
|
||||
o := int(float64(b.spaceWidth) * stackAllowance)
|
||||
if b.overlapSize >= o {
|
||||
b.overlapSize = o
|
||||
break
|
||||
}
|
||||
|
||||
b.horizontalBorderSize++
|
||||
b.overlapSize = (((float64(b.h) - (b.verticalBorderSize * 2)) - (b.triangleOffset * 2)) / 2) / 5
|
||||
if b.overlapSize > b.spaceWidth*0.94 {
|
||||
b.overlapSize = b.spaceWidth * 0.94
|
||||
}
|
||||
|
||||
extraSpace := b.w - (b.spaceWidth * 12)
|
||||
largeBarWidth := int(float64(b.spaceWidth) * 1.25)
|
||||
extraSpace := float64(b.w) - (b.spaceWidth * 12)
|
||||
largeBarWidth := float64(b.spaceWidth) * 1.25
|
||||
if extraSpace >= largeBarWidth {
|
||||
b.barWidth = largeBarWidth
|
||||
}
|
||||
|
||||
b.horizontalBorderSize = ((b.w - (b.spaceWidth * 12)) - b.barWidth) / 2
|
||||
if b.horizontalBorderSize < 0 {
|
||||
b.horizontalBorderSize = 0
|
||||
b.spaceWidth = ((float64(b.w) - (b.horizontalBorderSize * 2)) - b.barWidth) / 12
|
||||
}
|
||||
|
||||
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)
|
||||
b.innerW = int(float64(b.w) - (b.horizontalBorderSize * 2))
|
||||
b.innerH = int(float64(b.h) - (b.verticalBorderSize * 2))
|
||||
|
||||
loadAssets(b.spaceWidth)
|
||||
loadAssets(int(b.spaceWidth))
|
||||
|
||||
for i := 0; i < b.Sprites.num; i++ {
|
||||
s := b.Sprites.sprites[i]
|
||||
|
@ -588,7 +572,7 @@ func (b *board) setRect(x, y, w, h int) {
|
|||
}
|
||||
|
||||
func (b *board) offsetPosition(x, y int) (int, int) {
|
||||
return b.x + x + b.horizontalBorderSize, b.y + y + b.verticalBorderSize
|
||||
return b.x + x + int(b.horizontalBorderSize), b.y + y + int(b.verticalBorderSize)
|
||||
}
|
||||
|
||||
func (b *board) positionCheckers() {
|
||||
|
@ -663,34 +647,34 @@ func (b *board) setSpaceRects() {
|
|||
if !b.bottomRow(trueSpace) {
|
||||
y = 0
|
||||
} else {
|
||||
y = (b.h / 2) - b.verticalBorderSize
|
||||
y = int((float64(b.h) / 2) - b.verticalBorderSize)
|
||||
}
|
||||
|
||||
w = b.spaceWidth
|
||||
w = int(b.spaceWidth)
|
||||
|
||||
var hspace int // horizontal space
|
||||
var add int
|
||||
if space == 0 {
|
||||
hspace = 6
|
||||
w = b.barWidth
|
||||
w = int(b.barWidth)
|
||||
} else if space == 25 {
|
||||
hspace = 6
|
||||
w = b.barWidth
|
||||
w = int(b.barWidth)
|
||||
} else if space <= 6 {
|
||||
hspace = space - 1
|
||||
} else if space <= 12 {
|
||||
hspace = space - 1
|
||||
add = b.barWidth
|
||||
add = int(b.barWidth)
|
||||
} else if space <= 18 {
|
||||
hspace = 24 - space
|
||||
add = b.barWidth
|
||||
add = int(b.barWidth)
|
||||
} else {
|
||||
hspace = 24 - space
|
||||
}
|
||||
|
||||
x = (b.spaceWidth * hspace) + add
|
||||
x = int((b.spaceWidth * float64(hspace)) + float64(add))
|
||||
|
||||
h = (b.h - (b.verticalBorderSize * 2)) / 2
|
||||
h = int((float64(b.h) - (b.verticalBorderSize * 2)) / 2)
|
||||
|
||||
b.spaceRects[trueSpace] = [4]int{x, y, w, h}
|
||||
}
|
||||
|
@ -719,8 +703,8 @@ func (b *board) stackSpaceRect(space int, stack int) (x, y, w, h int) {
|
|||
x, y, w, h = b.spaceRect(space)
|
||||
|
||||
// Stack pieces
|
||||
osize := float64(stack)
|
||||
var o int
|
||||
osize := float64(stack)
|
||||
if stack > 4 {
|
||||
osize = 3.5
|
||||
}
|
||||
|
@ -728,15 +712,21 @@ func (b *board) stackSpaceRect(space int, stack int) (x, y, w, h int) {
|
|||
osize += 1.0
|
||||
}
|
||||
o = int(osize * float64(b.overlapSize))
|
||||
padding := int(b.spaceWidth - b.overlapSize)
|
||||
if b.bottomRow(space) {
|
||||
o += padding
|
||||
} else {
|
||||
o -= padding - 3
|
||||
}
|
||||
if !b.bottomRow(space) {
|
||||
y += o
|
||||
} else {
|
||||
y = y + (h - o)
|
||||
}
|
||||
|
||||
w, h = b.spaceWidth, b.spaceWidth
|
||||
w, h = int(b.spaceWidth), int(b.spaceWidth)
|
||||
if space == 0 || space == 25 {
|
||||
w = b.barWidth
|
||||
w = int(b.barWidth)
|
||||
}
|
||||
|
||||
return x, y, w, h
|
||||
|
@ -820,8 +810,10 @@ func (b *board) _movePiece(sprite *Sprite, from int, to int, speed int, pause bo
|
|||
stack++
|
||||
}
|
||||
|
||||
x, y, _, _ := b.stackSpaceRect(space, stack)
|
||||
x, y, w, _ := b.stackSpaceRect(space, stack)
|
||||
x, y = b.offsetPosition(x, y)
|
||||
// Center piece in space
|
||||
x += (w - int(b.spaceWidth)) / 2
|
||||
|
||||
sprite.toX = x
|
||||
sprite.toY = y
|
||||
|
|
|
@ -3,10 +3,12 @@ package game
|
|||
import "image/color"
|
||||
|
||||
var (
|
||||
tableColor = color.RGBA{0, 102, 51, 255}
|
||||
frameColor = color.RGBA{65, 40, 14, 255}
|
||||
borderColor = color.RGBA{0, 0, 0, 255}
|
||||
faceColor = color.RGBA{120, 63, 25, 255}
|
||||
triangleA = color.RGBA{225.0, 188, 125, 255}
|
||||
triangleB = color.RGBA{120.0, 17.0, 0, 255}
|
||||
tableColor = color.RGBA{0, 0, 0, 255}
|
||||
//tableColor = color.RGBA{0, 102, 51, 255}
|
||||
frameColor = color.RGBA{65, 40, 14, 255}
|
||||
borderColor = color.RGBA{0, 0, 0, 255}
|
||||
faceColor = color.RGBA{120, 63, 25, 255}
|
||||
triangleA = color.RGBA{225, 188, 125, 255}
|
||||
triangleALight = color.RGBA{255, 218, 155, 255}
|
||||
triangleB = color.RGBA{120.0, 17.0, 0, 255}
|
||||
)
|
||||
|
|
100
game/game.go
100
game/game.go
|
@ -5,7 +5,6 @@ import (
|
|||
"embed"
|
||||
"fmt"
|
||||
"image"
|
||||
"image/color"
|
||||
_ "image/png"
|
||||
"log"
|
||||
"os"
|
||||
|
@ -36,13 +35,16 @@ var (
|
|||
imgCheckerWhite *ebiten.Image
|
||||
imgCheckerBlack *ebiten.Image
|
||||
|
||||
mplusNormalFont font.Face
|
||||
monoFont font.Face
|
||||
mplusBigFont font.Face
|
||||
smallFont font.Face
|
||||
normalFont font.Face
|
||||
monoFont font.Face
|
||||
largeFont font.Face
|
||||
)
|
||||
|
||||
const defaultServerAddress = "fibs.com:4321"
|
||||
|
||||
const maxStatusWidthRatio = 0.5
|
||||
|
||||
func init() {
|
||||
loadAssets(0)
|
||||
|
||||
|
@ -79,7 +81,15 @@ func initializeFonts() {
|
|||
}
|
||||
|
||||
const dpi = 72
|
||||
mplusNormalFont, err = opentype.NewFace(tt, &opentype.FaceOptions{
|
||||
smallFont, err = opentype.NewFace(tt, &opentype.FaceOptions{
|
||||
Size: smallFontSize,
|
||||
DPI: dpi,
|
||||
Hinting: font.HintingFull,
|
||||
})
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
normalFont, err = opentype.NewFace(tt, &opentype.FaceOptions{
|
||||
Size: 24,
|
||||
DPI: dpi,
|
||||
Hinting: font.HintingFull,
|
||||
|
@ -87,7 +97,7 @@ func initializeFonts() {
|
|||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
mplusBigFont, err = opentype.NewFace(tt, &opentype.FaceOptions{
|
||||
largeFont, err = opentype.NewFace(tt, &opentype.FaceOptions{
|
||||
Size: 32,
|
||||
DPI: dpi,
|
||||
Hinting: font.HintingFull,
|
||||
|
@ -101,7 +111,7 @@ func initializeFonts() {
|
|||
log.Fatal(err)
|
||||
}
|
||||
monoFont, err = opentype.NewFace(tt, &opentype.FaceOptions{
|
||||
Size: 12,
|
||||
Size: monoFontSize,
|
||||
DPI: dpi,
|
||||
Hinting: font.HintingNone,
|
||||
})
|
||||
|
@ -168,7 +178,8 @@ type Game struct {
|
|||
keyboardInput []*kibodo.Input
|
||||
shownKeyboard bool
|
||||
|
||||
buffers *tabbedBuffers
|
||||
statusBuffer *tabbedBuffers
|
||||
gameBuffer *tabbedBuffers
|
||||
|
||||
cpuProfile *os.File
|
||||
|
||||
|
@ -188,15 +199,17 @@ func NewGame() *Game {
|
|||
|
||||
keyboard: kibodo.NewKeyboard(),
|
||||
|
||||
buffers: newTabbedBuffers(),
|
||||
statusBuffer: newTabbedBuffers(),
|
||||
gameBuffer: newTabbedBuffers(),
|
||||
|
||||
debugImg: ebiten.NewImage(200, 200),
|
||||
}
|
||||
g.keyboard.SetKeys(kibodo.KeysQWERTY)
|
||||
|
||||
msgHandler := NewMessageHandler(g)
|
||||
fibs.StatusWriter = msgHandler
|
||||
fibs.GameWriter = msgHandler
|
||||
g.statusBuffer.acceptInput = true
|
||||
|
||||
fibs.StatusWriter = NewMessageHandler(g.statusBuffer.buffers[0])
|
||||
fibs.GameWriter = NewMessageHandler(g.gameBuffer.buffers[0])
|
||||
|
||||
// TODO
|
||||
go func() {
|
||||
|
@ -259,7 +272,7 @@ func (g *Game) Connect() {
|
|||
g.Client = fibs.NewClient(address, g.Username, g.Password)
|
||||
g.lobby.c = g.Client
|
||||
g.Board.Client = g.Client
|
||||
g.buffers.client = g.Client
|
||||
g.statusBuffer.client = g.Client
|
||||
|
||||
go g.handleEvents()
|
||||
|
||||
|
@ -280,7 +293,7 @@ func (g *Game) Connect() {
|
|||
go func() {
|
||||
err := c.Connect()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
fibs.StatusWriter.Write([]byte(err.Error()))
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
@ -398,7 +411,7 @@ func (g *Game) Update() error { // Called by ebiten only when input occurs
|
|||
} else {
|
||||
g.Board.update()
|
||||
|
||||
g.buffers.update()
|
||||
g.statusBuffer.update()
|
||||
}
|
||||
|
||||
return nil
|
||||
|
@ -413,7 +426,7 @@ func (g *Game) Draw(screen *ebiten.Image) {
|
|||
}
|
||||
g.lastDraw = time.Now()
|
||||
|
||||
screen.Fill(color.RGBA{0, 102, 51, 255})
|
||||
screen.Fill(tableColor)
|
||||
|
||||
// Log in screen
|
||||
if !g.loggedIn {
|
||||
|
@ -442,9 +455,9 @@ http://www.fibs.com/help.html#register`
|
|||
g.lobby.draw(screen)
|
||||
} else {
|
||||
// Game board screen
|
||||
g.gameBuffer.draw(screen)
|
||||
g.statusBuffer.draw(screen)
|
||||
g.Board.draw(screen)
|
||||
|
||||
g.buffers.draw(screen)
|
||||
}
|
||||
|
||||
if g.Debug > 0 {
|
||||
|
@ -488,19 +501,37 @@ func (g *Game) Layout(outsideWidth, outsideHeight int) (int, int) {
|
|||
|
||||
g.screenW, g.screenH = outsideWidth, outsideHeight
|
||||
|
||||
g.Board.setRect(0, 0, g.screenW, g.screenH)
|
||||
statusBufferWidth := g.statusBuffer.chatFontSize * 77
|
||||
if statusBufferWidth > int(float64(g.screenW)*maxStatusWidthRatio) {
|
||||
statusBufferWidth = int(float64(g.screenW) * maxStatusWidthRatio)
|
||||
}
|
||||
|
||||
gameBufferheight := 100
|
||||
|
||||
g.Board.setRect(0, 0, g.screenW-statusBufferWidth, g.screenH-gameBufferheight)
|
||||
g.lobby.setRect(0, 0, g.screenW, g.screenH)
|
||||
|
||||
availableWidth := g.Board.w - (g.Board.spaceWidth * 14)
|
||||
if availableWidth >= 150 {
|
||||
g.Board.setRect(0, 0, g.screenW-availableWidth, g.screenH)
|
||||
g.buffers.setRect(g.screenW-availableWidth, 0, availableWidth, g.screenH)
|
||||
// TODO set flag to restore user position (could use extra state for this? docked state?)
|
||||
availableWidth := g.screenW - (g.Board.innerW + int(g.Board.barWidth))
|
||||
if availableWidth > statusBufferWidth {
|
||||
statusBufferWidth = availableWidth
|
||||
g.Board.setRect(0, 0, g.screenW-statusBufferWidth, g.screenH-gameBufferheight)
|
||||
}
|
||||
|
||||
if g.Board.h > g.Board.w {
|
||||
g.Board.setRect(0, 0, g.Board.w, g.Board.w)
|
||||
}
|
||||
|
||||
if true || availableWidth >= 150 { // TODO allow chat window to be repositioned
|
||||
g.statusBuffer.docked = true
|
||||
g.statusBuffer.setRect(g.screenW-statusBufferWidth, 0, statusBufferWidth, g.screenH)
|
||||
|
||||
g.gameBuffer.docked = true
|
||||
g.gameBuffer.setRect(0, g.Board.h, g.Board.w, g.screenH-(g.Board.h))
|
||||
} else {
|
||||
// Clamp buffer position.
|
||||
bx, by := g.buffers.x, g.buffers.y
|
||||
bx, by := g.statusBuffer.x, g.statusBuffer.y
|
||||
var bw, bh int
|
||||
if g.buffers.w == 0 && g.buffers.h == 0 {
|
||||
if g.statusBuffer.w == 0 && g.statusBuffer.h == 0 {
|
||||
// Set initial buffer position.
|
||||
bx = 0
|
||||
by = g.screenH / 2
|
||||
|
@ -510,7 +541,7 @@ func (g *Game) Layout(outsideWidth, outsideHeight int) (int, int) {
|
|||
} else {
|
||||
// Scale existing buffer size
|
||||
bx, by = bx*(outsideWidth/g.screenW), by*(outsideHeight/g.screenH)
|
||||
bw, bh = g.buffers.w*(outsideWidth/g.screenW), g.buffers.h*(outsideHeight/g.screenH)
|
||||
bw, bh = g.statusBuffer.w*(outsideWidth/g.screenW), g.statusBuffer.h*(outsideHeight/g.screenH)
|
||||
if bw < 200 {
|
||||
bw = 200
|
||||
}
|
||||
|
@ -526,7 +557,8 @@ func (g *Game) Layout(outsideWidth, outsideHeight int) (int, int) {
|
|||
by = g.screenH - padding
|
||||
}
|
||||
|
||||
g.buffers.setRect(bx, by, bw, bh)
|
||||
g.statusBuffer.docked = false
|
||||
g.statusBuffer.setRect(bx, by, bw, bh)
|
||||
}
|
||||
|
||||
displayArea := 200
|
||||
|
@ -572,18 +604,18 @@ func (g *Game) Exit() {
|
|||
}
|
||||
|
||||
type messageHandler struct {
|
||||
g *Game
|
||||
t *textBuffer
|
||||
}
|
||||
|
||||
func NewMessageHandler(g *Game) *messageHandler {
|
||||
func NewMessageHandler(t *textBuffer) *messageHandler {
|
||||
return &messageHandler{
|
||||
g: g,
|
||||
t: t,
|
||||
}
|
||||
}
|
||||
|
||||
func (m messageHandler) Write(p []byte) (n int, err error) {
|
||||
log.Print(string(p))
|
||||
func (m *messageHandler) Write(p []byte) (n int, err error) {
|
||||
fmt.Print(string(p))
|
||||
|
||||
m.g.buffers.buffers[0].Write(p)
|
||||
m.t.Write(p)
|
||||
return len(p), nil
|
||||
}
|
||||
|
|
|
@ -120,12 +120,12 @@ func (l *lobby) _drawBufferButtons() {
|
|||
}
|
||||
}
|
||||
}
|
||||
bounds := text.BoundString(mplusNormalFont, button.label)
|
||||
bounds := text.BoundString(normalFont, button.label)
|
||||
|
||||
labelColor := triangleA
|
||||
|
||||
img := ebiten.NewImage(bounds.Dx()*2, bounds.Dy()*2)
|
||||
text.Draw(img, button.label, mplusNormalFont, 0, bounds.Dy(), labelColor)
|
||||
text.Draw(img, button.label, normalFont, 0, bounds.Dy(), labelColor)
|
||||
|
||||
l.op.GeoM.Reset()
|
||||
l.op.GeoM.Translate(float64(buttonWidth*i)+float64((buttonWidth-bounds.Dx())/2), float64(l.buttonBarHeight-bounds.Dy())/2-float64(bounds.Dy()/2))
|
||||
|
@ -149,10 +149,10 @@ func (l *lobby) drawBuffer() {
|
|||
lineHeight := 30
|
||||
padding := 24.0
|
||||
for i, label := range labels {
|
||||
bounds := text.BoundString(mplusNormalFont, label)
|
||||
bounds := text.BoundString(normalFont, label)
|
||||
labelColor := triangleA
|
||||
img := ebiten.NewImage(l.w-int(l.padding*2), int(l.entryH))
|
||||
text.Draw(img, label, mplusNormalFont, 4, bounds.Dy(), labelColor)
|
||||
text.Draw(img, label, normalFont, 4, bounds.Dy(), labelColor)
|
||||
l.op.GeoM.Reset()
|
||||
l.op.GeoM.Translate(padding, padding+float64(i*lineHeight))
|
||||
l.buffer.DrawImage(img, l.op)
|
||||
|
@ -160,9 +160,9 @@ func (l *lobby) drawBuffer() {
|
|||
} else {
|
||||
var img *ebiten.Image
|
||||
drawEntry := func(cx float64, cy float64, colA string, colB string, colC string, highlight bool) {
|
||||
boundsA := text.BoundString(mplusNormalFont, colA)
|
||||
boundsB := text.BoundString(mplusNormalFont, colB)
|
||||
boundsC := text.BoundString(mplusNormalFont, colC)
|
||||
boundsA := text.BoundString(normalFont, colA)
|
||||
boundsB := text.BoundString(normalFont, colB)
|
||||
boundsC := text.BoundString(normalFont, colC)
|
||||
y := (boundsA.Dy() + boundsB.Dy() + boundsC.Dy()) / 3 // TODO this isn't correct
|
||||
|
||||
labelColor := triangleA
|
||||
|
@ -184,9 +184,9 @@ func (l *lobby) drawBuffer() {
|
|||
}
|
||||
}
|
||||
|
||||
text.Draw(img, colA, mplusNormalFont, 4, y+2, labelColor)
|
||||
text.Draw(img, colB, mplusNormalFont, int(250*ebiten.DeviceScaleFactor()), y+2, labelColor)
|
||||
text.Draw(img, colC, mplusNormalFont, int(500*ebiten.DeviceScaleFactor()), y+2, labelColor)
|
||||
text.Draw(img, colA, normalFont, 4, y+2, labelColor)
|
||||
text.Draw(img, colB, normalFont, int(250*ebiten.DeviceScaleFactor()), y+2, labelColor)
|
||||
text.Draw(img, colC, normalFont, int(500*ebiten.DeviceScaleFactor()), y+2, labelColor)
|
||||
|
||||
l.op.GeoM.Reset()
|
||||
l.op.GeoM.Translate(cx, cy)
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
package game
|
||||
|
||||
import (
|
||||
"image"
|
||||
"image/color"
|
||||
|
||||
"code.rocketnine.space/tslocum/fibs"
|
||||
"github.com/hajimehoshi/ebiten/v2"
|
||||
"github.com/hajimehoshi/ebiten/v2/inpututil"
|
||||
"github.com/hajimehoshi/ebiten/v2/text"
|
||||
"golang.org/x/exp/shiny/materialdesign/colornames"
|
||||
"golang.org/x/image/font"
|
||||
)
|
||||
|
||||
const (
|
||||
|
@ -18,7 +18,8 @@ const (
|
|||
|
||||
const windowStartingAlpha = 0.9
|
||||
|
||||
const bufferCharacterWidth = 12
|
||||
const smallFontSize = 14
|
||||
const monoFontSize = 10
|
||||
|
||||
type tabbedBuffers struct {
|
||||
buffers []*textBuffer
|
||||
|
@ -27,6 +28,8 @@ type tabbedBuffers struct {
|
|||
x, y int
|
||||
w, h int
|
||||
|
||||
padding int
|
||||
|
||||
unfocusedAlpha float64
|
||||
|
||||
buffer *ebiten.Image
|
||||
|
@ -38,6 +41,8 @@ type tabbedBuffers struct {
|
|||
|
||||
state int
|
||||
|
||||
docked bool
|
||||
|
||||
focused bool
|
||||
|
||||
touchIDs []ebiten.TouchID
|
||||
|
@ -47,6 +52,11 @@ type tabbedBuffers struct {
|
|||
inputBuffer []byte
|
||||
|
||||
client *fibs.Client
|
||||
|
||||
chatFont font.Face
|
||||
chatFontSize int
|
||||
|
||||
acceptInput bool
|
||||
}
|
||||
|
||||
func newTabbedBuffers() *tabbedBuffers {
|
||||
|
@ -55,8 +65,14 @@ func newTabbedBuffers() *tabbedBuffers {
|
|||
unfocusedAlpha: windowStartingAlpha,
|
||||
buffer: ebiten.NewImage(1, 1),
|
||||
op: &ebiten.DrawImageOptions{},
|
||||
chatFont: monoFont,
|
||||
chatFontSize: monoFontSize,
|
||||
}
|
||||
|
||||
// TODO
|
||||
//tab.chatFont = smallFont
|
||||
//tab.chatFontSize = smallFontSize
|
||||
|
||||
b := &textBuffer{
|
||||
tab: tab,
|
||||
}
|
||||
|
@ -70,15 +86,21 @@ func (t *tabbedBuffers) setRect(x, y, w, h int) {
|
|||
return
|
||||
}
|
||||
|
||||
// TODO dynamic padding
|
||||
|
||||
if t.w != w || t.h != h {
|
||||
t.buffer = ebiten.NewImage(w, h)
|
||||
t.bufferDirty = true
|
||||
}
|
||||
|
||||
if t.w != w {
|
||||
t.wrapWidth = w / bufferCharacterWidth
|
||||
if w > 200 {
|
||||
t.padding = 2
|
||||
} else if w > 100 {
|
||||
t.padding = 1
|
||||
} else {
|
||||
t.padding = 0
|
||||
}
|
||||
|
||||
t.wrapWidth = (w - (t.padding * 4)) / t.chatFontSize
|
||||
for _, b := range t.buffers {
|
||||
b.wrapDirty = true
|
||||
}
|
||||
|
@ -88,20 +110,27 @@ func (t *tabbedBuffers) setRect(x, y, w, h int) {
|
|||
}
|
||||
|
||||
func (t *tabbedBuffers) drawBuffer() {
|
||||
t.buffer.Fill(borderColor)
|
||||
t.buffer.Fill(color.Black)
|
||||
|
||||
sub := t.buffer.SubImage(image.Rect(1, 1, t.w-1, t.h-1)).(*ebiten.Image)
|
||||
sub.Fill(frameColor)
|
||||
textColor := triangleALight
|
||||
|
||||
/*sub := t.buffer.SubImage(image.Rect(1, 1, t.w-1, t.h-1)).(*ebiten.Image)
|
||||
sub.Fill(frameColor)*/
|
||||
|
||||
b := t.buffers[0]
|
||||
|
||||
l := len(b.contentWrapped)
|
||||
|
||||
lineHeight := 16
|
||||
lineHeight := 14
|
||||
showLines := t.h / lineHeight
|
||||
// Leave space for the input buffer.
|
||||
if showLines > 1 {
|
||||
showLines--
|
||||
if t.acceptInput {
|
||||
// Leave space for the input buffer.
|
||||
if showLines > 1 {
|
||||
showLines--
|
||||
}
|
||||
if showLines > 1 {
|
||||
showLines--
|
||||
}
|
||||
}
|
||||
|
||||
if l < showLines {
|
||||
|
@ -110,12 +139,14 @@ func (t *tabbedBuffers) drawBuffer() {
|
|||
for i := 0; i < showLines; i++ {
|
||||
line := b.contentWrapped[l-showLines+i]
|
||||
|
||||
bounds := text.BoundString(monoFont, line)
|
||||
bounds := text.BoundString(t.chatFont, line)
|
||||
_ = bounds
|
||||
text.Draw(t.buffer, line, monoFont, 0, (lineHeight * (i + 1)), colornames.White)
|
||||
text.Draw(t.buffer, line, t.chatFont, t.padding*2, t.padding+(lineHeight*(i+1)), textColor)
|
||||
}
|
||||
|
||||
text.Draw(t.buffer, "> "+string(t.inputBuffer), monoFont, 0, t.h, colornames.White)
|
||||
if t.acceptInput {
|
||||
text.Draw(t.buffer, "> "+string(t.inputBuffer), t.chatFont, t.padding*2, t.h-(t.padding*2), textColor)
|
||||
}
|
||||
}
|
||||
|
||||
func (t *tabbedBuffers) draw(target *ebiten.Image) {
|
||||
|
@ -123,7 +154,7 @@ func (t *tabbedBuffers) draw(target *ebiten.Image) {
|
|||
return
|
||||
}
|
||||
|
||||
if t.state == windowMinimized {
|
||||
if !t.docked && t.state == windowMinimized {
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -192,20 +223,31 @@ func (t *tabbedBuffers) update() {
|
|||
|
||||
if inpututil.IsKeyJustPressed(ebiten.KeyEnter) {
|
||||
if len(t.inputBuffer) == 0 {
|
||||
if t.state == windowMinimized {
|
||||
t.state = windowNormal
|
||||
} else {
|
||||
t.state = windowMinimized
|
||||
if !t.docked {
|
||||
if t.state == windowMinimized {
|
||||
t.state = windowNormal
|
||||
} else {
|
||||
t.state = windowMinimized
|
||||
}
|
||||
|
||||
t.bufferDirty = true
|
||||
}
|
||||
} else {
|
||||
if t.client != nil {
|
||||
t.client.Out <- t.inputBuffer
|
||||
if len(t.inputBuffer) > 0 {
|
||||
if t.inputBuffer[0] == '/' {
|
||||
// TODO add chat modes and show (kibitz/yell)
|
||||
t.inputBuffer = t.inputBuffer[1:]
|
||||
}
|
||||
t.client.Out <- t.inputBuffer
|
||||
}
|
||||
} else {
|
||||
fibs.StatusWriter.Write([]byte("* You have not connected to a server yet"))
|
||||
}
|
||||
t.inputBuffer = nil
|
||||
|
||||
t.bufferDirty = true
|
||||
}
|
||||
t.bufferDirty = true
|
||||
}
|
||||
|
||||
// TODO add show virtual keyboard button
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
package game
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"unicode"
|
||||
|
||||
"github.com/hajimehoshi/ebiten/v2"
|
||||
)
|
||||
|
||||
|
@ -19,7 +22,7 @@ type textBuffer struct {
|
|||
}
|
||||
|
||||
func (b *textBuffer) Write(p []byte) {
|
||||
b.content = append(b.content, p)
|
||||
b.content = append(b.content, bytes.TrimRightFunc(p, unicode.IsSpace))
|
||||
|
||||
b.wrapDirty = true
|
||||
b.tab.bufferDirty = true
|
||||
|
|
6
go.mod
6
go.mod
|
@ -8,7 +8,6 @@ require (
|
|||
github.com/hajimehoshi/ebiten/v2 v2.2.2
|
||||
github.com/llgcode/draw2d v0.0.0-20210904075650-80aa0a2a901d
|
||||
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646
|
||||
golang.org/x/exp v0.0.0-20211105205138-14c72366447f
|
||||
golang.org/x/image v0.0.0-20211028202545-6944b10bf410
|
||||
)
|
||||
|
||||
|
@ -21,9 +20,10 @@ require (
|
|||
github.com/modern-go/reflect2 v1.0.1 // indirect
|
||||
github.com/reiver/go-oi v1.0.0 // indirect
|
||||
github.com/reiver/go-telnet v0.0.0-20180421082511-9ff0b2ab096e // indirect
|
||||
golang.org/x/mobile v0.0.0-20211103151657-e68c98865fb2 // indirect
|
||||
golang.org/x/exp v0.0.0-20211109222223-9df80dc805b5 // indirect
|
||||
golang.org/x/mobile v0.0.0-20211109191125-d61a72f26a1a // indirect
|
||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c // indirect
|
||||
golang.org/x/sys v0.0.0-20211108224332-cbcd623f202e // indirect
|
||||
golang.org/x/sys v0.0.0-20211109184856-51b60fd695b3 // indirect
|
||||
golang.org/x/text v0.3.7 // indirect
|
||||
nhooyr.io/websocket v1.8.7 // indirect
|
||||
)
|
||||
|
|
12
go.sum
12
go.sum
|
@ -351,8 +351,8 @@ golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL
|
|||
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20190731235908-ec7cb31e5a56/go.mod h1:JhuoJpWY28nO4Vef9tZUw9qufEGTyX1+7lmHxV5q5G4=
|
||||
golang.org/x/exp v0.0.0-20211012155715-ffe10e552389/go.mod h1:a3o/VtDNHN+dCVLEpzjjUHOzR+Ln3DHX056ZPzoZGGA=
|
||||
golang.org/x/exp v0.0.0-20211105205138-14c72366447f h1:LOrKZCSwatuEIzc+tzZRm7m5pmv+xxDXjGqElpd2LGA=
|
||||
golang.org/x/exp v0.0.0-20211105205138-14c72366447f/go.mod h1:OyI624f2tQ/aU3IMa7GB16Hk54CHURAfHfj6tMqtyhA=
|
||||
golang.org/x/exp v0.0.0-20211109222223-9df80dc805b5 h1:z5bapnFL1WqWwTUpFQTSwLVQEgLuY39KXDYgBTM+DrI=
|
||||
golang.org/x/exp v0.0.0-20211109222223-9df80dc805b5/go.mod h1:OyI624f2tQ/aU3IMa7GB16Hk54CHURAfHfj6tMqtyhA=
|
||||
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=
|
||||
|
@ -370,8 +370,8 @@ golang.org/x/mobile v0.0.0-20190415191353-3e0bab5405d6/go.mod h1:E/iHnbuqvinMTCc
|
|||
golang.org/x/mobile v0.0.0-20201217150744-e6ae53a27f4f/go.mod h1:skQtrUTUwhdJvXM/2KKJzY8pDgNr9I/FOMqDVRPBUS4=
|
||||
golang.org/x/mobile v0.0.0-20210902104108-5d9a33257ab5/go.mod h1:c4YKU3ZylDmvbw+H/PSvm42vhdWbuxCzbonauEAP9B8=
|
||||
golang.org/x/mobile v0.0.0-20210924032853-1c027f395ef7/go.mod h1:c4YKU3ZylDmvbw+H/PSvm42vhdWbuxCzbonauEAP9B8=
|
||||
golang.org/x/mobile v0.0.0-20211103151657-e68c98865fb2 h1:SFpMH29/c2+VPCOcOlLPQiAVqU2sXiFvwfdtQfVEEJ8=
|
||||
golang.org/x/mobile v0.0.0-20211103151657-e68c98865fb2/go.mod h1:pe2sM7Uk+2Su1y7u/6Z8KJ24D7lepUjFZbhFOrmDfuQ=
|
||||
golang.org/x/mobile v0.0.0-20211109191125-d61a72f26a1a h1:VGK2tvC63sblAsLlPgn0AXI/qQJfdEODdMGCJdgmCBw=
|
||||
golang.org/x/mobile v0.0.0-20211109191125-d61a72f26a1a/go.mod h1:pe2sM7Uk+2Su1y7u/6Z8KJ24D7lepUjFZbhFOrmDfuQ=
|
||||
golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
|
||||
golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY=
|
||||
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
|
||||
|
@ -442,8 +442,8 @@ golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBc
|
|||
golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210917161153-d61c044b1678/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20211108224332-cbcd623f202e h1:9nbuBbpiqktwdlzHKUohsD5+y2a0QvX98gIWK2ARkqc=
|
||||
golang.org/x/sys v0.0.0-20211108224332-cbcd623f202e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20211109184856-51b60fd695b3 h1:T6tyxxvHMj2L1R2kZg0uNMpS8ZhB9lRa9XRGTCSA65w=
|
||||
golang.org/x/sys v0.0.0-20211109184856-51b60fd695b3/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=
|
||||
|
|
11
main.go
11
main.go
|
@ -3,13 +3,14 @@ package main
|
|||
import (
|
||||
"bufio"
|
||||
"log"
|
||||
"net/http"
|
||||
_ "net/http/pprof"
|
||||
"os"
|
||||
"os/signal"
|
||||
"syscall"
|
||||
|
||||
"code.rocketnine.space/tslocum/fibs"
|
||||
|
||||
"code.rocketnine.space/tslocum/boxcars/game"
|
||||
"code.rocketnine.space/tslocum/fibs"
|
||||
"github.com/hajimehoshi/ebiten/v2"
|
||||
)
|
||||
|
||||
|
@ -40,6 +41,12 @@ func main() {
|
|||
|
||||
fibs.Debug = g.Debug
|
||||
|
||||
if g.Debug > 0 {
|
||||
go func() {
|
||||
log.Fatal(http.ListenAndServe("localhost:8880", nil))
|
||||
}()
|
||||
}
|
||||
|
||||
if AutoWatch {
|
||||
g.Watch = true
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue