package game import ( "image/color" "math" "github.com/hajimehoshi/ebiten/v2" "github.com/hajimehoshi/ebiten/v2/vector" "gitea.brasse-pc.eu/brasse/metro-puzzle-jp/internal/level" "gitea.brasse-pc.eu/brasse/metro-puzzle-jp/internal/sim" ) // Folk, affischer och kömarkeringar (M9b). // npcTints är gråtoner för passagerare tills de har egna sprites. var npcTints = [][3]float32{{0.75, 0.75, 0.8}, {0.7, 0.8, 0.75}, {0.8, 0.72, 0.72}, {0.78, 0.78, 0.7}} // drawNPCs ritar passagerarna på spelarens våning. func (s *LevelScene) drawNPCs(g *Game, screen *ebiten.Image, ox, oy float64) { z := s.run.Player.Tile.Z for i, n := range s.run.NPCs { if n.Mover.Tile.Z != z { continue } x, y := n.Mover.WorldPos(TileSize) var op ebiten.DrawImageOptions op.GeoM.Translate(ox+math.Round(x), oy+math.Round(y)) t := npcTints[i%len(npcTints)] op.ColorScale.Scale(t[0], t[1], t[2], 1) screen.DrawImage(g.Assets.PlayerFrame(n.Mover.Facing, n.Mover.Moving(), s.animT+float64(i)*0.07), &op) } } // buildPosters väljer seedat vilka väggrutor som får affischer (visuell röra). func (s *LevelScene) buildPosters() { s.posters = map[level.Point]int{} l := s.run.Level if l.Clutter == 0 { return } r := s.run.Seed.Derive("posters").New() chance := 0.12 * float64(l.Clutter) for z := 0; z < l.NumFloors(); z++ { for y := 0; y < l.Height(); y++ { for x := 0; x < l.Width(); x++ { p := level.Point{X: x, Y: y, Z: z} if l.At(p) != level.Wall { continue } adjFloor := false for _, n := range l.Neighbors(p) { if n.Z == z && l.At(n).Passable() { adjFloor = true } } if adjFloor && r.Float64() < chance { s.posters[p] = r.IntN(posterCount) } } } } } // drawQueueMarks ritar kömarkeringar på perrongen (var man ställer sig för // varje vagn) när tåget är på väg in eller står inne. func (s *LevelScene) drawQueueMarks(screen *ebiten.Image, ox, oy float64) { z := s.run.Player.Tile.Z for _, tr := range s.tracks { if tr.platform.Z != z { continue } phase, _ := s.run.PlatformPhase(tr.tile) if phase == level.Away || phase == level.Leaving { continue } train := s.run.Level.TrainAt(tr.tile) if train == nil { continue } x := float32(ox + float64(tr.platform.X*TileSize)) y := float32(oy + float64(tr.platform.Y*TileSize)) cars := train.Cars for k := 0; k < cars && k < 4; k++ { col := color.RGBA{255, 255, 255, 200} if train.WomenOnlyActive(s.run.Time) && k+1 == train.WomenOnlyCar { col = color.RGBA{255, 150, 200, 230} // rosa: kvinnovagn } if tr.horizontal { vector.DrawFilledRect(screen, x+float32(2+k*4), y+TileSize-6, 2, 3, col, false) } else { vector.DrawFilledRect(screen, x+TileSize-6, y+float32(2+k*4), 3, 2, col, false) } } } } var _ = sim.NPCSpeed