All checks were successful
release / build-release (push) Successful in 1m36s
Ett tåg kan vara en buss (vehicle: bus): samma tidtabell, faser, bedömning i nätet och ombordstigning, men ett fordon på en väg i stället för vagnar på räls, hållplatsskylt, "1番" på tavlan, tuta vid inrullning och dörrsignal före avgång. Nätet har tre busslinjer från Narita. Nya sidobanor: 001b Flygbussterminalen (biljettbana med tre bussar) och 003b Harajuku (Yamanote åt rätt eller fel håll runt ringen). Overload-flaggan ger en rullande reklamticker och maximalt med affischer (Ueno, Tokyo). Romaji utan makroner (fonten saknar dem). Skärmdumparna som börjar på bankartan går via titelskärmen. Tester, docs och wiki uppdaterade. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
99 lines
2.8 KiB
Go
99 lines
2.8 KiB
Go
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 s.clutterLevel() == 0 {
|
|
return
|
|
}
|
|
r := s.run.Seed.Derive("posters").New()
|
|
chance := 0.12 * float64(s.clutterLevel())
|
|
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
|