From 3f5602077758c7301216d29e1e7c68e363769194 Mon Sep 17 00:00:00 2001 From: claude Date: Sat, 24 Oct 2026 09:28:01 +0200 Subject: [PATCH] =?UTF-8?q?M5:=20minikarta=20med=20dimma,=20riktm=C3=A4rke?= =?UTF-8?q?n=20och=20avg=C3=A5ngslista?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - sim.Fog: avslöjar tre gångsteg från spelaren plus gränsande väggar (ser längs gången, inte genom väggen); riktmärken (perronger, start, spärrar) syns alltid; Explored ger utforskad andel; nollställs per omgång - game/minimap: 1–3 px per ruta i det hörn som varken täcker inforutan eller spelaren, perrong vit när tåget är inne, spelaren blinkar, följarna i sina toner, avgångslista per spår (● inne / ○ kommer); M döljer/visar - resultatskärmen visar utforskad andel och antal försörjda; layout justerad - docs/README/wiki uppdaterade Co-Authored-By: Claude Fable 5.1 --- README.md | 18 +++-- doc/img/level-001.png | Bin 17016 -> 18481 bytes doc/img/level-002.png | Bin 16437 -> 18062 bytes doc/img/menu.png | Bin 14304 -> 14271 bytes doc/img/platform.png | Bin 21652 -> 22972 bytes doc/img/result.png | Bin 24921 -> 25758 bytes doc/img/sign-help.png | Bin 23655 -> 25215 bytes doc/img/sign-learned.png | Bin 24051 -> 25487 bytes doc/img/sign.png | Bin 24222 -> 25682 bytes doc/mal-och-tester.md | 3 +- doc/plan.md | 2 +- doc/roadmap.md | 24 +++++-- internal/game/input.go | 5 ++ internal/game/minimap.go | 126 ++++++++++++++++++++++++++++++++++ internal/game/scene_level.go | 49 ++++++++----- internal/game/scene_result.go | 11 +-- internal/sim/fog.go | 110 +++++++++++++++++++++++++++++ internal/sim/fog_test.go | 92 +++++++++++++++++++++++++ internal/sim/run.go | 6 ++ resources/text/en.json | 6 +- resources/text/sv.json | 6 +- 21 files changed, 419 insertions(+), 39 deletions(-) create mode 100644 internal/game/minimap.go create mode 100644 internal/sim/fog.go create mode 100644 internal/sim/fog_test.go diff --git a/README.md b/README.md index 3579290..d144ae2 100644 --- a/README.md +++ b/README.md @@ -10,11 +10,12 @@ Storyn följer några polare på semester i Japan, från landningen på flygplatsen till avresan. Efter storyn låses ett oändligt läge och New Game+ upp. Hela speldesignen finns i [doc/spelbeskrivning.md](doc/spelbeskrivning.md). -**Status:** M4 klar (2026-10-23) – skyltarna är på japanska och du lär dig +**Status:** M5 klar (2026-10-24) – skyltarna är på japanska och du lär dig ord genom att läsa, fråga om hjälp, klara banor med bra tid eller lägga -språkpoäng i ordlistan. Lämmeltåget följer efter dig: polarna blir hungriga, -törstiga och måste på toa, oftare ju fler ni är, och du löser det vid kiosker -och toaletter. Nästa är M5: minikartan. Se [doc/roadmap.md](doc/roadmap.md). +språkpoäng i ordlistan. Lämmeltåget följer efter dig med sina behov, och +minikartan visar bara avgångar och riktmärken tills du utforskat stationen. +Nästa är M6: tågkort, biljetter, telefon och minispel. Se +[doc/roadmap.md](doc/roadmap.md). ![Skylt på japanska med delvis översättning](doc/img/sign.png) @@ -31,7 +32,9 @@ Klarar du banan under par får du stjärnor, språkpoäng och resmålets namn. Ditt sällskap följer efter i en rad. Mätarna uppe till höger visar mat, dryck och toa för var och en; faller de får någon ett behov som saktar ned -er alla tills ni hittar en kiosk eller en toalett. +er alla tills ni hittar en kiosk eller en toalett. Minikartan i hörnet visar +från början bara perrongerna, starten och spärrarna plus en avgångslista; +resten fylls i allt eftersom ni går. ![Shinjuku station med sällskapet](doc/img/level-002.png) @@ -119,8 +122,9 @@ metro-puzzle-jp -version Pilar eller WASD går. Enter väljer, kliver på tåget, använder toaletten eller handlar i kiosken. H frågar om hjälp vid en skylt, L öppnar -ordlistan, Esc går tillbaka, R spelar om. Gamepad med standardlayout -fungerar: d-pad/vänster spak, A = välj, B = tillbaka, Y = hjälp, X = ordlista. +ordlistan, M döljer/visar minikartan, Esc går tillbaka, R spelar om. Gamepad +med standardlayout fungerar: d-pad/vänster spak, A = välj, B = tillbaka, +Y = hjälp, X = ordlista, Back/Select = karta. ### Verktyg diff --git a/doc/img/level-001.png b/doc/img/level-001.png index b20a8ad725edb43b9ebdf3833456a909c7d1d505..ba959708b165ae8659444e9c35aea8a8c27662c0 100644 GIT binary patch delta 6013 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 KUAoKb(tiQK2vhz5 diff --git a/doc/img/level-002.png b/doc/img/level-002.png index af2c800807e18a1de62837f04849fdae6b7c0f1f..884b333e036379ba9563902e5a8e0f0bf70c926c 100644 GIT binary patch delta 5772 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 Y3>T;Nr~BVfm1F<{Pgg&ebxsLQ0F8@!AOHXW diff --git a/doc/img/platform.png b/doc/img/platform.png index 592b0b70e8e5fae863fbd8a435312942c401ac57..5b38c4daa610c36d8c9ede86fad5ae7b6534145f 100644 GIT binary patch delta 6612 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 m$N~XA>;5rC-cRx!2 diff --git a/doc/img/result.png b/doc/img/result.png index db3a1f53e2f41fd7e09a9828452708b3c1ff20db..5ad2513dc6579282a57bca9d69cf598543898a64 100644 GIT binary patch delta 11939 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 O>TTt_N+k+r0sjwnO+;P* delta 10824 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 diff --git a/doc/img/sign-help.png b/doc/img/sign-help.png index f569a4011a1f4d157b440ce02893f9da55b9f82f..4b2c4b3578f28ba7ac2b4b195f33803fcbd86f0a 100644 GIT binary patch delta 6834 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 Q?x2~1tPG!DymI@00LQ}d-2eap delta 5518 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 GZvGzu`~yq? diff --git a/doc/img/sign-learned.png b/doc/img/sign-learned.png index 6ad0243c10284c005f49a3383dc362dd09225c15..baa6590f050371b27ca5ed94e4fa78402de69e89 100644 GIT binary patch delta 7236 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 delta 5949 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 diff --git a/doc/img/sign.png b/doc/img/sign.png index 7cac225a0d815d2dfaa72b6f7770c2ae1c86edb3..c8af9babb03cf071c4873d8127a4c3834104e59a 100644 GIT binary patch delta 7636 zcma(#2Ut@}vj|GBO78+n2ay(9=uHF!r6WjDLNB4WBLdQk25dlxA|e9Pl_GGd5itox zdWj(*2xz1uf$-4#|L@|{|Gl?6UuI`FXU>_K-I>{ew;UUMdn{X++?}iX%w26A`p7)W zTVg&)^;o*e&^U#tb#bANlY=G)5Ev5sh`-3lU4~;i&t_NRxwR`5NmzY8tiD7FYjalOh*av~&sd!_(7H zmDl;`(zR-0$GEteK!{&-0|;B!renbP9kyQPKR6YBMk084JOr{Hc;2VMC)l!i$Cnqp zWzEVhlb5aeF#4?rVU6Z{=ENsZxxk1yY%?A<%zFl)VrP`%wFOlL)Vbq0SrhBZto%x9 zp(acP1z_&oTUprwPAMmc4W0WD3$M&vcl-9U(UGL(V3|~x9pltYpM{#_cXmV65!|#M z?k(5lKS*x5i_Ur4f-ou~3{;zIfm?}A1N-wE)h7ZzRJnALWa(nSyS57O)@W(ercIeb z!a6{|Dcm3Z1gw2k6V1BI&+dVrjLw%dOPD(q62z^j_C4Etbe-lS&uOe1_(K2<9gF1+s+IBpDHkp+M|nArJKn=!Vs+_3^*x4u`!Zh7x3M5-Rw zX8r+zkYjPTwR91u`4-GBxI%c8f zqmd!D(8J#GNY3(f?g=rK$XAIpvs$i=*Dt!^)gR^ZAvCnFL0WRG9@i@Z0xC3r(TV zSkFZzCs4pL&vC#s3|SnFK-mHGA~*=QcJjm}v!X979)q#bns?Xb(>$z2;5b(CsMQsj zX;jPs<-6CIjve#9$D^L%$@;z(&rKEx_rJ3!6~mt~hZt_{zjOWMA<92{8cx$gp|}iR zEhRpNX&G}+Bun8ua0AqNH-G&0vaWg* zj|;D&$(Wu+0*ek;&zt2zzP#4jald8jYd4@VHeo0Hl}3cw6({U1SkrEU6y$E3axmR- zmYhpT)A{t7>lMtwYPel%2^}$rnU4=&anz8 zvyHYMk)^>{bmn>li*j*mnVr8j_2~p=9qJN;laN33#pL6veww4N9%Q^4l}b;{_$K_! zA?tNDzrWPSk~F)H9;QT2x*fY>=6My7D>xOeCfloBQn%0BaKKIE^753G{lCh!G#VrRb4TWA$tvZUhQnh*h$96JO{=azU5?MlQ(}0@|XI71XV0@}1DNd7U>hy{g=e1+hTiB30POw52{0S1dMF zSquAyUfwSB(|jd_Px%@~x6%kVAThw!x8E6*uU(}=a+Q@L2gBrKxi@20U} zARs|Tb`z$(Xa6p;1-z37Yc%FLzHkL`2Ucmop}|js3?Qy_JRXzdSRKo*TJ1UeFg(^# zF`ng|W--J?FXEN?l1IvEEZ*b$vRiF}2LU;ma8Wk%xjw4r#`n{(7Gn;WnK3n;0vkl4 z{|W+mHO>GQca|M6^rSKTa64$?EA*|DKR&8U{FKE8e8?xE8rvYi=ycv?R8)kXZYF&n z$@0xa&y<4^m1Wz(kO9lhJf6$F;v%vmAdscdVRfp8RmI4pjpf$Qx_6@v15T!TD#kHDgUrov@FyMzBGS zqOhl06biq>2AP%zlYlzIa!k1Yt~&<0DsgIZKPzh621E3A#>f|9{9B)3i(i%vM=+k< zpKSJgG>^2iv-Y;}A#NFeAqDX-1j4}!rDYjF;iqmK%H|>oSP$r*tPIZoHhVX*yTQ|q zARjVOby;au&jDnP>@@i8o7fiRPH-cR{R&iMs%ovekxr`Xl+NRE6t{L`2R$M*Nt&CaC^oux=C zs`Wj8z7;L>vT|j|dGwnoB3SC+J3;X)XPSRuXAu5FNc|p2vd`;FstI&Ilt0Wkv=GQl z%J@yKlKpP9M|KlI1#wUnrhGbg#DW(o;B4IlxntyaON-p(`4xI{hr~R=)Ksy=K-h>k`or7ECe+5ku?$8lL}Lv^qSNw=Yj@qxY8kI)zlQhR(emZ z{T$oaeIvdWMhi{6^6y!!k>*WOX2RQHt}o6IpIk?9K`0-^-8h1p*eJQRC?I4Eh+_&j zDf`KO5(VT4sv?#i6G|V|(Rg(a%=*NVmwI1U zMD+gDRcB2r^!l2Ozy9Q`kIX`mDHL9@3313raRf2si+Ue8nZiAy@O_ZtA}((J%vZBY zStQakN8iVnl0SKa;Po1tRdN(4E%|3tiHm1{!UN_=2gS0qgf1 zd76fKLIRbotiIiER&fS(TpC%HFDR^bvw(VEVcuc_Sz-ABCkA$mnG;Yo`438yJpev` zh|f_OOT(t}c`v>8cBoI(oimF)SjI+b)(aEz>(`Tm!(zjs(ki{?-@C)D;ki#|$>St8 z`zIy`*lU}=In~W`wQ+`bX5W^m6he3Dj6d6=~Y08twf9L(w~EZ!wR5a3MqV7tu3!-G55;gZlvoy5W@ z%xeHj58(V?Cw#ea$p%l=YNxj?>bj+P7i7N`)Q0lkfur__(18*3E>6650NzU?sW6$3 z&IlCF#2VjiOi2~yU3ZW?T-L~HvsXH^w!5A+0`S9Fm^qJs&5sL(HJft*vqEefr5k(t z5*NgW15mLfOt1IacJojPxF2#Mo*lm`Vs+zwnvWTK z&&42Cz6xhVlDiP5c|p$*Xn9AEuPSi73e@An=t6TtR#NBt&i9{C3#}@;FpQ-D3~Nbg z9l@5_u8}euU8(LxOf~{uoL8pRNEF6L@AuM;HZJ9;nJYM_1nRBhrUkmj@+weYIH}-0 zD=~76@@;$HtkSt540V+D6cuqJTHXl7{-5OT6UBa*j3u{JLdR(#8!$@9Y=YybmB&Wj9r(n#NSpohpf7owV$q>j)U^=bw%8ST?_?FZy z71h)MuuWhg6`@i1WkC$IJ?4|!^LZf6VzR{j{C4R$60D0|NJ}E^0foJjH}LkQbza1S zeTS%xJcn8PxESt=*RJJaSyE>OZa}5KTtN_xTf!wX4yWfP)!Y1(P^ zshC~)DMBB3OS}d{Ds6jVad z2T!NL#@ty2-KkqWvzmM65kTy77iP zHA`;Zk;MQ+$MlwnYfH_XbRzipcj3%vfo;wF=#tGyN6G79b2zKt?PE`I6%hwBQ#Med zSWG+K?-t=7%!>@nrwe*S)k`R;yYV7|7r92*?g@u0Xige$MTCmK%zd|p_IpYE$5iC} zkua3yX~%{RTEn)!0aOpMv@LW%L(;#M!>#*s6Yq3wbt}J{m$kKxTh8f)lCXo6)n}Y{ zov{yq80nWHTmmLu?@Cc$8mt8!^kSzk^&24OXq;r}0+5^+J*m=k^7XhOT9XYBwtyGF$+|+HJ04^xag-pjd zR!d8CE-XbU^Ftksq8DDSUoF5@Uqf0^9I+>EMlh=1tBx6;Xo=ch?f%V^{_0o%O=Z;X* zi8$laBvnxA3%#%&_`*)OB>ehW)4LSdN|=r0{^uV#N{=CDtq;Y~F!(c;$&mH8T=u9$ z&LmHb&172X>ABmj?Ty217aF7WOXO@yR@+;et1o!S6VIpBZ|${(N?9K|y;I~IE3-q034g?AtdDc?qP*V^~)VC$&I*s z&#W}Xk+3O1a|Jw`)gTJvQpC;u9&%-cT6P{ zjMdF`Fwfn>1Y!L$tUx8-pR(2_?Kl!)W}nK%IZa(1L|tZtk5<=YDoalG(Tj~Ho*eOl z=fmrtMGO&8%{8_)h3kGhLXKshR#%Ppqh>|GA!(m>7eZ`p;A(1NovFXcP94nn-)Sgt zB+CzuC!d~~Cfsg$RE8-UQAmkex>y7a-QMbGGI}W^>o64DWTLU&4VjDZn_piEtBq!Y z#uOIdc^5!Pl``I|tcUsZZ8=cP>2K$=9nXsI|KOC<|^ioYtjL zTw=jG%u(KLbCN3yKoKE!8Rs8fWZ(H*y3o53Wp**btbl;CY~%ZJemLEfd|7|Fdi}f{ z_+3Iwa-o@7SXl0qM;t7cSvHjQ2WIHNsn_M>+Dw-pyPFCfHW(w0KPREciaX$`-} zW)-zp1r?*a3MXbr0KCLPbkzaG7!@OfTyliTS_&Roj2_^5889Wri&3lWY`UcCVs~Dx z7I1b_FYrD5EYif@4Z@6F(a!9-O#e`*c@sblu(4hqgGk%b%oa0~AJ&EodX%&83*H^g z?m3H~*7-~4MEixRSEpuAykT}NNf~!%mwPDx(XZy=bb-5vd?DfT9P)kdSC*~%4H1X2mZj|Ci+{0arLRte&*Jo3LM0=Mo5Ft23Hdk#& z;PB3isCpjo=gy0zHSCxSD|1P240lmY*RVa@_c=iQqK*4zoOC3&XKRdib1U%+69IXq z_i=lWviHf5SC=WHX61?_Fa9_odd-&q;Y5pRB?_CS%!-YYkzEQ1HIC%o6iXd?cVQlT zrXuH=USN)Ql_saKVM`VN;mCl=bNv(xXlDkf%yTp&11QA2#atHwI#zq-2x4$!_XYk?>KR#0S-@)#pNWTKEe~EJ}li(HT#^fLx^SL+cAs z*gV|CV|fzxz$Hh^1aYSSB!s5!xIMXa+`XTqoyadKy!F2_`qwT9D*2uCi^j1-1j}Ck zU8IkuNm`oA`xB!c9-R-;77kVPA#1`GOYL^w{c;E=7axtAIE?Z35yt=h9vMG!6s%qF z6u?6niHIa|wsPH|o{T)^K`1DKM4Lrc4xKr5c;=RN5&_wx>1SMpQW;OU8p zh^1K8<%IR~vjeKzG{1(?zbRkN#r7;hb7Wli#OobwiP@pbTe@ObkpBYO`a-ePj-0cV@P8%ueZ06)iQ>gH(Jt+ zMjAU1jqw>)pevv&z>lB*(6>qh_FM=gyCUiiP$u?{P{1vb@$zatPpm-_u3<;;JN~S&>4|fLE zPFZb*{m~7r9)AQ2xWoz5uw-DmP2HrwE*B|4K40Rouv=&`I`7cO=d}FP> zb7)MmILGqBzQ^zfXSX~Xjy9oQ&dw2|MB)8NE50y+yOyz+tv&rVxSs-+qswFHm)65y z#)SSy>^ux`8Ykk|5hozW>~9`LO@=p};Q6iTF;3XlXj`A9kpkkXkC6&e1s#|P%|DD3 zKA-c=30OapV{}_9NuP>|adtkNJHpIse_#+=By zOhpBs#4!I7k$-x2_$@7-r>@zl+7gtdod4&bR^Vw3ELT0l$*VnU^TSnHMkY7qMbUdj z!PI}W6&5)Dt8D)pwd+i^ShzCr*lYP3C(?x+CKvax{X^Ha74lGu=7iFR z@}^vD_Tl1-7o%BYJ`VfJzZcICY>PeQzOXwsd@zI!wW(Yt4HDnypn> z3oxu4x~BW5^kp~w_iCgXnQByQOx9~CT4f=>IkhiM9iC+KvM-$RyY?SNu>PIJk@}|A m|15SMSv#_{dylMzhYW{2O*j8n)5{x}H{ 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 1; i-- { + from, _ := r.Party.FollowerTiles(i) + tint := memberTints[i%len(memberTints)] + vector.DrawFilledRect(screen, float32(x0+from.X*sc), float32(y0+from.Y*sc), float32(sc), float32(sc), + color.RGBA{uint8(255 * tint[0]), uint8(255 * tint[1]), uint8(255 * tint[2]), 255}, false) + } + if math.Mod(r.Time, 0.6) < 0.4 { + pt := r.Player.Tile + vector.DrawFilledRect(screen, float32(x0+pt.X*sc), float32(y0+pt.Y*sc), float32(sc), float32(sc), colText, false) + } + // Avgångar: "2 ●6s" = inne, avgår om 6 s; "1 ○14s" = kommer om 14 s. + for i, d := range deps { + mark, col := "○", colDim + if d.at { + mark, col = "●", colGood + } + a.Draw(screen, fmt.Sprintf("%s %s%.0fs", d.track, mark, math.Ceil(d.secs)), x0, y0+mapH+2+i*LineH, col) + } + _ = sim.FogRadius +} diff --git a/internal/game/scene_level.go b/internal/game/scene_level.go index 7500093..3de34b1 100644 --- a/internal/game/scene_level.go +++ b/internal/game/scene_level.go @@ -2,6 +2,7 @@ package game import ( "fmt" + "image" "image/color" "math" "path/filepath" @@ -26,10 +27,11 @@ const ( // LevelScene är själva spelandet av en bana. All spellogik ligger i sim.Run; // scenen översätter input och ritar. type LevelScene struct { - id string - run *sim.Run - cam *sim.Camera - animT float64 + id string + run *sim.Run + cam *sim.Camera + animT float64 + hideMap bool // M döljer/visar minikartan } // NewLevelScene laddar banan och ställer spelaren på startrutan. know är @@ -77,6 +79,9 @@ func (s *LevelScene) Update(g *Game) error { if helpJustPressed() { s.run.AskHelp() } + if mapJustPressed() { + s.hideMap = !s.hideMap + } s.run.Step(dt, dirInput(), confirmJustPressed()) if s.run.Player.Moving() { s.animT += dt @@ -219,7 +224,7 @@ func (s *LevelScene) drawHUD(g *Game, screen *ebiten.Image) { s.drawMeters(g, screen) if r.Outcome != sim.Ongoing { - return + return // resultatpanelen tar över; ingen inforuta eller minikarta } lines, accent, bar := s.infoLines(a) if entry := a.Dict.Lookup(r.Learned); entry != nil && r.Time-r.LearnedAt < learnedShowSec { @@ -236,20 +241,30 @@ func (s *LevelScene) drawHUD(g *Game, screen *ebiten.Image) { } lines = append(lines, a.wrapLine(plainLine(strings.Join(parts, " "), colWarn), ScreenW-8)...) } - if len(lines) == 0 { + + // Inforutans läge: nederkant, men flyttas upp under HUD:en om spelaren + // (eller tåget under hen) annars skulle hamna bakom den. + var box image.Rectangle + hasBox := len(lines) > 0 + if hasBox { + h := 8 + LineH*len(lines) + if bar { + h += 8 + } + _, py := r.Player.WorldPos(TileSize) + y := ScreenH - h + if int(py-s.cam.Y)+2*TileSize > y { + y = 24 + } + box = image.Rect(0, y, ScreenW, y+h) + } + if !s.hideMap { + s.drawMinimap(g, screen, box, hasBox) + } + if !hasBox { return } - h := 8 + LineH*len(lines) - if bar { - h += 8 - } - // Rutan ligger i nederkant, men flyttas upp under HUD:en om spelaren - // (eller tåget under hen) annars skulle hamna bakom den. - _, py := r.Player.WorldPos(TileSize) - y := ScreenH - h - if int(py-s.cam.Y)+2*TileSize > y { - y = 24 - } + y, h := box.Min.Y, box.Dy() vector.DrawFilledRect(screen, 0, float32(y), ScreenW, float32(h), colPanel, false) vector.DrawFilledRect(screen, 0, float32(y), ScreenW, 2, accent, false) a.drawLines(screen, lines, 4, y+4) diff --git a/internal/game/scene_result.go b/internal/game/scene_result.go index 481e734..ac60c71 100644 --- a/internal/game/scene_result.go +++ b/internal/game/scene_result.go @@ -42,7 +42,7 @@ func (r *ResultScene) Draw(g *Game, screen *ebiten.Image) { r.from.Draw(g, screen) // banan i bakgrunden run := r.from.run a := g.Assets - vector.DrawFilledRect(screen, 20, 36, ScreenW-40, 112, colPanel, false) + vector.DrawFilledRect(screen, 20, 36, ScreenW-40, 120, colPanel, false) accent, headline := colBad, a.T("level.wrong_train") if run.Outcome == sim.Won { @@ -71,8 +71,11 @@ func (r *ResultScene) Draw(g *Game, screen *ebiten.Image) { } } y += 4 - a.Draw(screen, fmt.Sprintf("%s %.1fs (%s %.0fs) %s %d %s %d %s %d¥", a.T("hud.time"), run.Time, a.T("result.par"), run.ParSec(), - a.T("hud.steps"), run.Steps, a.T("result.gates"), run.GatePasses, a.T("result.card"), run.Card.Balance), 28, y, colText) + a.Draw(screen, fmt.Sprintf("%s %.1fs (%s %.0fs) %s %d %s %.0f %%", a.T("hud.time"), run.Time, a.T("result.par"), run.ParSec(), + a.T("hud.steps"), run.Steps, a.T("result.explored"), 100*run.Fog.Explored(run.Level)), 28, y, colText) + y += LineH + a.Draw(screen, fmt.Sprintf("%s %d %s %d¥ %s %d", a.T("result.gates"), run.GatePasses, a.T("result.card"), run.Card.Balance, + a.T("result.served"), run.Served), 28, y, colText) y += LineH if run.Outcome == sim.Won { msg := fmt.Sprintf("+%d %s", run.PointsEarned, a.T("words.points")) @@ -84,5 +87,5 @@ func (r *ResultScene) Draw(g *Game, screen *ebiten.Image) { } a.Draw(screen, fmt.Sprintf("%s Lv%d %d %s %s %d (%d %s)", a.T("hud.japanese"), run.Know.Level(), run.Know.Count(), a.T("hud.words"), a.T("words.points"), run.Know.Points, run.Know.Helps, a.T("result.helps")), 28, y, colDim) - a.Draw(screen, a.T("result.hint"), 28, 130, colDim) + a.Draw(screen, a.T("result.hint"), 28, 141, colDim) } diff --git a/internal/sim/fog.go b/internal/sim/fog.go new file mode 100644 index 0000000..fdb7fe4 --- /dev/null +++ b/internal/sim/fog.go @@ -0,0 +1,110 @@ +package sim + +import "gitea.brasse-pc.eu/brasse/metro-puzzle-jp/internal/level" + +// FogRadius är hur många steg från spelaren som avslöjas (gångavstånd, så +// väggar skymmer – man ser längs gången, inte genom väggen). +const FogRadius = 3 + +// Fog håller reda på vilka rutor spelaren har sett i den här omgången. +// Minikartan ritar bara sedda rutor plus riktmärken som alltid syns. +type Fog struct { + w, h int + seen []bool + Radius int + count int +} + +// NewFog skapar en tom dimma för banan. +func NewFog(l *level.Level, radius int) *Fog { + return &Fog{w: l.Width(), h: l.Height(), seen: make([]bool, l.Width()*l.Height()), Radius: radius} +} + +func (f *Fog) idx(p level.Point) (int, bool) { + if p.X < 0 || p.Y < 0 || p.X >= f.w || p.Y >= f.h { + return 0, false + } + return p.Y*f.w + p.X, true +} + +// Seen rapporterar om rutan har setts. +func (f *Fog) Seen(p level.Point) bool { + i, ok := f.idx(p) + return ok && f.seen[i] +} + +func (f *Fog) mark(p level.Point) { + if i, ok := f.idx(p); ok && !f.seen[i] { + f.seen[i] = true + f.count++ + } +} + +// Reveal avslöjar allt inom Radius steg från from via passerbara rutor, +// samt väggarna som gränsar till dem (så att gångarnas form syns). +func (f *Fog) Reveal(l *level.Level, from level.Point) { + dist := map[level.Point]int{from: 0} + queue := []level.Point{from} + for len(queue) > 0 { + p := queue[0] + queue = queue[1:] + f.mark(p) + for dx := -1; dx <= 1; dx++ { + for dy := -1; dy <= 1; dy++ { + n := level.Point{X: p.X + dx, Y: p.Y + dy} + if !l.At(n.X, n.Y).Passable() { + f.mark(n) // gränsande vägg + } + } + } + if dist[p] >= f.Radius { + continue + } + for _, d := range [...]level.Point{{X: 1}, {X: -1}, {Y: 1}, {Y: -1}} { + n := level.Point{X: p.X + d.X, Y: p.Y + d.Y} + if _, ok := dist[n]; ok || !l.At(n.X, n.Y).Passable() { + continue + } + dist[n] = dist[p] + 1 + queue = append(queue, n) + } + } +} + +// Landmark är rutor som alltid syns på minikartan: perrongerna (avgångarna), +// starten och spärrarna – det man orienterar sig efter. +func Landmark(l *level.Level, p level.Point) bool { + switch l.At(p.X, p.Y) { + case level.Platform, level.WrongPlatform, level.Spawn, level.Gate: + return true + } + return false +} + +// Visible rapporterar om rutan ska ritas på minikartan. +func (f *Fog) Visible(l *level.Level, p level.Point) bool { + return f.Seen(p) || Landmark(l, p) +} + +// Count är antalet sedda rutor (inkl. väggar). +func (f *Fog) Count() int { return f.count } + +// Explored är andelen passerbara rutor som setts, 0..1. +func (f *Fog) Explored(l *level.Level) float64 { + total, seen := 0, 0 + for y := 0; y < l.Height(); y++ { + for x := 0; x < l.Width(); x++ { + if !l.At(x, y).Passable() { + continue + } + total++ + if f.Seen(level.Point{X: x, Y: y}) { + seen++ + } + } + } + if total == 0 { + return 0 + } + return float64(seen) / float64(total) +} diff --git a/internal/sim/fog_test.go b/internal/sim/fog_test.go new file mode 100644 index 0000000..ff9f15a --- /dev/null +++ b/internal/sim/fog_test.go @@ -0,0 +1,92 @@ +package sim + +import ( + "testing" + + "gitea.brasse-pc.eu/brasse/metro-puzzle-jp/internal/level" + "gitea.brasse-pc.eu/brasse/metro-puzzle-jp/internal/rng" +) + +const fogSample = `{ + "id": "fog", "name": {"sv": "Fog"}, "difficulty": 1, "destination": {"sv": "x"}, + "grid": [ + "#########", + "#S......#", + "#.#####.#", + "#.#...#.#", + "#.#.#.#.#", + "#.#.#P#.#", + "#.#.###.#", + "#.......#", + "#########" + ], + "trains": [{"platform": "P", "track": "1", "line": {"en": "A"}, "destination": {"en": "B"}, "correct": true}] +}` + +func TestFogRevealsAlongCorridorsNotThroughWalls(t *testing.T) { + l, err := level.Parse([]byte(fogSample)) + if err != nil { + t.Fatal(err) + } + f := NewFog(l, 3) + f.Reveal(l, pt(1, 1)) + for _, p := range []level.Point{pt(1, 1), pt(4, 1), pt(1, 4), pt(2, 1)} { + if !f.Seen(p) { + t.Errorf("%v inom 3 steg ska vara sedd", p) + } + } + // (2,2) är vägg bredvid gången -> sedd; (3,3) är golv men 2 steg bort fågelvägen + // och mycket längre gångvägen -> inte sedd. + if !f.Seen(pt(2, 2)) { + t.Error("väggen vid gången ska synas") + } + if f.Seen(pt(3, 3)) || f.Seen(pt(5, 1)) || f.Seen(pt(1, 5)) { + t.Errorf("för långt bort ska inte vara sett: (3,3)=%v (5,1)=%v (1,5)=%v", f.Seen(pt(3, 3)), f.Seen(pt(5, 1)), f.Seen(pt(1, 5))) + } + if f.Seen(pt(-1, 0)) || f.Seen(pt(99, 99)) { + t.Error("utanför kartan är aldrig sett") + } +} + +func TestLandmarksAlwaysVisible(t *testing.T) { + l, _ := level.Parse([]byte(fogSample)) + f := NewFog(l, FogRadius) + if f.Count() != 0 { + t.Fatal("tom dimma från start") + } + if !f.Visible(l, pt(5, 5)) || !f.Visible(l, pt(1, 1)) { + t.Fatal("perrong och start ska alltid synas") + } + if f.Visible(l, pt(7, 7)) { + t.Fatal("vanligt golv långt bort ska vara dolt") + } + if Landmark(l, pt(7, 7)) || !Landmark(l, pt(5, 5)) { + t.Fatal("Landmark") + } +} + +func TestFogGrowsWithMovementAndResetsPerRun(t *testing.T) { + l := loadLevel(t, "001-flygplatsen") + r := NewRun(l, RunOptions{Seed: rng.FromInt(1)}) + start := r.Fog.Count() + if start == 0 || !r.Fog.Seen(l.SpawnPoint()) { + t.Fatal("starten ska vara avslöjad direkt") + } + e0 := r.Fog.Explored(l) + walk(t, r, l.Path(r.Player.Tile, l.Find(level.Sign)[1], r.CanEnter)) + if r.Fog.Count() <= start || r.Fog.Explored(l) <= e0 { + t.Fatalf("dimman ska lätta när man går: %d -> %d", start, r.Fog.Count()) + } + if e := r.Fog.Explored(l); e <= 0 || e > 1 { + t.Fatalf("Explored=%.2f", e) + } + fresh := NewRun(l, RunOptions{Seed: rng.FromInt(1)}) + if fresh.Fog.Count() != start { + t.Fatal("ny omgång = ny dimma") + } + // Gates är riktmärken men ändå inte "sedda" förrän man är där. + gate := l.Find(level.Gate)[0] + if fresh.Fog.Seen(gate) || !fresh.Fog.Visible(l, gate) { + t.Fatal("spärren syns som riktmärke utan att vara sedd") + } +} diff --git a/internal/sim/run.go b/internal/sim/run.go index 4075c28..0f9bec2 100644 --- a/internal/sim/run.go +++ b/internal/sim/run.go @@ -70,6 +70,9 @@ type Run struct { LearnedDest []string // resmålets ord som lärdes in tack vare bra resultat parSec float64 + // Minikartans dimma: vad spelaren sett i den här omgången. + Fog *Fog + // Sällskapet (lämmeltåget) och pågående toalettbesök. Party *Party Facility FacilityState @@ -142,7 +145,9 @@ func NewRun(l *level.Level, o RunOptions) *Run { Party: NewParty(l.Party, l.SpawnPoint(), o.Seed.Derive("party")), baseSpeed: o.Speed, NoticeAt: -1, + Fog: NewFog(l, FogRadius), } + r.Fog.Reveal(l, l.SpawnPoint()) if r.parSec <= 0 { n := len(l.Path(l.SpawnPoint(), l.CorrectPlatform(), l.CanEnter)) r.parSec = float64(max(0, n-1))*ParSecPerTile + ParSlackSec @@ -196,6 +201,7 @@ func (r *Run) Step(dt float64, want Dir, board bool) { r.Steps += r.Player.Step(dt, want, r.CanEnter) if r.Player.Tile != before { r.Party.OnLeaderArrived(r.Player.Tile) + r.Fog.Reveal(r.Level, r.Player.Tile) } logged := len(r.Party.Log) r.Party.Advance(dt, r.Time) diff --git a/resources/text/en.json b/resources/text/en.json index 238a199..82673f7 100644 --- a/resources/text/en.json +++ b/resources/text/en.json @@ -18,7 +18,7 @@ "menu.hint": "Arrows/WASD: select Enter: start L: word list Esc: quit", "hud.time": "Time", "hud.steps": "Steps", - "hud.controls": "Esc: menu", + "hud.controls": "Esc: menu M: map", "level.wrong_train": "Wrong train!", "result.hint": "R: replay L: word list Enter/Esc: menu", "hud.card": "Card", @@ -58,5 +58,7 @@ "hud.toilet_busy": "In the toilet…", "hud.toilet_none": "Nobody needs the toilet right now.", "hud.kiosk_prompt": "Enter: buy food/drink for %d person(s), %d¥", - "hud.kiosk_none": "Nobody is hungry or thirsty right now." + "hud.kiosk_none": "Nobody is hungry or thirsty right now.", + "result.explored": "Explored", + "result.served": "served" } diff --git a/resources/text/sv.json b/resources/text/sv.json index 6041f55..710d592 100644 --- a/resources/text/sv.json +++ b/resources/text/sv.json @@ -18,7 +18,7 @@ "menu.hint": "Pilar/WASD: välj Enter: starta L: ordlista Esc: avsluta", "hud.time": "Tid", "hud.steps": "Steg", - "hud.controls": "Esc: meny", + "hud.controls": "Esc: meny M: karta", "level.wrong_train": "Fel tåg!", "result.hint": "R: spela om L: ordlista Enter/Esc: meny", "hud.card": "Kort", @@ -58,5 +58,7 @@ "hud.toilet_busy": "På toaletten…", "hud.toilet_none": "Ingen behöver toa just nu.", "hud.kiosk_prompt": "Enter: köp mat/dryck åt %d person(er), %d¥", - "hud.kiosk_none": "Ingen är hungrig eller törstig just nu." + "hud.kiosk_none": "Ingen är hungrig eller törstig just nu.", + "result.explored": "Utforskat", + "result.served": "försörjda" }