All checks were successful
release / build-release (push) Successful in 1m42s
- level.Schedule.Phase: away/approaching/arriving/dwelling/closing/leaving ur tidtabellen med progress; Boardable (öppna dörrar) och Present; validering av minsta uppehåll/borta-tid; TrackTile för rälsen - sim.Run: ombordstigning bara med öppna dörrar, TrainVisible via Present, PlatformPhase och NearTrack (närmaste perrong inom två rutor) - game/trains.go: rälsrutor längs kantraden (roterade för vertikala spår), tre vagnar som bromsar in och accelererar ut längs rälsen, strålkastare under inrullningen, blinkande lampor vid kanten för den som står nära, dammpartiklar längs perrongen; kameran får en rutas marginal så att kanträlsen syns - game/audio.go: ebiten/v2/audio med avgångsmelodi (approaching) och dörrsignal (closing), volym efter avstånd, -mute; tools/gensound syntetiserar placeholder-WAV:ar - HUD: fasberoende perrongtext och "tåg på väg in" nära rälsen; skriptkommandot waitphase; skärmdump av ankomsten - plan (Björn 2026-10-24): räls/väg-grafik och melodierna i M7b; folk/NPC:er, vänster-/högertrafik, bredare gångar, reklam- och ljudröra som nytt steg M9b – i spelbeskrivning, roadmap, testplan - docs/README/wiki uppdaterade Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
41 lines
1.3 KiB
Go
41 lines
1.3 KiB
Go
package sim
|
|
|
|
// Camera är en vy över världen som följer en punkt men aldrig visar utanför
|
|
// kartan. Är världen mindre än vyn centreras den i stället.
|
|
type Camera struct {
|
|
ViewW, ViewH float64
|
|
WorldW, WorldH float64
|
|
Margin float64 // så många pixlar utanför världen får vyn visa (räls vid kanten)
|
|
X, Y float64 // vyns övre vänstra hörn i världskoordinater
|
|
}
|
|
|
|
// NewCamera skapar en kamera för en värld av given storlek (pixlar).
|
|
func NewCamera(viewW, viewH, worldW, worldH float64) *Camera {
|
|
c := &Camera{ViewW: viewW, ViewH: viewH, WorldW: worldW, WorldH: worldH}
|
|
c.Follow(worldW/2, worldH/2)
|
|
return c
|
|
}
|
|
|
|
// Follow centrerar vyn på (cx, cy) och klampar mot världens kanter (plus
|
|
// Margin).
|
|
func (c *Camera) Follow(cx, cy float64) {
|
|
c.X = clampAxis(cx-c.ViewW/2+c.Margin, c.ViewW, c.WorldW+2*c.Margin) - c.Margin
|
|
c.Y = clampAxis(cy-c.ViewH/2+c.Margin, c.ViewH, c.WorldH+2*c.Margin) - c.Margin
|
|
}
|
|
|
|
// Offset returnerar översättningen världs- -> skärmkoordinater.
|
|
func (c *Camera) Offset() (ox, oy float64) { return -c.X, -c.Y }
|
|
|
|
func clampAxis(pos, view, world float64) float64 {
|
|
if world <= view {
|
|
return -(view - world) / 2 // centrera en liten värld
|
|
}
|
|
if pos < 0 {
|
|
return 0
|
|
}
|
|
if max := world - view; pos > max {
|
|
return max
|
|
}
|
|
return pos
|
|
}
|