gridpathingtest/cmd/prog/main.go

169 lines
4.0 KiB
Go

package main
import (
"fmt"
"gridpathingtest/sauce"
"image/color"
"math"
"github.com/hajimehoshi/ebiten/v2"
"github.com/hajimehoshi/ebiten/v2/ebitenutil"
"github.com/hajimehoshi/ebiten/v2/inpututil"
"github.com/hajimehoshi/ebiten/v2/vector"
"github.com/tinne26/etxt"
"github.com/tinne26/fonts/liberation/lbrtserif"
)
var (
txt *etxt.Renderer
)
const (
CellSize = 20
)
type Game struct {
world *sauce.World
cellX, cellY int
fromX, fromY int
toX, toY int
path []sauce.Node
pathSuccess bool
whichFromTo bool
}
func NewGame() *Game {
g := &Game{}
g.world = sauce.NewWorld(3, 3)
g.world.HueristicLine(10, 0, 10, 10, 1)
g.world.HueristicLine(10, 13, 10, 30, 1)
g.fromX = -1
g.fromY = -1
g.toX = -1
g.toY = -1
return g
}
var (
lastOutsideWidth int
lastOutsideHeight int
lastScreenWidth int
lastScreenHeight int
)
func (g *Game) Layout(outsideWidth, outsideHeight int) (screenWidth, screenHeight int) {
if lastOutsideWidth == outsideWidth && lastOutsideHeight == outsideHeight {
return lastScreenWidth, lastScreenHeight
}
lastOutsideWidth = outsideWidth
lastOutsideHeight = outsideHeight
scale := ebiten.DeviceScaleFactor()
txt.SetScale(scale)
lastScreenWidth, lastScreenHeight = int(math.Ceil(float64(outsideWidth)*scale)), int(math.Ceil(float64(outsideHeight)*scale))
return lastScreenWidth, lastScreenHeight
}
func (g *Game) Update() error {
cursorX, cursorY := ebiten.CursorPosition()
g.cellX = cursorX / CellSize
g.cellY = cursorY / CellSize
if cell := g.world.At(g.cellX, g.cellY); cell != nil {
var reroll bool
if inpututil.IsMouseButtonJustPressed(ebiten.MouseButtonLeft) {
cell.Hueristic++
reroll = true
} else if inpututil.IsMouseButtonJustPressed(ebiten.MouseButtonRight) {
cell.Hueristic--
reroll = true
} else if inpututil.IsMouseButtonJustPressed(ebiten.MouseButtonMiddle) {
if !g.whichFromTo {
g.fromX, g.fromY = g.cellX, g.cellY
} else {
g.toX, g.toY = g.cellX, g.cellY
}
g.whichFromTo = !g.whichFromTo
reroll = true
}
if reroll {
if g.fromX != -1 && g.fromY != -1 && g.toX != -1 && g.toY != -1 {
g.path, g.pathSuccess = sauce.FindPath(g.world, g.fromX, g.fromY, g.toX, g.toY)
}
}
}
return nil
}
func (g *Game) Draw(screen *ebiten.Image) {
for i, chunk := range g.world.Chunks {
cx, cy := float32(chunk.X*CellSize), float32(chunk.Y*CellSize)
c := color.NRGBA{255, 255, 255, 255}
c.G = 255 - uint8(i*100/len(g.world.Chunks))
for x := 0; x < chunk.Width(); x++ {
for y := 0; y < chunk.Height(); y++ {
cell := chunk.At(x, y)
if cell == nil {
continue
}
px := cx + float32(x*CellSize)
py := cy + float32(y*CellSize)
c.A = 255 - cell.Hueristic*255/10
if g.cellX == chunk.X+x && g.cellY == chunk.Y+y {
c.R = 0
c.B = 0
} else {
c.R = 255
c.B = 255
c.G = 255 - uint8(i*100/len(g.world.Chunks))
}
if g.fromX == chunk.X+x && g.fromY == chunk.Y+y {
c.R = 0
c.G = 0
}
if g.toX == chunk.X+x && g.toY == chunk.Y+y {
c.B = 0
c.G = 0
}
vector.DrawFilledRect(screen, px, py, CellSize, CellSize, c, false)
vector.StrokeRect(screen, px, py, CellSize, CellSize, 1, color.Black, false)
s := fmt.Sprintf("%d", cell.Hueristic)
txt.Draw(screen, s, int(px+CellSize/2), int(py+CellSize/2))
}
}
}
// Draw path dots overtop.
for _, node := range g.path {
x := node.X*CellSize + CellSize/2
y := node.Y*CellSize + CellSize/2
c := color.RGBA{0, 255, 0, 255}
if !g.pathSuccess {
c = color.RGBA{255, 0, 0, 255}
}
vector.DrawFilledCircle(screen, float32(x), float32(y), 5, c, false)
}
ebitenutil.DebugPrint(screen, fmt.Sprintf("TPS: %0.2f\nFPS: %0.2f", ebiten.ActualTPS(), ebiten.ActualFPS()))
}
func main() {
g := NewGame()
txt = etxt.NewRenderer()
txt.SetFont(lbrtserif.Font())
txt.Utils().SetCache8MiB()
txt.SetColor(color.Black)
txt.SetAlign(etxt.Center)
txt.SetSize(12)
ebiten.SetWindowSize(1280, 720)
if err := ebiten.RunGameWithOptions(g, &ebiten.RunGameOptions{
GraphicsLibrary: ebiten.GraphicsLibraryOpenGL,
}); err != nil {
panic(err)
}
}