Moved initialization of textures to main (appContext).
Added info screen.
This commit is contained in:
parent
45b64a46ec
commit
157ec6d42d
@ -55,11 +55,9 @@ func (a *app) Init(ctx ui.Context) error {
|
||||
|
||||
ctx.Overlays().AddOnTop(fpsOverlayName, &play.FPS{Align: ui.AlignRight}, false)
|
||||
|
||||
a.context = &appContext{
|
||||
setView: func(control ui.Control) {
|
||||
a.context = newAppContext(ctx, func(control ui.Control) {
|
||||
a.Content = control
|
||||
},
|
||||
}
|
||||
})
|
||||
a.context.ShowMainMenu(ctx)
|
||||
|
||||
return nil
|
||||
|
@ -1,6 +1,8 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"image"
|
||||
|
||||
"opslag.de/schobers/tins2021"
|
||||
"opslag.de/schobers/zntg/ui"
|
||||
)
|
||||
@ -9,6 +11,36 @@ type appContext struct {
|
||||
setView func(ui.Control)
|
||||
|
||||
Debug bool
|
||||
|
||||
MonsterTextureNames map[tins2021.MonsterType]string
|
||||
}
|
||||
|
||||
func newAppContext(ctx ui.Context, setView func(ui.Control)) *appContext {
|
||||
newAnimatedTexture(ctx, "star", "resources/images/star.png", func() image.Image {
|
||||
return tins2021.AnimatePolygon(tins2021.CreateStar(5), tins2021.Yellow, tins2021.NewRotateAnimation(defaultAnimationFrames))
|
||||
})
|
||||
newAnimatedTexture(ctx, "heart", "resources/images/heart.png", func() image.Image {
|
||||
return tins2021.AnimatePolygon(tins2021.CreateHeart(), tins2021.Red, tins2021.NewRotateAnimation(defaultAnimationFrames))
|
||||
})
|
||||
|
||||
app := &appContext{
|
||||
setView: setView,
|
||||
MonsterTextureNames: map[tins2021.MonsterType]string{
|
||||
tins2021.MonsterTypeStraight: "straight-walking-monster",
|
||||
tins2021.MonsterTypeRandom: "random-walking-monster",
|
||||
tins2021.MonsterTypeChaser: "chasing-monster",
|
||||
},
|
||||
}
|
||||
newAnimatedTexture(ctx, app.MonsterTextureNames[tins2021.MonsterTypeStraight], "resources/images/monster-straight.png", func() image.Image {
|
||||
return tins2021.AnimatePolygon(tins2021.CreateHexagon(), tins2021.Green, tins2021.NewWobbleAnimation(defaultAnimationFrames, 30))
|
||||
})
|
||||
newAnimatedTexture(ctx, app.MonsterTextureNames[tins2021.MonsterTypeRandom], "resources/images/monster-random.png", func() image.Image {
|
||||
return tins2021.AnimatePolygon(tins2021.CreateHexagon(), tins2021.Blue, tins2021.NewWobbleAnimation(defaultAnimationFrames, 30))
|
||||
})
|
||||
newAnimatedTexture(ctx, app.MonsterTextureNames[tins2021.MonsterTypeChaser], "resources/images/monster-chaser.png", func() image.Image {
|
||||
return tins2021.AnimatePolygon(tins2021.CreateHexagon(), tins2021.Purple, tins2021.NewWobbleAnimation(defaultAnimationFrames, 30))
|
||||
})
|
||||
return app
|
||||
}
|
||||
|
||||
const numberOfStars = 5
|
||||
@ -41,7 +73,9 @@ func (app *appContext) ShowCredits(ctx ui.Context) {
|
||||
app.setView(newCredits(app, ctx))
|
||||
}
|
||||
|
||||
func (app *appContext) ShowInfo(ctx ui.Context) {}
|
||||
func (app *appContext) ShowInfo(ctx ui.Context) {
|
||||
app.setView(newInfo(app, ctx))
|
||||
}
|
||||
|
||||
func (app *appContext) ShowMainMenu(ctx ui.Context) {
|
||||
app.show(newMainMenu(app, ctx))
|
||||
|
89
cmd/tins2021/info.go
Normal file
89
cmd/tins2021/info.go
Normal file
@ -0,0 +1,89 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"opslag.de/schobers/geom"
|
||||
"opslag.de/schobers/tins2021"
|
||||
"opslag.de/schobers/zntg/ui"
|
||||
)
|
||||
|
||||
type info struct {
|
||||
ui.StackPanel
|
||||
|
||||
app *appContext
|
||||
legend *ui.StackPanel
|
||||
}
|
||||
|
||||
const infoText = "Qbitter is a game loosly based on a work \"LW305 Kringloop\" of M.C. Escher where a gnome runs down a stairs and morphs into its 2D abstract shape. The game also lends ideas from Q*Bert, a game from the eighties that was itself based on the works of M.C. Escher. In the game you (represented as a gnome) have to collect stars while trying to avoid enemies (hexagons). Every level has increasing difficulty."
|
||||
|
||||
type infoLegend struct {
|
||||
ui.ControlBase
|
||||
|
||||
Icon ui.Texture
|
||||
Description string
|
||||
}
|
||||
|
||||
func (l *infoLegend) DesiredSize(ctx ui.Context, size geom.PointF32) geom.PointF32 {
|
||||
return geom.PtF32(geom.NaN32(), .4*tins2021.TextureSize)
|
||||
}
|
||||
|
||||
const infoLegenIconSize = .36
|
||||
|
||||
var infoLegendIconRectangle = geom.RectRelF32(0, 0, infoLegenIconSize*tins2021.TextureSize, infoLegenIconSize*tins2021.TextureSize)
|
||||
|
||||
func (l *infoLegend) Render(ctx ui.Context) {
|
||||
bounds := l.Bounds()
|
||||
separator := .3 * bounds.Dx()
|
||||
textureHeight := float32(l.Icon.Height())
|
||||
renderer := ctx.Renderer()
|
||||
renderer.DrawTexturePointOptions(l.Icon, bounds.Min.Add2D(separator-textureHeight, 0), ui.DrawOptions{Source: &infoLegendIconRectangle})
|
||||
font := ctx.Fonts().Font("score")
|
||||
fontHeight := float32(font.Height())
|
||||
renderer.Text(font, bounds.Min.Add2D(separator+12, .5*(textureHeight-fontHeight)), ctx.Style().Palette.Text, l.Description)
|
||||
}
|
||||
|
||||
func newInfo(app *appContext, ctx ui.Context) ui.Control {
|
||||
legend := ui.BuildStackPanel(ui.OrientationVertical, func(p *ui.StackPanel) {
|
||||
p.AddChild(&infoLegend{
|
||||
Icon: ctx.Textures().ScaledByName("star", infoLegenIconSize),
|
||||
Description: "Collect them to complete the level.",
|
||||
})
|
||||
p.AddChild(&infoLegend{
|
||||
Icon: ctx.Textures().ScaledByName("heart", infoLegenIconSize),
|
||||
Description: "Gives (back) a life.",
|
||||
})
|
||||
p.AddChild(&infoLegend{
|
||||
Icon: ctx.Textures().ScaledByName("straight-walking-monster", infoLegenIconSize),
|
||||
Description: "Monster that walks over a fixed diagonal.",
|
||||
})
|
||||
p.AddChild(&infoLegend{
|
||||
Icon: ctx.Textures().ScaledByName("random-walking-monster", infoLegenIconSize),
|
||||
Description: "Monster that walks randomly.",
|
||||
})
|
||||
p.AddChild(&infoLegend{
|
||||
Icon: ctx.Textures().ScaledByName("chasing-monster", infoLegenIconSize),
|
||||
Description: "Monster that walks towards you.",
|
||||
})
|
||||
})
|
||||
return Center(&info{StackPanel: ui.StackPanel{
|
||||
ContainerBase: ui.ContainerBase{
|
||||
Children: []ui.Control{
|
||||
labelOpts("QBITTER", "title", labelOptions{TextAlignment: ui.AlignCenter}),
|
||||
label("", "score"), // spacing
|
||||
paragraphOpts(infoText, "score", labelOptions{TextAlignment: ui.AlignCenter}),
|
||||
label("", "score"), // spacing
|
||||
legend,
|
||||
},
|
||||
},
|
||||
Orientation: ui.OrientationVertical,
|
||||
}, app: app})
|
||||
}
|
||||
|
||||
func (i *info) Handle(ctx ui.Context, e ui.Event) bool {
|
||||
switch e := e.(type) {
|
||||
case *ui.KeyDownEvent:
|
||||
if e.Key == ui.KeyEscape || e.Key == ui.KeyEnter {
|
||||
i.app.ShowMainMenu(ctx)
|
||||
}
|
||||
}
|
||||
return i.ControlBase.Handle(ctx, e)
|
||||
}
|
@ -2,7 +2,6 @@ package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"image"
|
||||
"image/color"
|
||||
"math/rand"
|
||||
"strconv"
|
||||
@ -24,50 +23,22 @@ type levelController struct {
|
||||
Cubes cubeTexture
|
||||
Animations map[string]*tins2021.Animations
|
||||
|
||||
MonsterTextureNames map[tins2021.MonsterType]string
|
||||
IdleMonsters *tins2021.Animations
|
||||
MovingMonsters *tins2021.Animations
|
||||
|
||||
SmallFont *tins2021.BitmapFont
|
||||
Font *tins2021.BitmapFont
|
||||
}
|
||||
|
||||
func newLevelControl(app *appContext, ctx ui.Context, level *tins2021.Level) *levelController {
|
||||
control := &levelController{app: app}
|
||||
textures := ctx.Textures()
|
||||
control.Cubes = newCubeTexture(textures, tins2021.Orange)
|
||||
newAnimatedTexture(ctx, "star", "resources/images/star.png", func() image.Image {
|
||||
return tins2021.AnimatePolygon(tins2021.CreateStar(5), tins2021.Yellow, tins2021.NewRotateAnimation(defaultAnimationFrames))
|
||||
})
|
||||
newAnimatedTexture(ctx, "heart", "resources/images/heart.png", func() image.Image {
|
||||
return tins2021.AnimatePolygon(tins2021.CreateHeart(), tins2021.Red, tins2021.NewRotateAnimation(defaultAnimationFrames))
|
||||
})
|
||||
|
||||
control.MonsterTextureNames = map[tins2021.MonsterType]string{
|
||||
tins2021.MonsterTypeStraight: "straight-walking-monster",
|
||||
tins2021.MonsterTypeRandom: "random-walking-monster",
|
||||
tins2021.MonsterTypeChaser: "chasing-monster",
|
||||
}
|
||||
newAnimatedTexture(ctx, control.MonsterTextureNames[tins2021.MonsterTypeStraight], "resources/images/monster-straight.png", func() image.Image {
|
||||
return tins2021.AnimatePolygon(tins2021.CreateHexagon(), tins2021.Green, tins2021.NewWobbleAnimation(defaultAnimationFrames, 30))
|
||||
})
|
||||
newAnimatedTexture(ctx, control.MonsterTextureNames[tins2021.MonsterTypeRandom], "resources/images/monster-random.png", func() image.Image {
|
||||
return tins2021.AnimatePolygon(tins2021.CreateHexagon(), tins2021.Blue, tins2021.NewWobbleAnimation(defaultAnimationFrames, 30))
|
||||
})
|
||||
newAnimatedTexture(ctx, control.MonsterTextureNames[tins2021.MonsterTypeChaser], "resources/images/monster-chaser.png", func() image.Image {
|
||||
return tins2021.AnimatePolygon(tins2021.CreateHexagon(), tins2021.Purple, tins2021.NewWobbleAnimation(defaultAnimationFrames, 30))
|
||||
})
|
||||
|
||||
small, err := tins2021.NewBitmapFont(ctx.Renderer(), ctx.Fonts().Font("small"), tins2021.NumericCharacters...)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
control.SmallFont = small
|
||||
font, err := tins2021.NewBitmapFont(ctx.Renderer(), ctx.Fonts().Font("default"), tins2021.AllCharacters...)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
control.Font = font
|
||||
|
||||
control.Play(level)
|
||||
|
||||
@ -183,7 +154,7 @@ func (r *levelController) Play(level *tins2021.Level) {
|
||||
for monster := range level.Monsters {
|
||||
r.IdleMonsters.Frame(monster)
|
||||
}
|
||||
for _, monster := range r.MonsterTextureNames {
|
||||
for _, monster := range r.app.MonsterTextureNames {
|
||||
r.Animations[monster] = tins2021.NewAnimations(80*time.Millisecond, defaultAnimationFrames, true, true)
|
||||
}
|
||||
}
|
||||
@ -228,7 +199,7 @@ func (r levelController) Render(ctx ui.Context) {
|
||||
star := tins2021.NewAnimatedTexture(ctx.Textures().ScaledByName("star", scale*.4), defaultAnimationFrames)
|
||||
heart := tins2021.NewAnimatedTexture(ctx.Textures().ScaledByName("heart", scale*.4), defaultAnimationFrames)
|
||||
monsterTextures := map[tins2021.MonsterType]tins2021.AnimatedTexture{}
|
||||
for typ, name := range r.MonsterTextureNames {
|
||||
for typ, name := range r.app.MonsterTextureNames {
|
||||
monsterTextures[typ] = tins2021.NewAnimatedTexture(ctx.Textures().ScaledByName(name, scale*.4), defaultAnimationFrames)
|
||||
}
|
||||
propOffset := geom.PtF32(-.5*float32(star.Texture.Height()), -.8*float32(star.Texture.Height()))
|
||||
@ -283,7 +254,7 @@ func (r levelController) Render(ctx ui.Context) {
|
||||
continue
|
||||
}
|
||||
_, platformPos := positionOfTile(pos, tile)
|
||||
name := r.MonsterTextureNames[monsterType.Type()]
|
||||
name := r.app.MonsterTextureNames[monsterType.Type()]
|
||||
monsterTextures[monsterType.Type()].Draw(renderer, platformPos.Add(propOffset), r.Animations[name].Frame(pos))
|
||||
}
|
||||
|
||||
|
@ -33,18 +33,21 @@ type mainMenu struct {
|
||||
|
||||
func newMainMenu(app *appContext, ctx ui.Context) ui.Control {
|
||||
menu := NewMenu()
|
||||
// menu.Add("Info", func(ctx ui.Context) { app.ShowInfo(ctx) })
|
||||
menu.Add("Info", func(ctx ui.Context) { app.ShowInfo(ctx) })
|
||||
menu.Add("Play", func(ctx ui.Context) {
|
||||
app.Play(ctx)
|
||||
})
|
||||
menu.Add("Credits", func(ctx ui.Context) { app.ShowCredits(ctx) })
|
||||
menu.Add("Quit", func(ctx ui.Context) { ctx.Quit() })
|
||||
|
||||
menu.Activate(1) // play
|
||||
|
||||
return Center(&mainMenu{
|
||||
StackPanel: ui.StackPanel{
|
||||
ContainerBase: ui.ContainerBase{
|
||||
Children: []ui.Control{
|
||||
label("QBITTER", "title"),
|
||||
label("", "default"), // spacing
|
||||
menu,
|
||||
},
|
||||
},
|
||||
|
@ -24,3 +24,10 @@ func paragraph(text, font string) *ui.Paragraph {
|
||||
l.Font.Name = font
|
||||
})
|
||||
}
|
||||
|
||||
func paragraphOpts(text, font string, opts labelOptions) *ui.Paragraph {
|
||||
return ui.BuildParagraph(text, func(l *ui.Paragraph) {
|
||||
l.Font.Name = font
|
||||
l.TextAlignment = opts.TextAlignment
|
||||
})
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user