Add title screen

This commit is contained in:
Trevor Slocum 2023-06-12 21:56:44 -07:00
parent 5f45a35c6a
commit e4eb19a2d1
7 changed files with 140 additions and 40 deletions

View file

@ -13,6 +13,5 @@ func parseFlags() {
flag.BoolVar(&world.Fullscreen, "fullscreen", false, "run in fullscreen mode")
flag.BoolVar(&world.DisableVsync, "no-vsync", false, "do not enable vsync (allows the game to run at maximum fps)")
flag.IntVar(&world.Debug, "debug", 0, "debug level (0 - disabled, 1 - print fps and net stats, 2 - draw hitboxes)")
flag.IntVar(&world.TPS, "tps", world.DefaultTPS, "set ticks per second (this is not normally required)")
flag.Parse()
}

View file

@ -1,6 +1,7 @@
package game
import (
"bytes"
"fmt"
"image"
"image/color"
@ -18,9 +19,20 @@ import (
"golang.org/x/image/font/opentype"
)
type viewType int
const (
viewTitle = iota
viewIntro1
viewFinancialReport
)
type Game struct {
inputBuffer *etk.Input
textBuffer *dummyTextBuffer
currentView viewType
viewTicks int
}
var addedGame bool
@ -75,6 +87,7 @@ func NewGame() (*Game, error) {
g.textBuffer.Field.SetHorizontal(messeji.AlignStart)
g.textBuffer.Field.SetVertical(messeji.AlignStart)
g.textBuffer.Field.SetPadding(0)
g.textBuffer.Field.SetLineHeight(10)
// Create window input buffer and text buffer.
w := etk.NewWindow()
@ -91,11 +104,68 @@ func (g *Game) Layout(_, _ int) (screenWidth, screenHeight int) {
if world.InternalScreenWidth != world.ScreenWidth || world.InternalScreenHeight != world.ScreenHeight {
world.ScreenWidth, world.ScreenHeight = world.InternalScreenWidth, world.InternalScreenHeight
etk.Layout(world.ScreenWidth, world.ScreenHeight)
g.textBuffer.SetRect(image.Rect(0, 3, world.ScreenWidth, world.ScreenHeight))
g.textBuffer.SetRect(image.Rect(0, 1, world.ScreenWidth, world.ScreenHeight))
}
return world.ScreenWidth, world.ScreenHeight
}
func (g *Game) refreshBuffer() error {
// TODO only do this when the view buffer or input buffer changes
currentDay := 1
pretzelsSold := 50
pretzelPrice := "$.10"
totalIncome := "$5.00"
pretzelsMade := 50
signsMade := 3
totalExpenses := "$1.45"
profit := "$3.55"
assets := "$6.60"
viewBytes := viewText[g.currentView]
writeLines := g.viewTicks - 1
// Append start screen text.
if g.currentView == viewTitle && g.viewTicks%200 < 150 {
viewBytes = append(viewBytes, bytes.TrimRight(centeredText("PRESS SPACE TO START"), "\n")...)
}
// Format view.
var lines [][]byte
switch g.currentView {
case viewTitle, viewIntro1:
lines = bytes.Split(viewBytes, []byte("\n"))
case viewFinancialReport:
viewBytes = []byte(fmt.Sprintf(string(viewBytes), currentDay, pretzelsSold, pretzelPrice, totalIncome, pretzelsMade, signsMade, totalExpenses, profit, assets))
lines = bytes.Split(viewBytes, []byte("\n"))
}
g.textBuffer.Clear()
if writeLines <= 0 {
return nil
} else if writeLines >= len(lines) {
g.textBuffer.Write(viewBytes)
return nil
}
wrote := 0
for i := 0; i < len(lines); i++ {
if i != 0 {
g.textBuffer.Write([]byte("\n"))
}
if len(lines[i]) == 0 {
continue
} else if wrote == writeLines {
return nil
}
g.textBuffer.Write(lines[i])
wrote++
}
return nil
}
func (g *Game) Update() error {
if ebiten.IsWindowBeingClosed() || (!world.WASM && ebiten.IsKeyPressed(ebiten.KeyEscape)) {
g.Exit()
@ -123,36 +193,28 @@ func (g *Game) Update() error {
log.Fatal(err)
}
// TODO only do this when the view buffer or input buffer changes
pretzelsSold := 50
pretzelPrice := "$.10"
totalIncome := "$5.00"
pretzelsMade := 50
signsMade := 3
totalExpenses := "$1.45"
profit := "$3.55"
assets := "$6.60"
g.textBuffer.Clear()
g.textBuffer.Write([]byte(fmt.Sprintf(viewFinancialReport, pretzelsSold, pretzelPrice, totalIncome, pretzelsMade, signsMade, totalExpenses, profit, assets)))
g.textBuffer.Clear()
for i := 0; i < 22; i++ {
if i != 0 {
g.textBuffer.Write([]byte("\n"))
if inpututil.IsKeyJustPressed(ebiten.KeySpace) {
g.currentView++
if g.currentView > viewFinancialReport {
g.currentView = viewTitle
}
g.textBuffer.Write([]byte(fmt.Sprintf("%d", i)))
g.viewTicks = 0
}
err = g.refreshBuffer()
if err != nil {
return err
}
g.viewTicks++
// TODO fix trailing newline causing scroll bar to appear
//g.textBuffer.Clear()
//g.textBuffer.Write([]byte(viewIntro1))
return nil
}
func (g *Game) Draw(screen *ebiten.Image) {
//screen.cl
// Draw the text buffer over the hidden input buffer.
g.textBuffer.Draw(screen)

View file

@ -5,12 +5,51 @@ import (
"strings"
)
// Note: The screen size is 40x22.
// Note: Screen fits 40x19 characters.
var viewFinancialReport = ` $$ PRETZELSVILLE FINANCIAL REPORT $$
var viewText = [][]byte{
// viewTitle
[]byte(`
____ ____ _____ _____ __________ _
| _ \| _ \| ____|_ _|__ / ____| |
| |_) | |_) | _| | | / /| _| | |
| __/| _ <| |___ | | / /_| |___| |_
|_| |_| \_\_____| |_| /____|_____|___|
_______ ______ ___ ___ _ _
|_ _\ \_/ / ___/ _ \ / _ \| \ | |
| | \ / | | | | | | | | \| |
| | | || |__| |_| | |_| | |\ |
|_| |_| \____\___/ \___/|_| \_|
` + string(centeredText("DAY 1")) + `
`),
// viewIntro1
[]byte(`GREETINGS! WELCOME TO PRETZELSVILLE!
IN THIS GREAT SOCIETY, YOU ARE IN CHARGE
OF RUNNING YOUR OWN PRETZEL STAND. TO
GROW YOUR PRETZEL EMPIRE, YOU WILL NEED
TO MAKE THESE DECISIONS EVERY DAY:
1. WHO TO USE FOR YOUR OWN GAIN
2. HOW FAR TO BEND OR BREAK THE RULES
3. WHAT PRICE TO CHARGE FOR EACH PRETZEL
YOU WILL BEGIN WITH $4.20 CASH (ASSETS).
` + string(bytes.TrimRight(centeredText("PRESS SPACE TO CONTINUE..."), "\n"))),
// viewFinancialReport
[]byte(` $$ PRETZELSVILLE FINANCIAL REPORT $$
DAY %d
%7d PRETZELS SOLD INCOME
@ -21,13 +60,12 @@ var viewFinancialReport = ` $$ PRETZELSVILLE FINANCIAL REPORT $$
%7d SIGNS MADE %s
PROFIT %s
ASSETS %s
` + string(bytes.TrimRight(centeredText("PRESS SPACE TO CONTINUE..."), "\n"))
` + string(bytes.TrimRight(centeredText("PRESS SPACE TO CONTINUE..."), "\n"))),
}
func centeredText(text string) []byte {
if len(text) > 40 {

4
go.mod
View file

@ -16,6 +16,6 @@ require (
golang.org/x/exp/shiny v0.0.0-20230522175609-2e198f4a06a1 // indirect
golang.org/x/mobile v0.0.0-20230531173138-3c911d8e3eda // indirect
golang.org/x/sync v0.2.0 // indirect
golang.org/x/sys v0.8.0 // indirect
golang.org/x/text v0.9.0 // indirect
golang.org/x/sys v0.9.0 // indirect
golang.org/x/text v0.10.0 // indirect
)

7
go.sum
View file

@ -37,8 +37,8 @@ golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.8.0 h1:EBmGv8NaZBZTWvrbjNoL6HVt+IVy3QDQpJs7VRIw3tU=
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.9.0 h1:KS/R3tvhPqvJvwcKfnBHJwwthS11LRhmM5D59eEXa0s=
golang.org/x/sys v0.9.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
@ -46,8 +46,9 @@ golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE=
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
golang.org/x/text v0.10.0 h1:UpjohKhiEgNc0CSauXmwYftY1+LlaC75SJwh0SgCX58=
golang.org/x/text v0.10.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=

View file

@ -16,11 +16,13 @@ func main() {
ebiten.SetWindowResizingMode(ebiten.WindowResizingModeEnabled)
ebiten.SetWindowSize(world.DefaultScreenWidth, world.DefaultScreenHeight)
ebiten.SetWindowClosingHandled(true)
ebiten.SetCursorMode(ebiten.CursorModeHidden)
ebiten.SetRunnableOnUnfocused(true)
ebiten.SetTPS(world.DefaultTPS)
ebiten.SetScreenClearedEveryFrame(false)
parseFlags()
ebiten.SetTPS(world.TPS)
ebiten.SetFullscreen(world.Fullscreen)
ebiten.SetVsyncEnabled(!world.DisableVsync)

View file

@ -1,7 +1,7 @@
package world
const (
DefaultTPS = 60
DefaultTPS = 100
DefaultScreenWidth = 1280
DefaultScreenHeight = 720
@ -13,8 +13,6 @@ const (
)
var (
TPS = DefaultTPS
ScreenWidth int
ScreenHeight int