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>
86 lines
2.5 KiB
Go
86 lines
2.5 KiB
Go
package game
|
|
|
|
import (
|
|
"strings"
|
|
|
|
"github.com/hajimehoshi/ebiten/v2"
|
|
"github.com/hajimehoshi/ebiten/v2/vector"
|
|
)
|
|
|
|
// Tutorialtips i spelet: visas en gång var, i ordning när villkoret
|
|
// uppfylls, tills första banan är klarad. {dest} och {ja} byts mot
|
|
// resmålet i latinska bokstäver respektive japanska tecken.
|
|
type tipDef struct {
|
|
key string
|
|
when func(s *LevelScene) bool
|
|
}
|
|
|
|
var tutorialTips = []tipDef{
|
|
{"tip.start", func(s *LevelScene) bool { return true }},
|
|
{"tip.sign", func(s *LevelScene) bool { return s.run.SignHere() != nil }},
|
|
{"tip.party", func(s *LevelScene) bool { return len(s.run.Party.Urges()) > 0 }},
|
|
{"tip.gate", func(s *LevelScene) bool { return s.run.DeniedAt >= 0 || s.run.GatePasses > 0 }},
|
|
{"tip.platform", func(s *LevelScene) bool { tr, _, _ := s.run.PlatformHere(); return tr != nil }},
|
|
}
|
|
|
|
const tipShowSec = 7.0
|
|
|
|
type tipState struct {
|
|
shown map[string]bool
|
|
current string
|
|
since float64
|
|
}
|
|
|
|
// tutorialActive: tipsen och skyltmarkeringen gäller tills första banan är
|
|
// klarad (och aldrig i oändligt läge).
|
|
func (s *LevelScene) tutorialActive(g *Game) bool {
|
|
return !s.endless && !g.Progress.Cleared("001-flygplatsen")
|
|
}
|
|
|
|
// updateTips väljer nästa tips som ska visas.
|
|
func (s *LevelScene) updateTips(g *Game) {
|
|
if !s.tutorialActive(g) {
|
|
return
|
|
}
|
|
r := s.run
|
|
t := &s.tips
|
|
if t.shown == nil {
|
|
t.shown = map[string]bool{}
|
|
}
|
|
if t.current != "" && r.Time-t.since < tipShowSec {
|
|
return
|
|
}
|
|
t.current = ""
|
|
for _, d := range tutorialTips {
|
|
if !t.shown[d.key] && d.when(s) {
|
|
t.shown[d.key] = true
|
|
t.current, t.since = d.key, r.Time
|
|
return
|
|
}
|
|
}
|
|
}
|
|
|
|
// tipText fyller i resmålet i ett tips.
|
|
func (s *LevelScene) tipText(a *Assets, key string) string {
|
|
d := s.run.Level.Destination
|
|
return strings.NewReplacer("{dest}", d.Get("romaji"), "{ja}", d.Get("ja")).Replace(a.T(key))
|
|
}
|
|
|
|
// drawTip ritar det aktuella tipset under HUD:en.
|
|
func (s *LevelScene) drawTip(g *Game, screen *ebiten.Image) {
|
|
t := &s.tips
|
|
if t.current == "" || s.run.Mini != nil || s.run.Outcome != 0 {
|
|
return
|
|
}
|
|
a := g.Assets
|
|
lines := a.wrapLine(highlightLine(s.tipText(a, t.current), s.run.Level.Destination.Get("ja"), colGood, colText), ScreenW-16)
|
|
h := 6 + LineH*len(lines)
|
|
y := 26
|
|
if s.infoBox.Dy() > 0 && s.infoBox.Min.Y < ScreenH/2 {
|
|
y = s.infoBox.Max.Y + 2 // inforutan ligger upptill: lägg tipset under den
|
|
}
|
|
vector.DrawFilledRect(screen, 4, float32(y), ScreenW-8, float32(h), colPanel, false)
|
|
vector.DrawFilledRect(screen, 4, float32(y), 2, float32(h), colKnown, false)
|
|
a.drawLines(screen, lines, 10, y+3)
|
|
}
|