Draw customers and cash given

This commit is contained in:
Trevor Slocum 2023-02-18 16:24:36 -08:00
parent 5dd5219b5a
commit a6bca58bfc
18 changed files with 275 additions and 15 deletions

View File

@ -5,23 +5,26 @@ import (
"image"
"io"
"github.com/hajimehoshi/ebiten/v2/audio"
"github.com/hajimehoshi/ebiten/v2/audio/vorbis"
_ "image/jpeg"
_ "image/png"
"code.rocketnine.space/tslocum/gas-station-sim/world"
"github.com/hajimehoshi/ebiten/v2"
"github.com/hajimehoshi/ebiten/v2/audio"
"github.com/hajimehoshi/ebiten/v2/audio/vorbis"
)
//go:embed image sound
var fs embed.FS
var (
ImageInterior = interiorImage()
ImageExterior = exteriorImage()
ImageCursor = LoadImage("image/cursor.png")
ImageInterior = interiorImage()
ImageExterior = exteriorImage()
ImageCursor = LoadImage("image/cursor.png")
ImageCustomerFrontMale = LoadImage("image/s_front_male.png")
ImageCustomerFrontFemale = LoadImage("image/s_front_female.png")
ImageDollarTwo = LoadImage("image/dollar_two.jpg")
ImageDollarTwenty = LoadImage("image/dollar_twenty.jpg")
)
const sampleRate = 44100
@ -30,6 +33,12 @@ var (
audioContext = audio.NewContext(sampleRate)
SoundChime = LoadOGG(audioContext, "sound/chime.ogg", false)
SoundHelloAndWelcome = LoadOGG(audioContext, "sound/hello-and-welcome.ogg", false)
SoundOnPumpMale = LoadOGG(audioContext, "sound/on-pump-male.ogg", false)
SoundOnPumpFemale = LoadOGG(audioContext, "sound/on-pump-female.ogg", false)
SoundEightMale = LoadOGG(audioContext, "sound/eight-male.ogg", false)
SoundEightFemale = LoadOGG(audioContext, "sound/eight-female.ogg", false)
SoundTwentyMale = LoadOGG(audioContext, "sound/twenty-male.ogg", false)
SoundTwentyFemale = LoadOGG(audioContext, "sound/twenty-female.ogg", false)
)
func interiorImage() *ebiten.Image {

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

BIN
asset/image/dollar_two.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

BIN
asset/sound/eight-male.ogg Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
asset/sound/twenty-male.ogg Normal file

Binary file not shown.

View File

@ -11,19 +11,24 @@ import (
func parseFlags() {
var (
skipIntro bool
skipName bool
skipIntro bool
skipName bool
skipTutorial bool
)
flag.BoolVar(&world.Fullscreen, "fullscreen", true, "run in fullscreen mode")
flag.BoolVar(&skipIntro, "skip-intro", false, "skip intro screen")
flag.BoolVar(&skipName, "skip-name", false, "skip name input screen")
flag.BoolVar(&skipTutorial, "skip-tutorial", false, "skip tutorial")
flag.Parse()
if skipIntro || skipName {
if skipIntro || skipName || skipTutorial {
world.StartGame()
if skipName {
if skipName || skipTutorial {
world.Name = world.NameInput
world.NameInput = ""
if skipTutorial {
world.TutorialIntroFinished = true
}
}
}
}

View File

@ -64,6 +64,8 @@ func NewGame() *Game {
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 {

View File

@ -1,26 +1,48 @@
package system
import (
"log"
"time"
"code.rocketnine.space/tslocum/gas-station-sim/asset"
"github.com/hajimehoshi/ebiten/v2/audio"
"code.rocketnine.space/tslocum/gas-station-sim/world"
"code.rocketnine.space/tslocum/gohan"
"github.com/hajimehoshi/ebiten/v2"
)
type speakPhrase int
const (
phraseUnknown speakPhrase = iota
phraseEight
phraseTwenty
phraseOnPump
)
type Customer struct {
}
const CashTime = world.TPS * 5.25
func (r *Customer) Update(_ gohan.Entity) error {
if !world.TutorialIntroFinished {
return nil
}
world.CustomerGenderMale = false
const SpeakTime = world.TPS * 3.5
if world.CustomerTicks == 0 {
world.CustomerGenderMale = world.Rand.Intn(2) == 0
asset.SoundChime.Rewind()
asset.SoundChime.Play()
//asset.SoundChime.Play()
// TODO
} else if world.CustomerTicks == SpeakTime {
//go r.Speak(phraseTwenty, phraseOnPump, phraseEight)
}
world.CustomerTicks++
return nil
@ -30,5 +52,62 @@ func (r *Customer) Draw(_ gohan.Entity, screen *ebiten.Image) error {
if !world.TutorialIntroFinished {
return nil
}
const waitTime = world.TPS * 2.5
const fadeInEnd = world.TPS * 3
if world.CustomerTicks > waitTime {
scale := 1.0
if world.CustomerTicks < fadeInEnd {
scale = float64(world.CustomerTicks-waitTime) / float64(fadeInEnd-waitTime)
}
customerImg := asset.ImageCustomerFrontMale
if !world.CustomerGenderMale {
customerImg = asset.ImageCustomerFrontFemale
}
op := &ebiten.DrawImageOptions{}
op.GeoM.Translate(128, 16)
op.ColorM.Scale(1, 1, 1, scale)
screen.DrawImage(customerImg, op)
}
return nil
}
func (r *Customer) Speak(phrase ...speakPhrase) {
var sound *audio.Player
var waitTime time.Duration
for _, p := range phrase {
switch p {
case phraseEight:
if world.CustomerGenderMale {
sound = asset.SoundEightMale
} else {
sound = asset.SoundEightFemale
}
waitTime = 600 * time.Millisecond
case phraseTwenty:
if world.CustomerGenderMale {
sound = asset.SoundTwentyMale
} else {
sound = asset.SoundTwentyFemale
}
waitTime = 600 * time.Millisecond
case phraseOnPump:
if world.CustomerGenderMale {
sound = asset.SoundOnPumpMale
} else {
sound = asset.SoundOnPumpFemale
}
waitTime = 650 * time.Millisecond
default:
log.Printf("warning: unknown phrase %d", phrase)
return
}
sound.Rewind()
sound.Play()
time.Sleep(waitTime)
}
}

26
system/pumpconsole.go Normal file
View File

@ -0,0 +1,26 @@
package system
import (
"code.rocketnine.space/tslocum/gas-station-sim/world"
"code.rocketnine.space/tslocum/gohan"
"github.com/hajimehoshi/ebiten/v2"
)
type PumpConsole struct {
}
func (r *PumpConsole) Update(_ gohan.Entity) error {
if !world.TutorialIntroFinished || ebiten.IsKeyPressed(ebiten.KeyShift) || (!ebiten.IsKeyPressed(ebiten.KeyAlt) && !ebiten.IsKeyPressed(ebiten.KeyControl)) {
return nil
}
return nil
}
func (r *PumpConsole) Draw(_ gohan.Entity, screen *ebiten.Image) error {
if !world.TutorialIntroFinished || ebiten.IsKeyPressed(ebiten.KeyShift) || (!ebiten.IsKeyPressed(ebiten.KeyAlt) && !ebiten.IsKeyPressed(ebiten.KeyControl)) {
return nil
}
world.DrawText(screen, 1, world.ScreenWidth-16-(12*6), 16, true, "PUMP CONSOLE")
return nil
}

View File

@ -2,6 +2,14 @@ package system
import (
"fmt"
"image"
"image/color"
"math"
"math/rand"
"github.com/hajimehoshi/ebiten/v2/inpututil"
"code.rocketnine.space/tslocum/gas-station-sim/asset"
"code.rocketnine.space/tslocum/gas-station-sim/world"
"code.rocketnine.space/tslocum/gohan"
@ -9,14 +17,63 @@ import (
)
type RenderUI struct {
cashX, cashY float64
dragCash bool
dragX, dragY float64
}
const (
cashWidth = 25.0
cashHeight = 59.0
)
const surfaceHeight = 45
const cashEndTime = CashTime + world.TPS/8
func (r *RenderUI) Update(_ gohan.Entity) error {
if !world.GameStarted {
if !world.TutorialIntroFinished {
return nil
}
if world.Name == "" {
if world.CustomerTicks == 1 {
r.cashX = 150 + float64(rand.Intn(50))
r.cashY = 155
}
if world.CustomerTicks >= CashTime {
cashRect := image.Rect(int(r.cashX), int(r.cashY), int(r.cashX+cashWidth), int(r.cashY+cashHeight))
cx, cy := ebiten.CursorPosition()
if inpututil.IsMouseButtonJustPressed(ebiten.MouseButtonLeft) {
point := image.Point{
X: cx,
Y: cy,
}
if point.In(cashRect) {
if !r.dragCash {
r.dragCash = true
r.dragX, r.dragY = float64(cx)-r.cashX, float64(cy)-r.cashY
}
}
} else if r.dragCash && !ebiten.IsMouseButtonPressed(ebiten.MouseButtonLeft) {
r.dragCash = false
if cy >= world.ScreenHeight-surfaceHeight {
r.cashX, r.cashY = float64(cx)-r.dragX, float64(cy)-r.dragY
if r.cashX < -cashWidth+2 {
r.cashX = -cashWidth + 2
} else if r.cashX > world.ScreenWidth-2 {
r.cashX = world.ScreenWidth - 2
}
if r.cashY > world.ScreenHeight-2 {
r.cashY = world.ScreenHeight - 2
}
}
}
if world.CustomerTicks < cashEndTime && !r.dragCash {
r.cashY += 6.25
}
}
return nil
@ -34,6 +91,62 @@ func (r *RenderUI) Draw(_ gohan.Entity, screen *ebiten.Image) error {
world.DrawText(screen, 2, 64, 128, true, fmt.Sprintf("%s_", world.NameInput))
}
}
return nil
}
// Draw surface.
const surfaceBorderHeight = 10
const paddingWidth = 20
screen.SubImage(image.Rect(0, world.ScreenHeight-surfaceHeight, world.ScreenWidth, world.ScreenHeight)).(*ebiten.Image).Fill(color.RGBA{255, 255, 255, 255})
screen.SubImage(image.Rect(0, world.ScreenHeight-surfaceHeight, world.ScreenWidth, world.ScreenHeight-surfaceHeight+surfaceBorderHeight)).(*ebiten.Image).Fill(color.RGBA{50, 50, 50, 255})
screen.SubImage(image.Rect(0, world.ScreenHeight-surfaceHeight, world.ScreenWidth, world.ScreenHeight-surfaceHeight+2)).(*ebiten.Image).Fill(color.RGBA{0, 0, 0, 255})
screen.SubImage(image.Rect(paddingWidth-1, world.ScreenHeight-surfaceHeight+6, world.ScreenWidth-paddingWidth, world.ScreenHeight-surfaceHeight+surfaceBorderHeight)).(*ebiten.Image).Fill(color.RGBA{255, 255, 255, 255})
// Draw cash.
if world.CustomerTicks >= CashTime {
cx, cy := ebiten.CursorPosition()
onSurface := cy >= world.ScreenHeight-surfaceHeight
op := &ebiten.DrawImageOptions{}
drawX, drawY := r.cashX, r.cashY
if r.dragCash {
drawX, drawY = float64(cx), float64(cy)
}
target := screen.SubImage(image.Rect(0, world.ScreenHeight-surfaceHeight, world.ScreenWidth, world.ScreenHeight)).(*ebiten.Image)
if world.CustomerTicks >= cashEndTime {
target = screen
}
scale := 0.5
if r.dragCash {
target = screen
if !onSurface {
scale = 2.5
op.GeoM.Rotate(math.Pi / 2)
}
}
op.GeoM.Scale(scale, scale)
if r.dragCash {
if onSurface {
op.GeoM.Translate(-r.dragX, -r.dragY)
} else {
op.GeoM.Translate(cashWidth*scale*2.35, -2)
}
}
op.GeoM.Translate(drawX, drawY)
if !r.dragCash || onSurface {
op.ColorM.ChangeHSV(0, 0, 0.34)
} else {
op.ColorM.ChangeHSV(0, -1, 0.7)
}
target.DrawImage(asset.ImageDollarTwenty, op)
}
//screen.SubImage(image.Rect(0, 0, 50, 118)).(*ebiten.Image).Fill(color.RGBA{255, 255, 255, 255})
return nil
}

26
system/till.go Normal file
View File

@ -0,0 +1,26 @@
package system
import (
"code.rocketnine.space/tslocum/gas-station-sim/world"
"code.rocketnine.space/tslocum/gohan"
"github.com/hajimehoshi/ebiten/v2"
)
type Till struct {
}
func (r *Till) Update(_ gohan.Entity) error {
if !world.TutorialIntroFinished || ebiten.IsKeyPressed(ebiten.KeyAlt) || ebiten.IsKeyPressed(ebiten.KeyControl) || !ebiten.IsKeyPressed(ebiten.KeyShift) {
return nil
}
return nil
}
func (r *Till) Draw(_ gohan.Entity, screen *ebiten.Image) error {
if !world.TutorialIntroFinished || ebiten.IsKeyPressed(ebiten.KeyAlt) || ebiten.IsKeyPressed(ebiten.KeyControl) || !ebiten.IsKeyPressed(ebiten.KeyShift) {
return nil
}
world.DrawText(screen, 1, 16, 16, true, "TILL")
return nil
}

View File

@ -54,8 +54,8 @@ var img = ebiten.NewImage(ScreenWidth, ScreenHeight)
func DrawText(screen *ebiten.Image, scale int, x int, y int, fill bool, text string) {
const (
paddingW = 6
paddingH = 2
paddingW = 5
paddingH = 1
)
var maxLen int