M3: japanska skyltar – pixelfont, ordbok, kunskap, delvis översättning, hjälp
All checks were successful
release / build-release (push) Successful in 1m42s
All checks were successful
release / build-release (push) Successful in 1m42s
- resources/text/fonts: PixelMplus 10/12 px (M+ FONT LICENSE) + licens; all text ritas via text/v2 på heltalspositioner, debugfonten är borta - internal/lang: ordbok (60 ord, validerad), tokenisering med längsta matchning, Knowledge (ord + kana, nivå 0–5, hintar), Render (kända ord markerade/översatta, okända kvar, kana som romaji), EnglishShare/ ShowEnglish per svårighet (deterministiskt per bana+position), HelpSeconds; datatest kräver att all japanska i banorna finns i ordboken - sim.Run: AskHelp (H) med väntetid efter nivå, avbryts om man går, avslöjar skylten och lär första okända ordet; Knowledge delas mellan banor - game: skylt- och avgångstavlor renderade genom kunskapen med färgkodning, engelsk rad på lätta banor, hjälp-förlopp, "Nytt ord"-notis, HUD visar resmålet på japanska från nivå 1 och japanska-nivå; meny med svårighet; pixelbaserad radbrytning av färgade textsegment; -know-flagga - tools/shots: tre skyltbilder (skylt, hjälp, nytt ord) med förkunskap - docs/README/wiki uppdaterade Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
@@ -1,16 +1,26 @@
|
||||
package game
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"image"
|
||||
"image/color"
|
||||
|
||||
"github.com/hajimehoshi/ebiten/v2"
|
||||
"github.com/hajimehoshi/ebiten/v2/text/v2"
|
||||
|
||||
"gitea.brasse-pc.eu/brasse/metro-puzzle-jp/internal/lang"
|
||||
"gitea.brasse-pc.eu/brasse/metro-puzzle-jp/internal/level"
|
||||
"gitea.brasse-pc.eu/brasse/metro-puzzle-jp/internal/res"
|
||||
"gitea.brasse-pc.eu/brasse/metro-puzzle-jp/internal/sim"
|
||||
)
|
||||
|
||||
// UILang är UI-språket (sv/en) – blir en inställning i M12.
|
||||
const UILang = "sv"
|
||||
|
||||
// Radhöjd för 10-pixelsfonten.
|
||||
const LineH = 12
|
||||
|
||||
// Ordningen på rutorna i resources/sprites/tiles.png (måste matcha tools/genart).
|
||||
var tileOrder = []level.Tile{
|
||||
level.Wall, level.Floor, level.Spawn, level.Platform, level.Gate, level.TicketMachine, level.Sign,
|
||||
@@ -24,6 +34,9 @@ type Assets struct {
|
||||
Train *ebiten.Image // tågvagn, ritas vid perrongen när tåget är inne
|
||||
Player [4][3]*ebiten.Image // [riktning: ner, upp, vänster, höger][bildruta: stilla, gå1, gå2]
|
||||
Text map[string]string
|
||||
Dict *lang.Dictionary
|
||||
Font *text.GoTextFace // PixelMplus 10 px – UI och skyltar
|
||||
FontBig *text.GoTextFace // PixelMplus 12 px – rubriker
|
||||
}
|
||||
|
||||
// LoadAssets läser grafik och texter.
|
||||
@@ -61,12 +74,62 @@ func LoadAssets() (*Assets, error) {
|
||||
}
|
||||
}
|
||||
|
||||
if err := res.LoadJSON(&a.Text, "text", "sv.json"); err != nil {
|
||||
if err := res.LoadJSON(&a.Text, UILang+".json"); err != nil {
|
||||
if err := res.LoadJSON(&a.Text, "text", UILang+".json"); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
dict, err := res.ReadFile("text", "jp-dictionary.json")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if a.Dict, err = lang.ParseDictionary(dict); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if a.Font, err = loadFont("PixelMplus10-Regular.ttf", 10); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if a.FontBig, err = loadFont("PixelMplus12-Regular.ttf", 12); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return a, nil
|
||||
}
|
||||
|
||||
func loadFont(name string, size float64) (*text.GoTextFace, error) {
|
||||
b, err := res.ReadFile("text", "fonts", name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
src, err := text.NewGoTextFaceSource(bytes.NewReader(b))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("font %s: %w", name, err)
|
||||
}
|
||||
return &text.GoTextFace{Source: src, Size: size}, nil
|
||||
}
|
||||
|
||||
// Draw ritar en rad text med 10-pixelsfonten; (x, y) är övre vänstra hörnet.
|
||||
// Heltalspositioner ger pixelskarpa glyfer.
|
||||
func (a *Assets) Draw(dst *ebiten.Image, s string, x, y int, col color.Color) {
|
||||
a.drawFace(dst, a.Font, s, x, y, col)
|
||||
}
|
||||
|
||||
// DrawBig ritar med 12-pixelsfonten.
|
||||
func (a *Assets) DrawBig(dst *ebiten.Image, s string, x, y int, col color.Color) {
|
||||
a.drawFace(dst, a.FontBig, s, x, y, col)
|
||||
}
|
||||
|
||||
func (a *Assets) drawFace(dst *ebiten.Image, face *text.GoTextFace, s string, x, y int, col color.Color) {
|
||||
op := &text.DrawOptions{}
|
||||
op.GeoM.Translate(float64(x), float64(y))
|
||||
op.ColorScale.ScaleWithColor(col)
|
||||
text.Draw(dst, s, face, op)
|
||||
}
|
||||
|
||||
// Width är textens bredd i pixlar med 10-pixelsfonten.
|
||||
func (a *Assets) Width(s string) int { return int(text.Advance(s, a.Font)) }
|
||||
|
||||
// T slår upp en UI-text; saknas nyckeln visas nyckeln själv så att det syns.
|
||||
func (a *Assets) T(key string) string {
|
||||
if s, ok := a.Text[key]; ok {
|
||||
|
||||
Reference in New Issue
Block a user