From a9528f7ed7a945fce2c9ec900e9acd4ed09fd450 Mon Sep 17 00:00:00 2001 From: Andrea Manzi Date: Sat, 24 Oct 2026 23:56:07 +0200 Subject: [PATCH] Le nuvole che scorrono sono quelle disegnate da Codex nello stile degli sfondi (tools/ritaglia_sprite.py) Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01ApqNBvNbNCwXqR2RLo8QJh --- Dockerfile | 1 + assets/effects/nuvola-1.png | Bin 0 -> 12309 bytes assets/effects/nuvola-2.png | Bin 0 -> 11117 bytes assets/effects/nuvola-3.png | Bin 0 -> 5549 bytes assets/effects/nuvola-4.png | Bin 0 -> 4926 bytes assets/effects/nuvola-5.png | Bin 0 -> 4315 bytes assets/effects/nuvola-6.png | Bin 0 -> 1806 bytes assets/effects/nuvola-7.png | Bin 0 -> 1145 bytes assets/effects/nuvola-8.png | Bin 0 -> 1638 bytes src/engine/render.js | 39 +++++++++----------------------- src/story/story.js | 6 ++--- tools/ritaglia_sprite.py | 43 ++++++++++++++++++++++++++++++++++++ 12 files changed, 57 insertions(+), 32 deletions(-) create mode 100644 assets/effects/nuvola-1.png create mode 100644 assets/effects/nuvola-2.png create mode 100644 assets/effects/nuvola-3.png create mode 100644 assets/effects/nuvola-4.png create mode 100644 assets/effects/nuvola-5.png create mode 100644 assets/effects/nuvola-6.png create mode 100644 assets/effects/nuvola-7.png create mode 100644 assets/effects/nuvola-8.png create mode 100644 tools/ritaglia_sprite.py diff --git a/Dockerfile b/Dockerfile index 1f9eb20..16aaacb 100644 --- a/Dockerfile +++ b/Dockerfile @@ -11,6 +11,7 @@ COPY assets/icons /usr/share/nginx/html/assets/icons COPY assets/fonts /usr/share/nginx/html/assets/fonts COPY assets/voices /usr/share/nginx/html/assets/voices COPY assets/credits /usr/share/nginx/html/assets/credits +COPY assets/effects /usr/share/nginx/html/assets/effects EXPOSE 80 HEALTHCHECK --interval=30s --timeout=3s CMD wget -qO- http://127.0.0.1/ >/dev/null || exit 1 diff --git a/assets/effects/nuvola-1.png b/assets/effects/nuvola-1.png new file mode 100644 index 0000000000000000000000000000000000000000..e8a102f8fc681dcbae5705a41fbb1f1ff210e654 GIT binary patch literal 12309 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 literal 0 HcmV?d00001 diff --git a/assets/effects/nuvola-4.png b/assets/effects/nuvola-4.png new file mode 100644 index 0000000000000000000000000000000000000000..8ce62e626aefcd55ba6690893684aaf015c074ac GIT binary patch literal 4926 zcmV-E6T$3>P)P8>OogRBsFf*=GC2+0wVfDw~O778#x5hPQTQ3OH? zFabsgi3ty33n76JLrX{ygn*C^s0nHNcK5w~p5Jrty&hEz)_1xcr6b%OckYEXIp;gy z-e>RnuUb|A`d116k1hN6*TgOO&zZ?%0UYi!iu}HZFZ$KK=Or)t1wP6u|9xwC1r&KQ zU}6B+*2B&y8&CJu#{w{Xtu0m1O+knHU5<$Bp;@0cMllSr0_h4|j~S%jct!NTv@E{9cp-L$7xL8aag}Y0 z`{S6&1O|p82pFId2w)jd!~pNXIY2Q>2nEQX1yTe@-GEQMZSmU=-~~CIdl3))UYEUx znHY!zsbNBHJ(~vfh*$=37=nq^6HsmtDVU9rM?@1tTyc4^=4!Lz&G+tc{lmujzr1=O zcD>Y~D-Lq1o(doaVu(1f0TIDmTSJUgCIi&Z<$&Z=H%UCZv1b+r_JilF-E+MWhT+AS z|5Aq+hE{mf8DBh{lBUO?f{Md1$oqN{(C@lYz&tjMl*vd4njm%!is$*ooMOh)Urk*6 zm23R#SbqnZ{mk9p6SH2rL>m8V#6670MS_Dv9!~IZhX|Mi&`KH6RIzmnByTZs2u3wY zuwft_;SguEZRYuANlJm3GdH^yFT&y&c>N1|EPB$eL#`UyZ;0IeN1rVCFO{d~HwMHH zCaVF~f(;Q`1!*xIfkMrwx8Q=5EhZfz#s}VR2ry^|Bo48`sW7BKaEh8Ectaj%rVdI| z*!n_#UU>NW>=U>1<%;R+qw#9OPOl|>Q$vS+;K7K24Vd_PjR@j|Tc8m^1Z39Ib&)nq z1P7Zb5VN7qK@jE(2(2-U4acFy3+ShXO>*|u&!2yyX1>tyVt@IZ<0Z6zsk7z}ttG#C zVe-nYHw#cIQ?Y_ci`WFN1)bi1bGh9V%kT4e!w@YeS}B-yy!))@7+dz^ZC((ZJMF0o zW(o*S8{Ev~M}O>-lNDZAcq#uj89#KO6GiSM%JIe+%LlcOMzBI9*AB7q1a7L>qNmy@ zBjpt5y+fR@_uOuRc*M`xC(qq=p$mn}UBfsEV-&Om#21|N6m$5-Bl(l{#TNp4{tsL1 zY>(a<5hvAK)u6Kz*EU3~CeCsIX@Of>STHk0Cq#kqfXR#)4K&cK9Ig`(;W#Xq&n7fR zdf$)+m~{!+1+qdaj$Dk^8#zHN1+O08{C^0#%?EQ&GBu?LYFZPa*{R};l@0DVbL8alVh477nq_Dv*0|W1SNrQgm4o$ zEb}L7|BDGP(oxkv1lnsf?> zg8%aU-}#Jw(_?>8kXiL^lL|BdHe%9O;OiewRj9{A0S~htb{k@DnM%v~q34(z%!I@B z5|bq&!Yqu;`-IcN^6tcTa$N5lF1L=(E1R953M$Z8$K&6e@zr1GzMqhM==xoQe)#L> zbYJVt=88N%BAsB9r(AAKZ=w);nlG+?>qBEBx;+~G1h?Qya|$cIvJ?#SE2QjBci9J2 z>qH@&p!iW)xQQfzWWF+WtD@L?S;*0|9~|#qt|$fYa5gX8Y#LUbaeWlJ4)uGaqHkFUvptQ+n8 zP<8GfPe#rlCqc?iQmQ2+ZJ|U|dg6Y;)xWqe?)PJhn~CYQ$l}RFw}hO$8&fp8u8<~2Ov+R|O)!eW zI5}{F7r|$keMec(JU{XWW+F$2bw_hwN|p0lLErAMcLaB@75|?S^7W6-=Ra0>(WoY0 zny@%k$1^)|={+Vb;Gop_Yo#zbW&Fv}Vs^-9CT4S`TXu*SS|^YXwMx-cb@6iepkYz_ zLf|}Na{4<6ig9Y)HG#9)kzo+}5ZT6-%@#sX_C*MdXFeCSF)TWqfU2WwV4P}R2|+nK z%gBAt*&h7;YqK9}s&tIi=UPTS9g$C0kvTo@NdN6xnlFDet>*s6H+kfrh4a4vGSU*WxSem>)FwMgWTl1=9(!h-ITB zBd0164AY!rY1mH?8;7898E z_xaT01D21BLtt~9)3nOwu)=Ak6xi%Nu^8S7vtCd&_D3)iQi8r!Ogw+^$2K@gNLf`c z#sjH>FZFskb)?F%Q1%m>beBj^(m>HF5qmM5|7c?EhliIKA;kA-8&(ieR07xt7N~-g zJJH125~B>YvMdSddfwN*1)NPaZcCx{^%y_f-r?Q~^6o*B{nTNHFYmd znE8RAnRlPg*&hOnxiU^IhUaSElCrTIJjLYwJnX%&>XqFPFejKm(**FLhBl42%KYi4 z0#+0Htq-+AyL9M<$NR)Fx2HxqSaIwwf0v-!Hw?YHfrV6RW*H-cDz1#D)|i0nD@C*# zRy0SBJ7_4x)Udb{K>`v4Qie2=lV?B9aZSTi8p`NFB5Vt33(og%^@9kgiqZ-DVS?dYF?^^iPn<6s()6)k3}?%q@8CvG-w-m zw!h2g!gI1Ex-&%%1LgweR~+<=Vwv6O(JUN>jt9#ls(~_r$ANh6+*igaGfpjvKx6E* zhYW}886r#(R0TDo6mSC0Rc&~jP9?qytA%5|%#5RF$}mlZ!zQ6;31_~t6$3pKLX#*O zI8GhmIucxAD4v^}hNLUDL&L0tl!d+(d?VcXJUsprlj(7f{;wIV_xLXa=5vSpY+?L` zcclNDPu>Sz0MdWl;eXf+XF!I$IW>J#WfdmG=n!f6&a)XYD(h~~*PFgiPVVd?0Fz6{GJa zHp7Cf!o`KJ;8WYA;-Hw2BBW#-2chIjHs>=K2VuD=G{ND0;`P^RSnE$L<^J7~!}*@Y zJhMGCgudnJ)dRlx_#JN2lEb#;!TQLX&s!E<<~RkOZPs)h#K|%13yq5ia3YE`0SGd56?1fpV=Q8?k#r& zEnFR!WNFBwaGV53!N-opIOEYz-V@2cdQHA}uptT>0=Wpj3|w6r#gw8Avzams#>I8O zc|mEIasV+_eWh193%i43zY8>tV|7+TzLv!OI|VDyHp(IPq$G@!<2Wi)H1>nAY737Z zd%X8NzCUt#=`ksUAPh(0IC}7cIAaP~}S1=NK5_Z(dZ-U;3n9-bwJ z0opdR9~>$zX2Nn-2)@pO9rlh?1f2@0s>ie)>?hBnH_kVXt~FZcI9n;NJ{p)}rtyWo zRZ4^hcN#8+mSck63eUGKeG5e#5D;dyrhfYGo^u$*Zi*sj9rNbMvrRo7X>_a?iT#an zz4y$P0KRTcsQg^jFo9tR^qu0U-S%d`zS2bK62jOsl;{c5)zJW=FnHNei-rGXo8mpPGUch`_h#7(u`Yy2_ z8=lJiGRY8S`FvdfCu*l>}Yx z1ykdYg$FB-CC4P5KlP`pbo`;E>p%J1M_XS-h9B(+{~Tt!EK?`g7m7XoqTvTcvtVLa zHYA+7YFa;Q0i{&E!a)e9q0a)UM&YFF6^8}IoYf{$vG=tl@eUsh=LF4AvQo^jQrU?( ztK%1Zz+&aQ%*mzlM*|vHM>UKS4R$B}$|~dWC^6OhRTb}Qou?!^^35!B&={ ziSk(uUr-A#SAVO(DPp(59K_qHdKPBEQL+)U;Tl0rz~n@I<+eSGTKz6Gibi3*2E)?? z!3pg5f(4L6!z>56=`*WK$Jx2s@ykX{`I%yleyL~^m~C5dtz10FTo1n;;*TxF|DC^o zprLT~o@cjAsIMN?XsL}}Jl?_F!#Fy851sQIj|uM`uJOzc0U0uzd10_(^u}yf0ggrJ z8)J+{DTX;=y-m5mC{VgvD6q}<_&Ia_}b6> z&XZy<%`D^J{aXX;mD+5XNu$1B#*YPhsinB)jG&;#F$NY3=o%wVhMHqGhd4sh)bWa0 zpSjs7-P{v*fCScWc}C~B?pqmOiMGTsZxsUc0Wy`f$hl|s8?e4M`6K_}`#Wm)(tr-| zum4%%xQv$7(Z81o&XEq8yKfrPk9(3T(>~Fym8&su_l}Ya1aCN3<3$<;Cxy^Dnj_f3 zb9@vyKFfr?5WY3%r@s+isNF9W=-<75<*yB-;B5cdDE&K)-L%GhQE2v=c1neb|lv^&D9d+h2R&u>2Q;b(5Jr`K+mPdxwewLi!0|3B;h>!|r= zS9gjVk z)8A^x_*)LI?6KSI(iL0;pKcHV;s!(zQQQ;m1+fXS87x80;12B?56xl-OL!TuD`S4y zWxf9Fb30pnZcly&D?dKCKA7+}0|E|G1>8a0zy+5AB$R-A0hi?`Wl+IO0uML>^90i^ zM366c&T|ah=Zcv8_NB|20!PDYjcOEGufO4S_NB>rAwzAzf(9tyendz{$_}If$+$F- z_Y0B`yv#_yM>OD8@Yx_J#RF5Sx!m7p-DNfx753G@<{!NBvD@jnI3|7J;Mx@Yr5UXY zZWDsxWbDgEwn4hT|AQZTefj*>d3{7`$5Ei*?g)l>UZS50JmI7zeTf1e)OJS>JJ5g| zt}b5e#tfj369g1M3q2 zJPZ44BZrplp`sr<%$251G*!V`B|ZH3$?M1J7(c&r34+wdVnG2V5eO`{?&Vq;llm#1JK$g!1$B$S-YP3txxH!u z!*E=TX^M<GzpdbF+Se(9xWV!LmvW8|M#t|t@a zsz=QT7a6x1kq;P>@j=nX4Vikt!3<(#nARL_D^4#a`XQhWU-?SSXTR@eiT;vsjfe)s zfN*42%mBCu^aB!|GDohiJH!J`m{?uiVXcw~L8CB4M3vpHp;=|d6p&zSe#m$) z7SGY)uhiw?SN;O|Nxb@>8(jUF)uCrz(EN7?@_BUqOaXd`Wl2|-5HU2o%s3u{|yo;^T6o;!L-h zKCNj(=J9n$Um|r7f*3D8=$T6eC3AD=C||reA|8!6EGlAwu?tNrCK6A&+pMT<7MdY>dnBRpDitmDkadChPq6Vd4 zhZ#>Z(@=4cj(Jjo8h68rQX;V~Z1)uos0t77kG%ZiL<|K&4PI~pLOI^sAar0ocC*Dr zm~z8*UvU^~hSE?hkWygPmStN-NyXU@0WV0O5%`jE0>cs87WmPBEZRYh?M@n&G zlwwZc5ZG%0OkRFzZQ z`Tp-uh$^Cjn}e5yu%rVbir9>sFG|ClVHgl8ymfVta@Ty_ZvM+##@G}86>jf}H2?6$ zZ)oRl8fN*wA6#Ao*Mw?bqQwu0ACR*23b|jS7<7t;vEQ5rOMl z=sIX?dS6|)|qmYa6@SbDIXzK$uI-UgW91nre zC|-;?1?I^qGziX|gxz?~<0ncfaCxn$E`+)ir*7Z}zIWo4M-z49paN1s?(tHNl-nT$ z*dD;0!LhH#0F%zCC?QqN(u4U7AT03?S!0KqB}z`ggCJ~7<1)BEmR@1 z?Q2%GQB}}&f!KDWNm$i|!*1Zc%N5`8LQf-wDK*4k#6~&XwrE?p+rr9w3JO)AA1iiy zp^lJ5I6ZatyT$%4js`&k)U6>RI0k8ln?hQ|QfU;X37QQ1j3^Wf^kYlc9vFwfAQf|+ zIqVMTc}qAoG>?pZVfT3C%fB=5AOr8f>WxDE)`0xt!w+|if9{4cLu?~C?&*H>B_tMH zh9!qHLve%*5;1UKC@LlTBg0DinwJFC(Q0ZGa#xF($5e8@g(uikXxua$lk9Tt98`09WaRRX4J| z>d09cvoa+iL?;BOYb9Gj1%ehzDx?WS9VMajK$v>~Dn9^oM)&ht#Fr z<6?a6-_AVxF-1=%RFBlxWkF7e;IO|7Y;S8k&5WhyQ=hz}suM`X_1i7CQ;oD0FTZ#o zC8zWO!UukbG|x| z({j(y2rkaeF5(^-_kww(sS5jpkWE00SPAV)dGWzaPBZt{&O9fsu3OH|5^WQCa53-rr8Ms#e}MI9z1YPH!b`< zcM-{%Ld9H``e`N{Mx|{EW=cHL`5?la19NfQAqJh5sLjKPbsFXTI1fy z%wd2Kgkh=>3YXhJ6AS&ckQ6V1nNtunD7grp3`QW!DR1-VlSJ8kkGuyW=%)zPl!6C=w8X5IFo&@(S*R<> zS?N~7I0=_m#)ES}0x8ljl6-3jZpvkA(6aQ0g#=)xGgm14F8 zOI;f&FHY_{xZF3~+(48iK&BiRvyyALz73qMLCnc{NyUpv95*F4(A^fM7>HveMVJrD zd?(l*zO%Ia$ZyC}W4`cfiD{nPU&&M_GrRXInl~oW)KIT_o<40!L&01KQCO|PEpWb? zc>76%xlzQ40kR8SZ9KhER<&V8XllbPAhN)|t(5aq2Q_wk!Az+uXS-b#;Ms&2g~Lz~ z6ij$@VchP7Qk;9I#`Uf8@M4MLV~5G@cIj)n&het0uASsgKR6T^CTGrq9}TKN3~+i9 zNy(|z7{@>^u-+_^OxHRg7H;=}uFh1QvhJKGPlah*&NdVXDu@VqR)RYxCy*wknT(1G zvV$n=m!P{W?A8rG@vplNrOO}skN@!Rd$;7UE<`b&JPt4#k_9?AJ#pr+P(=4c0ZQ@( z`bYSeVwgE@j=KlN(Q@mqGv^5kc*{^L&$ zeEIuEPB$%6m%W~iya7r<47wKfJ=78U*%ua7!!Rz)Dyk48><+MAFDY>tg|kz`6{09r zEsWD~ker>ST|`GO&SCGgoq`HOzuaG?Fi(Ni>C(8i-7+l8MZgwRFid+cWe3&p-Z@FaC?Q z*L^{XQFR4Z!4gbqDX`gAYae|5S0 zY~bFTf%NIw>pD>Zrba17LV4+OBR~4{^)t2MxAg^sKm6$lN8JADOu!iS#^jD=!&A+= zRjPeqJQLcR!uh!}HHrxo$&`@s>ev$$q1g*lEz2Z-rEm*B_PIsX{*zyuc>B9>&rTR8 zth3|cY}w2)HKnw4`gWXbD#ChSaR`E#LnU-y6!Lj3|Ku4(|3_IL+nXQ1{crY^(Y$&L z2T@L@hLf*CeA&<;!J`hl%QUB%E=0-q#n(@EeC^W_qM#G-rHGwpe*EW7zu~_B;PaQ$PFHN5{`&{a>2L;aA<+R1W|E002ov JPDHLkV1nn?FR=gs literal 0 HcmV?d00001 diff --git a/assets/effects/nuvola-6.png b/assets/effects/nuvola-6.png new file mode 100644 index 0000000000000000000000000000000000000000..1ef709863073a827c6453f8bb925b22d036e15bf GIT binary patch literal 1806 zcmV+p2l4ocP)eE!UA-XXJyAQ*<&2)ToC1|nGWxbM$Io?4zq$p1Tc zEG|9Um|ldu(_lFg{xsq#(Z@=J0AgedkRxINA%cO0%n+w^O$EKOIGIWLiQWHUNp}bT zpBwh%3EU6zg}v?i{Vi=Wg2g%uI?WI-~S(mWgS= z?{$c;5Ldwvv2+GDfG?0ZfGZ$JY#cd$t%3~dGk;$l^4PssL15J_INCiUMk8iVeZeEH z2AvaL>CxX!VdX?VKbmU9Ot$q(!a|P_$;Wew2QCXh_~WV38TxPwK7h=C2svN^LIO3& z0TP%55*2$YGnRfu?3F>MoHRAp*99R$MMO*Eo@Kzfn&}h{E}bG{3)LLFLo8$FAx@wOU>Q=v zux(a3L5>hXvd78_@d;adD2|a7pk9JF%n6V%DIm0H*J8=YYQ&Q{BL&57O@0-sxubaW z%Da9WJ-}(q0GJq|06%(8Z%mmvEAFlM(RYLG3|UqWMoS@*MnUFAdd`!sl^i6K{_J?^noxA45M-LWWr(^QSV52`d|!$0!9iTL@X;ii^QzXOiSZ%FLG8M8n%FhNaN>|}~6Fq;YWL@2zFqvC7?%j_?DW_3@N84{G?+5|rdgt6qekO3LiB}r4X*a@BQ4;NSD374E5(Xp0 zgswAjs)UIWT%tJk_=^dv6A}f}jPo#YN=Qb?8K*`vMY50uM1EH<8MAvATsEfa`QIzb1e7?p5ECB2+%Y(2Uv<>-dtCYg_ZYYN{9AxTF@mCY>kvX6KZ1J{k-V@^Pl;1vSgo~ZY)X>*F w;bNw2B7RijLRmat%h}~2z7i6YpyEOj+_+M~jSCkFA)qS}_wL=f(2d|i5L_7% zbfXIe5ma#D0|_D`NDOMwnaOldPxtM6Z#|BS(YO#4lZoH5pz8nsQ|A;VTqhPUEy$m) zl%QyeAOglYwNV;dLW*(3`8^U)J_@f)*1~gL9xl2{c zM0^O*6ARMmEj9NklBSRnqzW{lX5a2SyAo-3NNvPOi?)%ZCEKCH>VcNwevhPpU1{OL zjQFFdbo!W+kvw@cc#>oo9h2RjD@MVZE55FkD~D`6xxp`^0ol@yZk-Ag2*cQ6?PQG~ zFJReYIvF}Ikk(+z8pY!rh&C8%kVsk>l!9cGPzjTn<=|?=yeWv1;UtokV4YxHfXsko z5Cw2(jHpJ$1SGZi3Z~nA>X5V3T4onB)-G8_2P*92N3OaE|G4qO*$e!3+aZ;sGsfMV z&NmsIgEf~r1*HoF8_9E}-%AXaVae5O?HH=c(9LT$+7836XMNL>l0kqN4Qn^e>696Z zP_QSuW&R zpq}lTuDvjA3_T~z=U_y4M2EXh+F=2|q{-@W_fI0?sz%ttVkvANS}c@Y{jb3Z`;k3Yv?uHxI?1 zeDaE?`+3W~ul261eSD^-$(7C1o?MfX-&wc(5?U^xdE#1Y700000 LNkvXXu0mjf3l9nC literal 0 HcmV?d00001 diff --git a/assets/effects/nuvola-8.png b/assets/effects/nuvola-8.png new file mode 100644 index 0000000000000000000000000000000000000000..6a48ec98eefc4baaca66ce1f1c9167d3c1e95c9f GIT binary patch literal 1638 zcmV-s2ATPZP)@zu+K7FtHJ{A*#kcecHvGBWUsj92K_vz}ls)R>a!!H`# z=aV4~42GKGrWt;8RvzZO4|VYWRq4&jxH5nwWEMdO=t?XAaSZDTC@6vK>SL$w;gN%q z4oVYkVQ0VuaDWa-zXCG|BXGh{MbHB0gzO_9KUE*$GzU8sO)CsLc{T-&AYf`(J0Kxq z-lH)?+aC9?zNe^10*bx9PrNoGd+t24zrsGYiv zv(Wr(LH2Aw=`DLhWb;gG5B>MCH#_JRw!jUL?~VW6_M;<|squV=v4uV&qaMZ{^Sd}J zK_ku9L0PhCc4<-uPPp^#nBWHLHs}0brt+z8V0NKG@Yqia@y{od-QD;7b*~-azY}Qw zW;S`o;F?jbVc7-N3s|&@lfZK}y!X;^+bhx4< z8wYR>!;st{4PYho4Q4`-w=_-}PkZVrqv-{Q(nlfB5_@0X*w89@szC*PN-Zsw;SYbe zK0ia4IJ$+>?I`QDF+K5T1Oz z<;v5Ef85IX=$V#wD^#^()sJW`F!Dy(2vsGtWx(}D^ck|v`1-4p5A=R&P=@^m_gH0E z0vo_};73SmKqDp|ae}EL7#b$XutDgtZ6tOXBFb?+q0&8`IJ4yU`)4UT=o%=3QshQe zJGQkacx7jj$h{(kvD##$=xJ+XI&<`9Cuf=Hag{NwM!fXHo%`~8dYST$n!Bi&4kuq6 zuv9@DASMK`kb?|ZOh{7!1FFXH>MU*J$@9dzpVAGU!!%)2Iock&*4Pfv4>{foJ~KwS zv1tRT1CpRlaN=-4*E>eN!>=5}`5>{3v_89UD-Q(4UN_>bHm)d4z_|z-(OC`K2JJV9 zGpy_A+CU6rLWL({S#IER4$2veP2h>$nj3d=vP`)-OzEQsGc-Zh zIzo1GY{?6usxw?LRE4y1%r($u0T-a$ON?(JaWChEZ;u|t;)6rs#tL3)k?u81Ru-NR7iE_9+L)qtCnJ+oIJ7Z^_P;xfih;0pjUQTFgK_sAJ zhyy2%kU8cvN3W3}#yB{0TMF@_ zClkkBV=zk;E2S$vXB*GqJo2^I_D+4X_^&Ia`|%R@bg=M~Ao^W3iWYNw|Ay1om*Z@zW!w0Qs^?a%L;zdV-aSCQfqBa<+|#*wb{ zG`BqN!WNw=F%D={GAF#Vm@>|LVxL%UJkASs8`!pvvJ6bd2^~B`=ZGEjjgm%=-O4kI zj;<5@+;AA08(Mmt8SX+PYJdf_=W@RJ%IN=cVGTnSvBQX6RJ;9l%j1_m@D94$xWqYR%J{U)QR9TH(YQrg3uY`14R6>e>XqA`3Q=z5Rq1KpV@ zm|6bYT=HuL91VXQYLF}6`@&Et;07*qoM6N<$f`kbGm;e9( literal 0 HcmV?d00001 diff --git a/src/engine/render.js b/src/engine/render.js index e5adf31..0636e24 100644 --- a/src/engine/render.js +++ b/src/engine/render.js @@ -226,28 +226,7 @@ const scratch = () => { if (!scratchCanvas) { scratchCanvas = document.createElement('canvas'); scratchCanvas.width = WIDTH; scratchCanvas.height = HEIGHT; } return scratchCanvas; }; -// Una nuvola a pixel: qualche cerchio pieno uno accanto all'altro, la cima color panna e la pancia azzurrina. -const cloudSprites = new Map(); -function cloudSprite(n) { - if (cloudSprites.has(n)) return cloudSprites.get(n); - const w = 34 + Math.floor(hash(n * 13 + 1) * 30), h = 18, c = document.createElement('canvas'); - c.width = w; c.height = h; - const x = c.getContext('2d'), blobs = []; - const count = 3 + Math.floor(hash(n * 3) * 3); - for (let b = 0; b < count; b++) { - const r = 4 + hash(n * 17 + b) * 5, cx = 5 + (w - 10) * (b + 0.5) / count + (hash(n + b * 3) - 0.5) * 4; - blobs.push([cx, h - 4 - r * 0.8, r]); - } - for (let py = 0; py < h; py++) for (let px = 0; px < w; px++) { - const inside = blobs.some(([cx, cy, r]) => (px - cx) ** 2 + (py - cy) ** 2 <= r * r) && py <= h - 3; - if (!inside) continue; - const top = !blobs.some(([cx, cy, r]) => (px - cx) ** 2 + (py - 2 - cy) ** 2 <= r * r); - x.fillStyle = py >= h - 6 ? '#c7d4ec' : top ? '#ffffff' : py < h - 9 ? '#fbf3dc' : '#eae6dc'; - x.fillRect(px, py, 1, 1); - } - cloudSprites.set(n, c); - return c; -} +const CLOUDS = Array.from({ length: 8 }, (_, i) => `assets/effects/nuvola-${i + 1}.png`); // Un effetto o una luce vale adesso? `when` (condizione sui flag) e `phase` (una fase del giorno o un elenco). function onNow(e, game) { @@ -402,24 +381,26 @@ export const EFFECTS = { ctx.restore(); } }, - // Nuvole a pixel che attraversano il cielo, lentissime, ognuna a una sua altezza e velocità; uscita da un lato - // rientra dall'altro. Si vedono solo dove lo sfondo è cielo (skyMask): passano dietro alberi, torri e tetti. + // Nuvole che attraversano il cielo, lentissime (disegnate da Codex nello stile degli sfondi, assets/effects/): + // ognuna a una sua altezza e velocità, uscita da un lato rientra dall'altro. Si vedono solo dove lo sfondo è + // cielo (skyMask): passano dietro alberi, torri e tetti. Le due grandi solo coi cieli larghi (`big`). clouds(ctx, e, time, game) { const bg = backgrounds.get(game.scene.background), mask = bg && skyMask(bg); if (!mask) return; const layer = scratch(), lc = layer.getContext('2d'), [ax, ay, aw, ah] = e.area; + const pool = e.big ? CLOUDS : CLOUDS.slice(2); lc.clearRect(0, 0, WIDTH, HEIGHT); for (let i = 0; i < (e.count ?? 3); i++) { - const sprite = cloudSprite(i + (e.seed ?? 0)), speed = (e.speed ?? 3) * (0.6 + hash(i * 7) * 0.8); - const span = aw + sprite.width + 20, x = ax - sprite.width - 10 + ((hash(i * 11) * span + time / 1000 * speed) % span); - lc.drawImage(sprite, Math.round(x), ay + Math.floor(hash(i * 5 + 2) * ah)); + const src = pool[Math.floor(hash(i * 19 + (e.seed ?? 0) + game.state.scene.length) * pool.length)], img = backgrounds.get(src); + if (!img) { loadBackground(src); continue; } + const speed = (e.speed ?? 2.5) * (0.6 + hash(i * 7) * 0.8), span = aw + img.width + 20; + const x = ax - img.width - 10 + ((hash(i * 11) * span + time / 1000 * speed) % span); + lc.drawImage(img, Math.round(x), ay + Math.floor(hash(i * 5 + 2) * ah)); } lc.globalCompositeOperation = 'destination-in'; lc.drawImage(mask, 0, 0); lc.globalCompositeOperation = 'source-over'; - ctx.globalAlpha = e.alpha ?? 0.92; ctx.drawImage(layer, 0, 0); - ctx.globalAlpha = 1; }, // Lampioni: un alone caldo che si accende (di solito solo di sera, con `phase`). lamps(ctx, e, time) { diff --git a/src/story/story.js b/src/story/story.js index 22e27be..9403dd1 100644 --- a/src/story/story.js +++ b/src/story/story.js @@ -249,7 +249,7 @@ export const story = { name: 'Piazza Colonna', map: [32, 45], background: 'assets/scenes/piazza-colonna.png', - effects: [{ type: 'clouds', area: [180, 10, 420, 90], count: 3 }, { type: 'windows', phase: 'sera', rects: [[16, 37, 8, 18], [48, 42, 8, 18], [50, 110, 8, 16], [97, 77, 8, 12], [122, 80, 8, 12], [170, 90, 8, 12], [204, 103, 8, 12], [239, 111, 8, 12], [268, 117, 7, 14], [287, 125, 6, 14], [97, 130, 9, 14], [127, 133, 9, 14], [170, 142, 9, 14], [204, 150, 8, 12], [239, 155, 8, 12], [268, 160, 7, 14], [287, 163, 6, 14], [386, 163, 14, 16], [424, 160, 14, 16], [472, 157, 14, 16], [524, 155, 14, 16], [390, 212, 14, 16], [526, 208, 14, 16]] }, { type: 'birds', phase: ['pomeriggio', 'tramonto'], area: [150, 20, 460, 80] }], + effects: [{ type: 'clouds', area: [160, 0, 440, 80], count: 3, big: true }, { type: 'windows', phase: 'sera', rects: [[16, 37, 8, 18], [48, 42, 8, 18], [50, 110, 8, 16], [97, 77, 8, 12], [122, 80, 8, 12], [170, 90, 8, 12], [204, 103, 8, 12], [239, 111, 8, 12], [268, 117, 7, 14], [287, 125, 6, 14], [97, 130, 9, 14], [127, 133, 9, 14], [170, 142, 9, 14], [204, 150, 8, 12], [239, 155, 8, 12], [268, 160, 7, 14], [287, 163, 6, 14], [386, 163, 14, 16], [424, 160, 14, 16], [472, 157, 14, 16], [524, 155, 14, 16], [390, 212, 14, 16], [526, 208, 14, 16]] }, { type: 'birds', phase: ['pomeriggio', 'tramonto'], area: [150, 20, 460, 80] }], walk: [[84, 244], [330, 238], [345, 230], [362, 238], [462, 246], [466, 276], [544, 276], [548, 248], [588, 250], [600, 290], [640, 300], [640, 360], [0, 360], [0, 330], [84, 318]], depth: [[236, 0.5], [360, 1.35]], entry: [345, 240], @@ -1144,7 +1144,7 @@ export const story = { name: 'La Provinciale lungo la Carza', map: [66, 73], background: 'assets/scenes/verso-luna.png', - effects: [{ type: 'birds', phase: ['pomeriggio', 'tramonto'], area: [200, 30, 400, 90] }, { type: 'clouds', area: [180, 10, 460, 120], count: 3 }, { type: 'fireflies', phase: 'sera', area: [200, 210, 220, 80], count: 8 }, { type: 'sparkle', area: [380, 288, 200, 30], count: 5 }, { type: 'sparkle', area: [430, 210, 40, 30], count: 2 }, { type: 'smoke', at: [113, 116] }, { type: 'lamps', phase: 'sera', points: [[165, 93]] }], + effects: [{ type: 'birds', phase: ['pomeriggio', 'tramonto'], area: [200, 30, 400, 90] }, { type: 'clouds', area: [160, 0, 480, 110], count: 3, big: true }, { type: 'fireflies', phase: 'sera', area: [200, 210, 220, 80], count: 8 }, { type: 'sparkle', area: [380, 288, 200, 30], count: 5 }, { type: 'sparkle', area: [430, 210, 40, 30], count: 2 }, { type: 'smoke', at: [113, 116] }, { type: 'lamps', phase: 'sera', points: [[165, 93]] }], walk: [[0, 360], [0, 200], [168, 190], [182, 196], [330, 360]], depth: [[192, 0.45], [360, 1.7]], entry: [150, 206], @@ -1764,7 +1764,7 @@ export const story = { name: 'Castello del Trebbio', map: [84, 6], background: 'assets/scenes/trebbio.png', - effects: [{ type: 'clouds', area: [200, 10, 440, 120], count: 3 }, { type: 'sway', rects: [[237, 140, 20, 60], [165, 160, 20, 48], [305, 132, 14, 30], [560, 120, 22, 80], [600, 120, 20, 80], [620, 100, 20, 100], [530, 160, 20, 40]] }, { type: 'fireflies', phase: 'sera', area: [80, 290, 440, 60], count: 10 }, { type: 'birds', phase: ['pomeriggio', 'tramonto'], area: [200, 30, 400, 80] }], + effects: [{ type: 'clouds', area: [180, 0, 460, 110], count: 3, big: true }, { type: 'sway', rects: [[237, 140, 20, 60], [165, 160, 20, 48], [305, 132, 14, 30], [560, 120, 22, 80], [600, 120, 20, 80], [620, 100, 20, 100], [530, 160, 20, 40]] }, { type: 'fireflies', phase: 'sera', area: [80, 290, 440, 60], count: 10 }, { type: 'birds', phase: ['pomeriggio', 'tramonto'], area: [200, 30, 400, 80] }], music: 'assets/audio/ricordi.mp3', walk: [[86, 308], [300, 306], [356, 308], [470, 312], [500, 324], [486, 360], [88, 360], [80, 330]], depth: [[306, 0.75], [360, 1.05]], diff --git a/tools/ritaglia_sprite.py b/tools/ritaglia_sprite.py new file mode 100644 index 0000000..cff240a --- /dev/null +++ b/tools/ritaglia_sprite.py @@ -0,0 +1,43 @@ +"""Ritaglia un foglio di sprite su fondo magenta pieno (#ff00ff) nei suoi pezzi separati: ogni macchia (con i suoi +pixel staccati vicini) diventa un PNG trasparente, rimpicciolito di SCALA, in ordine da sinistra a destra e +dall'alto in basso. + python3 tools/ritaglia_sprite.py assets/generated/nuvole.png assets/effects/nuvola 0.24""" +import sys +from PIL import Image, ImageFilter + +src, prefix, scale = sys.argv[1], sys.argv[2], float(sys.argv[3]) +im = Image.open(src).convert('RGBA') +px = im.load() +W, H = im.size +for y in range(H): + for x in range(W): + r, g, b, a = px[x, y] + if r > 200 and g < 90 and b > 200: px[x, y] = (0, 0, 0, 0) +# Le macchie: si uniscono i pixel vicini (dilatando l'alfa) e si cercano i pezzi connessi. +mask = im.getchannel('A').point(lambda v: 255 if v else 0).filter(ImageFilter.MaxFilter(15)) +m = mask.load() +seen = [[False] * W for _ in range(H)] +boxes = [] +for y in range(0, H, 2): + for x in range(0, W, 2): + if m[x, y] and not seen[y][x]: + stack, l, t, r, b = [(x, y)], x, y, x, y + seen[y][x] = True + while stack: + cx, cy = stack.pop() + l, t, r, b = min(l, cx), min(t, cy), max(r, cx), max(b, cy) + for nx, ny in ((cx + 1, cy), (cx - 1, cy), (cx, cy + 1), (cx, cy - 1)): + if 0 <= nx < W and 0 <= ny < H and not seen[ny][nx] and m[nx, ny]: + seen[ny][nx] = True + stack.append((nx, ny)) + if (r - l) * (b - t) > 400: boxes.append((l, t, r + 1, b + 1)) +boxes.sort(key=lambda bx: (bx[1] // 150, bx[0])) +for i, bx in enumerate(boxes, 1): + piece = im.crop(bx) + piece = piece.crop(piece.getbbox()) + w, h = max(1, round(piece.width * scale)), max(1, round(piece.height * scale)) + piece = piece.resize((w, h), Image.BOX) + a = piece.getchannel('A').point(lambda v: 255 if v > 110 else 0) + piece.putalpha(a) + piece.save(f'{prefix}-{i}.png') + print(f'{prefix}-{i}.png', w, h)