Handle user input

This commit is contained in:
Trevor Slocum 2023-06-13 21:35:08 -07:00
parent e4eb19a2d1
commit 9541cbcca2
6 changed files with 152 additions and 27 deletions

View file

@ -2,7 +2,11 @@
[![Donate via LiberaPay](https://img.shields.io/liberapay/receives/rocketnine.space.svg?logo=liberapay)](https://liberapay.com/rocketnine.space)
[![Donate via Patreon](https://img.shields.io/badge/dynamic/json?color=%23e85b46&label=Patreon&query=data.attributes.patron_count&suffix=%20patrons&url=https%3A%2F%2Fwww.patreon.com%2Fapi%2Fcampaigns%2F5252223)](https://www.patreon.com/rocketnine)
This game was created for the [Fuck Capitalism Jam 2023](https://itch.io/jam/fuck-capitalism-jam-2023).
This game was created for the [Fuck Capitalism Jam 2023](https://itch.io/jam/fuck-capitalism-jam-2023)
game jam.
It is a parody of the 1973 business simulation game [Lemonade Stand](https://en.wikipedia.org/wiki/Lemonade_Stand)
by Bob Jamison.
**Note:** This game has not yet been released. The following links are placeholders.

View file

@ -5,6 +5,7 @@ package main
import (
"code.rocketnine.space/tslocum/pretzel-tycoon/world"
"github.com/hajimehoshi/ebiten/v2"
)
func parseFlags() {

View file

@ -7,6 +7,8 @@ import (
"image/color"
"log"
"os"
"regexp"
"strconv"
"code.rocketnine.space/tslocum/etk"
"code.rocketnine.space/tslocum/messeji"
@ -24,15 +26,30 @@ type viewType int
const (
viewTitle = iota
viewIntro1
viewStartDayProduction1
viewStartDayProduction2
viewStartDayProduction3
viewStartDaySupplies
viewFinancialReport
)
var matchNumbers = regexp.MustCompile("^[0-9]+$")
type Game struct {
inputBuffer *etk.Input
textBuffer *dummyTextBuffer
currentView viewType
viewTicks int
day int
inputLetters bool // Whether to allow the user to input letters.
makePretzels int // In dozens.
makeSigns int
pretzelPrice int // In cents.
}
var addedGame bool
@ -74,13 +91,11 @@ func NewGame() (*Game, error) {
etk.Style.TextFont = loadFont()
g := &Game{
inputBuffer: etk.NewInput("", "", func(text string) (handled bool) {
log.Println("selected", text)
return true
}),
textBuffer: &dummyTextBuffer{
Text: etk.NewText("Hello world!"),
},
day: 1,
}
g.inputBuffer = etk.NewInput("", "", g.acceptInput)
g.textBuffer = &dummyTextBuffer{
Text: etk.NewText("Hello world!"),
}
// Configure text buffer.
@ -109,10 +124,43 @@ func (g *Game) Layout(_, _ int) (screenWidth, screenHeight int) {
return world.ScreenWidth, world.ScreenHeight
}
func (g *Game) inputActive() bool {
return g.currentView == viewStartDayProduction1 || g.currentView == viewStartDayProduction2 || g.currentView == viewStartDayProduction3
}
func (g *Game) acceptInput(text string) (handled bool) {
log.Println("selected", text)
i, err := strconv.Atoi(text)
if err != nil {
log.Println(err) // TODO this shouldnt happen
return false
}
switch g.currentView {
case viewStartDayProduction1:
g.makePretzels = i
case viewStartDayProduction2:
g.makeSigns = i
case viewStartDayProduction3:
g.pretzelPrice = i
}
g.currentView++
partialTransition := g.currentView == viewStartDayProduction2 || g.currentView == viewStartDayProduction3
if partialTransition {
viewBytes := viewText[g.currentView-1]
lines := bytes.Split(viewBytes, []byte("\n"))
g.viewTicks = len(lines) - 2
} else {
g.viewTicks = 0
}
return true
}
func (g *Game) refreshBuffer() error {
// TODO only do this when the view buffer or input buffer changes
currentDay := 1
// TODO fix trailing newline causing scroll bar to appear
pretzelsSold := 50
pretzelPrice := "$.10"
@ -133,13 +181,35 @@ func (g *Game) refreshBuffer() error {
viewBytes = append(viewBytes, bytes.TrimRight(centeredText("PRESS SPACE TO START"), "\n")...)
}
// Append user input.
if g.inputActive() {
viewBytes = append(viewBytes, g.inputBuffer.Text()...)
// Append cursor icon.
if g.viewTicks%150 < 100 {
viewBytes = append(viewBytes, '|')
}
}
// Format view.
var lines [][]byte
switch g.currentView {
case viewTitle, viewIntro1:
case viewStartDayProduction1:
viewBytes = []byte(fmt.Sprintf(string(viewBytes), g.day))
lines = bytes.Split(viewBytes, []byte("\n"))
case viewStartDayProduction2:
viewBytes = []byte(fmt.Sprintf(string(viewBytes), g.day, g.makePretzels))
lines = bytes.Split(viewBytes, []byte("\n"))
case viewStartDayProduction3:
viewBytes = []byte(fmt.Sprintf(string(viewBytes), g.day, g.makePretzels, g.makeSigns))
lines = bytes.Split(viewBytes, []byte("\n"))
case viewStartDaySupplies:
viewBytes = []byte(fmt.Sprintf(string(viewBytes), g.day))
lines = bytes.Split(viewBytes, []byte("\n"))
case viewFinancialReport:
viewBytes = []byte(fmt.Sprintf(string(viewBytes), currentDay, pretzelsSold, pretzelPrice, totalIncome, pretzelsMade, signsMade, totalExpenses, profit, assets))
viewBytes = []byte(fmt.Sprintf(string(viewBytes), g.day, pretzelsSold, pretzelPrice, totalIncome, pretzelsMade, signsMade, totalExpenses, profit, assets))
lines = bytes.Split(viewBytes, []byte("\n"))
default:
lines = bytes.Split(viewBytes, []byte("\n"))
}
@ -188,12 +258,24 @@ func (g *Game) Update() error {
}
// Handle user input.
err := etk.Update()
if err != nil {
log.Fatal(err)
}
if g.inputActive() {
err := etk.Update()
if err != nil {
log.Fatal(err)
}
if inpututil.IsKeyJustPressed(ebiten.KeySpace) {
inputText := g.inputBuffer.Text()
if len(inputText) > 0 && !g.inputLetters && !matchNumbers.MatchString(inputText) {
var newInput string
for _, r := range inputText {
if matchNumbers.MatchString(string(r)) {
newInput += string(r)
}
}
g.inputBuffer.Clear()
g.inputBuffer.Write([]byte(newInput))
}
} else if inpututil.IsKeyJustPressed(ebiten.KeySpace) {
g.currentView++
if g.currentView > viewFinancialReport {
g.currentView = viewTitle
@ -201,21 +283,16 @@ func (g *Game) Update() error {
g.viewTicks = 0
}
err = g.refreshBuffer()
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) {
// Draw the text buffer over the hidden input buffer.
g.textBuffer.Draw(screen)
if world.Debug != 0 {

View file

@ -46,6 +46,50 @@ YOU WILL BEGIN WITH $4.20 CASH (ASSETS).
` + string(bytes.TrimRight(centeredText("PRESS SPACE TO CONTINUE..."), "\n"))),
// viewStartDayProduction1
[]byte(` DAY %d
STARTING SUPPLIES
PRODUCTION AMOUNTS
HOW MANY BATCHES (DOZENS) OF PRETZELS
DO YOU WISH TO MAKE ?`),
// viewStartDayProduction2
[]byte(` DAY %d
STARTING SUPPLIES
PRODUCTION AMOUNTS
HOW MANY BATCHES (DOZENS) OF PRETZELS
DO YOU WISH TO MAKE ?%d
HOW MANY ADVERTISING SIGNS ($1.25 EACH)
DO YOU WISH TO MAKE ?`),
// viewStartDayProduction3
[]byte(` DAY %d
STARTING SUPPLIES
PRODUCTION AMOUNTS
HOW MANY BATCHES (DOZENS) OF PRETZELS
DO YOU WISH TO MAKE ?%d
HOW MANY ADVERTISING SIGNS ($1.25 EACH)
DO YOU WISH TO MAKE ?%d
WHAT PRICE (IN CENTS) DO YOU WISH TO
CHARGE FOR PRETZELS ?`),
// viewStartDaySupplies
[]byte(` DAY %d
TODO`),
// viewFinancialReport
[]byte(` $$ PRETZELSVILLE FINANCIAL REPORT $$

2
go.mod
View file

@ -6,7 +6,7 @@ require (
code.rocketnine.space/tslocum/etk v0.0.0-20230608043113-585e23b06fff
code.rocketnine.space/tslocum/messeji v1.0.3
github.com/hajimehoshi/ebiten/v2 v2.5.4
golang.org/x/image v0.7.0
golang.org/x/image v0.8.0
)
require (

5
go.sum
View file

@ -16,8 +16,8 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/exp/shiny v0.0.0-20230522175609-2e198f4a06a1 h1:NxHSRPlbeyFGDc6rU7YsvxV/4bXS9XhuvUt5pP63XUs=
golang.org/x/exp/shiny v0.0.0-20230522175609-2e198f4a06a1/go.mod h1:UH99kUObWAZkDnWqppdQe5ZhPYESUw8I0zVV1uWBR+0=
golang.org/x/image v0.7.0 h1:gzS29xtG1J5ybQlv0PuyfE3nmc6R4qB73m6LUUmvFuw=
golang.org/x/image v0.7.0/go.mod h1:nd/q4ef1AKKYl/4kft7g+6UyGbdiqWqTP1ZAbRoV7Rg=
golang.org/x/image v0.8.0 h1:agUcRXV/+w6L9ryntYYsF2x9fQTMd4T8fiiYXAVW6Jg=
golang.org/x/image v0.8.0/go.mod h1:PwLxp3opCYg4WR2WO9P0L6ESnsD6bLTWcw8zanLMVFM=
golang.org/x/mobile v0.0.0-20230531173138-3c911d8e3eda h1:O+EUvnBNPwI4eLthn8W5K+cS8zQZfgTABPLNm6Bna34=
golang.org/x/mobile v0.0.0-20230531173138-3c911d8e3eda/go.mod h1:aAjjkJNdrh3PMckS4B10TGS2nag27cbKR1y2BpUxsiY=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
@ -46,7 +46,6 @@ 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/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=