added welcome scene with text rendering using etxt
This commit is contained in:
parent
48396e7e0a
commit
4f5bbdc56a
BIN
assets/fonts/x12y20pxScanLine.ttf
Normal file
BIN
assets/fonts/x12y20pxScanLine.ttf
Normal file
Binary file not shown.
59
assets/loader-fonts.go
Normal file
59
assets/loader-fonts.go
Normal file
@ -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
|
||||
}
|
||||
@ -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")
|
||||
|
||||
21
game/game.go
21
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 := 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) {
|
||||
|
||||
@ -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 {
|
||||
|
||||
@ -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
|
||||
|
||||
62
game/welcome_scene.go
Normal file
62
game/welcome_scene.go
Normal file
@ -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)
|
||||
|
||||
}
|
||||
4
go.mod
4
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
|
||||
)
|
||||
|
||||
5
go.sum
5
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=
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user