M6: plånbok, biljetter, kortet i telefonen och seedade minispel
All checks were successful
release / build-release (push) Successful in 1m41s
All checks were successful
release / build-release (push) Successful in 1m41s
- sim.Wallet: IC-kort, kontanter, pappersbiljett, telefon med batteri, spenderat; följer med mellan banor (Game.Wallet) - internal/minigame: gemensamt Game-gränssnitt (Update/Done/Success), all slump från del-seeds: TopUp (hitta チャージ, belopp, mata sedlar), Ticket (taxetavla med resmål på japanska), Crowd (tidsfönster, två försök), Ride (stationerna passerar, kliv av vid resmålet) - sim.Run: spärren kräver biljett på biljettbanor annars användbart kort; telefonen ger ×1,1 fart men 15 % seedad omskanning (frysning 1,5 s), dött batteri gör kortet oanvändbart; automaten startar påfyllning eller biljettköp; tåget kontrollerar biljetten; fulla tåg kräver trängsel; resan avgör vinst/förlust (fel station, åkte förbi, fel tåg); StepMini låter klockan och sällskapet ticka medan rörelsen pausar - level: ticketRequired, rideStops, Train.Crowded; 002 är biljettbana med fullt tåg och fyra stopp; ordboken har stationer (kind) + sju nya namn - game: vyer för minispelen, plånbok i HUD, P i menyn = kort i telefonen, förlustorsaker och spenderat på resultatet, flaggor -phone/-card, skriptkommandon hold/waitstop; inforuta/minikarta döljs under minispel - plan: M7b (Björn) – tågvind, ankomstindikator nära rälsen, in-/utkörningsanimation för tåg och bussar – i spelbeskrivning, roadmap, testplan - docs/README/wiki med tre nya bilder (automat, biljettavla, tågresa) Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
56
internal/minigame/crowd.go
Normal file
56
internal/minigame/crowd.go
Normal file
@@ -0,0 +1,56 @@
|
||||
package minigame
|
||||
|
||||
import "gitea.brasse-pc.eu/brasse/metro-puzzle-jp/internal/rng"
|
||||
|
||||
// Crowd är "få plats på det fulla tåget": en markör pendlar över en stapel,
|
||||
// tryck Enter när den är i den gröna zonen. Två försök, sedan går tåget.
|
||||
type Crowd struct {
|
||||
base
|
||||
Pos float64 // markörens läge 0..1
|
||||
dir float64
|
||||
Speed float64 // enheter per sekund
|
||||
ZoneLo float64
|
||||
ZoneHi float64
|
||||
Attempts int
|
||||
MaxTries int
|
||||
}
|
||||
|
||||
const crowdZoneWidth = 0.22
|
||||
|
||||
// NewCrowd seedar zonens läge och markörens fart.
|
||||
func NewCrowd(seed rng.Seed, tries int) *Crowd {
|
||||
r := newRand(seed, "crowd")
|
||||
lo := r.between(0.1, 0.9-crowdZoneWidth)
|
||||
return &Crowd{dir: 1, Speed: r.between(0.9, 1.5), ZoneLo: lo, ZoneHi: lo + crowdZoneWidth, MaxTries: max(1, tries)}
|
||||
}
|
||||
|
||||
// InZone rapporterar om markören är i zonen just nu.
|
||||
func (g *Crowd) InZone() bool { return g.Pos >= g.ZoneLo && g.Pos <= g.ZoneHi }
|
||||
|
||||
// Update pendlar markören och tar emot försök.
|
||||
func (g *Crowd) Update(in Input, dt float64) {
|
||||
if g.done {
|
||||
return
|
||||
}
|
||||
if in.Cancel {
|
||||
g.done = true
|
||||
return
|
||||
}
|
||||
g.Pos += g.dir * g.Speed * dt
|
||||
for g.Pos < 0 || g.Pos > 1 {
|
||||
if g.Pos < 0 {
|
||||
g.Pos = -g.Pos
|
||||
} else {
|
||||
g.Pos = 2 - g.Pos
|
||||
}
|
||||
g.dir = -g.dir
|
||||
}
|
||||
if in.Confirm {
|
||||
g.Attempts++
|
||||
if g.InZone() {
|
||||
g.done, g.success = true, true
|
||||
} else if g.Attempts >= g.MaxTries {
|
||||
g.done = true
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user