M13: titelskärm, språkval, tutorial, tips och pausmeny
All checks were successful
release / build-release (push) Successful in 1m40s
All checks were successful
release / build-release (push) Successful in 1m40s
Björns feedback efter v0.1.0. Titelskärm med premissen i text och menyn Fortsätt/Starta, Tutorial, Inställningar, Avsluta (Enter två gånger); språkval första gången spelet startar. Tutorial i fem sidor med riktiga sprites och en exempelskylt där resmålet markeras och resten tonas ned, plus nyckeln 番線/方面/改札 och biljettipset. Kontextuella tips i spelet tills första banan är klarad, och resmålets tecken markeras på skyltar och avgångstavlor under tiden. Esc i en bana öppnar en pausmeny (Fortsätt, Lämna banan, Inställningar, Avsluta spelet) i stället för att lämna banan; Esc på bankartan går till titeln. Kortare lägestexter så att bankartans rader ryms på svenska. Test för markeringen, docs, wiki och skärmdumpar. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
92
internal/game/scene_tutorial.go
Normal file
92
internal/game/scene_tutorial.go
Normal file
@@ -0,0 +1,92 @@
|
||||
package game
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"image/color"
|
||||
"strings"
|
||||
|
||||
"github.com/hajimehoshi/ebiten/v2"
|
||||
"github.com/hajimehoshi/ebiten/v2/vector"
|
||||
|
||||
"gitea.brasse-pc.eu/brasse/metro-puzzle-jp/internal/level"
|
||||
)
|
||||
|
||||
// TutorialScene är genomgången av grundmekaniken i fem sidor: målet och
|
||||
// stationen, hur man läser en skylt (med resmålet markerat och resten
|
||||
// nedtonat), kort/biljetter/spärrar, sällskapet och tåget, lägen och
|
||||
// tangenter. ←/→ bläddrar, Esc går tillbaka.
|
||||
type TutorialScene struct {
|
||||
back Scene
|
||||
page int
|
||||
}
|
||||
|
||||
const tutorialPages = 5
|
||||
|
||||
// NewTutorialScene öppnar tutorialen.
|
||||
func NewTutorialScene(back Scene) *TutorialScene { return &TutorialScene{back: back} }
|
||||
|
||||
func (s *TutorialScene) Update(g *Game) error {
|
||||
if backJustPressed() {
|
||||
g.SetScene(s.back)
|
||||
return nil
|
||||
}
|
||||
dx, _ := miniMoveXY()
|
||||
if confirmJustPressed() {
|
||||
dx = 1
|
||||
}
|
||||
if dx != 0 {
|
||||
s.page += dx
|
||||
if s.page >= tutorialPages {
|
||||
g.SetScene(s.back)
|
||||
return nil
|
||||
}
|
||||
if s.page < 0 {
|
||||
s.page = 0
|
||||
}
|
||||
g.Audio.Play(SoundConfirm, 0.4)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *TutorialScene) Draw(g *Game, screen *ebiten.Image) {
|
||||
a := g.Assets
|
||||
screen.Fill(color.RGBA{24, 20, 37, 255})
|
||||
vector.DrawFilledRect(screen, 0, 0, ScreenW, 22, color.RGBA{38, 43, 68, 255}, false)
|
||||
key := fmt.Sprintf("tutorial.p%d", s.page+1)
|
||||
a.DrawBig(screen, a.T(key+".title"), 8, 5, colText)
|
||||
a.Draw(screen, fmt.Sprintf(a.T("tutorial.page"), s.page+1, tutorialPages), ScreenW-70, 8, colDim)
|
||||
y := 28
|
||||
for _, para := range strings.Split(a.T(key), "\n") {
|
||||
for _, l := range a.wrapLine(plainLine(para, colText), ScreenW-16) {
|
||||
a.drawLines(screen, []line{l}, 8, y)
|
||||
y += LineH
|
||||
}
|
||||
y += 3
|
||||
}
|
||||
switch s.page {
|
||||
case 0: // rutlegend med riktiga sprites
|
||||
x := 12
|
||||
for _, t := range []struct {
|
||||
tile level.Tile
|
||||
key string
|
||||
}{{level.Sign, "tile.sign"}, {level.Gate, "tile.gate"}, {level.TicketMachine, "tile.machine"}, {level.Toilet, "tile.toilet"}, {level.Kiosk, "tile.kiosk"}, {level.Platform, "tile.platform"}} {
|
||||
var op ebiten.DrawImageOptions
|
||||
op.GeoM.Scale(2, 2)
|
||||
op.GeoM.Translate(float64(x), float64(y))
|
||||
screen.DrawImage(a.Tiles[t.tile], &op)
|
||||
a.Draw(screen, a.T(t.key), x, y+2*TileSize+2, colDim)
|
||||
x += 52
|
||||
}
|
||||
case 1: // exempelskylten: resmålet markerat, resten nedtonat
|
||||
sample := "14番線 山手線 渋谷方面 → 南東口 改札"
|
||||
body := append([]line{highlightLine(sample, "渋谷", colGood, colDim)}, a.wrapLine(line{{"→ ", colDim}, {a.T("tutorial.p2.sample"), colText}}, ScreenW-28)...)
|
||||
vector.DrawFilledRect(screen, 8, float32(y), ScreenW-16, float32(LineH*len(body)+8), colPanel, false)
|
||||
a.drawLines(screen, body, 14, y+4)
|
||||
y += LineH*len(body) + 12
|
||||
for _, l := range a.wrapLine(plainLine(a.T("tutorial.p2b"), colText), ScreenW-16) {
|
||||
a.drawLines(screen, []line{l}, 8, y)
|
||||
y += LineH
|
||||
}
|
||||
}
|
||||
a.Draw(screen, a.T("tutorial.hint"), 8, ScreenH-12, colDim)
|
||||
}
|
||||
Reference in New Issue
Block a user