gas-station-sim/game/game.go

149 lines
3.4 KiB
Go

package game
import (
"log"
"os"
"code.rocketnine.space/tslocum/gas-station-sim/asset"
"code.rocketnine.space/tslocum/gas-station-sim/entity"
"code.rocketnine.space/tslocum/gas-station-sim/system"
"code.rocketnine.space/tslocum/gas-station-sim/world"
"code.rocketnine.space/tslocum/gohan"
"github.com/hajimehoshi/ebiten/v2"
"github.com/hajimehoshi/ebiten/v2/inpututil"
)
const shaderSrc = `
//go:build ignore
// +build ignore
package main
func Fragment(position vec4, tex vec2, color vec4) vec4 {
xCol := int(position.x) % int(2) == int(0)
yCol := int(position.y) % int(2) == int(0)
clr := imageSrc0UnsafeAt(tex)
brightness := max(max(clr.r, clr.g), clr.b)
if brightness > 0.75 {
return vec4(1, 1, 1, 1)
} else if brightness > 0.5 {
if (!xCol && yCol) {
return vec4(0, 0, 0, 1)
} else {
return vec4(1, 1, 1, 1)
}
} else if brightness > 0.25 {
if (xCol && yCol) || (!xCol && !yCol) {
return vec4(1, 1, 1, 1)
} else {
return vec4(0, 0, 0, 1)
}
} else if brightness > 0.075 {
if (xCol && yCol) {
return vec4(1, 1, 1, 1)
} else {
return vec4(0, 0, 0, 1)
}
} else {
return vec4(0, 0, 0, 1)
}
}
`
type Game struct {
target *ebiten.Image
shader *ebiten.Shader
}
func NewGame() *Game {
entity.NewOnceEntity()
gohan.AddSystem(&system.NewEmployee{})
gohan.AddSystem(&system.RenderBackground{})
gohan.AddSystem(&system.Customer{})
gohan.AddSystem(&system.Tutorial{})
gohan.AddSystem(&system.RenderUI{})
gohan.AddSystem(&system.Till{})
gohan.AddSystem(&system.PumpConsole{})
s, err := ebiten.NewShader([]byte(shaderSrc))
if err != nil {
panic(err)
}
return &Game{
target: ebiten.NewImage(world.ScreenWidth, world.ScreenHeight),
shader: s,
}
}
func (g *Game) Layout(_, _ int) (screenWidth, screenHeight int) {
return world.ScreenWidth, world.ScreenHeight
}
func (g *Game) handleTransition() error {
if world.GameStarting == 0 && !world.GameStarted && (ebiten.IsMouseButtonPressed(ebiten.MouseButtonLeft) || inpututil.IsKeyJustPressed(ebiten.KeyEnter) || inpututil.IsKeyJustPressed(ebiten.KeyKPEnter)) {
asset.SoundChime.Play()
world.GameStarting = world.TPS * 2
return nil
}
if world.GameStarting != 0 {
world.GameStarting--
if world.GameStarting == 0 {
world.StartGame()
}
}
return nil
}
func (g *Game) Update() error {
if !world.DisableEsc && ebiten.IsKeyPressed(ebiten.KeyEscape) {
os.Exit(0)
return nil
}
if (inpututil.IsKeyJustPressed(ebiten.KeyEnter) || inpututil.IsKeyJustPressed(ebiten.KeyKPEnter)) && ebiten.IsKeyPressed(ebiten.KeyAlt) {
world.Fullscreen = !world.Fullscreen
ebiten.SetFullscreen(world.Fullscreen)
return nil
}
err := g.handleTransition()
if err != nil {
return err
}
if world.GameStarted {
world.Ticks++
}
return gohan.Update()
}
func (g *Game) Draw(screen *ebiten.Image) {
//g.target.Clear()
err := gohan.Draw(g.target)
if err != nil {
log.Fatal(err)
}
// Customer target on screen using dither shader.
op := &ebiten.DrawRectShaderOptions{}
op.Images[0] = g.target
screen.DrawRectShader(world.ScreenWidth, world.ScreenHeight, g.shader, op)
// Draw cursor.
cx, cy := ebiten.CursorPosition()
imgOp := &ebiten.DrawImageOptions{}
imgOp.GeoM.Reset()
imgOp.GeoM.Translate(float64(cx), float64(cy))
screen.DrawImage(asset.ImageCursor, imgOp)
//ebitenutil.DebugPrint(screen, fmt.Sprintf("TPS: %.0f\nFPS: %.0f", ebiten.ActualTPS(), ebiten.ActualFPS()))
}