From 4f5bbdc56afb7c8152cf309977b8395d876bcb7a Mon Sep 17 00:00:00 2001 From: Thomas von Dein Date: Wed, 14 Feb 2024 19:35:36 +0100 Subject: [PATCH] added welcome scene with text rendering using etxt --- assets/fonts/x12y20pxScanLine.ttf | Bin 0 -> 150776 bytes assets/loader-fonts.go | 59 ++++++++++++++++++++++++++++ assets/loader-sprites.go | 2 +- game/game.go | 23 +++++++---- game/levelscene.go | 17 ++++---- game/scene.go | 5 ++- game/welcome_scene.go | 62 ++++++++++++++++++++++++++++++ go.mod | 4 +- go.sum | 5 +++ 9 files changed, 159 insertions(+), 18 deletions(-) create mode 100644 assets/fonts/x12y20pxScanLine.ttf create mode 100644 assets/loader-fonts.go create mode 100644 game/welcome_scene.go diff --git a/assets/fonts/x12y20pxScanLine.ttf b/assets/fonts/x12y20pxScanLine.ttf new file mode 100644 index 0000000000000000000000000000000000000000..46900c5b4335140d816bc4441f80fe6612feecc8 GIT binary patch literal 150776 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 literal 0 HcmV?d00001 diff --git a/assets/loader-fonts.go b/assets/loader-fonts.go new file mode 100644 index 0000000..adee5fe --- /dev/null +++ b/assets/loader-fonts.go @@ -0,0 +1,59 @@ +package assets + +import ( + "log" + + "github.com/tinne26/etxt" +) + +var FontRenderer = LoadFonts("fonts") + +const ( + GameFont string = "x12y20pxScanLine" + FontSize int = 16 +) + +type Texter struct { + Renderer *etxt.Renderer +} + +func LoadFonts(dir string) *Texter { + fontlib := etxt.NewFontLibrary() + _, _, err := fontlib.ParseEmbedDirFonts(dir, assetfs) + if err != nil { + log.Fatalf("Error while loading fonts: %s", err.Error()) + } + + if !fontlib.HasFont(GameFont) { + log.Fatal("missing font: " + GameFont) + } + + err = fontlib.EachFont(checkMissingRunes) + if err != nil { + log.Fatal(err) + } + + renderer := etxt.NewStdRenderer() + + glyphsCache := etxt.NewDefaultCache(10 * 1024 * 1024) // 10MB + renderer.SetCacheHandler(glyphsCache.NewHandler()) + renderer.SetFont(fontlib.GetFont(GameFont)) + + return &Texter{renderer} +} + +// helper function used with FontLibrary.EachFont to make sure +// all loaded fonts contain the characters or alphabet we want +func checkMissingRunes(name string, font *etxt.Font) error { + const letters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" + const symbols = "0123456789 .,;:!?-()[]{}_&#@" + + missing, err := etxt.GetMissingRunes(font, letters+symbols) + if err != nil { + return err + } + if len(missing) > 0 { + log.Fatalf("Font '%s' missing runes: %s", name, string(missing)) + } + return nil +} diff --git a/assets/loader-sprites.go b/assets/loader-sprites.go index 6429ee3..7a6fa4c 100644 --- a/assets/loader-sprites.go +++ b/assets/loader-sprites.go @@ -16,7 +16,7 @@ import ( // Maps image name to image data type AssetRegistry map[string]*ebiten.Image -//go:embed levels/*.lvl sprites/*.png +//go:embed levels/*.lvl sprites/*.png fonts/*.ttf var assetfs embed.FS var Assets = LoadImages("sprites") diff --git a/game/game.go b/game/game.go index 2acb0ce..f4e8493 100644 --- a/game/game.go +++ b/game/game.go @@ -13,7 +13,8 @@ type Game struct { World *ecs.World Bounds image.Rectangle ScreenWidth, ScreenHeight int - Scenes map[int]Scene + Scenes map[SceneName]Scene + CurrentScene SceneName Observer *observers.GameObserver } @@ -25,20 +26,26 @@ func NewGame(width, height, cellsize, startlevel int, startscene int) *Game { World: &world, ScreenWidth: width, ScreenHeight: height, - Scenes: map[int]Scene{}, + Scenes: map[SceneName]Scene{}, } observers.NewPlayerObserver(&world) observers.NewParticleObserver(&world) game.Observer = observers.NewGameObserver(&world, startlevel, width, height, cellsize) + game.Scenes[Welcome] = NewWelcomeScene(game) game.Scenes[Play] = NewLevelScene(game, startlevel) + game.CurrentScene = Welcome fmt.Println(game.World.Stats().String()) return game } +func (game *Game) GetCurrentScene() Scene { + return game.Scenes[game.CurrentScene] +} + func (game *Game) Update() error { gameobserver := observers.GetGameObserver(game.World) timer := gameobserver.StopTimer @@ -49,8 +56,12 @@ func (game *Game) Update() error { gameobserver.Score++ // FIXME: use level.Score(), see TODO } - for _, scene := range game.Scenes { - scene.Update() + scene := game.GetCurrentScene() + scene.Update() + + next := scene.GetNext() + if next != game.CurrentScene { + game.CurrentScene = next } timer.Update() @@ -59,9 +70,7 @@ func (game *Game) Update() error { } func (game *Game) Draw(screen *ebiten.Image) { - for _, scene := range game.Scenes { - scene.Draw(screen) - } + game.GetCurrentScene().Draw(screen) } func (g *Game) Layout(newWidth, newHeight int) (int, int) { diff --git a/game/levelscene.go b/game/levelscene.go index a9a4fed..27a43d9 100644 --- a/game/levelscene.go +++ b/game/levelscene.go @@ -11,14 +11,14 @@ type LevelScene struct { Game *Game CurrentLevel int Levels []*Level - Next int - Whoami int + Next SceneName + Whoami SceneName UseCache bool } // Implements the actual playing Scene func NewLevelScene(game *Game, startlevel int) Scene { - scene := &LevelScene{CurrentLevel: startlevel, Whoami: Play, Game: game} + scene := &LevelScene{CurrentLevel: startlevel, Whoami: Play, Next: Play, Game: game} scene.GenerateLevels(game) scene.Levels[scene.CurrentLevel].SetupGrid(game) @@ -33,12 +33,13 @@ func (scene *LevelScene) GenerateLevels(game *Game) { } // Interface methods -func (scene *LevelScene) SetNext() int { - if scene.Whoami != scene.Next { - return scene.Next - } +func (scene *LevelScene) SetNext(next SceneName) { + scene.Next = next +} - return 0 +func (scene *LevelScene) GetNext() SceneName { + // FIXME: set to winner or options screen + return scene.Next } func (scene *LevelScene) Update() error { diff --git a/game/scene.go b/game/scene.go index fdc7c50..5d64933 100644 --- a/game/scene.go +++ b/game/scene.go @@ -18,7 +18,10 @@ const ( // to render its content onto the running level, e.g. the options scene // etc. type Scene interface { - SetNext() int + SetNext(SceneName) + GetNext() SceneName Update() error Draw(screen *ebiten.Image) } + +type SceneName int diff --git a/game/welcome_scene.go b/game/welcome_scene.go new file mode 100644 index 0000000..4085ad0 --- /dev/null +++ b/game/welcome_scene.go @@ -0,0 +1,62 @@ +package game + +import ( + "image/color" + "log/slog" + "openquell/assets" + + "github.com/hajimehoshi/ebiten/v2" + "github.com/tinne26/etxt" +) + +type WelcomeScene struct { + Game *Game + Next SceneName + Whoami SceneName + UseCache bool +} + +func NewWelcomeScene(game *Game) Scene { + scene := &WelcomeScene{Whoami: Welcome, Game: game, Next: Welcome} + return scene +} + +func (scene *WelcomeScene) SetNext(next SceneName) { + scene.Next = next +} + +func (scene *WelcomeScene) GetNext() SceneName { + return scene.Next +} + +func (scene *WelcomeScene) Update() error { + switch { + case ebiten.IsKeyPressed(ebiten.KeyEnter): + slog.Debug("welcome.Update() next") + scene.SetNext(Play) + } + + return nil +} + +func (scene *WelcomeScene) Draw(screen *ebiten.Image) { + screen.Clear() + + op := &ebiten.DrawImageOptions{} + + background := assets.Assets["background-lila"] + screen.DrawImage(background, op) + + blue := color.RGBA{0, 255, 128, 255} + + assets.FontRenderer.Renderer.SetTarget(screen) + assets.FontRenderer.Renderer.SetColor(blue) + assets.FontRenderer.Renderer.SetAlign(etxt.YCenter, etxt.XCenter) + assets.FontRenderer.Renderer.SetSizePx(45) + assets.FontRenderer.Renderer.Draw("Welcome to Open Quell!", 320, 200) + + assets.FontRenderer.Renderer.SetAlign(etxt.Top, etxt.Left) + assets.FontRenderer.Renderer.SetSizePx(32) + assets.FontRenderer.Renderer.Draw("[press enter to start]", 100, 300) + +} diff --git a/go.mod b/go.mod index 3eb6fa8..0aaed6c 100644 --- a/go.mod +++ b/go.mod @@ -14,11 +14,13 @@ require ( github.com/jezek/xgb v1.1.0 // indirect github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.20 // indirect - github.com/tlinden/yadu v0.1.2 // indirect + github.com/tinne26/etxt v0.0.8 // indirect + github.com/tlinden/yadu v0.1.3 // indirect golang.org/x/exp/shiny v0.0.0-20230817173708-d852ddb80c63 // indirect golang.org/x/image v0.12.0 // indirect golang.org/x/mobile v0.0.0-20230922142353-e2f452493d57 // indirect golang.org/x/sync v0.3.0 // indirect golang.org/x/sys v0.14.0 // indirect + golang.org/x/text v0.13.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index 8a3bfcb..ea49675 100644 --- a/go.sum +++ b/go.sum @@ -15,8 +15,12 @@ github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWE github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mlange-42/arche v0.10.0 h1:fEFDAYMAnWa+xHc1oq4gVcA4PuEQOCGSRXSKITXawMw= github.com/mlange-42/arche v0.10.0/go.mod h1:gJ5J8vBreqrf4TcBomBFPGnWdE5P3qa4LtxYHn1gDcg= +github.com/tinne26/etxt v0.0.8 h1:rjb58jkMkapRGLmhBMWnT76E/nMTXC5P1Q956BRZkoc= +github.com/tinne26/etxt v0.0.8/go.mod h1:QM/hlNkstsKC39elTFNKAR34xsMb9QoVosf+g9wlYxM= github.com/tlinden/yadu v0.1.2 h1:TYYVnUJwziRJ9YPbIbRf9ikmDw0Q8Ifixm+J/kBQFh8= github.com/tlinden/yadu v0.1.2/go.mod h1:l3bRmHKL9zGAR6pnBHY2HRPxBecf7L74BoBgOOpTcUA= +github.com/tlinden/yadu v0.1.3 h1:5cRCUmj+l5yvlM2irtpFBIJwVV2DPEgYSaWvF19FtcY= +github.com/tlinden/yadu v0.1.3/go.mod h1:l3bRmHKL9zGAR6pnBHY2HRPxBecf7L74BoBgOOpTcUA= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= @@ -56,6 +60,7 @@ 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.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k= golang.org/x/text v0.13.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=