Files
claude 5114115976
All checks were successful
release / build-release (push) Successful in 1m37s
Texterna ryms på skärmen på svenska och engelska
Björn såg att bankartans tangentrad klipptes på engelska. Nu mäts alla
enradstexter med den riktiga fonten i båda språken mot sitt utrymme
(game.TestSingleLineTextsFit) och HUD-raden för alla banor
(TestLevelNamesFitHUD). Åtgärder: kortare etiketter ("Mål"/"To"),
bankartans tangentrad på två rader (versionen står på titelskärmen),
HUD:en stryker japansk hint, "via" och valfria plånboksdelar som inte
får plats och kortar med "..", fler rutor radbryts, kortare bannamn,
kortare minispelstexter. Skärmdumpar på engelska (map-en, sign-en) via en
engelsk demosparfil. Alla skärmdumpar omtagna.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-25 18:10:26 +01:00

176 lines
3.9 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package game
import (
"image/color"
"strings"
"github.com/hajimehoshi/ebiten/v2"
"gitea.brasse-pc.eu/brasse/metro-puzzle-jp/internal/lang"
)
type drawTarget = *ebiten.Image
// Färger för text.
var (
colText = color.RGBA{255, 255, 255, 255}
colDim = color.RGBA{139, 155, 180, 255} // oöversatt / sekundärt
colKnown = color.RGBA{254, 174, 52, 255} // kända ord / översättning
colReading = color.RGBA{99, 199, 77, 255} // kana som kan läsas men inte förstås
colEnglish = color.RGBA{44, 232, 245, 255}
colBad = color.RGBA{228, 59, 68, 255}
colGood = color.RGBA{99, 199, 77, 255}
colWarn = color.RGBA{254, 174, 52, 255}
colPanel = color.RGBA{24, 20, 37, 230}
colBar = color.RGBA{58, 68, 102, 255}
)
// span är en textbit med färg; en rad är flera spans.
type span struct {
text string
col color.Color
}
type line []span
// plainLine gör en rad av en enda sträng.
func plainLine(s string, col color.Color) line { return line{{s, col}} }
// shownLine gör en rad av språksystemets segment med färg efter kunskap.
// Med readings visas läsningen (romaji) efter kända ord – hinten från nivå 2.
func shownLine(shown []lang.Shown, base color.Color, readings bool) line {
var l line
for _, sh := range shown {
col := base
switch {
case sh.Reading:
col = colReading
case sh.Known && lang.IsJapanese(sh.Text):
col = colKnown
case sh.Known:
col = base
default:
col = colDim
}
l = append(l, span{sh.Text, col})
if readings && sh.Romaji != "" {
l = append(l, span{"(" + sh.Romaji + ")", colDim})
}
}
return l
}
// wrapLine radbryter en rad till maxW pixlar. Bryter vid mellanslag, och
// mitt i ett ord bara om ordet ensamt är för långt (japanska saknar mellanslag).
func (a *Assets) wrapLine(l line, maxW int) []line {
var out []line
var cur line
curW := 0
flush := func() {
if len(cur) > 0 {
out = append(out, cur)
cur, curW = nil, 0
}
}
add := func(s string, col color.Color) {
w := a.Width(s)
if curW+w > maxW && curW > 0 {
flush()
s = strings.TrimLeft(s, " ")
w = a.Width(s)
}
if s == "" {
return
}
if n := len(cur); n > 0 && cur[n-1].col == col {
cur[n-1].text += s
} else {
cur = append(cur, span{s, col})
}
curW += w
}
for _, sp := range l {
for _, tok := range tokens(sp.text) {
if a.Width(tok) <= maxW {
add(tok, sp.col)
continue
}
for _, r := range tok { // för långt ord: bryt per tecken
add(string(r), sp.col)
}
}
}
flush()
return out
}
// tokens delar en sträng i ord och mellanslagsrunor, båda bevarade.
func tokens(s string) []string {
var out []string
cur := ""
for _, r := range s {
if r == ' ' {
if cur != "" {
out = append(out, cur)
cur = ""
}
out = append(out, " ")
continue
}
cur += string(r)
}
if cur != "" {
out = append(out, cur)
}
return out
}
// drawLines ritar rader från (x, y) med radhöjd LineH.
func (a *Assets) drawLines(dst drawTarget, lines []line, x, y int) {
for i, l := range lines {
cx := x
for _, sp := range l {
a.Draw(dst, sp.text, cx, y+i*LineH, sp.col)
cx += a.Width(sp.text)
}
}
}
// fitText kortar en text med ".." tills den ryms i maxW pixlar.
func (a *Assets) fitText(s string, maxW int) string {
if a.Width(s) <= maxW {
return s
}
r := []rune(s)
for len(r) > 0 {
r = r[:len(r)-1]
if a.Width(string(r)+"..") <= maxW {
return string(r) + ".."
}
}
return ""
}
// highlightLine är tutorialens sätt att läsa en skylt: resmålets japanska
// tecken i markeringsfärg, allt annat nedtonat.
func highlightLine(text, needle string, hi, dim color.Color) line {
if needle == "" || !strings.Contains(text, needle) {
return plainLine(text, dim)
}
var l line
for {
i := strings.Index(text, needle)
if i < 0 {
if text != "" {
l = append(l, span{text, dim})
}
return l
}
if i > 0 {
l = append(l, span{text[:i], dim})
}
l = append(l, span{needle, hi})
text = text[i+len(needle):]
}
}