package game import ( "fmt" "image/color" "sort" "strings" "github.com/hajimehoshi/ebiten/v2" "github.com/hajimehoshi/ebiten/v2/vector" "gitea.brasse-pc.eu/brasse/metro-puzzle-jp/internal/lang" ) // WordsScene är ordlistan/språkträdet: alla ord i ordboken, vad spelaren // kan, framsteg på resten, och möjligheten att lägga språkpoäng på valfria // ord. Blir ett riktigt träd med skills i M8. type WordsScene struct { back Scene entries []*lang.Entry sel int top int msg string } const wordsRows = 9 // NewWordsScene listar ordboken sorterad på tier och ord. func NewWordsScene(a *Assets, back Scene) *WordsScene { var es []*lang.Entry for _, w := range a.Dict.Words() { es = append(es, a.Dict.Lookup(w)) } sort.Slice(es, func(i, j int) bool { if es[i].Tier != es[j].Tier { return es[i].Tier < es[j].Tier } return es[i].Word < es[j].Word }) return &WordsScene{back: back, entries: es} } func (w *WordsScene) Update(g *Game) error { if backJustPressed() || wordsJustPressed() { g.SetScene(w.back) return nil } if n := len(w.entries); n > 0 { w.sel = (w.sel + menuMove() + n) % n if w.sel < w.top { w.top = w.sel } if w.sel >= w.top+wordsRows { w.top = w.sel - wordsRows + 1 } if confirmJustPressed() { e := w.entries[w.sel] switch { case g.Know.Knows(e.Word): w.msg = g.Assets.T("words.already") case g.Know.Buy(e): w.msg = fmt.Sprintf(g.Assets.T("words.bought"), e.Word, e.Translation(UILang)) default: w.msg = fmt.Sprintf(g.Assets.T("words.too_expensive"), lang.WordCost(e)) } } } return nil } func (w *WordsScene) Draw(g *Game, screen *ebiten.Image) { a := g.Assets k := g.Know screen.Fill(color.RGBA{24, 20, 37, 255}) vector.DrawFilledRect(screen, 0, 0, ScreenW, 22, color.RGBA{38, 43, 68, 255}, false) a.DrawBig(screen, a.T("words.title"), 8, 5, colText) hdr := fmt.Sprintf("%s %d %s Lv%d %d/%d %s", a.T("words.points"), k.Points, a.T("hud.japanese"), k.Level(), k.Count(), len(w.entries), a.T("hud.words")) a.Draw(screen, hdr, ScreenW-8-a.Width(hdr), 6, colKnown) y0 := 30 for i := w.top; i < len(w.entries) && i < w.top+wordsRows; i++ { e := w.entries[i] y := y0 + (i-w.top)*LineH if i == w.sel { vector.DrawFilledRect(screen, 4, float32(y-1), ScreenW-8, LineH, colBar, false) } status, scol := strings.Repeat("●", lang.WordCost(e)), colDim if k.CanBuy(e) { scol = colKnown } wcol := colText switch { case k.Knows(e.Word): status, scol, wcol = "✓", colGood, colKnown case k.ProgressOf(e.Word) > 0: status, scol = fmt.Sprintf("%d/%d", k.ProgressOf(e.Word), lang.ProgressToLearn), colWarn } a.Draw(screen, e.Word, 8, y, wcol) a.Draw(screen, e.Romaji, 92, y, colDim) a.Draw(screen, e.Translation(UILang), 180, y, colText) a.Draw(screen, status, ScreenW-8-a.Width(status), y, scol) } // rullningsindikator if len(w.entries) > wordsRows { a.Draw(screen, fmt.Sprintf("%d-%d / %d", w.top+1, min(len(w.entries), w.top+wordsRows), len(w.entries)), 8, ScreenH-38, colDim) } if w.msg != "" { a.Draw(screen, w.msg, 8, ScreenH-26, colKnown) } a.Draw(screen, a.T("words.hint"), 8, ScreenH-13, colDim) }