From c836ccbb219969f45e72b6c0f6cafed61e8f22a8 Mon Sep 17 00:00:00 2001 From: Jose Luis Date: Fri, 20 Mar 2026 16:02:44 +0100 Subject: [PATCH] refactor: migrate world rendering from programmatic sprites to PNG assets Replace pixel-art drawing with pre-rendered PNG map backgrounds and character/NPC sprite images from pokemon-js reference. Maps now use coordinate-based wall arrays instead of tile grids. Co-Authored-By: Claude Opus 4.6 --- assets/character/back-still.png | Bin 0 -> 8352 bytes assets/character/back-walk-1.png | Bin 0 -> 8343 bytes assets/character/back-walk-2.png | Bin 0 -> 8352 bytes assets/character/front-still.png | Bin 0 -> 8360 bytes assets/character/front-walk-1.png | Bin 0 -> 8354 bytes assets/character/front-walk-2.png | Bin 0 -> 8360 bytes assets/character/left-still.png | Bin 0 -> 8371 bytes assets/character/left-walk-1.png | Bin 0 -> 8372 bytes assets/character/left-walk-2.png | Bin 0 -> 8371 bytes assets/character/right-still.png | Bin 0 -> 8369 bytes assets/character/right-walk-1.png | Bin 0 -> 8354 bytes assets/character/right-walk-2.png | Bin 0 -> 8369 bytes assets/map/house-a-1f.png | Bin 0 -> 3448 bytes assets/map/lab.png | Bin 0 -> 3489 bytes assets/map/pallet-town.png | Bin 0 -> 8842 bytes assets/map/route-1.png | Bin 0 -> 17163 bytes assets/npcs/a-down.png | Bin 0 -> 2107 bytes assets/npcs/a-left.png | Bin 0 -> 2067 bytes assets/npcs/a-right.png | Bin 0 -> 2062 bytes assets/npcs/a-up.png | Bin 0 -> 2063 bytes js/world/maps.js | 459 +++++++-------- js/world/sprites.js | 894 ++++++++---------------------- js/world/worldRenderer.js | 107 ++-- js/world/worldState.js | 8 +- 24 files changed, 479 insertions(+), 989 deletions(-) create mode 100644 assets/character/back-still.png create mode 100644 assets/character/back-walk-1.png create mode 100644 assets/character/back-walk-2.png create mode 100644 assets/character/front-still.png create mode 100644 assets/character/front-walk-1.png create mode 100644 assets/character/front-walk-2.png create mode 100644 assets/character/left-still.png create mode 100644 assets/character/left-walk-1.png create mode 100644 assets/character/left-walk-2.png create mode 100644 assets/character/right-still.png create mode 100644 assets/character/right-walk-1.png create mode 100644 assets/character/right-walk-2.png create mode 100644 assets/map/house-a-1f.png create mode 100644 assets/map/lab.png create mode 100644 assets/map/pallet-town.png create mode 100644 assets/map/route-1.png create mode 100644 assets/npcs/a-down.png create mode 100644 assets/npcs/a-left.png create mode 100644 assets/npcs/a-right.png create mode 100644 assets/npcs/a-up.png diff --git a/assets/character/back-still.png b/assets/character/back-still.png new file mode 100644 index 0000000000000000000000000000000000000000..4b75198b2732c64ba84dd3d145adafd421934c02 GIT binary patch literal 8352 zcmZ{~bx<5k@GZKyJHch~;1GOqcY;fB2*KUmgD(=?JrE#BfCOi8*8q#V!{Tl?-+lFa zRj=N?HPzESa{Bz&Refe+)Yas%(8r0H&a=w6wad zr6mBM5R;~dqOCPdmT#y@(eJFtLs(XA}8i0(DGk2vr?O+|eF*7Fa)`MGaS)YzuZc(2Bql51WgS;=6o3_ zWK7K9i%xUbAaqNrkVqNKxePAf4$gQMSq#Ck*Pr`UX6||^)Z4x~mWN9-c!YZw%~M=V zGaq^%u25JPMN;-Ad1XmctM-mU0T#|xzA}&_@f;6ibm!r=mvhbU1 zKX(ePp=8?{)^{D;(sAtlf)|9ZDMneV@~D2hsYALX`rm-)oWKe{bL%^!s+|pJwi65a7Al{1{@pX@0MUUOmvAigi`U6aR^eHdpVw5ChGRf`5NYoez=Y&fR zK?nm744I7s2qds^o9=k8yM?VjqHe%355Y@qR9GO((X;yX)g_?xZ+wi7C^U01DlFDR zjRn4WCh0VTfm+jsr6kE1`4YJ}v=UV98O(AqC>;!;gGqQVy}~%UV(|hvy1s8+R|qHG zU$L?j-qDet5B;U6qemtPk2deaEv9see%ciCp?5$q^Mn}uS?Ct&TqelJ1)<`gEuiK_ z7;eil%oG$;Ac2a4qFIPZ#rNQUf6a#Z0AUz&MIR=*u|nx!$S-xS!3T?!4HP;nm(^Us zGq1~-K|W+G!m&I^Wtc^X>JGtFmFBgZVimNLH;E4#1KHe}&J$*nldnSJpG^U^c;bc@ zSM@JY(i224Y~e6I0ONc-pM@h-Lx{@AIPqPTeYasQZN5GZhzWox_?J7uGk`XBkBVT1*wTQ z-~uE7sK}c@GWrlgE^N61tc4ar75Le12X*uj2!0)YH4=IEmpaN5_$LVjL3p*0*$wzV zh(AMxU2Z%=i3^F_5eo1SX=r#Oz$C!(=yzKoe}HU#IB0UT$%6Dqit-J(+_ci=H10`m zpGg~t79;)w{gb7K&~_+hLRX}yfU86HI|Q*sM-?1)@t;b1HHb#!=%x@o*s>$lWa6e< z4ro32J|)0pj;9F@kgmy=Vmc+BxI!w;F~>07`}9dr;s!M9Ra9cfyGQEKtI4W*vp3v3 z!#piSq4K%Wv#yLVR6Q4x{OGHTn0w3snogp1@WOV@{kvzlwYXrqDO5Q`lrVu%WfIjP zS{2$wR~lDJSAh$``tbW`s61^lrUEv- zsU~lXJPUnV%6yVnO15H#qH!tCXTApJ#YhS%HHNrhh8^@v>`U%Tt4pm*>sX@x*e%tV za@6-)@8g&a->as^rE-i||KOkddZescxTkKdrKfdV@x8*k()sV-zhiUle=X)@?0)^# ztvb~ZuDX>tEolX}c7WtXRgKF#6#{b}U2hDJoNais`Pf6!l~_yJi|3})W?-{oHdB1L zyno2x6SBzC$Zp6o_)P3Hd24tVv$uKU_*i-G>`nfjOc&c2*t<6ReBxcA4#KPSHAeFG&PkgSGH6kQ#<9~d5dKQL~UF(x&FafpM&Qt(u5ZiVAelcMSWb`N`jaNJ)CLAyzxwL_D|LKY7HkxT$)mXek=Z6jqZ) zrPq#e=5VHnk1`I==DW(@hC^&|9g^(p{uV+u@@brGoJs5jhg~{0nS1k#TBQTOUPh&3 ztqNQ>nJdFO$l5w@%LrYvM`4D~f z%j~|2C}U36pwYO4)onIuR%F)j7=Kn%P9Xnp?vK2j-0O}(lVNs{hM`7%^J$A|ds{o9 z5w~osnq5cM*mt8W%XVpVq*ZtG{PV-}SJmXz1&asEE{?H|c8;*68HX1~rX}5FlP0>Q z`V+U)`9^0 z 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 it&4}PvlBqZ*4@Ry+?SX!$dBem5n}`g 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 z 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 it&4}PvlBqZ*4@Ry+?SXef4`) zuim{i)zdw4`ux{beP&|SRpl_zNznlS0H%VxwB|n#{Lc^({>@?9HbVfwI{`Z>DRnzb zO8`JVHeC-zTWf^0z)+K_NgS~(at$$sR9q32E%b&uMo}I<63-G?37wWfT3{!vFRrGJ zqrkz4gBlP7n6g$f9$P?ubSS_X`>gxzj|+0&x3526zq~#B?5zm_Y$^8@X#FY)0S{Y} zc1E^94^KtruQvqAVOZj!3}zQFBs_0rW!g~djYla7fUl478ocX(#t)>|?h-Z}!i!?% zcl{*c@WG<}D1e@77@i#!Kw8j+t4f`Es2<*!=^f72gL__izm9ueaen{-ADSC^j3FGb z`r3Df6~MzTQDD$N8BR*ti6az`M9l@rQI2`Jx@JHHszyTzm*jyN$3H&?PmMh0ejY5M zPs-$tN%znoa8IrjPaVp=3aQu*$$S=G48?ZPpZi&E?sg^E*RlF1ABSq_2g2i7cc#;61O`P!2_8XM+n1L0vCr&f}DCHK2H0RB)bHMz27ye=&MZB z3S!JHRRISpDp+sPF-p}9EyPUiwPHgNe^YduXYUVC|qt0X9&nTmG(F%>c{N#6B z?=8ltH8ctONpXbU?+nUSI?58-c$6SJmNg3aJ!jwyp$!y=DF)RrYLVi7YvdT?AkN}w z;WF$`)Z7e;T0}D+eKxBNET9e+AUa7^|D#Gig-e(KCeMl&Cnl)L6S`AoR87!33`{0K z9%LHY(pE4@7^UPV+KU?X^N3kRkK59*yeyOa4NQOZttjK9mmpy<$?L;N(in{3fJ+HQ z2nXN~n~ekT#j$Xj?|E)|gsjz2H{h6t;UzaJEs$ktS^WF!6Hx{>)M6rw%v_C%O7u|U zfNx&OIxS$J*0f<6aSBF(cpf&jIAupBlWZ(XCtcW3GVV*C5Vo#p0zbB{-&^-J!imop z%xwAhG-MaUf641XlD4b)SHbs4D9TCjDAO^n|dW5@{@e6Q3sMu%=sQHnG z+cI=Bg(c)jpyJ>dW+D=?J@{W=a?X5#XBczEA18V+!)VTsU+UdL4i+gI$#qt)YB)n? zUYFkm`;syX#c?B*zbi&mcMPGdGOybdt)!m3O?uE6%;Cy%nJ}B2d=(V4G6mG(iWyp5 zH@rYeP7uAZgu;0N^z#Y47EVwNK}sXzr1#YhJ%)MI1xA%LkI~&>3@npYVIH*}zpja_ zO^aO{pD8c}@M*QmN@`9d>B)j|Bb9$-o%19dZk=qQhdw`*1O|1+>ICxR$S(UhPkaEt z`0nrTKfF#v@gvkP;5)xbtqU3wK6_Tex!&QJ(z9v0|L&mb`4vgOVu##=s1Gm{_&~G) z7bp%uMcxFG(uNXnV#yX_F0>LT!_W3Os-urW@apkukjQ#I*HfIpKZzp732Ma2^dCI(i-yx$7_4P@=dMw6vZ5uimNRb*w+aaF`Taly$t`0lw;KvmoRkGVBd@AkJARLvYnL_kr&52T#j-PHl zp!Veblz1k6JdJ;VbVIrn+a>p3!>r8q(^%oDGkz za4!oHs9avmtQ-9qs-7!xLCp1KEbLt%RTtqpcwxI1_Wl`eEk1;13RM;nC7eG@iCATr zTA4Zxj~Uev4F&DnhRG3i2Mu2AyAsT4{IdZ93oJKgH!3#@H~ve3h6q>;RE|33ojew; zsU}aX95Zct>U^?yYK}stf^iwP6>lTcVidWgDqZ{t-46N{))m*4^_A9@O&sAs+?Gmg z1uCN!V?2`~qe@zQ8vCftcfPqVM@lM1d+Ih?dRoVo-zt5oT>k$3`)97>uf?3S{m;L; z)u$Rl)pz2jrETE0PLQ04ig87kd{FMA+pXb|i!DzMFI#AaB1;)t$=sCc%-O7{?G$ew z&u>!r#B9=Z(p%C@UK4vwo?4#8oNbX zQftT9bJ$ZvN12D`^W7D1BcXOUj>!)7e~Ta+1ys(qF2oK3Bd(pBOnn8#ZBjvBuA(zA zSNU&RaP6&J2yA%fY=3IxY7{oax>Yvx`zBs0Y*XTYQ3zE4kD!0Gq+hM@)DqK5IYgiR zJiD(fLZ6#GWHjz*eV0R$9hE)uhcCN1H;C^Sml_WT*Sb^iWVk(~akxp}eA;5#!OmWA z)IG<#cGrm|?)@0^vVHm-N%j3a-~7n@bq!ff;o`xvt5cklz0=v!jN^+F!;_RY$(VQ*IV8n3{Oe%Clp zW;c6Rf58=Z-=mB2zR7oQdnadk`yB%h6R7#Pn>32DJc+)i7U#V_Ri3R!iXND5`G-pf zkE7!dm4lYG(+Z*0ptL99d&2uV$^uHwBv6vGn$o1_B=aO0tFi7o2dd*5A_&WrL&XAa zUD6umTGZN8$J>?L&B*QI=CxzlxcufY8_kD@oTsZm{s-?zu9uk?zDKXe+=uJu>X#45 z`iQ9TEy%*w%MBh-p+ydae1!5a6ohq;4#8Q$p@{mTsiMZBJG1h#ihM+Y#+S% zN0}AL=WsAfTBpZK&j+CW$_awxN(qUvwFyCZ{M62$ROLY1M`(;#A!fnWv8xJWI}>7#yb z!`Gn#G8+MQmzC+uoNd4D`)~L&UuS*FLN;ZtzxxG|tR#F-FcFRJj(d~D0qRp75I&-3 zq7{CA{LDTUn6aDNEL<(LEY?olF4vD+`@VA&ZEP|5T9hB;W9S@W;=Xnk=pO9(b{?)%g61Ilq{YLVn2(C|S?V;Idk{m=9l>Hzf}J#B*vn!E3#E`MNT1}cQ-2B$s{D)pFV&3lPC1kLHD5M z^k>yi51TiWEu+SoozuJ>K^2e0{fV5XgUl&YdnI1Q@^b#Yhd;}l9|}2g*1LMVAUR0u zqlnh~WBFq&qus1K9KvtMF{XNNOWlkf8c!BU1IL*-nK7A0rbpeLPajXM2gWGbJ~Vd( zBYDUy#{FU$suR}R)NL?-@0ISTvwt)^m*~K{z-n-9?R2-~kRF!aUY+orP`lHVLEpzO zsOPZ_bC7J5KX8e0$=5^cpyJW~_$Y3?e_STF&{1K@eUE?Mh1U@CSBA?=n@UHmN5IP6 zJn3Xk4uz}`;X+As=k=G{atAIHh;_(3k{ z&Z6z)FphO*JJ9`SsKu8qF{R4 zZ2}wI7;pLI>|*$6@p#rf7IOa(w1^Ucy)4!!TJVtee0aF8U@C8_8`Au=bi=l_y!!h5 z8jPkks`ZR+R$r2x4d_@y2CyLkK*EI@LyVIlap8=UHRy=1WV!{o?*|YQL25oDcC8v2HCeK*pR z?1iAM==nk*EvS(?q>Ikr=`1OFcA%>I$8~V@KBN~%>z4_Bizr5VK=HA+7(>j!p$p#b zI^Em{TCe?x=luxmn?AP*#khkYIBFSc&Z|8DoNg2@@2;WAudY0N@{Y+XLs*bpIl0(heYkUaAw0VQ zxUC{nrer7@e3XvDEBlD=sz1r>whU2BQqgD-Rvn_nj)h1veKu5J3O207HEp{roGgu+ zcsyW?dm|T%dw9!jEG!+5>J3n=L%YZIR=>-5+?efD7uJR^_e%0xUUcQ3xNu}WuLw|-~AV%-X^Cfl_;ZpMX3qC@T7YB0;o z!a-lM?H`cyh!fkwp`F85OO1irv~%WxjoD4gbQv;B!dh-;qxI7!8`GlqpI)5P?lD&! zq9gBSZ;Xm<@EK$$?dF@BGcI1T){|IgjiJ_ZFxO$vfUC!8kw_jdg&b7~ZQ~T(D_skY zl(#ZB6PzCfnziD}LW5IDV*0t_uOeQw*Q4YR-hO=gdr7sdK*M_XDo@=QYwK~+QJ36c zrht@qU1c%(YhRd4aM?Lt)CcO9Xoc?To>lA+G=#Bx?~uVQQz9=buq0m$Af&?Y({Aw8 zm7u_#ishgBu7{(yv_Gg%EUDMnDX(APAA$WJC|}tgL*igWz5~8I{U%Viq>80$P0*n2K$J4B5J;erp^8`Jen>!}A z0!O-ut~#~zvu|NDkAn42z74DM$7vAau`2j8SiZ_u@ra8O^2E^o&_*5M`w?Sf1b z849$|1Ugqs#BvhnP6Ef9JlT{#Hd>=`&29Im%>s6NVccjyC)qO4!P|idKw}_DYakz%6R}=+^GCEG zL{Hp5@|D07&n%X~(hn(?(xX?ly74FQGT(6XaBk)O!TNN2*4h^_=>ddEiBD@kHVP6< zWqVL}R0u)!IYr7!tnOP)SKRP@{2`m7?nYrMtem`H29 zK#+MN;&G(P2d4L$fyiLHD4r<(oGx4JaQ8Meq6eMg zPGNW@RG<17iqfT#@_&o>Nn#o|34&Y3r=B5nppgayUWzotpri@t8k;}xgks!BS)iyl zB8|s2DrHbY1dX-EvL`D#iUcgA@455=3p5~EOM&0~Cwz{cT?_?b4@Cc{|GTgEiE!SK z++i29*SlAvICE3q0XO3oN*=PkOJ)Tnp>RrTZkM_tbYp7l3V4;aA%I{mKo9Khr8K&@yORtVY|fGVMIN_|&pM znM@$II&M=>6@Q;bDoSK4ZAiI(ucGpd<|Ww4wWvNTO@!Ck<|w$Tf4UpsnI-n zk+n_I!c~(rTL^QBKH?|mp$K#g_p}LVQK7R6d`9M$%Q~?BjQKTx zzn9}OhmHnFj8lL>g)dNqFlGpyiyqgwLvE#x%Eb#zJjl-%?@33xE~Z{@J;PCHDdPIF z1PKbuR3@U?AioCJHxhGY18ej<4fWCtfQ(%90MPrRD_n~u?j;tA@q@0~O4o`6X@U{j z1dv66AR)Gl+90wVYiX$HA&;hY>5?D}`AomUIyNt@zmWz7Y}`)M*96srln6>zZEeU~ z4hS@GPUBt9qV`HFrpdSB5s{$LLWD(~3tWUP>o$fHG$#D3@;4&vFD2>9mV15)HNT>1>6x}ofDfMxl zRN!(z5+X(uC+N!Lebzhgkr^nO#PEsKM5Zw7ie3*?h4XvD8e%4%>_`pN0?QydR3@Db z)|<{6l?Uk)VVg#PE;1xjRHCp9NA*ZhbKpv2Mo|^V zd;*WUqp}LVoejGkI7gfweKJM2kR9%!%(YM+;7@pqHfh1z2nQSciX20uFJ4}Z6-CdK zRV$Dwt2t)yLC=l3dP~Gn2kpw*CHoumdaOHLox=|SE=yELIuQp0DHe>mr6y;OwBC_l z5j0k(Co5zNowz*5wq$3YLS23%{LR*ny7w_ga1q}oE2$6jgcAEvF2R$G@8I_cS_{A< z)8~QM`SwmAT;V6j{C9k4DIRzE4RZ9sPisnfA5^m)NF!BuGSWB*R@)$#>ps8)E&Oj z4NB{ZW|5M32V$7w&E~#mKjxWW7E0wi{%+HZazXy}FZ|O@t@aE`(JFJ*O89_I58`l` z*86aAd(PZSFk0rgD$0&cEFTxF`f)TPKvB5gDuto$}&9TBKp- zZVIWJU;FcKil9~T8A3c%Ka?iqfc>TK9@Qk66$Zpw7obWks$~A*Ml$8D{SGdMFimpO zngBc+rAHHw(3Dvd&7JM%!>R60Ro`IkdQ*=HB22OaP{8N!`?;v8PrQ-aLC=G*TfY#S ztF`;Kwsp$D^EX)SmC~@*M`GCRQuI6juJ4%wY8p(vJA!?JYvfP<67F#Y6Fw>RNxof= zf^}!L+uPTd)d$trcp1G5=L)Nwx3`abA3{LSFu_~V$)KP#%EBm7(Ars&+!Bm#q3-@H zBsAY`T>l)L4ger*{vVr5Unkf9p3d_1BvMN`-*p_ne?m-lL@SVjUum&VdU`(1_$m(n zb>u`HA2nlFSIJ)J>Ysf75Y^o!%i-P3`{kg+=Q@6YajDh+_F|eSS10qHU1BXWA=3 zZvSJ!W@Mdq8ukUEaJW-L%D{MlA7`s0FX+Q$5_9^a8g=S0u!X76{x!2M24)bAUH zynR7`SqA^YT-vsr!^yh;%=cOKvJ{0gt#ldrV`zpAIDP-5c*!O{g1QWhATQZCa+Fke z*!foyX*Q_OdU`t(JMd!Zapnwi@bmlN4X8P|fC8KYmo@~Up^;P+N0wK-;SBn&Mz(;) z_s3x-CH6OG+>$v-z8(#`1&nYb7|gb}B*pJ~W^sk(&(BDfjV$8wai-wl$&G&<*u_l7 z#ik?msP{R8pGqyY=R#Y>3FseSY!?hG?T1c$nW@)6QVwfbn!w+Yd2R^N*RdY)n)bd* zBh?-cA47@uPiDnu%zx^Re>5w2f0uq%t}&WpckGeat61eKP1)q0GFKN(8L*|8%6g{^ z84c4F$EYZ4x>Ba0=+>{um^tIa_VuTfACL3ScQtT=I2{; zmo!?gJa@Sn=HLfPR)d{)H~DXea>rixf9%frv_N(W=0svAScYb}AU_U_E5~w*zjcs8aI;5C7-}jA+Rv?>xecO zV3DxNbgPL<(5HgnkP}8?#?3Rt0-`r_6r#j2zPGi;zK7_wUdoV(~wH8Ef-Hs7F z(|If?ph$VQXZm-fSlOgE!^f=~`-vn}8o1aT_M%21?=$nPabARg`0;W}Hl)Ud9aNL`729HH&J8e>$hH`?Az4=VDRD@QE4E04kM^ zPfSTkwLo`Xgh@qOGl3~ju8cg@Zq;-G8QUOqoQ*tk51$XM4Y-iIwyGXuf$h`$$Qi=+ zj8x#A#n?(G8TMIzyTkfmhRJA-mu;c;kCx6;M&HxQ+|wFl>2Cec0X}km{(mIA zeE$#0$_LzE|AYCbqJb=3T>aebY-~LNQvVYHC0t$q32h3_mh7y+{}O%une^X>1ET+U q{=-;Vdsw>Lxq8~UI0K~ZJX{^k{fNlYfB(AzP>@lT{vl}={=Wc6GR0*8 literal 0 HcmV?d00001 diff --git a/assets/character/front-walk-1.png b/assets/character/front-walk-1.png new file mode 100644 index 0000000000000000000000000000000000000000..102108c20fdc9856332c87ad9074393a00226de2 GIT binary patch literal 8354 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 literal 0 HcmV?d00001 diff --git a/assets/character/left-still.png b/assets/character/left-still.png new file mode 100644 index 0000000000000000000000000000000000000000..41c6397f3259d071a9ca5bd8eff1315ec4ded78a GIT binary patch literal 8371 zcmZ{~Wl$VU&@Q^T1t&OU@!$}Aad-FN7Tn!E_#(mG0|9~rNN^T+4Y0U7Ebeylo?G9o zx^>T~sh*aZr+a=)RX;N^YAUjr=%nZX002{7PD<3#E$cx5;2poMq@cKjABgS_)TMurzWqsOixkY{c1iWajN6XfXuaUT^MKnVIXQKyUl%SRM}5;1SMUG*@vk z)qLoExLjdf6mi*?(H^|C+X~#S5CnH*VjMvXA8}k9GI4V1iMUv;3zDp29JW4}$ii>Z zkt>MNH&prTET~}JMTbG<=p)4ue7`dwTj3x>XzgB%>`>ak@B5sNGl7z=#?qNU@ z0rCLj;FgxWar_7+AJJaqh_8F}Dthdew#7xM#2;YVqfdD$2fa86gK=&zMxy#aI6GW& z2tpVDf5>zkfG>uH({#su-7RRPin;;EI0P@TQDKfOL(A;fSC@d&zo8l(QE2L7SXiu! z8Vh{$Oww)!12v}&N{N#(^2Ktosl_PUGZIu>Rv(PQnxs0EW146|{TR_c= zFxZx+n<*$JM*=hTp$yEEmZ9!7?!T{y ztW1hr8lEXI`SEErON*;dB-efQq~cB&7`@;J}h8z+7k{P=cTBc2Gkff#B8QRU?sgf2pH5fqxQ1;D=WUncaZ@ zgZML4(B;M>l&FxX9iadhk&22t0!$1nkAA-u@(0M$hm9sfoy<>*Brn^5!$~b!PUW8D zW=YaOxES#l=$|Y(gtkLI6S^Wn30xhr-@%V9I;vo^i~n5Gt4=r~LoPwc=t#hdNpZPZ}x_J zXPBqCFjO`-de)U5hN|mAoF9F45p(}8fU1*l9lWqzbN~JsZY?gDW(rjX5haW-RFPPD zh+2s{6^{wk01XB0`-brmbvq4S%)4UDX?$2efjO2dlPi@gg)83$e|`9UG*p&4`JEgV zt%(MAj4TsvTFQKqS4y^ghP+WJwk1yk<6QtSo3s&8VotCtMTRT9q!pcVFopOOWkFGZcN6t3f**vTv=?cuHti^LvDl@QI5t}KV zT<$-l@CjL@X{0x#89c^z8r(J9i`m=UaXif2clO4APo|4)^zB_6eLizFGBsh@u1+1z zmfI&zf#)X{j4L`MpK@=xC{n;pDs^Bn>z@-}^1gu*4~SR8CW@{O-46^7z8@I1N*R$E z{d595wZPa`y;hBdDTMhtXgh}e()?s^KqSPy*$}H8PC~9*&YxT&n4FY7l+@%6rgE!E zqmpaK*mKxZL`NBiXY*aVloQDNn^TpWopaqWXfn(W(lFGhXEtpN# z@HjFKQ9fv1J1rMn4NQF!x+A=+rOc<)NCYK1sVYu-OfpT9u^8#Rv!^<)CW0_e*_SWi z)+Vk|u0^grwZC1uUJu_aZeBT*j>~NhvC@2a$bPyE;Ct|T z`bn-ze*a2|O%ovWVDPL)z`80r-s4q~?JT6?refp@E zQ~zx+pUj${&3R?|B756+`|dmb%(q$Z(%?<$s~^6BBrEYh;*CY3x?1`S2Bh!iGznD+E{nENx5@V5*1Yc+K^t96x)R|7c^fzd8@sK+0^EZ9Ua9KA z{JJY3h-J?X8U-GTd}XP7@m*gUzJD3+ObwD81R6FVVRTQkPX8y>ptoBcSY_us@OgbdWJ+VyDQXP*%pb_b|51@u7e{d%d&U6OxUz zK7weqKbkknJkrIo!!Go89Brcew$$~}UH!>CvHv&&CnGw;(B!DgRsSd@>xZWH zAS8F`#n|7>gSA4sn>zJo?>*BTwD*sO<`V2#7FhJJtQ>Eb?9)Qi+N$Dz5NdUpFz9*v z26jKTVh)gv@C7V=T=H?(JScy(J3fjX?;DrSDR7Wqa@*sZcjhs`{GIOn(yH8EST%V**JKv^f-y#KIv-LY^dePX{jxn$zq zeIzy~{s?LCD-BWzbe8mzw6;*N7%V!MWK|YXM!^=OSo7*Tk=s@8D2Yo{PaGGXUpHJ? z@iug8-2nGo32(-nSw?TY;@Zdu%$4SHmlpB%WfFgI`1lc@iJ&QH?KW}jDDiJImN&WS zGQJF!H<){v0)!4tI-i($#n8@-}fVgfbQQYml58a zoB(y!7(zkff#ci&a~lAy58U55&pNE!If8u!U#cGW?g3~m$pguTN$lm=gXD^+NvPo* z=5xRc_DXwz2l^b^m;V|H3povC0KktP00@Zy03QE^LJj}`PYwX!$P@qoWdZ<1F1fAh zLjM-9)s(cP-`?K-ncY7J@9*#b*?Bf)_5XZ04-FMffY=`NznpO9in3CGXe0``e-4_9 zoW45%fPw#?zyY#ziT?#rJmi(7QTEZ0FaZ3E@1)8B04#MsEje5 zuZtD%e|I-}ku_QRDYVR3(r^0G><~CAQ-Sy|9dDS|$=J!b`dK$8S)P{alwdAYOkG_{ zSeM10xASBgWN)Z-qGX`RWzjb3>&Z+dvmzFwTsjU|OGBBJT-G>iaF<_*4<(%D&N$C6 zA?s{wHW`a#@Z}-sZFGOd^H-I>(+QVFCj0Q~?%+$?=314_i2Al?4lD>$rN7nF7`ruB zw=x{zgTT(QaRD0DUi=>T`&%caG5L|uoR9FwUEjiojxMn7+u(grJ3Fo39-j7KlcWH$ z%(;M#$k{>wEvSJyxRXx*36>Z&+h1Ar^C~E6AJT)P`P&%3Sp*}^zv$RYlp(tR&>3%c zoo?;}t>=FD^L{w?aX?@!uC_cK|v#Pq0i^3u{}($|@+ z0_irVLq;JCqoA#Y?pX2k6|b8GsV@m4|3Cqrno4Ukv0KgA6KgO**fT|%s{q2 zl!LfPBt_(fqOYMu{^7cWKLUFDCDOmgDvv)=llo2Wksen^ad-6DWL{k5c{j_&Xp5;? z?Qv-%-G)d~5zR!l%`3e`-!RxJ(I5UHI`ZodgH+Gz2e_kZ;?3Q~1?iOh7NyR90xSo? zZ-tam?H)|f>Y~_muqs6!mg5X@VT>L}GVZLW_Nykj_A=U*eM0`ipZq+KA3a*z$KtH- zq*MAws8{ZrXE~+MV`fyn_HCTfdtQ*8#X*TZ^v#^qJ;ho~$9ObTtd@Q3@OAIz$n{cT zhP50$kb=E9 z!GI6h_D{%J_=!!y;LhQzg?fKY>KRl2#_T3#nlzaOVGWm);reN#wMpUo&o54?cbF^o zQ4zPZ*M>#b_zW_Ww)2fm>E|z*>xnG0Mo=r+dzT>(|I5c|;RtR|`D_&kZNn7ZD_t{= zq?ZyGBb+YgLfV7}gfeDnSA$J5MbU4?o-vv^(Y>svk|lYsF?4_2j54OVEJbK8BXvw+>6doDDfqs$?aHUU@gA)y*KVFint zej#V&e}ii{0A(F?&V|aBARq&S)L49`=d@yX(h)5ai36{y|9-Jrl7dUtu_a?lvJu)R zpnUNGqQWG46NQ>@qMZ+O&BF#Hfju?~n@ou80x11-V_pc75*(h{n)_wrMZ!x_?p zTME8A-n|SoD1^p(cF0&Bt3U4tfI>HJs z0A!YccpRbpf$_aY05aG%k~>nXavEfdF5z9qOsXUD_M8QbQLNfwu`m~ol(U81uK_qs ziyTc3#3yE@)x*Fn>0E5di$c9xzZ_5$Ar>FK82M0xD2or2s(0n-#(w$|DNKP8oQrwX zB#+dmtRTt?o0PVS_E>}E;qq3yB^&W`2F-GoNiuuTs5ITQ;$MWFe4Qodp!*5>w2Oo! z$56ats?WU)g=tbqd4I%uB`}Q|1;EYYQ_m1O&~QBh4@D|sVB!RHjnxl$LNV^G#9!DG zp33bKnLHpajK)%J(VZC;Ndgws^H}&Fp+QctJZX3>J6vbILE$9i7a9i*U^Io$Y z%Ndd;gN=DPKppJ8zUyiW6>GIUn+*&<1Cn;aV;MXGY^I~c4RG~sLkH;9Z6oJh4wK2{ zl2DZo1e0a!52bT5W{R%xJ@g#V`R_L>@hfcqe&Yhf!88l zCJ~6Pj$7AJ#oeWniV)dI8BnfY`dXWG<8G~J9^GqXvpWi!(DNw?QAN>cpLV*2Mt^}2(a!4(+2W7qefudC;!=lp*)gU+=qrS6!OGu zWnuRG7@P@efLH2k=al&sNy86X#A!}h+;d0qXzUKNS2FfAO4Vn)r2oC!B? z#&}-Kk2QXa=?H$G`5u1kTQ+Y*&qA|g=C{&WxoWx)Z7Ll!*9ZU^B8xXpmR3(MQiEC2 zB1@};xr+vAmLTR5efTeqLt*GB?r9^^@C|n*m349agKvWxWK(gaXhWimYKS0{?<7ZB zJ)pu9c`9NRaHXRL+7$+Zr3ZK6aVblOR7d5Vai`+sTnS&RQaFCZL)}4lQRYbks0>e>mF68{W z1PKhyP$Ht)Aio0FH4t-V0ju>o40KcVfgd^P0igFsm$>FjTuaOp;|HBJ6)xrRQUt@a z@gVbj0YYqP)d6H#mXZ*WLv9VLk|lwAWSCyLRZMPbUjq#a*r<)Bw-KrfDHf2Z+}e<{ z=;yEJn8v%9MeUJNNR?~BBO*bgg$Ri_knD;S=I-HP-u^`QgSLv%A)U%iP;}AsC)dS# zP=U(;iHI1D9H2|%_nGg!hG(E?;zK8r6B$A*E4tlKWsV>5YlsZo(2$q58Hwr7+ z=i|B69F&ytZLQgC!P#Q;=#$Ah1#EB+r7i_>06)STv`KTG2DtmtZ^+R!dSYcoSdsLM znKk?wG8&`$A9P)rsc(1FW+Y(ob79OC>3;cu2+g0t8*S#e#c2b9>CatWSfdah}FrXVG;9l#-A zgH=p|4UzHCozSpjDE8;ZGqkf8tkeeAug0^O^`m1tL!%KMxk^i{O~-Pz3MaiRL1*Y% zCor`$idj zn(xEF{PMO7+)S>~+W;|=fe2pa*a~SGRtks<(~wb({{~`NbC%($X`pjk3i7e(7_>#j zFrGzAKESgnvP}tV>39t@46P&2QhV4^2Wiz-n_@Q(@1FZp8IE>@FAZzcU+B9ZVaTK^ z;TbhwwQ7>&Mv{=bKNa^_$=F-9$tc+7aU55r%*c{)Kp0(c-5#jDS!Ox~IPey$ENmRY zJe#mE4}(%_BO*k@j)_YUI&+iwYa$vFh0~BlCC?27yT2}^fw?1iH-#Ckhkke>x+$F1 zFz9>+JMUR{CN3phT%$GZB6jm<$~2+Z(6|B9)P^k}AGv$UL+%^p{VWkfXjNPhaw)n` z&k*DHVH(J-#3B6$d6!wV{Q@gM3(WKQz9IyzkUx9% z0)V+OAy6YL78U|#g1-i<@%k+xs*dC9Oe%9U2c(x8+5%C!3pG%YJ{Ba^T zo;fpKz{rLymP*}xh%m_xK>lBT?B}4SJn=+q2R;wn-}nYw zU#{J?wyskKoW0%GTq+J}ej>iVS&Dk+*ZCuZUsav4XGfq{V2%9APuwjwf5JPtF43p+ zQJ@x9v%P(FQFTytg_qv5a3;UXadY#y_aPYcd@pb#G8q_{N?8yo0$PJ5$}Zj0E!5t@ zf)ucI=r4?x+XpR z^oDRYv9*0>nq)qi3@PK7YexJfLSJljqdqODq;AX)>GB?#cT9B8Zua~j4A}3$ME$X0 zz|$M}mwDjty>si9Qy5v-*nF>L4|8D{<4UKYABIL~zvGY33Ky(m!>G%^aPs1fBL@jJ z`<;JRBFzRhth=Wpp&c)V9%oKJ8$YiXUZ0ws6Ufiee_>4!5)wg0ab$7H6ULzDVrT&Ho5DjKO4cLsImvdlpwn?hHnvhcg8SPj2-4z&3g^ zHYN?JTdmg#{8VD0H5bw%MnL~?&w9?V(st;`n~`z_BxSdfp$YgCk?V>Obrs_tr(x%# zI9%oa@F|37|72Ed#_X5Q_$Sl+_qS=VGWC&c+hg~H9)(I5DauB-F&%o%;%|G7Ko-3-~upA(riqW9n7+WGxOob3Q%i@)+D z=JIPSH?bYWa?Me5kh!2l8eW z=)1926jqrz)?Qc=vJcFx&_^8`RgaG_k-n40XXc@Yu>R`~Gc=_7h2n6mYRA^hK3I&U@xr{j3lH$;n^FxS=+4`p&Jn zGAn?_`uICz5-Umox=To7^ABIM(5QN#rm~yOLbIZr__DN(n0&Y0N$X&KXAf)am9IPh z;+zk<9v!xaY|R6IslOBy90Hk?c=%JS;j^`53dU9lVrQmllUoBIx{c|caLhr>5tJJRfiW84qdfHoY^3sKv4bduHQX& zW?GH&2yclLagO0LKK`Z^XJYLXU6{AH)Qv{4OnG&aCm{Uq1auzKdLEW$9#$X=H>-aN z@QLFS7b}MVD+iAjCnt!51H>)B{BP#q=x(|%`TqbMoh@y@`2ODk^#@`f{sBJzzZE=e z9j)9w%>G?v|Gy$Uy#G&;l@GYT{|EDrPy<;wyZE}%?(io3Y{*8VS>;#aqb$4+v^Ccon`}1!LKwer!>ZgQh*#83m Cq|BrM literal 0 HcmV?d00001 diff --git a/assets/character/left-walk-1.png b/assets/character/left-walk-1.png new file mode 100644 index 0000000000000000000000000000000000000000..9477a52a3d38271c8694680eff06b8760068768a GIT binary patch literal 8372 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 A(f|Me literal 0 HcmV?d00001 diff --git a/assets/character/left-walk-2.png b/assets/character/left-walk-2.png new file mode 100644 index 0000000000000000000000000000000000000000..41c6397f3259d071a9ca5bd8eff1315ec4ded78a GIT binary patch literal 8371 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 Cq|BrM literal 0 HcmV?d00001 diff --git a/assets/character/right-still.png b/assets/character/right-still.png new file mode 100644 index 0000000000000000000000000000000000000000..358a93c79b3d444c20835c91dce187cd37146d5c GIT binary patch literal 8369 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 literal 0 HcmV?d00001 diff --git a/assets/character/right-walk-2.png b/assets/character/right-walk-2.png new file mode 100644 index 0000000000000000000000000000000000000000..358a93c79b3d444c20835c91dce187cd37146d5c GIT binary patch literal 8369 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 literal 0 HcmV?d00001 diff --git a/assets/map/lab.png b/assets/map/lab.png new file mode 100644 index 0000000000000000000000000000000000000000..42ba6082878bd23729cdee815c7d83e52fbd6c09 GIT binary patch literal 3489 zcmbtX2~-p37LMqFmep2Y1r-UwrKs5hSs>vddo`dCTacm*Gm{V@GcgGekVTD@`mj<3 z;V2*qQk1=Qqexh!7Am+Qs1+4dtcavofubPrW&o-6*;mhd$(fmdx&OW2z27%CC%e{q zdzcu`HzW`UCSIPdzS#3HcGbS8huw_>#);VDeYt0Vl0Yz;gI_ZU2eZrx1bwblMt2uxAScDZ(f9ovk4er4XO=nVpa(l)J#8QqLF# z>=)xL0%O8JE<|z?5FOP#%z+G60YtSd98vPreA0wp9yZ38sU+fri7Jdwa>fG^{e^3Z zE~o+~aw&8&NTbn-Y%T@hKrFT$lf_+0WY8E)Dve2HFv)Z#k7mbX*%7BcBrKo;67zgr z-KWA~Gd?L)rIPcg)TpQ^N)(fVDkM}om&>Kn7*qy>j9HMC(TECAlM$uOD-W))5>!a# zDk+K(agRU<8lmEoFtC$Z$mG**5#>~+u$ocTfSgLF(D1A#3?XpZP9C8Mp9l_tR5%=# z!H7zU+0v(N<)NqwRfeK};d*-ePXVy%3Wd`#-ik#gn+~B=xkX}WOcms<)=E*d9H#oh zN;Eri%Dn}$F;&dT-E@(Kazyf3Fm=h?3LY^0*Q~?MGd%5ySSk@G&6yiZ*nwSZ* zLdXn&Wlv@?05&-UW&mV5n+b@SbU1_tPiBFgcSXSnoLl_-q|zZ2#C-e_mCc1AmVF3= z9KysZ!h~2fG6!PAWDZ9h!eDXjAQp4ln~y?@y=*}E>t1nG&;%+DixDCglf_~&L}sz< zIb;r#E+#`T#9?!2Ts!QG>v=*VJWr_-BQJXD4e^7wOpU^�gdK01#I@p9JDG!w_j| zS^Cy`yhG%v^HHHN=JdaiKN($#id9j70(O>QwR;D7QU4M?ibTSS*AkEe3IOXgutLcv zi4~}f2*~B(QV_tirA8vq)Z07F4^f2@|4_?c#!&*1e^;b;5zS=wZxrc2W&ghwX^H|c z6hI^})~Tr^JRK_D&?W^yeN!6~d#^RWSLRqp#fQ_~9Ggu49>56ZT7h+YQx4 z%hg$=&eCO551w$Gd;Z#x^X_6-(ux%xk?-$6kw!VvWX}C=^)YN|Z{vjvK1Wj-wmWCN zcRQ=^=tAtn!kZ5d-LKr7W_T?lWw>H|pmo!QOy5t^1S8L6 z#i5sOxZ9p;zn+~?@@t}RkE+q5J7vTt&j0ygGs|_u&3?_t(yT2b zCFZF^uhYiB)Vy)_vD6f9Zoir`)zxA`RWgC|6R6b6fS(O}F03H*#jUDf>4(M4un3CBza$NlWdmtWmStl$u9e<{lKLgzhKEe z+263|^z2*%3%4_m4uIY3pUh3%QyHLhh_H4|nceA~d~h9lFM;8)Ltu30_V}C}Ft>7b zt3s(q4obJXbaP zXsqJ$(2emk(tp$A!am0YC+@~{Y--c4Ekv~OOTLN+etB4OqQukRB5$Z{@Ee=@Pg|X4 z##Y-mXp81vPpThTsO1(H*YQ3$$E>ZHwy7n!m(%B+{k%b4vc2tD zgnUC)WvFDQVVE}V)Z@p89~nJ4P;<~qJ$SR~2J;G()&o@I4jY&wEN(?{q)}cQ_@VQ#o6HHsKTvBqO>26F6}@J^5+~6T>or$uahBD z@5=@x^LJg|>RFuSPxa}0*Nm1Neso@CyY7t7LYk)T=i5C!731N{ey%vVb-WdQaWogn zi73y!TeKV;idV|;@x_wT=I4RT^NjX(dbXrjH^(3|FsNkI($jTc&C~2fy-QyZu4(QZ z=AYZ{Ppj>O258}o7<2pH+&W-e-4O$gi`gRgOXPDlVo7RF_m{%fkxUnhEl#YNy@@;9 zmp23{z0JILUr}Gx%&}o@T$x%sacG%7-+W;V?ZwQQ#-@A@y}PdSismOP^I&;*-7aUd zLpio7_p`IFsDD%4qkU^d>b(4=!|&#uz`p8>vHjW4eX1JVo$|op(Thi#Bb-=#_2RI6 zJH9%8pq|rSlsx+6@sLaZSg_pRz>IkD+^PrXjrEiK_IF~?uW0H3OJmcsq4J4H6Z3f{ zrZ@&14d=C#^pk>E9Ag@10Eg6Bo~)lVLqBPev3L5g8FB0K0%D1_&S|!8+!2afaq{E1 zUULIJbwlS^^xfEB`W?G|@Bdf+W6-8VJ2u?aN9i&@Cww+TY}xk({2}i0r>Ls~!R!OR zJq7E|>dFTSqP1V=ZK~C{onni|n}c(1eLos*C>_4(8CF&^_OLGF**D8fnp#F?z7FmbmPZmW`$dUcvP4suy47w;OJ$_LtVwt z9bv{JUGk2BZ~2_T(fSUdUeaXIV%-fmvECoO14THOkyoea#^hN~nZHnff?kZvn{JwV z0;X7;%l}6QSdgr)gfyE-v$Pn!#a5kVjWxH{3hpCL_L+UHf&a`}+*j9|d#8Mj-lS|y z`RZ-0LuRiD&%iToTwbWy*6L8vHS^`QAMT7H3!+B8^%{$n_flAcqy1L-AMMTV-t!;{ Q{}biq=IvU#DtO1g0g*_gNB{r; literal 0 HcmV?d00001 diff --git a/assets/map/pallet-town.png b/assets/map/pallet-town.png new file mode 100644 index 0000000000000000000000000000000000000000..953ee35f9725b80ed81d11bf141626d76b49b87f GIT binary patch literal 8842 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 N_9K1u3RRoP{{zFGmVy8P literal 0 HcmV?d00001 diff --git a/assets/map/route-1.png b/assets/map/route-1.png new file mode 100644 index 0000000000000000000000000000000000000000..05dc04fcec13be8992ca8b7c5a5dcd0b3438e08f GIT binary patch literal 17163 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 M=kmFNv$l8s7bT=tQvd(} literal 0 HcmV?d00001 diff --git a/assets/npcs/a-down.png b/assets/npcs/a-down.png new file mode 100644 index 0000000000000000000000000000000000000000..2c265dae1f929db8e8f09795ca31541c6e2fbe7d GIT binary patch literal 2107 zcmcgte{9rL9Pehf05Xv19|VHyI-=u8udnU(dMzBdt%Dum=CYmfj3n^d_wKIj`op%{ z-S!WeF=i$#Q4-KBgM|2pk;Eks6r-3W42@+S9WxFJDf zleVv~pYM;)_xpM8z0%vWyJ^L`6%<7^CA+mg@_r<|mo<`S^Y6DHc`bLlpYti|;YY)} zj+&TUOHqxt%ycHmr1q+YV?`ixbQ~#JEb(}Np1oO*>(+q8*1oNzv z0x7o>=gsaB5BHDsq>YgQLqW{W9rX5+N*q`?fON?!*uGjyFlE0g8HdvxLzf}JK!Rxx z1JapPFWu>Qm{uY@YXHF0G8si8$uKoB_);{=HnL{*YiK1x?EhD7vGR_)Vv zRpODa1d|T}SLL{3u^1_e5y#7MyrL)^5I8|#34-;9?Esco+i$IU(6DcKrW=@!O@|(# z?hFPAhGe@y!*XkGZNE|~QZ%jvU5<}{kX9Lpj2g}z^a|zR$l!1RTi6bKg5_&iH}3?F zpLdpUUHg4U08-vmsup9>Tr8^=!VkKJ2#rcX7DfB%VHb0K*mnj!19uIPG+RS9uG;Bg z7&uXL8UYgR4J;0JE25V2nO&U!N^dvj%Ptq4by@- z%(-@sp=&i(JDq~#k-#K7v7ALJr6z4ZfVP2?T7n@3iI^r*b)d%(k|7J?Fvdn97Fb0> znAP>D9tAo!1W~HmYmPA(w!LbPh<(h6At??Ki{!XW>_x=t2omMX&>*&114V1`pY}|$ z^kCtE{e%lL)Qj3}`lOS?mF3cpU#N@56<-dG`uL&zpujoi76NE$_v8f?$&hq-)%cM zkwAHh91G#Fb|#UJ+Np+ZQbdoOS*xTC`^b4Wm(<$R@$sYmEvsh0%HY(FmM7MKy}I#_ zmrfqJsXITlZa(_h__6duH`+5D7e0y2jehpbNkIT{L<95v1MnU(q8*i+1B*K z!O@A#ZuZMRJHG%d^)DAM|e6JF}ACIM!mJFB;a=tr?v^aen^n z;VmESZ@$iczvr-Vf`0w#Z_m%39?O4MQs0<41Kw%8db4@{Ns7Ao>gV;_M%NzsQJa02 zn!eVd&F!IXygh%eXYAKq6Kv-4&y(*rXd9>YajP%AIXyV{_{IGso%c?4rM^+xj_2#I bBoEb{|Md~e;4!rmmad4)A literal 0 HcmV?d00001 diff --git a/assets/npcs/a-left.png b/assets/npcs/a-left.png new file mode 100644 index 0000000000000000000000000000000000000000..08378e56f5281a859acb76b0b600e1dc7d8cd84d GIT binary patch literal 2067 zcmcgtUuYaf7+)h+lQwBVg{l>Ytq)D@-p=fwyWJ(%n&x5?>BW#7G-8X+&d%K}x!u|B zZgQ81kk*RzL9K!a+Cp3U&<9Z{t*8gKl~zd~6nyA|iaseKief>e3U&7W(blwG>w5xORk?4f3BYtf$L<&ZF(N& zgCSaWN9IF1IX_k)^V7t1#7!H)K+WO?JQ`zA^D2I1)v{v4uEod6v@C)KB%aQSgNZ{h zl^+K~ETq6pA&EeUK!%UBv|^ZMCX?9!6sV{&Ov{QcDXOJsETn>kF@;p zudG;(8^XB#w}xIX}iV$&c2yE#zoKLN|zA=7Yo{w%JUa z6?wEx8eY&b>qjlAxM*?>2Qo^*gjNISkPa@G2`dff4v}evdeo02jzt}8P-ZcU%Iq4Z zJHM}Rz~#;7J3f|-#q&BYqIh_g(`X5@Bswb01yr7(5t|7K9iHW3u1(kk)=)@s%)$a= zm3Fem+aUu*Pa&`_$qh7>bjnL9s-^;@WJob%_5-jkkBRFi{Q57mMsql(Sut5AAt*t$ zfOHEYOI04?PY9dPJagRQ+*MG$fS{#o7Q7P5Ys$ef{ztGwtRf3N%++u`T%vN|mqgIf z*cxIL7IMctI<*l+K5vcsQH*^;M{`+`3zBkO$5J&DQfwm0E;<=W(~u^aM7Jf!)^$U( zNztTD7JPkCV=u;(|trSePWGpA|`xbLxn#X?F<)Zj3?GY_&|e(d(qU z35!@UuHujmmbhB~uGZvhF^ll*^?7MJp=mp9NRXdAl9q-@8uU0}x8T%#5PhnZSd8Rj3!%JrH@4N7SVk#%6am`rOCT z{za+s)|%5F_5OH#an;mwx1-3s)JjCJijdSu}2ZN@9lE`NC%XjU{5?nC{Na4J+1K@c>EgEw>z^on*bNRJ z`}CCZ&da%Q`=h($&-&kec<=M?u`R|Y7tZwr$_c%1@>uZtNnxLV^e literal 0 HcmV?d00001 diff --git a/assets/npcs/a-right.png b/assets/npcs/a-right.png new file mode 100644 index 0000000000000000000000000000000000000000..c2b71d693491646459e0c9824b9e45251d310176 GIT binary patch literal 2062 zcmcgtU1%It6rN}(Yiy;ZLB*P8oIEsD=YMABhpuIlP23eHE}O+h5b51JcXo&D{5Uh4 z-OZD<1QZn{wiLpO6e?2Df)9O=7K`|(rKL~4ST+yhW5pI9S|r}tKiayjrHTVHbLY-? zzjMBG&b{Zo{KCsS#-14?2x3PrndOv8&EUbPavlQ8ZM9V2E9UCN#MNwWP1x^rIF3AcqEr`0T=)6SsE(%)=OiM3h=6m+=SBk1c zk*~9CyE}_LJna0if;1`u5+(hB6>RDJot@^Bm2IMPAl9 zUKfQI@RQ@ZP{T8At9chxF7li%OFDNa6xWmqBJhu36Y7>1H~>e(c0d`izFVfqL5%fT zuj&QZF!oODcwrcN&J82rLX^v-C>#*RwoP3`P=Tr?(j`d~XbB}{8i+7S^P*<)B`aBi z5cbz+JXnj<-d}Ix^;%NqBvnDQ7O#?23DE$_fEG9zQh}b5eq=)0o_;=!=IdPz5B%Kb0^h5c7G`v z*FIBTnb~-%`O*BzFA_WX6ZMH(no;;FpP1fz>6X8?_T&!})4MKycX?zjx_tHXZ=H|* U_BZ=Bj>a83H@A>EGjsUJUtD*J3;+NC literal 0 HcmV?d00001 diff --git a/assets/npcs/a-up.png b/assets/npcs/a-up.png new file mode 100644 index 0000000000000000000000000000000000000000..eb513da39b9709653a5c4f768fb76aeae1bf4e3e GIT binary patch literal 2063 zcmcgtU1%It6rPAJO-m#sFV%{UQ>iU=X72p$?2K7!l8x?SCke?0BevK(_ukzdvh(B2 zB)c0FO%*YPYKSiyTYM9dD%6L96tPf|D)gz~TND~W5TOqZ_@Gkn>>q92)>6fRnYnZ4 zyXTzmobTSVJURYM-}VQ#GYr$0&t<3RyFa=n)f?oVj~HghU~=~`YbSOx z%+_m8VK$z%4w}e!1&Do{2sJmLXoeX&PzxZMBQa}}lH+B#D`&srSO;gg=QImg!6+#^ zxy6u7FOC<`;v6zCci>5OsAf_FE{P#qb1PnC)-qhfu1Uwqw8*gyNIaL}h7*VEtToAw z`XONrLE;er606gZnv&Coq3inNtPEsD1SwJ0cv&$u-IP?eb#c^Vh>PY__UV>C`jz3z zaU7VUSglrtsv`JdNt6u35P>YpGEWhFRQF<7(8jI_8TtxBM0;SPPNLO@Js0T!xB9T8IA~Lo>!`z*)3Cz)uz}OE9zF%n< zYqA|OD{F$p?oDa~3^^sZf~=?tE6F-4>c&2n-D^SQcnQCK*I6T37?TW_EaN4>1EnBo zCXh@;-cO$ZG@+J{onrkas8*1Gsi`JVZh%rvVHm@I1Y=|t{m_Lp8;%Q0L=3zV$98gT zj`|fpq>gEHN+Sx(GV@*(Ll2RBHp9_`2#$lz6b7n|RKVM+Ci5z>5pSez%q!TIFjX0Z z0JYa=eKenxy}cgO^@^bvbsZsIQf-Y_RR!===QdwV!L)+0p-CjwUOy2!bnC&&UE4`E zWTF={=R~xU_11QoCNH%{6^Cs|#Dpl3euhIy%?ajO(@vKR+!=$W*=m_kqqiw{6BhZ! zxC%ouT%y_fcUlu~#Vmpgx924j8Nsxw@tUm>S{bDCHbe?9V^vPs&@O5^Z0DsLFO{B5 z>9#iib6%~2pfdDIgr348clS*1Ov7C(`1f7-KQR@PQ@JTz@n%go{#|#1QwcPtXj@2z zot{KLI$e!;G>IYYS*sJ9eYD@5$!CWP>Ejot_Yb@d`qzUuFAn!V*fVqKh0TMRdlhZw z^v*q;er{>`{8D`eug1NXj*Wl#UFpZip4heJwMWaJzPsbfm#e=Ngq6YQr;(ZEq2r3R zaY)S#ocQ9|{K(OX3(_Z7S6|%r^5CmK|MBhM+aH~J<6O^E%vP^n zl~WsQCx1)j-uYem^@B5eIBxDx`s@!v{_^>URM+}G{rNXr9_hVYIyU|Fh4rze!`XqA awLkBP&1&i64e7q5W#`Anv!9I|Ir= 0 && row < tiles.length && col >= 0 && col < tiles[0].length) { - tiles[row][col] = tileType; - } - } - } -} - -// Helper to place a horizontal line -function hline(tiles, x, y, length, tileType) { - for (let i = 0; i < length; i++) { - if (y >= 0 && y < tiles.length && x + i >= 0 && x + i < tiles[0].length) { - tiles[y][x + i] = tileType; - } - } -} - -// Helper to place a vertical line -function vline(tiles, x, y, length, tileType) { - for (let i = 0; i < length; i++) { - if (x >= 0 && x < tiles[0].length && y + i >= 0 && y + i < tiles.length) { - tiles[y + i][x] = tileType; - } - } -} +// ==================== Map definitions ==================== /** - * MAP 1: CIRCUIT LAB (20×15) - * Indoor tech lab with workstations, terminals, and a puzzle door + * MAP: LAB (10×12 tiles — lab.png is 160×192) + * Pokemon professor's lab interior */ -function createLabMap() { - const width = 20; - const height = 15; +const labMap = { + id: 'lab', + name: 'Circuit Lab', + image: 'map:lab', + widthTiles: 10, + heightTiles: 12, + spawn: { x: 4, y: 10 }, - // Start with all floor - const tiles = Array(height).fill(null).map(() => Array(width).fill(0)); + // Walls: { row: [col, col, ...] } + // Row 0-1: top shelves/machines + walls: { + 0: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9], + 1: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9], + 2: [0, 1, 2, 7, 8, 9], + 3: [0, 3, 4, 5, 6, 9], + 4: [0, 3, 4, 5, 6, 9], + 5: [0, 3, 4, 5, 6, 9], + 6: [0, 9], + 7: [0, 9], + 8: [0, 1, 2, 7, 8, 9], + 9: [0, 1, 8, 9], + 10: [0, 1, 2, 3, 6, 7, 8, 9], + 11: [0, 1, 2, 3, 4, 6, 7, 8, 9] + }, - // Border walls - for (let i = 0; i < width; i++) { - tiles[0][i] = 1; // top - tiles[height - 1][i] = 1; // bottom - } - for (let i = 0; i < height; i++) { - tiles[i][0] = 1; // left - tiles[i][width - 1] = 1; // right - } + exits: [ + // Exit at bottom center — door to town + { x: 4, y: 11, targetMap: 'town', targetX: 12, targetY: 10 }, + { x: 5, y: 11, targetMap: 'town', targetX: 12, targetY: 10 } + ], - // Internal wall structure - create lab rooms - // Vertical divider wall down the middle area - vline(tiles, 13, 1, 10, 1); + npcs: [ + { + id: 'professor', + x: 4, y: 3, + facing: 'down', + dialog: [ + 'Welcome to the Circuit Lab!', + 'I\'m the Professor. We study logic gates here.', + 'Use the workshop tables to design circuits.', + 'Press TAB to open the Workshop anytime!' + ] + } + ], - // Horizontal divider - hline(tiles, 1, 7, 12, 1); - - // Workshop area - left side with tables - tiles[4][3] = 3; // workshop table 1 - tiles[4][5] = 3; // workshop table 2 - tiles[4][7] = 3; // workshop table 3 - tiles[6][3] = 3; // workshop table 4 - tiles[6][5] = 3; // workshop table 5 - - // Terminal near workshop area - tiles[5][10] = 9; // terminal - - // Professor NPC spot at top - tiles[2][10] = 6; // NPC spawn location - - // Puzzle door leading to back room (top-right area) - tiles[2][16] = 4; // locked puzzle door - - // Door opening in the internal wall for navigation - tiles[7][7] = 0; // create passage - - // Exit point at bottom (to town) - tiles[13][10] = 0; // clear exit path - - return { - id: 'lab', - name: 'Circuit Lab', - width: width, - height: height, - tiles: tiles, - spawn: { x: 10, y: 12 }, - - exits: [ - { x: 10, y: 13, targetMap: 'town', targetX: 15, targetY: 1 } - ], - - npcs: [ - { - id: 'professor', - type: 0, - x: 10, - y: 2, - facing: 'down', - dialog: [ - 'Welcome to the Circuit Lab!', - 'I\'m the Professor. We study logic gates here.', - 'Try using the workshop tables to design circuits.', - 'Once you\'ve created some components, you can use them to solve puzzles.' - ] - } - ], - - interactions: [ - { x: 3, y: 4, type: 'workshop', action: 'openWorkshop', label: 'Workshop Table' }, - { x: 5, y: 4, type: 'workshop', action: 'openWorkshop', label: 'Workshop Table' }, - { x: 7, y: 4, type: 'workshop', action: 'openWorkshop', label: 'Workshop Table' }, - { x: 10, y: 5, type: 'terminal', action: 'openTerminal', label: 'Terminal' }, - { x: 16, y: 2, type: 'puzzle_door', puzzleId: 'lab_door_1', requiredOutputs: [1, 0, 1, 1], label: 'Locked Door' } - ] - }; -} - -/** - * MAP 2: NEON TOWN (30×20) - * Outdoor town with buildings, NPCs, water feature, and puzzle areas - */ -function createTownMap() { - const width = 30; - const height = 20; - - // Start with grass - const tiles = Array(height).fill(null).map(() => Array(width).fill(2)); - - // Add some paths (lighter grass/paths) - hline(tiles, 0, 10, width, 7); // horizontal path - vline(tiles, 15, 0, height, 7); // vertical path - - // Water feature on the left (pond) - fillRect(tiles, 2, 5, 5, 6, 8); - - // Lab entrance at top - tiles[0][15] = 0; // entrance floor - tiles[1][15] = 6; // NPC spawn for entrance - - // Building 1 (top-left) - House structure - fillRect(tiles, 5, 2, 7, 5, 1); // walls - fillRect(tiles, 6, 3, 5, 3, 0); // interior floor - tiles[4][8] = 0; // door to building 1 - - // Building 2 (top-right) - Shop - fillRect(tiles, 20, 2, 7, 5, 1); // walls - fillRect(tiles, 21, 3, 5, 3, 0); // interior floor - tiles[4][23] = 0; // door to building 2 - - // Building 3 (bottom-left) - Guard post - fillRect(tiles, 5, 14, 7, 5, 1); // walls - fillRect(tiles, 6, 15, 5, 3, 0); // interior floor - tiles[13][8] = 0; // door to guard post - - // Building 4 (bottom-right) - Town Hall - fillRect(tiles, 20, 14, 7, 5, 1); // walls - fillRect(tiles, 21, 15, 5, 3, 0); // interior floor - tiles[13][23] = 0; // door to town hall - - // Merchant NPC in center town square - tiles[10][15] = 6; // NPC spawn - - // Guard NPC at guard post entrance - tiles[13][8] = 6; // NPC spawn (overlays door, but NPC takes priority) - - // Puzzle door to eastern area (locked) - tiles[10][28] = 4; // locked puzzle door - - return { - id: 'town', - name: 'Neon Town', - width: width, - height: height, - tiles: tiles, - spawn: { x: 15, y: 2 }, - - exits: [ - { x: 15, y: 0, targetMap: 'lab', targetX: 10, targetY: 13 } - ], - - npcs: [ - { - id: 'merchant', - type: 0, - x: 15, - y: 10, - facing: 'down', - dialog: [ - 'Welcome to Neon Town!', - 'I trade in rare logic components.', - 'Show me what circuits you\'ve designed, and maybe we can make a deal.', - 'Some items are only available if you\'ve solved certain puzzles.' - ] - }, - { - id: 'guard', - type: 0, - x: 8, - y: 13, - facing: 'right', - dialog: [ - 'I guard the eastern territories.', - 'You need to solve the puzzle at the gate before you can pass.', - 'Bring me a component that produces the right output pattern!' - ] - } - ], - - interactions: [ - { x: 8, y: 4, type: 'door', action: 'openBuilding', label: 'House', buildingId: 'house_1' }, - { x: 23, y: 4, type: 'door', action: 'openBuilding', label: 'Shop', buildingId: 'shop_1' }, - { x: 8, y: 13, type: 'door', action: 'openBuilding', label: 'Guard Post', buildingId: 'guardpost_1' }, - { x: 23, y: 13, type: 'door', action: 'openBuilding', label: 'Town Hall', buildingId: 'townhall_1' }, - { x: 28, y: 10, type: 'puzzle_door', puzzleId: 'town_gate_1', requiredOutputs: [0, 1, 1, 0], label: 'Locked Gate' } - ] - }; -} - -// Map registry -const maps = { - lab: createLabMap(), - town: createTownMap() + interactions: [ + // Workshop tables (the big table in the middle of lab) + { x: 3, y: 5, type: 'workshop', label: 'Workshop Table' }, + { x: 4, y: 5, type: 'workshop', label: 'Workshop Table' }, + { x: 5, y: 5, type: 'workshop', label: 'Workshop Table' }, + { x: 6, y: 5, type: 'workshop', label: 'Workshop Table' }, + // Machine/bookshelf + { x: 8, y: 2, type: 'terminal', label: 'Terminal', + dialog: ['Circuit analysis terminal.', 'Connect components to solve puzzles.'] }, + // Puzzle door in top-right area + { x: 8, y: 3, type: 'puzzle_door', puzzleId: 'lab_door_1', + requiredOutputs: [1, 0, 1, 1], label: 'Locked Door' } + ] }; /** - * Get a complete map by ID + * MAP: TOWN (20×18 tiles — pallet-town.png is 320×288) + * Pokemon-style starting town with houses and paths */ +const townMap = { + id: 'town', + name: 'Neon Town', + image: 'map:pallet-town', + widthTiles: 20, + heightTiles: 18, + spawn: { x: 9, y: 9 }, + + // Walls based on pallet-town visual layout + // Trees around border, houses, fences, water + walls: (() => { + const w = {}; + // Helper to add walls + function addWall(row, cols) { + if (!w[row]) w[row] = []; + w[row].push(...cols); + } + function addRange(row, from, to) { + const cols = []; + for (let c = from; c <= to; c++) cols.push(c); + addWall(row, cols); + } + function addRect(rowStart, rowEnd, colStart, colEnd) { + for (let r = rowStart; r <= rowEnd; r++) addRange(r, colStart, colEnd); + } + + // Top border (trees/fence) — rows 0-1 + addRange(0, 0, 19); + addRange(1, 0, 19); + + // Left border trees + for (let r = 2; r <= 17; r++) addWall(r, [0, 1]); + + // Right border trees + for (let r = 2; r <= 17; r++) addWall(r, [18, 19]); + + // Bottom border + addRange(17, 0, 19); + + // House 1 (top-left area) — roughly rows 3-6, cols 3-7 + addRect(3, 5, 3, 7); + + // House 2 (top-right area) — rows 3-6, cols 12-16 + addRect(3, 5, 12, 16); + + // Fence segments + addRange(7, 2, 7); + addRange(7, 12, 17); + + // Water/pond (bottom-left) + addRect(13, 15, 2, 5); + + // Some trees/obstacles in bottom area + addWall(16, [2, 3, 4, 5, 6, 7]); + addWall(16, [12, 13, 14, 15, 16, 17]); + + return w; + })(), + + exits: [ + // North exit — goes to lab + { x: 12, y: 9, targetMap: 'lab', targetX: 4, targetY: 10 }, + // Route 1 south (future) + // { x: 9, y: 17, targetMap: 'route1', targetX: 10, targetY: 0 } + ], + + npcs: [ + { + id: 'merchant', + x: 9, y: 11, + facing: 'down', + dialog: [ + 'Welcome to Neon Town!', + 'I trade in rare logic components.', + 'Craft some circuits in the Lab workshop!', + 'Some doors need special output patterns to open.' + ] + }, + { + id: 'guide', + x: 14, y: 9, + facing: 'left', + dialog: [ + 'The Circuit Lab is just up ahead.', + 'Professor Oak.. I mean, the Professor can teach you about logic gates!', + 'Press TAB anytime to open your Workshop.' + ] + } + ], + + interactions: [ + // House 1 door + { x: 5, y: 6, type: 'door', label: 'House', + dialog: ['The door is locked.', 'Nobody seems to be home.'] }, + // House 2 door + { x: 14, y: 6, type: 'door', label: 'House', + dialog: ['This is the component shop.', 'Coming soon!'] }, + // Sign + { x: 10, y: 8, type: 'sign', label: 'Sign', + dialog: ['Welcome to Neon Town!', 'Circuit Lab ↑'] } + ] +}; + + +// ==================== Map registry ==================== + +const maps = { + lab: labMap, + town: townMap +}; + +// ==================== Public API ==================== + export function getMap(id) { return maps[id] || null; } /** - * Get tile type at position + * Check if a tile position is a wall */ -export function getTile(mapId, x, y) { +export function isWall(mapId, x, y) { const map = maps[mapId]; - if (!map) return null; - if (x < 0 || x >= map.width || y < 0 || y >= map.height) return null; - return map.tiles[y][x]; + if (!map) return true; + // Out of bounds = wall + if (x < 0 || x >= map.widthTiles || y < 0 || y >= map.heightTiles) return true; + const row = map.walls[y]; + if (!row) return false; + return row.includes(x); } /** - * Get interaction at position (if any) + * Check if a tile is walkable (not a wall and no NPC blocking) + */ +export function isWalkable(mapId, x, y) { + if (isWall(mapId, x, y)) return false; + if (getNPC(mapId, x, y)) return false; + return true; +} + +/** + * Get interaction at position */ export function getInteraction(mapId, x, y) { const map = maps[mapId]; if (!map) return null; - return map.interactions.find(inter => inter.x === x && inter.y === y) || null; + return map.interactions.find(i => i.x === x && i.y === y) || null; } /** - * Get NPC at position (if any) + * Get NPC at position */ export function getNPC(mapId, x, y) { const map = maps[mapId]; @@ -274,32 +236,17 @@ export function getNPC(mapId, x, y) { } /** - * Get exit at position (if any) + * Get exit at position */ export function getExit(mapId, x, y) { const map = maps[mapId]; if (!map) return null; - return map.exits.find(exit => exit.x === x && exit.y === y) || null; + return map.exits.find(e => e.x === x && e.y === y) || null; } -/** - * Check if a tile is walkable - * Walls (1), water (8), workshop tables (3), terminals (9), locked puzzle doors (4), and NPCs are not walkable - */ -export function isWalkable(mapId, x, y) { - const tile = getTile(mapId, x, y); - - // Out of bounds - if (tile === null) return false; - - // Non-walkable tiles - const nonWalkable = [1, 3, 4, 8, 9]; - if (nonWalkable.includes(tile)) return false; - - // Check for NPC - if (getNPC(mapId, x, y)) return false; - - return true; +// No longer needed but keep for compat — returns null always +export function getTile(mapId, x, y) { + return isWall(mapId, x, y) ? 1 : 0; } export { maps }; diff --git a/js/world/sprites.js b/js/world/sprites.js index 9d9d701..f7ff5f7 100644 --- a/js/world/sprites.js +++ b/js/world/sprites.js @@ -1,694 +1,238 @@ -// Cyberpunk pixel-art sprite system -// All sprites drawn on canvas, no image assets -// 16x16 tile size with 3x scaling for screen rendering +// sprites.js - PNG image-based sprite system +// Uses pre-rendered assets from assets/ directory +// 16px native tile size, 3x scale for screen rendering -export const TILE_SIZE = 16; +export const TILE = 16; export const SCALE = 3; +export const TILE_PX = TILE * SCALE; // 48px on screen -// Color palette -const COLORS = { - // Neon palette - neonGreen: '#00e599', - neonPink: '#ff44aa', - neonPurple: '#9900ff', - neonCyan: '#44ddff', - neonOrange: '#ff8844', +// Also export as TILE_SIZE for backward compat +export const TILE_SIZE = TILE; - // Dark palette - black: '#0a0e27', - darkGray: '#1a1f3a', - gray: '#3a3f5a', - lightGray: '#5a5f7a', +// ==================== Image cache ==================== - // Skin tones & details - skinLight: '#d4a574', - skinMid: '#c89860', - skinDark: '#a0704c', +const imageCache = {}; +let assetsLoaded = false; +let onAssetsReady = null; - // Material colors - metalDark: '#2a2f4a', - metalLight: '#4a4f6a', - copper: '#b87333', - blue: '#4488dd', - red: '#ee4444', - green: '#44aa44', - white: '#ffffff', -}; +function loadImage(key, src) { + return new Promise((resolve, reject) => { + if (imageCache[key]) { resolve(imageCache[key]); return; } + const img = new Image(); + img.onload = () => { imageCache[key] = img; resolve(img); }; + img.onerror = () => { console.warn(`[sprites] failed to load: ${src}`); resolve(null); }; + img.src = src; + }); +} -/** - * Helper function to draw a single scaled pixel - * @param {CanvasRenderingContext2D} ctx - * @param {number} baseX - Base X position (in pixels on screen) - * @param {number} baseY - Base Y position (in pixels on screen) - * @param {number} px - Pixel X offset (0-15 within tile) - * @param {number} py - Pixel Y offset (0-15 within tile) - * @param {string} color - Color hex code - */ -function pixel(ctx, baseX, baseY, px, py, color) { - ctx.fillStyle = color; - ctx.fillRect(baseX + px * SCALE, baseY + py * SCALE, SCALE, SCALE); +export function getImage(key) { + return imageCache[key] || null; } /** - * Draw a filled rectangle in tile space + * Preload all game assets. Returns a promise that resolves when done. */ -function rect(ctx, baseX, baseY, x, y, w, h, color) { - ctx.fillStyle = color; - ctx.fillRect(baseX + x * SCALE, baseY + y * SCALE, w * SCALE, h * SCALE); +export async function preloadAssets() { + if (assetsLoaded) return; + + const loads = []; + + // Map backgrounds + loads.push(loadImage('map:lab', 'assets/map/lab.png')); + loads.push(loadImage('map:pallet-town', 'assets/map/pallet-town.png')); + loads.push(loadImage('map:house-a-1f', 'assets/map/house-a-1f.png')); + loads.push(loadImage('map:route-1', 'assets/map/route-1.png')); + + // Character sprites (32x32 each) + const dirs = ['front', 'back', 'left', 'right']; + const frames = ['still', 'walk-1', 'walk-2']; + for (const dir of dirs) { + for (const frame of frames) { + const key = `char:${dir}-${frame}`; + loads.push(loadImage(key, `assets/character/${dir}-${frame}.png`)); + } + } + + // NPC sprites (16x16 each) + const npcDirs = ['down', 'up', 'left', 'right']; + for (const d of npcDirs) { + loads.push(loadImage(`npc:a-${d}`, `assets/npcs/a-${d}.png`)); + } + + await Promise.all(loads); + assetsLoaded = true; + console.log('[sprites] all assets loaded'); +} + +// ==================== Direction mapping ==================== + +// Map game direction to character sprite prefix +const DIR_TO_SPRITE = { + down: 'front', + up: 'back', + left: 'left', + right: 'right' +}; + +// Map game direction to NPC sprite suffix +const DIR_TO_NPC = { + down: 'down', + up: 'up', + left: 'left', + right: 'right' +}; + +// ==================== Drawing functions ==================== + +/** + * Draw a map background image + * @param {CanvasRenderingContext2D} ctx + * @param {string} mapImageKey - key in imageCache (e.g. 'map:lab') + * @param {number} offsetX - pixel offset for camera + * @param {number} offsetY - pixel offset for camera + */ +export function drawMapImage(ctx, mapImageKey, offsetX, offsetY) { + const img = imageCache[mapImageKey]; + if (!img) return; + // Draw scaled: native pixels * SCALE + ctx.imageSmoothingEnabled = false; + ctx.drawImage(img, offsetX, offsetY, img.width * SCALE, img.height * SCALE); } /** * Draw the player character * @param {CanvasRenderingContext2D} ctx - * @param {number} x - Screen X position - * @param {number} y - Screen Y position - * @param {string} direction - 'up', 'down', 'left', 'right' - * @param {number} frame - Animation frame (0 or 1) + * @param {number} screenX - top-left X on screen + * @param {number} screenY - top-left Y on screen + * @param {string} direction - 'up'|'down'|'left'|'right' + * @param {number} walkFrame - 0=still, 1=walk-1, 2=walk-2 */ -export function drawPlayer(ctx, x, y, direction, frame) { - const baseX = x * SCALE; - const baseY = y * SCALE; - - // Idle position or walking offset - const walkOffset = frame === 1 ? 1 : 0; - - // Head position shifts slightly with walk cycle - let headY = 2; - let legOffset = 0; - if (frame === 1 && direction === 'down') legOffset = 1; - if (frame === 1 && direction === 'up') legOffset = -1; - - if (direction === 'down') { - // Facing down - // Hair/head - pixel(ctx, baseX, baseY, 7, headY, COLORS.darkGray); - pixel(ctx, baseX, baseY, 8, headY, COLORS.darkGray); - - // Face - pixel(ctx, baseX, baseY, 7, headY + 1, COLORS.skinLight); - pixel(ctx, baseX, baseY, 8, headY + 1, COLORS.skinLight); - - // Hair back - pixel(ctx, baseX, baseY, 6, headY + 1, COLORS.darkGray); - pixel(ctx, baseX, baseY, 9, headY + 1, COLORS.darkGray); - - // Eyes (neon glow) - pixel(ctx, baseX, baseY, 7, headY + 2, COLORS.neonGreen); - pixel(ctx, baseX, baseY, 8, headY + 2, COLORS.neonGreen); - - // Mouth - pixel(ctx, baseX, baseY, 7, headY + 3, COLORS.red); - pixel(ctx, baseX, baseY, 8, headY + 3, COLORS.red); - - // Torso - black outfit with neon trim - pixel(ctx, baseX, baseY, 7, headY + 4, COLORS.black); - pixel(ctx, baseX, baseY, 8, headY + 4, COLORS.black); - pixel(ctx, baseX, baseY, 6, headY + 5, COLORS.neonGreen); - pixel(ctx, baseX, baseY, 7, headY + 5, COLORS.darkGray); - pixel(ctx, baseX, baseY, 8, headY + 5, COLORS.darkGray); - pixel(ctx, baseX, baseY, 9, headY + 5, COLORS.neonGreen); - - // Chest neon accent - pixel(ctx, baseX, baseY, 7, headY + 6, COLORS.neonPink); - pixel(ctx, baseY, baseY, 8, headY + 6, COLORS.neonPink); - - // Arms - pixel(ctx, baseX, baseY, 5, headY + 5, COLORS.skinDark); - pixel(ctx, baseX, baseY, 10, headY + 5, COLORS.skinDark); - - // Gloves/wrists - neon - pixel(ctx, baseX, baseY, 5, headY + 6, COLORS.neonCyan); - pixel(ctx, baseX, baseY, 10, headY + 6, COLORS.neonCyan); - - // Legs - pixel(ctx, baseX, baseY, 6, headY + 9 + legOffset, COLORS.black); - pixel(ctx, baseX, baseY, 7, headY + 9 + legOffset, COLORS.black); - pixel(ctx, baseX, baseY, 8, headY + 9 + legOffset, COLORS.black); - pixel(ctx, baseX, baseY, 9, headY + 9 + legOffset, COLORS.black); - - // Feet - boots with neon - pixel(ctx, baseX, baseY, 6, headY + 11 + legOffset, COLORS.neonGreen); - pixel(ctx, baseX, baseY, 7, headY + 11 + legOffset, COLORS.neonGreen); - pixel(ctx, baseX, baseY, 8, headY + 11 + legOffset, COLORS.neonGreen); - pixel(ctx, baseX, baseY, 9, headY + 11 + legOffset, COLORS.neonGreen); - - } else if (direction === 'up') { - // Facing up - back view - // Hair - pixel(ctx, baseX, baseY, 7, headY, COLORS.darkGray); - pixel(ctx, baseX, baseY, 8, headY, COLORS.darkGray); - pixel(ctx, baseX, baseY, 6, headY + 1, COLORS.darkGray); - pixel(ctx, baseX, baseY, 9, headY + 1, COLORS.darkGray); - - // Back of head - pixel(ctx, baseX, baseY, 7, headY + 1, COLORS.skinDark); - pixel(ctx, baseX, baseY, 8, headY + 1, COLORS.skinDark); - - // Neck - pixel(ctx, baseX, baseY, 7, headY + 2, COLORS.skinLight); - pixel(ctx, baseX, baseY, 8, headY + 2, COLORS.skinLight); - - // Jacket back with neon stripe - pixel(ctx, baseX, baseY, 6, headY + 3, COLORS.black); - pixel(ctx, baseX, baseY, 7, headY + 3, COLORS.neonCyan); - pixel(ctx, baseX, baseY, 8, headY + 3, COLORS.neonCyan); - pixel(ctx, baseX, baseY, 9, headY + 3, COLORS.black); - - // Torso - pixel(ctx, baseX, baseY, 6, headY + 4, COLORS.darkGray); - pixel(ctx, baseX, baseY, 7, headY + 4, COLORS.black); - pixel(ctx, baseX, baseY, 8, headY + 4, COLORS.black); - pixel(ctx, baseX, baseY, 9, headY + 4, COLORS.darkGray); - - // Waist - neon bands - pixel(ctx, baseX, baseY, 6, headY + 5, COLORS.neonPink); - pixel(ctx, baseX, baseY, 7, headY + 5, COLORS.darkGray); - pixel(ctx, baseX, baseY, 8, headY + 5, COLORS.darkGray); - pixel(ctx, baseX, baseY, 9, headY + 5, COLORS.neonPink); - - // Arms back - pixel(ctx, baseX, baseY, 5, headY + 4, COLORS.darkGray); - pixel(ctx, baseX, baseY, 10, headY + 4, COLORS.darkGray); - - // Legs - pixel(ctx, baseX, baseY, 6, headY + 9 - legOffset, COLORS.black); - pixel(ctx, baseX, baseY, 7, headY + 9 - legOffset, COLORS.black); - pixel(ctx, baseX, baseY, 8, headY + 9 - legOffset, COLORS.black); - pixel(ctx, baseX, baseY, 9, headY + 9 - legOffset, COLORS.black); - - // Feet - pixel(ctx, baseX, baseY, 6, headY + 11 - legOffset, COLORS.neonGreen); - pixel(ctx, baseX, baseY, 7, headY + 11 - legOffset, COLORS.neonGreen); - pixel(ctx, baseX, baseY, 8, headY + 11 - legOffset, COLORS.neonGreen); - pixel(ctx, baseX, baseY, 9, headY + 11 - legOffset, COLORS.neonGreen); - - } else if (direction === 'left') { - // Facing left - // Hair - pixel(ctx, baseX, baseY, 6, headY, COLORS.darkGray); - pixel(ctx, baseX, baseY, 7, headY, COLORS.darkGray); - - // Face - pixel(ctx, baseX, baseY, 6, headY + 1, COLORS.skinLight); - pixel(ctx, baseX, baseY, 7, headY + 1, COLORS.darkGray); - - // Eye (neon) - pixel(ctx, baseX, baseY, 6, headY + 2, COLORS.neonGreen); - - // Mouth - pixel(ctx, baseX, baseY, 6, headY + 3, COLORS.red); - - // Torso with side view - pixel(ctx, baseX, baseY, 5, headY + 4, COLORS.neonGreen); - pixel(ctx, baseX, baseY, 6, headY + 4, COLORS.black); - pixel(ctx, baseX, baseY, 7, headY + 4, COLORS.darkGray); - - pixel(ctx, baseX, baseY, 5, headY + 5, COLORS.neonGreen); - pixel(ctx, baseX, baseY, 6, headY + 5, COLORS.darkGray); - pixel(ctx, baseX, baseY, 7, headY + 5, COLORS.black); - - // Left arm - pixel(ctx, baseX, baseY, 4, headY + 5 - walkOffset, COLORS.skinDark); - pixel(ctx, baseX, baseY, 4, headY + 6, COLORS.neonCyan); - - // Right arm (back) - pixel(ctx, baseX, baseY, 8, headY + 5 + walkOffset, COLORS.skinDark); - pixel(ctx, baseX, baseY, 8, headY + 6, COLORS.darkGray); - - // Legs - pixel(ctx, baseX, baseY, 5, headY + 9, COLORS.black); - pixel(ctx, baseX, baseY, 6, headY + 9, COLORS.black); - pixel(ctx, baseX, baseY, 7, headY + 9, COLORS.darkGray); - - // Feet - pixel(ctx, baseX, baseY, 5, headY + 11, COLORS.neonGreen); - pixel(ctx, baseX, baseY, 6, headY + 11, COLORS.neonGreen); - - } else if (direction === 'right') { - // Facing right - // Hair - pixel(ctx, baseX, baseY, 8, headY, COLORS.darkGray); - pixel(ctx, baseX, baseY, 9, headY, COLORS.darkGray); - - // Face - pixel(ctx, baseX, baseY, 8, headY + 1, COLORS.darkGray); - pixel(ctx, baseX, baseY, 9, headY + 1, COLORS.skinLight); - - // Eye (neon) - pixel(ctx, baseX, baseY, 9, headY + 2, COLORS.neonGreen); - - // Mouth - pixel(ctx, baseX, baseY, 9, headY + 3, COLORS.red); - - // Torso with side view - pixel(ctx, baseX, baseY, 8, headY + 4, COLORS.darkGray); - pixel(ctx, baseX, baseY, 9, headY + 4, COLORS.black); - pixel(ctx, baseX, baseY, 10, headY + 4, COLORS.neonGreen); - - pixel(ctx, baseX, baseY, 8, headY + 5, COLORS.black); - pixel(ctx, baseX, baseY, 9, headY + 5, COLORS.darkGray); - pixel(ctx, baseX, baseY, 10, headY + 5, COLORS.neonGreen); - - // Left arm (back) - pixel(ctx, baseX, baseY, 7, headY + 5 + walkOffset, COLORS.skinDark); - pixel(ctx, baseX, baseY, 7, headY + 6, COLORS.darkGray); - - // Right arm - pixel(ctx, baseX, baseY, 11, headY + 5 - walkOffset, COLORS.skinDark); - pixel(ctx, baseX, baseY, 11, headY + 6, COLORS.neonCyan); - - // Legs - pixel(ctx, baseX, baseY, 8, headY + 9, COLORS.darkGray); - pixel(ctx, baseX, baseY, 9, headY + 9, COLORS.black); - pixel(ctx, baseX, baseY, 10, headY + 9, COLORS.black); - - // Feet - pixel(ctx, baseX, baseY, 9, headY + 11, COLORS.neonGreen); - pixel(ctx, baseX, baseY, 10, headY + 11, COLORS.neonGreen); - } -} - -/** - * Draw a tile - * @param {CanvasRenderingContext2D} ctx - * @param {number} x - Tile X position - * @param {number} y - Tile Y position - * @param {number} tileType - Tile type (0-9) - */ -export function drawTile(ctx, x, y, tileType) { - const baseX = x * SCALE; - const baseY = y * SCALE; - - switch (tileType) { - case 0: // Floor - metal grid pattern - rect(ctx, baseX, baseY, 0, 0, 16, 16, COLORS.metalDark); - // Grid pattern - for (let i = 0; i < 16; i += 4) { - rect(ctx, baseX, baseY, i, 0, 1, 16, COLORS.metalLight); - rect(ctx, baseX, baseY, 0, i, 16, 1, COLORS.metalLight); - } - // Corner accents - pixel(ctx, baseX, baseY, 0, 0, COLORS.neonGreen); - pixel(ctx, baseX, baseY, 15, 0, COLORS.neonGreen); - pixel(ctx, baseX, baseY, 0, 15, COLORS.neonGreen); - pixel(ctx, baseX, baseY, 15, 15, COLORS.neonGreen); - break; - - case 1: // Wall - solid dark with neon trim - rect(ctx, baseX, baseY, 0, 0, 16, 16, COLORS.darkGray); - rect(ctx, baseX, baseY, 1, 1, 14, 14, COLORS.black); - // Neon edges - rect(ctx, baseX, baseY, 0, 0, 16, 1, COLORS.neonCyan); - rect(ctx, baseX, baseY, 0, 15, 16, 1, COLORS.neonPink); - rect(ctx, baseX, baseY, 0, 0, 1, 16, COLORS.neonPurple); - rect(ctx, baseX, baseY, 15, 0, 1, 16, COLORS.neonOrange); - break; - - case 2: // Grass/outdoor ground - rect(ctx, baseX, baseY, 0, 0, 16, 16, COLORS.green); - // Grass tufts - for (let i = 0; i < 16; i += 4) { - for (let j = 0; j < 16; j += 4) { - if ((i + j) % 8 === 0) { - pixel(ctx, baseX, baseY, i, j, COLORS.neonGreen); - pixel(ctx, baseX, baseY, i + 1, j, COLORS.neonGreen); - } - } - } - break; - - case 3: // Workshop table - // Table surface - rect(ctx, baseX, baseY, 1, 1, 14, 10, COLORS.copper); - rect(ctx, baseX, baseY, 2, 2, 12, 8, COLORS.lightGray); - - // Electronic components on table - rect(ctx, baseX, baseY, 3, 3, 3, 3, COLORS.neonPurple); - rect(ctx, baseX, baseY, 10, 3, 3, 3, COLORS.neonCyan); - rect(ctx, baseX, baseY, 6, 5, 4, 2, COLORS.neonGreen); - - // Table legs - rect(ctx, baseX, baseY, 2, 11, 2, 5, COLORS.gray); - rect(ctx, baseX, baseY, 12, 11, 2, 5, COLORS.gray); - break; - - case 4: // Puzzle door - locked - rect(ctx, baseX, baseY, 0, 0, 16, 16, COLORS.metalDark); - // Door frame - rect(ctx, baseX, baseY, 1, 1, 14, 14, COLORS.darkGray); - - // LED indicators (locked - red) - pixel(ctx, baseX, baseY, 4, 4, COLORS.red); - pixel(ctx, baseX, baseY, 12, 4, COLORS.red); - pixel(ctx, baseX, baseY, 4, 12, COLORS.red); - pixel(ctx, baseX, baseY, 12, 12, COLORS.red); - - // Center lock symbol - rect(ctx, baseX, baseY, 6, 6, 4, 4, COLORS.neonPink); - pixel(ctx, baseX, baseY, 8, 8, COLORS.black); - break; - - case 5: // Puzzle door - open - rect(ctx, baseX, baseY, 0, 0, 16, 16, COLORS.metalLight); - // Door frame - rect(ctx, baseX, baseY, 1, 1, 14, 14, COLORS.darkGray); - - // LED indicators (unlocked - green) - pixel(ctx, baseX, baseY, 4, 4, COLORS.neonGreen); - pixel(ctx, baseX, baseY, 12, 4, COLORS.neonGreen); - pixel(ctx, baseX, baseY, 4, 12, COLORS.neonGreen); - pixel(ctx, baseX, baseY, 12, 12, COLORS.neonGreen); - - // Open door effect - rect(ctx, baseX, baseY, 6, 6, 4, 4, COLORS.neonGreen); - break; - - case 6: // NPC spot - empty, marked with neon circle - rect(ctx, baseX, baseY, 0, 0, 16, 16, COLORS.darkGray); - // Neon circle outline - for (let i = 3; i < 13; i++) { - pixel(ctx, baseX, baseY, i, 3, COLORS.neonCyan); - pixel(ctx, baseX, baseY, i, 12, COLORS.neonCyan); - pixel(ctx, baseX, baseY, 3, i, COLORS.neonCyan); - pixel(ctx, baseX, baseY, 12, i, COLORS.neonCyan); - } - break; - - case 7: // Path/road - rect(ctx, baseX, baseY, 0, 0, 16, 16, COLORS.gray); - // Road markings - rect(ctx, baseX, baseY, 6, 0, 4, 16, COLORS.neonOrange); - // Dashes - for (let i = 0; i < 16; i += 4) { - rect(ctx, baseX, baseY, 7, i, 2, 2, COLORS.black); - } - break; - - case 8: // Water/void - rect(ctx, baseX, baseY, 0, 0, 16, 16, COLORS.black); - // Ripple effect (animated-looking) - for (let i = 2; i < 14; i += 3) { - for (let j = 2; j < 14; j += 3) { - if ((i + j) % 6 === 0) { - pixel(ctx, baseX, baseY, i, j, COLORS.neonCyan); - } - } - } - // Neon glow edges - rect(ctx, baseX, baseY, 0, 0, 16, 1, COLORS.neonPurple); - rect(ctx, baseX, baseY, 0, 15, 16, 1, COLORS.neonPurple); - rect(ctx, baseX, baseY, 0, 0, 1, 16, COLORS.neonPurple); - rect(ctx, baseX, baseY, 15, 0, 1, 16, COLORS.neonPurple); - break; - - case 9: // Terminal/computer - rect(ctx, baseX, baseY, 0, 0, 16, 16, COLORS.black); - // Screen border - rect(ctx, baseX, baseY, 1, 1, 14, 12, COLORS.metalDark); - rect(ctx, baseX, baseY, 2, 2, 12, 10, COLORS.neonGreen); - - // Screen display with scanlines effect - for (let i = 0; i < 10; i += 2) { - rect(ctx, baseX, baseY, 3, 3 + i, 10, 1, COLORS.darkGray); - } - - // Keyboard - rect(ctx, baseX, baseY, 2, 13, 12, 2, COLORS.gray); - pixel(ctx, baseX, baseY, 4, 14, COLORS.neonPink); - pixel(ctx, baseX, baseY, 8, 14, COLORS.neonPink); - pixel(ctx, baseX, baseY, 12, 14, COLORS.neonPink); - break; - - default: - // Default: empty space - rect(ctx, baseX, baseY, 0, 0, 16, 16, COLORS.black); - } -} - -/** - * Draw an NPC character - * @param {CanvasRenderingContext2D} ctx - * @param {number} x - Screen X position - * @param {number} y - Screen Y position - * @param {number} npcType - NPC type (0 = scientist, 1 = guard, 2 = merchant) - * @param {number} frame - Animation frame (0 or 1) - */ -export function drawNPC(ctx, x, y, npcType, frame) { - const baseX = x * SCALE; - const baseY = y * SCALE; - const wobble = frame === 1 ? 1 : 0; - - if (npcType === 0) { - // Scientist - lab coat, goggles - // Hair - pixel(ctx, baseX, baseY, 7, 2, COLORS.lightGray); - pixel(ctx, baseX, baseY, 8, 2, COLORS.lightGray); - - // Goggles - pixel(ctx, baseX, baseY, 6, 3, COLORS.neonCyan); - pixel(ctx, baseX, baseY, 7, 3, COLORS.neonCyan); - pixel(ctx, baseX, baseY, 8, 3, COLORS.neonCyan); - pixel(ctx, baseX, baseY, 9, 3, COLORS.neonCyan); - pixel(ctx, baseX, baseY, 6, 4, COLORS.black); - pixel(ctx, baseX, baseY, 9, 4, COLORS.black); - - // Face - pixel(ctx, baseX, baseY, 7, 4, COLORS.skinLight); - pixel(ctx, baseX, baseY, 8, 4, COLORS.skinLight); - pixel(ctx, baseX, baseY, 7, 5, COLORS.skinLight); - pixel(ctx, baseX, baseY, 8, 5, COLORS.skinLight); - - // Nose - pixel(ctx, baseX, baseY, 7, 5, COLORS.skinMid); - - // Lab coat - white with neon trim - pixel(ctx, baseX, baseY, 5, 6, COLORS.white); - pixel(ctx, baseX, baseY, 6, 6, COLORS.white); - pixel(ctx, baseX, baseY, 7, 6, COLORS.white); - pixel(ctx, baseX, baseY, 8, 6, COLORS.white); - pixel(ctx, baseX, baseY, 9, 6, COLORS.white); - pixel(ctx, baseX, baseY, 10, 6, COLORS.white); - - // Coat buttons - neon - pixel(ctx, baseX, baseY, 7, 7, COLORS.neonGreen); - pixel(ctx, baseX, baseY, 8, 7, COLORS.neonGreen); - - // Arms - pixel(ctx, baseX, baseY, 4, 7, COLORS.skinDark); - pixel(ctx, baseX, baseY, 11, 7, COLORS.skinDark); - - // Hands - pixel(ctx, baseX, baseY, 4, 8 + wobble, COLORS.skinLight); - pixel(ctx, baseX, baseY, 11, 8 + wobble, COLORS.skinLight); - - // Legs - pixel(ctx, baseX, baseY, 6, 10, COLORS.gray); - pixel(ctx, baseX, baseY, 7, 10, COLORS.gray); - pixel(ctx, baseX, baseY, 8, 10, COLORS.gray); - pixel(ctx, baseX, baseY, 9, 10, COLORS.gray); - - // Feet - pixel(ctx, baseX, baseY, 6, 12, COLORS.black); - pixel(ctx, baseX, baseY, 7, 12, COLORS.black); - pixel(ctx, baseX, baseY, 8, 12, COLORS.black); - pixel(ctx, baseX, baseY, 9, 12, COLORS.black); - - } else if (npcType === 1) { - // Guard - helmet, armor - // Helmet with visor - pixel(ctx, baseX, baseY, 7, 2, COLORS.metalLight); - pixel(ctx, baseX, baseY, 8, 2, COLORS.metalLight); - pixel(ctx, baseX, baseY, 6, 3, COLORS.metalLight); - pixel(ctx, baseX, baseY, 7, 3, COLORS.neonPink); - pixel(ctx, baseX, baseY, 8, 3, COLORS.neonPink); - pixel(ctx, baseX, baseY, 9, 3, COLORS.metalLight); - - // Face hidden by visor - pixel(ctx, baseX, baseY, 7, 4, COLORS.black); - pixel(ctx, baseX, baseY, 8, 4, COLORS.black); - - // Armor - angular, metallic - pixel(ctx, baseX, baseY, 5, 5, COLORS.metalLight); - pixel(ctx, baseX, baseY, 6, 5, COLORS.metalLight); - pixel(ctx, baseX, baseY, 7, 5, COLORS.metalDark); - pixel(ctx, baseX, baseY, 8, 5, COLORS.metalDark); - pixel(ctx, baseX, baseY, 9, 5, COLORS.metalLight); - pixel(ctx, baseX, baseY, 10, 5, COLORS.metalLight); - - // Chest plate - pixel(ctx, baseX, baseY, 5, 6, COLORS.neonPurple); - pixel(ctx, baseX, baseY, 6, 6, COLORS.metalLight); - pixel(ctx, baseX, baseY, 7, 6, COLORS.metalLight); - pixel(ctx, baseX, baseY, 8, 6, COLORS.metalLight); - pixel(ctx, baseX, baseY, 9, 6, COLORS.metalLight); - pixel(ctx, baseX, baseY, 10, 6, COLORS.neonPurple); - - // Arms - armored - pixel(ctx, baseX, baseY, 4, 6, COLORS.metalLight); - pixel(ctx, baseX, baseY, 11, 6, COLORS.metalLight); - - // Gauntlets - neon edge - pixel(ctx, baseX, baseY, 4, 7, COLORS.neonCyan); - pixel(ctx, baseX, baseY, 11, 7, COLORS.neonCyan); - - // Legs - armored - pixel(ctx, baseX, baseY, 6, 10, COLORS.metalLight); - pixel(ctx, baseX, baseY, 7, 10, COLORS.metalLight); - pixel(ctx, baseX, baseY, 8, 10, COLORS.metalLight); - pixel(ctx, baseX, baseY, 9, 10, COLORS.metalLight); - - // Boots - pixel(ctx, baseX, baseY, 6, 12, COLORS.neonOrange); - pixel(ctx, baseX, baseY, 7, 12, COLORS.neonOrange); - pixel(ctx, baseX, baseY, 8, 12, COLORS.neonOrange); - pixel(ctx, baseX, baseY, 9, 12, COLORS.neonOrange); - - } else if (npcType === 2) { - // Merchant - fancy outfit, hat - // Hat - pixel(ctx, baseX, baseY, 6, 1, COLORS.neonPink); - pixel(ctx, baseX, baseY, 7, 1, COLORS.neonPink); - pixel(ctx, baseX, baseY, 8, 1, COLORS.neonPink); - pixel(ctx, baseX, baseY, 9, 1, COLORS.neonPink); - pixel(ctx, baseX, baseY, 6, 2, COLORS.neonPink); - pixel(ctx, baseX, baseY, 9, 2, COLORS.neonPink); - - // Face - pixel(ctx, baseX, baseY, 7, 3, COLORS.skinLight); - pixel(ctx, baseX, baseY, 8, 3, COLORS.skinLight); - pixel(ctx, baseX, baseY, 7, 4, COLORS.skinLight); - pixel(ctx, baseX, baseY, 8, 4, COLORS.skinLight); - - // Mustache (fancy) - pixel(ctx, baseX, baseY, 6, 4, COLORS.darkGray); - pixel(ctx, baseX, baseY, 9, 4, COLORS.darkGray); - - // Fancy jacket - colorful - pixel(ctx, baseX, baseY, 5, 5, COLORS.neonOrange); - pixel(ctx, baseX, baseY, 6, 5, COLORS.blue); - pixel(ctx, baseX, baseY, 7, 5, COLORS.blue); - pixel(ctx, baseX, baseY, 8, 5, COLORS.blue); - pixel(ctx, baseX, baseY, 9, 5, COLORS.blue); - pixel(ctx, baseX, baseY, 10, 5, COLORS.neonOrange); - - // Vest with gems - pixel(ctx, baseX, baseY, 5, 6, COLORS.neonGreen); - pixel(ctx, baseX, baseY, 6, 6, COLORS.blue); - pixel(ctx, baseX, baseY, 7, 6, COLORS.neonCyan); - pixel(ctx, baseX, baseY, 8, 6, COLORS.neonCyan); - pixel(ctx, baseX, baseY, 9, 6, COLORS.blue); - pixel(ctx, baseX, baseY, 10, 6, COLORS.neonGreen); - - // Arms - pixel(ctx, baseX, baseY, 4, 6, COLORS.skinDark); - pixel(ctx, baseX, baseY, 11, 6, COLORS.skinDark); - - // Rings on fingers - neon - pixel(ctx, baseX, baseY, 4, 7, COLORS.neonOrange); - pixel(ctx, baseX, baseY, 11, 7, COLORS.neonOrange); - - // Legs - fancy pants - pixel(ctx, baseX, baseY, 6, 10, COLORS.blue); - pixel(ctx, baseX, baseY, 7, 10, COLORS.blue); - pixel(ctx, baseX, baseY, 8, 10, COLORS.blue); - pixel(ctx, baseX, baseY, 9, 10, COLORS.blue); - - // Fancy shoes - pixel(ctx, baseX, baseY, 6, 12, COLORS.neonPink); - pixel(ctx, baseX, baseY, 7, 12, COLORS.neonPink); - pixel(ctx, baseX, baseY, 8, 12, COLORS.neonPink); - pixel(ctx, baseX, baseY, 9, 12, COLORS.neonPink); - } -} - -/** - * Draw interaction prompt - * @param {CanvasRenderingContext2D} ctx - * @param {number} x - Screen X position - * @param {number} y - Screen Y position - */ -export function drawInteractionPrompt(ctx, x, y) { - const baseX = x * SCALE; - const baseY = y * SCALE; - - ctx.fillStyle = COLORS.neonGreen; - ctx.font = `bold ${12 * SCALE}px monospace`; - ctx.textAlign = 'center'; - ctx.textBaseline = 'bottom'; - ctx.fillText('E', baseX + 8 * SCALE, baseY); -} - -/** - * Draw a dialog box at the bottom of the screen - * @param {CanvasRenderingContext2D} ctx - * @param {number} canvasWidth - Canvas width in pixels - * @param {number} canvasHeight - Canvas height in pixels - * @param {string} text - Dialog text - * @param {string} speakerName - NPC name - */ -export function drawDialogBox(ctx, canvasWidth, canvasHeight, text, speakerName) { - const padding = 20; - const boxHeight = 120; - const boxY = canvasHeight - boxHeight - padding; - const boxX = padding; - const boxWidth = canvasWidth - 2 * padding; - - // Dialog box background - ctx.fillStyle = COLORS.black; - ctx.fillRect(boxX, boxY, boxWidth, boxHeight); - - // Neon border - ctx.strokeStyle = COLORS.neonCyan; - ctx.lineWidth = 3; - ctx.strokeRect(boxX, boxY, boxWidth, boxHeight); - - // Corner accents - ctx.fillStyle = COLORS.neonGreen; - const cornerSize = 10; - ctx.fillRect(boxX, boxY, cornerSize, 3); - ctx.fillRect(boxX, boxY, 3, cornerSize); - ctx.fillRect(boxX + boxWidth - cornerSize, boxY, cornerSize, 3); - ctx.fillRect(boxX + boxWidth - 3, boxY, 3, cornerSize); - - // Speaker name - neon green - ctx.fillStyle = COLORS.neonGreen; - ctx.font = `bold 16px monospace`; - ctx.textAlign = 'left'; - ctx.textBaseline = 'top'; - ctx.fillText(speakerName, boxX + 15, boxY + 10); - - // Dialog text - cyan - ctx.fillStyle = COLORS.neonCyan; - ctx.font = `14px monospace`; - ctx.textAlign = 'left'; - ctx.textBaseline = 'top'; - - // Word wrap - const maxWidth = boxWidth - 30; - const lineHeight = 18; - const words = text.split(' '); - let line = ''; - let lineNum = 0; - - for (const word of words) { - const testLine = line + (line ? ' ' : '') + word; - const metrics = ctx.measureText(testLine); - - if (metrics.width > maxWidth && line) { - ctx.fillText(line, boxX + 15, boxY + 40 + lineNum * lineHeight); - line = word; - lineNum++; - } else { - line = testLine; +export function drawPlayer(ctx, screenX, screenY, direction, walkFrame) { + const spriteDir = DIR_TO_SPRITE[direction] || 'front'; + const frameName = walkFrame === 0 ? 'still' : walkFrame === 1 ? 'walk-1' : 'walk-2'; + const key = `char:${spriteDir}-${frameName}`; + const img = imageCache[key]; + if (!img) { + // Fallback: colored rectangle + ctx.fillStyle = '#00e599'; + ctx.fillRect(screenX, screenY, TILE_PX, TILE_PX * 2); + return; } - } - - if (line) { - ctx.fillText(line, boxX + 15, boxY + 40 + lineNum * lineHeight); - } - - // Cursor prompt - blinking indicator - ctx.fillStyle = COLORS.neonPink; - ctx.font = `bold 16px monospace`; - ctx.fillText('▼', boxX + boxWidth - 30, boxY + boxHeight - 20); + ctx.imageSmoothingEnabled = false; + // Character is 32x32 native = 2x2 tiles, draw at SCALE + ctx.drawImage(img, screenX, screenY, 32 * SCALE, 32 * SCALE); +} + +/** + * Draw an NPC + * @param {CanvasRenderingContext2D} ctx + * @param {number} screenX - top-left X on screen + * @param {number} screenY - top-left Y on screen + * @param {string} facing - 'up'|'down'|'left'|'right' + */ +export function drawNPC(ctx, screenX, screenY, facing) { + const dir = DIR_TO_NPC[facing] || 'down'; + const key = `npc:a-${dir}`; + const img = imageCache[key]; + if (!img) { + // Fallback + ctx.fillStyle = '#ff44aa'; + ctx.fillRect(screenX, screenY, TILE_PX, TILE_PX); + return; + } + ctx.imageSmoothingEnabled = false; + // NPC is 16x16 native = 1 tile + ctx.drawImage(img, screenX, screenY, TILE_PX, TILE_PX); +} + +/** + * Draw the interaction prompt (E button hint) above a tile + */ +export function drawInteractionPrompt(ctx, screenX, screenY) { + const cx = screenX + TILE_PX / 2; + const cy = screenY - 12; + + // Bubble background + ctx.fillStyle = 'rgba(0, 0, 0, 0.7)'; + ctx.beginPath(); + ctx.roundRect(cx - 18, cy - 12, 36, 22, 6); + ctx.fill(); + + // Border + ctx.strokeStyle = '#00e599'; + ctx.lineWidth = 1.5; + ctx.beginPath(); + ctx.roundRect(cx - 18, cy - 12, 36, 22, 6); + ctx.stroke(); + + // Text + ctx.fillStyle = '#ffffff'; + ctx.font = 'bold 12px "Segoe UI", system-ui, sans-serif'; + ctx.textAlign = 'center'; + ctx.textBaseline = 'middle'; + ctx.fillText('[E]', cx, cy); +} + +/** + * Draw the dialog box at the bottom of the screen + */ +export function drawDialogBox(ctx, canvasW, canvasH, text, speakerName) { + const boxH = 100; + const boxY = canvasH - boxH - 16; + const boxX = 32; + const boxW = canvasW - 64; + + // Background + ctx.fillStyle = 'rgba(10, 14, 39, 0.92)'; + ctx.beginPath(); + ctx.roundRect(boxX, boxY, boxW, boxH, 10); + ctx.fill(); + + // Border + ctx.strokeStyle = '#00e599'; + ctx.lineWidth = 2; + ctx.beginPath(); + ctx.roundRect(boxX, boxY, boxW, boxH, 10); + ctx.stroke(); + + // Speaker name + if (speakerName) { + ctx.fillStyle = '#00e599'; + ctx.font = 'bold 14px "Segoe UI", system-ui, sans-serif'; + ctx.textAlign = 'left'; + ctx.textBaseline = 'top'; + ctx.fillText(speakerName, boxX + 16, boxY + 12); + } + + // Text + ctx.fillStyle = '#ffffff'; + ctx.font = '14px "Segoe UI", system-ui, sans-serif'; + ctx.textAlign = 'left'; + ctx.textBaseline = 'top'; + const textY = speakerName ? boxY + 34 : boxY + 16; + // Simple word wrap + wrapText(ctx, text, boxX + 16, textY, boxW - 32, 20); + + // Continue prompt + ctx.fillStyle = '#555'; + ctx.font = '11px "Segoe UI", system-ui, sans-serif'; + ctx.textAlign = 'right'; + ctx.fillText('Press E to continue ▶', boxX + boxW - 16, boxY + boxH - 16); +} + +function wrapText(ctx, text, x, y, maxWidth, lineHeight) { + const words = text.split(' '); + let line = ''; + let currentY = y; + for (const word of words) { + const test = line + (line ? ' ' : '') + word; + if (ctx.measureText(test).width > maxWidth && line) { + ctx.fillText(line, x, currentY); + line = word; + currentY += lineHeight; + } else { + line = test; + } + } + if (line) ctx.fillText(line, x, currentY); } diff --git a/js/world/worldRenderer.js b/js/world/worldRenderer.js index c717d09..2b88320 100644 --- a/js/world/worldRenderer.js +++ b/js/world/worldRenderer.js @@ -1,7 +1,10 @@ -// worldRenderer.js - Renders the tile-based game world on canvas -import { drawPlayer, drawTile, drawNPC, drawInteractionPrompt, drawDialogBox, TILE_SIZE, SCALE } from './sprites.js'; +// worldRenderer.js - Renders PNG-based game world on canvas +import { + drawMapImage, drawPlayer, drawNPC, drawInteractionPrompt, + drawDialogBox, preloadAssets, TILE_PX, SCALE +} from './sprites.js'; import { worldState } from './worldState.js'; -import { getMap, getTile, getInteraction, getNPC } from './maps.js'; +import { getMap, getInteraction, getNPC } from './maps.js'; import { updateMovement } from './worldInput.js'; let canvas = null; @@ -9,14 +12,11 @@ let ctx = null; let animFrameId = null; let lastTime = 0; -const TILE_PX = TILE_SIZE * SCALE; // 48px per tile on screen - export function initWorldRenderer() { canvas = document.getElementById('canvas'); ctx = canvas.getContext('2d'); resizeCanvas(); window.addEventListener('resize', resizeCanvas); - return true; } function resizeCanvas() { @@ -25,36 +25,30 @@ function resizeCanvas() { canvas.height = canvas.offsetHeight || window.innerHeight; } -/** Convert tile coords → screen pixel coords (camera-relative) */ -export function worldToScreen(tileX, tileY) { +// ==================== Camera ==================== + +/** Get the pixel offset to draw the map so the player is centered */ +function getCameraOffset() { const p = worldState.player; - const cx = canvas.width / 2; - const cy = canvas.height / 2; - // Player world position with interpolation - const pwx = (p.x + p.px) * TILE_PX; - const pwy = (p.y + p.py) * TILE_PX; + const playerWorldX = (p.x + p.px) * TILE_PX; + const playerWorldY = (p.y + p.py) * TILE_PX; return { - x: cx + (tileX * TILE_PX - pwx), - y: cy + (tileY * TILE_PX - pwy) + x: canvas.width / 2 - playerWorldX - TILE_PX / 2, + y: canvas.height / 2 - playerWorldY - TILE_PX / 2 }; } -/** Visible tile range for culling */ -function getVisibleBounds() { - const p = worldState.player; - const halfW = canvas.width / 2; - const halfH = canvas.height / 2; - const pwx = (p.x + p.px) * TILE_PX; - const pwy = (p.y + p.py) * TILE_PX; +/** Convert tile position to screen position */ +function tileToScreen(tileX, tileY) { + const cam = getCameraOffset(); return { - minX: Math.floor((pwx - halfW) / TILE_PX) - 1, - minY: Math.floor((pwy - halfH) / TILE_PX) - 1, - maxX: Math.ceil((pwx + halfW) / TILE_PX) + 1, - maxY: Math.ceil((pwy + halfH) / TILE_PX) + 1 + x: tileX * TILE_PX + cam.x, + y: tileY * TILE_PX + cam.y }; } -/** Tile the player is facing */ +// ==================== Facing tile ==================== + function getFacingTile() { const p = worldState.player; let x = p.x, y = p.y; @@ -65,12 +59,13 @@ function getFacingTile() { return { x, y }; } -/** Main render frame */ +// ==================== Main render ==================== + export function renderWorld(timestamp) { const dt = (timestamp - lastTime) / 1000; lastTime = timestamp; - // Update movement interpolation + // Update movement updateMovement(dt); // Resize check @@ -85,34 +80,34 @@ export function renderWorld(timestamp) { const map = getMap(worldState.currentMap); if (!map) return; - const bounds = getVisibleBounds(); + const cam = getCameraOffset(); - // === Layer 1: Tiles === - for (let ty = bounds.minY; ty <= bounds.maxY; ty++) { - for (let tx = bounds.minX; tx <= bounds.maxX; tx++) { - const tileType = getTile(worldState.currentMap, tx, ty); - if (tileType === null) continue; - const pos = worldToScreen(tx, ty); - drawTile(ctx, pos.x, pos.y, tileType); - } - } + // === Layer 1: Map background (PNG) === + drawMapImage(ctx, map.image, cam.x, cam.y); // === Layer 2: NPCs === if (map.npcs) { for (const npc of map.npcs) { - const pos = worldToScreen(npc.x, npc.y); - drawNPC(ctx, pos.x, pos.y, npc.type, 0); + const pos = tileToScreen(npc.x, npc.y); + drawNPC(ctx, pos.x, pos.y, npc.facing || 'down'); } } // === Layer 3: Player === - const pp = worldToScreen(worldState.player.x + worldState.player.px, - worldState.player.y + worldState.player.py); - // Adjust: worldToScreen already offsets from player, so player is always at center - const pcx = canvas.width / 2 - TILE_PX / 2; - const pcy = canvas.height / 2 - TILE_PX / 2; - const frame = worldState.player.moving ? (Math.floor(Date.now() / 120) % 2) : 0; - drawPlayer(ctx, pcx, pcy, worldState.player.direction, frame); + // Character sprite is 32x32 native (2 tiles tall) + // Position so bottom half aligns with player tile, top half overlaps above + const playerScreen = tileToScreen( + worldState.player.x + worldState.player.px, + worldState.player.y + worldState.player.py + ); + // Offset upward by 1 tile since character is 2 tiles tall + const playerDrawX = playerScreen.x; + const playerDrawY = playerScreen.y - TILE_PX; + + const walkFrame = worldState.player.moving + ? (Math.floor(Date.now() / 150) % 2) + 1 // alternates 1, 2 + : 0; + drawPlayer(ctx, playerDrawX, playerDrawY, worldState.player.direction, walkFrame); // === Layer 4: Interaction prompt === if (!worldState.dialog && !worldState.player.moving) { @@ -120,12 +115,12 @@ export function renderWorld(timestamp) { const inter = getInteraction(worldState.currentMap, ft.x, ft.y); const npc = getNPC(worldState.currentMap, ft.x, ft.y); if (inter || npc) { - const pos = worldToScreen(ft.x, ft.y); + const pos = tileToScreen(ft.x, ft.y); drawInteractionPrompt(ctx, pos.x, pos.y); } } - // === Layer 5: Dialog box === + // === Layer 5: Dialog === if (worldState.dialog) { const line = worldState.dialog.lines[worldState.dialog.currentLine] || ''; const speaker = worldState.dialog.speakerName || ''; @@ -133,11 +128,10 @@ export function renderWorld(timestamp) { } // === HUD === - drawHUD(); + drawHUD(map); } -function drawHUD() { - const map = getMap(worldState.currentMap); +function drawHUD(map) { const mapName = map ? map.name : worldState.currentMap; // Background bar @@ -164,7 +158,12 @@ function drawHUD() { ctx.fillText('WASD: Move | E: Interact | TAB: Workshop', canvas.width / 2, 16); } -export function startWorldLoop() { +// ==================== Loop control ==================== + +export async function startWorldLoop() { + // Ensure assets are loaded before starting + await preloadAssets(); + lastTime = performance.now(); function loop(ts) { renderWorld(ts); diff --git a/js/world/worldState.js b/js/world/worldState.js index faf5de6..a56fca6 100644 --- a/js/world/worldState.js +++ b/js/world/worldState.js @@ -11,8 +11,8 @@ export const worldState = { // Player player: { - x: 10, - y: 12, // tile position in current map + x: 4, + y: 10, // tile position in current map px: 0, py: 0, // pixel offset for smooth movement (interpolation) direction: 'down', // 'up' | 'down' | 'left' | 'right' @@ -58,8 +58,8 @@ export const worldState = { */ export function resetWorldState() { worldState.mode = 'world'; - worldState.player.x = 10; - worldState.player.y = 12; + worldState.player.x = 4; + worldState.player.y = 10; worldState.player.px = 0; worldState.player.py = 0; worldState.player.direction = 'down';