From c82ce53433e5184ae81caf652f6e781b0c35685b Mon Sep 17 00:00:00 2001 From: Sander Schobers Date: Mon, 9 Aug 2021 09:25:06 +0200 Subject: [PATCH] Added stars & lives on screen (and fixed centering of level). --- cmd/tins2021/app.go | 5 +-- cmd/tins2021/appcontext.go | 4 ++- cmd/tins2021/levelcontroller.go | 59 +++++++++++++++++++++++++-------- level.go | 3 ++ 4 files changed, 54 insertions(+), 17 deletions(-) diff --git a/cmd/tins2021/app.go b/cmd/tins2021/app.go index 3140f06..5fb27a0 100644 --- a/cmd/tins2021/app.go +++ b/cmd/tins2021/app.go @@ -37,9 +37,9 @@ func (a *app) Init(ctx ui.Context) error { if err := a.loadFonts(ctx, fontDescriptor{"debug", "fonts/FiraMono-Regular.ttf", 12}, - fontDescriptor{"default", "fonts/escheresk.ttf", 32}, - fontDescriptor{"menu", "fonts/escheresk.ttf", 60}, + fontDescriptor{"default", "fonts/escheresk.ttf", 48}, fontDescriptor{"small", "fonts/escheresk.ttf", 16}, + fontDescriptor{"score", "fonts/FiraMono-Regular.ttf", 24}, fontDescriptor{"title", "fonts/escher.ttf", 80}, ); err != nil { return err @@ -79,6 +79,7 @@ func (a *app) Handle(ctx ui.Context, e ui.Event) bool { switch e.Key { case ui.KeyF3: ctx.Overlays().Toggle(ui.DefaultDebugOverlay) + a.context.Debug = !a.context.Debug ctx.Overlays().Toggle(fpsOverlayName) } } diff --git a/cmd/tins2021/appcontext.go b/cmd/tins2021/appcontext.go index c6490b4..7816b30 100644 --- a/cmd/tins2021/appcontext.go +++ b/cmd/tins2021/appcontext.go @@ -7,13 +7,15 @@ import ( type appContext struct { setView func(ui.Control) + + Debug bool } func (app *appContext) Play(ctx ui.Context) { level := tins2021.NewLevel() level.Randomize(100, 10) - app.show(newLevelControl(ctx, level)) + app.show(newLevelControl(app, ctx, level)) } func (app *appContext) show(control ui.Control) { diff --git a/cmd/tins2021/levelcontroller.go b/cmd/tins2021/levelcontroller.go index 34470fc..ff20842 100644 --- a/cmd/tins2021/levelcontroller.go +++ b/cmd/tins2021/levelcontroller.go @@ -1,6 +1,7 @@ package main import ( + "fmt" "image" "image/color" "math/rand" @@ -15,7 +16,8 @@ import ( type levelController struct { ui.ControlBase - Scale float32 + app *appContext + Level *tins2021.Level Cubes cubeTexture @@ -26,10 +28,11 @@ type levelController struct { MovingMonsters *tins2021.Animations SmallFont *tins2021.BitmapFont + Font *tins2021.BitmapFont } -func newLevelControl(ctx ui.Context, level *tins2021.Level) *levelController { - control := &levelController{Level: level, Scale: .6} +func newLevelControl(app *appContext, ctx ui.Context, level *tins2021.Level) *levelController { + control := &levelController{app: app, Level: level} textures := ctx.Textures() control.Cubes = newCubeTexture(textures, tins2021.Orange) newAnimatedTexture(ctx, "star", "resources/images/star.png", func() image.Image { @@ -54,11 +57,17 @@ func newLevelControl(ctx ui.Context, level *tins2021.Level) *levelController { return tins2021.AnimatePolygon(tins2021.CreateHexagon(), tins2021.Purple, tins2021.NewWobbleAnimation(defaultAnimationFrames, 30)) }) - small, err := tins2021.NewBitmapFont(ctx.Renderer(), ctx.Fonts().Font("small"), tins2021.AllCharacters...) + 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.Animations = map[string]*tins2021.Animations{ "star": tins2021.NewAnimations(50*time.Millisecond, defaultAnimationFrames, true, true), "heart": tins2021.NewAnimations(80*time.Millisecond, defaultAnimationFrames, true, true), @@ -144,24 +153,32 @@ const defaultAnimationFrames = 20 func (r levelController) Render(ctx ui.Context) { const twelfth = (1. / 6) * geom.Pi - renderer := ctx.Renderer() - - size := geom.Floor32(tins2021.TextureSize * r.Scale) - scale := size / tins2021.TextureSize centerTopSquare := geom.PtF32(.5, .5*geom.Sin32(twelfth)) - delta := geom.PtF32(geom.Cos32(twelfth), .5+centerTopSquare.Y).Mul(size) - centerTopSquare = centerTopSquare.Mul(size) + delta := geom.PtF32(geom.Cos32(twelfth), .5+centerTopSquare.Y) + + view := r.Bounds().Size() + levelView := geom.PtF32(float32(r.Level.Bounds.Dx()+2)*delta.X, float32(r.Level.Bounds.Dy()+2)*delta.Y) + textureWidth := geom.Min32( + geom.Floor32(tins2021.TextureSize*view.X*.75/(levelView.X*tins2021.TextureSize)), + geom.Floor32(tins2021.TextureSize*view.Y/(levelView.Y*tins2021.TextureSize))) + scale := textureWidth / tins2021.TextureSize + offsetY := .5 * (view.Y - (levelView.Y * textureWidth)) + + delta = delta.Mul(textureWidth) + centerTopSquare = centerTopSquare.Mul(textureWidth) + scoreView := geom.RectF32(levelView.X*textureWidth, offsetY+delta.Y, view.X, view.Y-offsetY-delta.Y) delta.X = geom.Round32(delta.X) delta.Y = geom.Round32(delta.Y) toScreen := func(p geom.Point) geom.PointF32 { if p.Y%2 == 0 { - return p.ToF32().Mul2D(delta.XY()).Add2D(.5*delta.X, 0) + return p.ToF32().Mul2D(delta.XY()).Add2D(.5*delta.X, offsetY) } - return p.ToF32().Mul2D(delta.XY()) + return p.ToF32().Mul2D(delta.XY()).Add2D(0, offsetY) } + renderer := ctx.Renderer() textures := ctx.Textures() cubes := r.Cubes.Scaled(textures, scale) @@ -200,7 +217,9 @@ func (r levelController) Render(ctx ui.Context) { tileTexture = cubes.Inversed.Texture } renderer.DrawTexturePoint(tileTexture, screenPos) - r.SmallFont.TextAlign(renderer, platformPos, color.Black, strconv.Itoa(distances[pos]), ui.AlignCenter) + if r.app.Debug { + r.SmallFont.TextAlign(renderer, platformPos, color.Black, strconv.Itoa(distances[pos]), ui.AlignCenter) + } if tile.Star { star.Draw(renderer, platformPos.Add(propOffset), r.Animations["star"].Frame(pos)) @@ -213,7 +232,7 @@ func (r levelController) Render(ctx ui.Context) { playerPosition := toScreen(r.Level.Player).Sub(geom.Pt(player.Width()/2, player.Height()).ToF32()) if r.Level.Tiles[r.Level.Player].Inversed { - centerBottomSquare := geom.PtF32(centerTopSquare.X, size-centerTopSquare.Y) + centerBottomSquare := geom.PtF32(centerTopSquare.X, textureWidth-centerTopSquare.Y) renderer.DrawTexturePoint(player, playerPosition.Add(centerBottomSquare)) } else { renderer.DrawTexturePoint(player, playerPosition.Add(centerTopSquare)) @@ -228,4 +247,16 @@ func (r levelController) Render(ctx ui.Context) { name := r.MonsterTextureNames[monsterType.Type()] monsterTextures[monsterType.Type()].Draw(renderer, platformPos.Add(propOffset), r.Animations[name].Frame(pos)) } + + textColor := ctx.Style().Palette.Text + scoreFont := ctx.Fonts().Font("score") + fontOffsetY := .5 * (float32(star.Texture.Height()) - scoreFont.Height()) + + scoreTopLeft := scoreView.Min + star.Draw(renderer, scoreTopLeft, 0) + renderer.Text(scoreFont, scoreTopLeft.Add2D(textureWidth, fontOffsetY), textColor, fmt.Sprintf("x %d / %d", r.Level.StarsCollected, r.Level.Stars)) + + scoreTopLeft.Y += textureWidth + heart.Draw(renderer, scoreTopLeft, 0) + renderer.Text(scoreFont, scoreTopLeft.Add2D(textureWidth, fontOffsetY), textColor, fmt.Sprintf("x %d", r.Level.Lives)) } diff --git a/level.go b/level.go index 3172179..ee46fd1 100644 --- a/level.go +++ b/level.go @@ -9,6 +9,7 @@ import ( type Level struct { Player geom.Point Lives int + Stars int StarsCollected int Tiles Tiles Monsters Monsters @@ -21,6 +22,7 @@ func NewLevel() *Level { f := &Level{ Player: geom.Pt(1, 1), Lives: 3, + Stars: 0, StarsCollected: 0, Tiles: Tiles{}, Monsters: Monsters{}, @@ -113,6 +115,7 @@ func (l *Level) Randomize(difficulty int, stars int) { l.Tiles[pos].Invert() } } + l.Stars = stars for stars > 0 { i := rand.Intn(len(positions)) pos := positions[i]