From 35027d1c6ac99076fed7cfe506cbc00b55e670a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sergio=20Valor=20Mart=C3=ADnez?= Date: Sun, 14 Feb 2021 14:49:45 +0100 Subject: [PATCH] first commit --- .gitignore | 7 + data/volcano - backup.map | Bin 0 -> 114242 bytes data/volcano - backup2.map | Bin 0 -> 114242 bytes data/volcano.map | Bin 0 -> 114242 bytes source/volcano.pas | 2704 ++++++++++++++++++++++++++++++++++++ sync.sh | 34 + 6 files changed, 2745 insertions(+) create mode 100644 .gitignore create mode 100644 data/volcano - backup.map create mode 100644 data/volcano - backup2.map create mode 100644 data/volcano.map create mode 100644 source/volcano.pas create mode 100755 sync.sh diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..974f65f --- /dev/null +++ b/.gitignore @@ -0,0 +1,7 @@ +.vscode/* +.DS_Store +thumbs.db +*debug* +*.psd +*.zip +*.aseprite diff --git a/data/volcano - backup.map b/data/volcano - backup.map new file mode 100644 index 0000000000000000000000000000000000000000..69766bd303d6fad83342480fa1891b832948b980 GIT binary patch literal 114242 zcmeHQPj4JYcJCIc8A_BB*`OuR3WUUFf+)#y2Z|urgdk|tP1@qF0S-ycF|aPY?0wD# zp%1`~zksmF7m#B)SHY1A9;Y|0;d*pP# zdR5i+e(zsb&y2)3zg??9fhW0^C{Ddx6hY#eJ1<#A!5e>)Y1$3e?=l@bMpdid4KxV& zie^Fu=2CWUu9@u|)=G806a;_$H%Sw`A;sewjCO4;Qh;&9kTRV50(?cx&FhzM4^y$E zZ~RNp3{Qc|mG_gFC*#Stm+;K75;-0bKexM>NrrAibZQ=FK6%vpN4rB;^B!Peu~ zp2yFLfByV=9&eHjJn?5geHQ$~Pyb$B(#%y%-ZA-hZuoSYS&-$eWK~3QY!t|iHrYV( z?c_yKVDrbBRUSJMAZkj%EM-Ce-Q*f3_3i-o^xJ&ge=3${8Ec#c_M{wZIx@T z!#Y2Y+Gf_r!6$}KnCI(A&Weu2M4vqH0~*K6frvHd%`FxwZA~U()#t&N||PpcARHJ{rwBvAF>!eVzT? zt-VJobd?Bp1KuwfG77bsyY^|yj>}Pa7PR-cNNx@(cx!8uPG9`sDpeV#D2g?!&gRO= z{fOGCrxV4%8}D1=f4Ch0FS+;~Dh}3Mq?Kun!2oJZG{%&4Xl6yyQsD*McNE_B^>ti3 z!U^=&AN{d9ufMf^1wZInzXIVENUyww<9_@;;l+3w%BUIaO`t|V$DcmBa^=eUTR6}Q zm!QLXs*VSzz)p%cV`I|q$NN9(1UI)k+uPfSzMH`ZAMgUv2N}8pQazcDD1JWz-cJFT zhEqxIyt921*QBd;w%?Cql4ELyJW%Q(iEjaSGXJL6L6|(!w7iCton$FaGFW9{%-Ik{V=TEFNp`l+nj~=A&$2Sl&Wvz4GV-tSfs+3f|CoHMNDd zX?6{}rTB`spnOCO^{>5pCA=w2!_5irT4_8}ZDGKQapR5SZ@%G*Li?+P45XpV-0)(X zz_6k(ztm3%Ze4V)Mw;2u2w|Bl-u!;Tf!tl2?1)nQl;c_Zm$y?I`W~2%)pCgmKEeJ{ z!6dYg62xx2Q2||AuS^%h!G+Bw%co$)HZMW2uDy$ccClVK)rv6!E%t>Pu^Vq(0PLvQ zn5vgZ&u-a74}s-IG0WZJXF}6trju#~yo{Fon;^FFS^-@EjB&=XilLd=m8j*GReMG# z0H=i_dRG67Kc{2X!FXt(ej@VkBZ_8@Xb$Nzym`PhE(4e+s>|9(H{OEAzJh!e@n}P_ zl2HVo)#ig;uSh^4olfK-Y12H+vV7#h6JGaE3)D@hqnYk8bG=?K?sjq1a@L_6$B=cq z=)xt%NRJy3`-EaXje{E}dMu(F$9@OIE@>;5Be)GCMfA3L&?n zR`LF_3V1sYgRpBqzW+Mo`S5nw4^H|}{-hs-C*j3|?%_$; z2TmBE*B|sxfFw|O3DIYVgj*By01OMTIe@o!h(`P1;f|qXunl-_cpu|kV)%9deE}AS z;Gp{?3$&uD{I`{?+T=xNyMKWW`ZrH$iWFIoq*c%9(kMbwHJE}E?ng&-kw z=Scz24e#SV)V!_TcX@NY-Fnb_ct03WMxG#Z5zC0qUT^ONh3Q6!sNa1ShVNavbn&y8 zD)M_b!iXRdvn7}CGMK3bHq>?RbVe~Zmzdl19bN;^D?L7&@oexa~0)xs0oQaDWHW`Hct5Tjl%=a@JuSw;Z+>Z$1wG3dwtGxR; zvJ=QpTEH8&uD*TeKKx76Zr^!udJ4Q4k=p8IFVFuxTk z-zFn^+ckaPZnA3>XE}g)irjgGKYILZlH^3dUosQ z3C=OheLVo6?L`<~<0Ee$6V5tm8&H~Rz{&e?xC!uFnm@+-a4AmBx%G1Z@f5kQ*KTW| z3LfR21vFu`tR2#iBF0N-4N){}?bCBLnI|~MF!#D&Ltp%IWuaqyO=B}Kz-U>D_u<2b zNLUMOcprCd_j}hVcFnnU(Y@)}`}x-!Z{pr`gJH1QctgOWb{fyzL?r7{9LIRHXhQxn zEIjtnZj9XZPuiEjpWy{{E$Sj^G={%HcT_F9O=e8&grnRGtmC z0eBJ6v?WecaTs0-Xp99Rz@yVs1y_egjNndlPjl5|j>Pm7x!3)=&A#DHwE|6hDTPTN zQO1(|)e?H5h;aYaZR{>VdyTjsam6~qR<%NTiB6!9sJU%rg*!d4d53vY2Z9>;C9)p$w7n+|obhf=sEInABP z!x9g%rqu6w!3Lpu+B^9XxzROppb05k|K}qs7&W`Yod_aM&0f9^a+hZ@gYhvzNJl9v|D7>B`w=Rj}0NZeQ zn}^=~v0t0$q%5{?H;i|{60*()r~&t1e5PL@`YKXnzs%hg=vKAw3GaYDkYd`njLT#V zlJsPZG`7ssnT}y)>#nZ$t%U9O-Q$qBl)8z&bc&NEoQupwC^K0D64re^-*FBgo}%(~ zfr28Ei3$-IZZi_*AWL1z<5;Yw;Ar5+Mr4@sb_fTJp53LU9HsoAM_hpu74^BtG|+ZIod z*08cQ2&z(?j;kejm9neB+1VLb{F?=;bL$)AVjJ$1{d*pG35oiil{#8>Ayd$+U;{ih zK!$&sbM@}d4wYp?G&)Px^-PDijJ{r%`St(4UFjOBbG4%lPNg72W_IHvqcY>g6Fwdq zm~j7EE%|PII!AM*y66GPdHV0y-Pzc%of}bBZfxxA(2?^r;nBRav2oB#KSoMi%6DDx zyEMLD`^iMZ%!zghj3GJl=3^JnO8f&1czhs_0acjp$bo7J#s4bpS9`t0&A>I^|uM_!0^hF7_ADY(evLNj4eO0FhAPg>NZ;6TI9BZv$-1kIVR)ld%hTszWuI6`*6X z&UpTsz*rszIISPyq!*EreSZ2BJW!EnbCcp2HzBkx@Z&PJntCn`&{Rz}CP-_z8*duS zI;5$Ffwa2Zh-1oIRAo5x>}-I(O@upcxS$IZ)XZtSB#mjvEd9r2op=c(9uXoc!wKMI zPob6OG>+qg-XTd&6Y*wr9eyJtFf|9S0+~5-xF)!g6YjOhTh3LIYyvLfJvx5OLh4Y7 z?3|mu7PY)%Top|m$Mr7$BN*p?!_;TEd4pkVUEpz(z)E%&;8~Dxot@pgelL!9kkC7) z*3XWfOH(yflO_AE@!^)@C6J751G{A|U8YQFmHE8MpQ13jolSfhmOf9(Q#EXv<+!1D znG?V*!P~(lag(L06vb#H+YGK!)&ZFsS>U4U_kh;~n_qm+XA-X8k)aY_4?$udfA$#B(J6 z&Bm77R@pJsn*KOnZx+Y7by4+d$^4tUna;v*zH1cy<|`TE-`vg8SC?6g^F>!2CwQs8 zxM&uB^IfCpH(!bPchUXpiru=)e51EGuI|X(`W12bO5FMDTQ}x4&KF&AoZvl={qD5m zpy)SWiTGFiOVL=bIPi_$;<$R@@Xhlg4qu7jty}E6eD3Sb;yCfI_;<1DvwKHgZ)q_v zeI@nARi>RUy5cygS5mJQt6sV8=XIAA^U_x$`78M=`K$7Ke!1YAt;KQk)457bEaLE$ z2wtgIi&d}6_T+Vz`(|r#T%A#s>sG|!E0KC7^=h%|Rh9exyyp65YjK?9ujH@fugcr` z2Ig|zV z2(tR4D{5E*B`?nZ-wNC|dE6u>kIda}5~AU{y7A?u&8)@6aQ6NG%>-`~-m4P-N<8N) zm1;}=O8!!HsDB)|<2Ns@KMq$dcFFR{+-(1A_v^jW2X_`mo zZcDwAdPUW+{&C=r-@LT`I9&H0mn@IW-4?t}h+Xlo|9-<|t0v0a`I?tX{!0E*bk{!) z@{#Lq*B^&(Epg+^OGoX(o7101=599!&nQjZ`0~=_i)Y{bsQb9QCsq4zbK)iNZwB%b z;58op1^zSx^OW}^7bn>SSBeXm#dac-De3eP5g>7(vAeD%}F zO3puz~DwE9h*zP6xc9siTulESU$X?_Tf$G9~Q-FUsKSG z)-%O4gj=Hh6j z&x`HfVSgJHzHbr@*=1N=O+qwWR}0h-wwZfJ*M4XSNUKZmHs*OD32)_V&+q3nbiYAR zO-v`at)MMu?RnM(3~Lzc`Zbl6gS2{@jQ5NUua0+d%cPKHqdjHdFIYA!Th z1Klu-?O%o|@jN7NbyqX<*MzZQmLQ(h9XPoU`{PZ@TjNhUVuzodFt-{=-uEL1;s(Oq z8XK>=eXkJwg~z)R;|EYz=&N$mTKXm2#{(E_OWc{v&0t zO$&{8jVl$y4OUk03tHrQ1-zQhK+NwoBV)5#dgiZ%SL0r3CSLk}^Jt1bHZWH~XnYbi zGoBp|{*3GD{V2ua*jJ5D47*CSE1YURRnuVUAN?giqpcINBi0c{=;y2=KH*02JOmt z=b>~3yHv(oVeNTL6}@jz?8zdisxQU3yaTnri7Q5vOs6{%&$i%GE2bI#5)3()ty^)hJbS` zTRP2>ogLtM;0#(;Ad}4h;+{Gyz?0#1>pV(26w}boQCIfwp9t@-1FIC5 zuEhw(gE5gdr3$z@rm})Y{~Ol|jhFrMSL!DN?@Wy=i#5sucyFUwZ*P!wtEFzE{Nqyg-)*67i`RC?(((&hnzPRRJ-HWm zZ3Pxgb4V#`$E}C%jMrmay@vcwtCOj*ueFrU>icFn2j-gg_{Q@8)>zHQR^0No#p=tr zojcasUHVdUKD&|3St(gwEFcyT3y1~80%Cy$u)v!Iz#tIB0%8HNfLK5*AQlh{hy}y~ zVga#$SU@Zw77z=F1;hek0kMEsKrA2@5DSO}!~$Xgv4B`WEFcyT3y1~80%8HNfLK5* zAQlh{hy}y~Vga#$SU@Zw77z=F1;hek0kMEsKrA2@5DSO}!~$Xgv4B`WEFcyT3y1~8 z0%8HNfLK5*AQlh{hy}y~Vga#$SU@Zw77z=F1;hek0kMEsKrA2@5DSO}!~$Xgv4B`W zEFcyT3y1~80%8HNfLK5*AQlh{hy}y~Vga#$SU@Zw77z=F1;hdqTHrSm&XZ|kfqGfs zzb$qC-{KdO{huI<_rDes<`Sd&y@maMEq*cC{|mBs<JaL)d}qr_R`HQx3Xdmwr;=n zGJZ+&%aCgg!eEZce={UY5u0FC|9@k_0t04GA(Bmd{pIONfW*J`QmujTT7jo#%?Q+j` zTIc&w-Sql2_{_+Ou)Vz=y!RWG(P>|Y1L?&^By#W0?IglyddB6wx7Mq*)MwLb_h)-X zPK0eF^mg#`YgA2vsI@Mw&s<8KO-zwLcW%G`Q#yaevyP-7=tb(RkH)iJY;M5Gwch^j z?Y$=|b(IRd0q<7~84I=PyY_i1PAXA)7QFWuB-e)=ymNbtPG9}}8m%&1qA1p)I-8M` z`w`XEm0lDBZ@h1{|HXCyycFX1XmPOmVp^Hn1OlMOR3_+>HqBThFBM+EeNW-t*x10> z5l$%Y{KZeydE=dptN6i{jjK>zh4$(@IPS+E5?-{Yri_}w-U4bQbo}{~t5>gXyn_S1 zFa#YoQg=Kg1$J7z8IH-nU+w?07u?$JZEtTQ`)&mveZ&T$k22*Rin@}y5XB!x!23A> zQ*&C9d+%-E!k9E#Z~MbICOx`liU&&FB#ABHP8Z*F9Hhw;UH13)pU~^c{u7!hNZaUB zc=#Dt^x^yO$to`CvQGl%Gb#5`-KXR8{V3jl4q54NdV-(tsX(5vut{~$u1|Hg#&L_g zh&>YZ{KENsezWQ=row4Dk^SA^Yx-eWyI+$Gh>VC@Gh`Y*>l=0z`gB_SHTTKvXQXiwxR6XN48N7q}4mcOL0x$ z&JJ(5r{My+jY`Sx_*(8(7b%|$Mf<|}mo#waa~gBimZDKe=g-zgR=n!kesaK2c(VWs{c=Ld%T?R0BRKwawH{OEBzKZ-R;!%fV zC9McPyUhoCy&?srblQ=dq*e1U%ldNwTF*Z8;~2Vr zAD8gTyS3H{!}!LH8>-9W;NUnZsv+>^drVueg7@*O(ca!(zdu^p>-YM5D+m4lGf0Ep z0|HFGukM|^I!Ti6(igqKZYL@0>+8c&7sr#~X#HgUW+&_bFR_Gvz-!=8XAW>O3L&?% zR>}Ul3V3^ugK&5<+#3Y}4x_!`V9@IgUjgdgXpivj4ZFi`CkP2+7AIICZ;pIYx8`hu!W0@S37fW&rzRGou*6`~K_9=fk_RD>O15y60h$R+ITJ+t5@NEkKA9n5dQrO?ytjnzxveJ#Lq!+SUk?!rGt zgs=eI!SUfHlADkYhm1DpbdQctsXPxm!)Kj`SZU*UFo-q)E#4q_cv0!Z3>Vc-h=m|2 z=FXD>o*Uk$L%4ZYhwsYPMz`~5@c3acq8WLDnTuRTb`A!6Cs>$nhRFKe7h(9p`ugQB zVp@?uxEV$SnM)_8WJW>$6JV^?n9v5VZZ^mD>hVbcFErlhbhq2>4NhMGB+bfK6kiAj z51x&t>xJftFDP_R7}QMyE4EL?1l^ z2OkH)UGkgf@B971voPHG*sMShuyO%s5@Lo;giw6dl;;TZ{mjN|rg9_qBSLsR1DNot z=zfXW3FIdo;0-(1-o5t_@ukx3-g|U<3cP5MmZu8u2e|2?#A}$+2(^wc-M~1)bT78> zVlzt3o62W^r9!ZES>?nfWFtn0!=u$s_si4gFFM_iQN!zW_zE+Z=4@I}SM!(M$0Wu? zR#O-BaXu%DV5gJrlxf>Yo5;rS0%aDiLi^2AovBxl)0csg=WXzAaPQi?_c`d{rltd^ z04eOePk2o^rnMTyD6~LfPD+$cehFKm7hX z`Z?$*g5mr!AiQ zXGb$Xi!|S+EA+N&`o7(CV-$NifOx9h^9YGJOqV8FtE^PCaxxLoTr1;Us~<#ko#1l= zy@;k~w|}1C9L?P00RU|;!tgpDdHa}1)=6_f(^Laa-iO0YfcsMa3EqcGacar!p96@e z$~|7UtAQ$bH1{l^iKunmkbYEQyoA;i%4Y3-dakDP1m|exw)-vo#V@Zcbd0ZSYz77d ztxNGfe*72{)&d(o#9iC{-gSyyOKxBE)%5KB{OgT332(Z=FxYIoA>dIx&1bG6ll4*@ z$9S|@g!#*`@YqMYF$&i|=~(iG^q}yfuJW0y2)tRdZc?z@A79Gn2(e+ToStLxBB5=( zF)hmI%Do{j0A3_CZHd#VI1Vo*G}@vd!K2et1y`p=jO0$|o|dZV923)1<+l56mt(`5 zY6Y71QVNqkVi`;3uh!5LMTGmWu48wJvbPZTBVMtN@c8#sd9UM3TYe2Zj(9u4>$qx# zsmq^ZgB;ph^8S)`M>?wMxth*1n2u&{yOf_Fhv9RepjS!J93ZTe!d&8Adb&s#c3QdG zKYsxi&w-)JXO)(OCc+28s&I10@qNa~&7z1;as2vqd>>p{rCoT7yYV>gs;$OrD!l1X z2fHbyYci+#V)C%WO{^~MdtR_XXqom-eucv5YB|ycQ?~ujM^-Xwan(_hYw>7E=`k8punXOflL6~ZLhf3#N1fi*H`CQ zcs*5aUy{H9wvq5Q554(gzqW9ZX0d&{VZ0;O5IdVF3vmC%XZnRgUqy=Sm$|zF-Kvf~ z;T_QjQd~B#V3;f+$(0OA6YD&K>1bAFcXf4WP1xbk-3}9%rf%Xdo#Ld5;9}+?mAP0A z645=LZ#xGNPgS{HprDN8LJJWDt}_yrpi4u^?O3h4;Ar5+MrDL@yQT>X?slHw9L?P0 z!IW_w0)9)|>4v7gR#YYY+ ztPKmEZ@ctwTRcHp&B|;LROL7wS4;3JXIF!>vonbJn+00uHa025Hr$%yI}5yoM19Xn z9W7pn3VIbdz+(e+_|u$g_jh(^SvG}QXNxtSx!|p%uh(UM{l9NlY9kG<4z$6k9AwBW zZhm51X1sX9$3p`b+`m>!z8jzR(Nd`|x#ynkh^J)U!h(A%s+mp#>&1czmYSF2tn=q(Wb9a2B zi0+|u)FtsRS-EoeC_FoD1sd-|`U(LR?s`4AvQ-V6_8>i1Tc2I=#X3V!)sYRc&xk6o zTnaAcapD7g)y3d_0VTstzAJvV0P)pO88A@Nnv-lYsDeUDg%`1<`J3S7i-qA zQUhJ8=_UkeHFx7plUb)UtzjtIU9QA2&0DO>2Thq&ZF0ThR@~jY#0KICvGv%#qVI!IhkFuf@FO zxk{QXz$Ls#$4^;F7t};{_RWq(HSZi(izbefMi>7OjB~$X)@OuylVNLL5OFhsmF_IS zvmoI*J9}{BK^*U3LhqbfKRdcFb=9SsF4=cY4!0C9fn;o(*e&zYWtJ)JGM~5jQxrzG zvxP6i(&s7pQVmXJL`*kTBEZ01mmu@zA zv+&w8He2yf(+1zq-m2E?{`rG+Nv)In&E8_Wwj*=(gi>mIIbppPk%DE*sjF zT+@21%1Fk1rc$ppGn&grgLsV}EHq$P@D^^3*%;JSqnpsoOVQc6#kc4RZ8&N!E+a)< z1JkHzlr(cPJSVe)*PR8mYbCz5Q|caYPDIbitju3`7Syhl_|{ITd%!snJtwm=f8AM7 zyH?^`JEiUc9YnhyAd21H?Mk)D0Lk^@aLs50uajrzGpvIvXXiF4J$)9uxRrTw)u!9EQi?<^PRy(u2cBBdQAdocPzD6e_oG z1f0W&;B}Bf&qC#8DdRg8s4<{Ci#9Ozr0ccJW4!q8GH7n<2RzBaa zIgVw+NqozgsaZcKqUU5*=5NjEQ#PE$w~U#Z^>ZS6PG)8P)|@_N!%2M0n5kJ`_j7>n zcs0Y2;e-KUKo}4PgaKhd7!U@80bxKG5C((+VL%uV21*(Dq4bJem@xzY>N~!7L*D`C z*zQ8*+nWo8HV6dn9B0-nO~0Mx;B}8Zk1U)gK{LfW)4`{Ud<$Kg4v1&3+2Q>Id!UY< z&NR?$c6b|behL$UcM8%Ls7qb(ee=cvx^0seF4l!NkM^xm{D+b9!jE}H1NF*y=izh( zUMl0QV0#{21@AmqZ_Z{r;_K(dk2S0newJpS&gLl?^rsMlDo3_8el4JMeP+0_x zziKrUu`UK`O6Mw(ds7z{pK)r!%cd;QnLYE{a~x?BaGiM1fn{CJS#1z-&a&lGlVWp# z+krP|4DfV#-<}uzOoPm1{%3dBrT|Ze*X{Fp+Oe3%UOaDP|LarX{X<|a#ih0w!DKL| z@}|@Q*M(XvX!QT-vas;F-~C?wWPrTQ)B<|}nk>Y*aavLRuRr1^_2hTIH!?9{Dk2C2 z!ob2X@OEK5t>$QYOPh8jUPz|&P1u*blqTOE3)ODP;g!ashPRMQ$DZ4Tr36(2n@N(t ztzoDI8DiQceL>)rxjE_LUN%lMdj3lDGJUVP8QR2(Fdz)Hh=GZ=9SgGFUDSPXi_%J5 zX%7R~PvW=aLzecqd7dY4{slO!*Lm%i`})F%(C&7H?w={VxN9r05EiE> zXYIW8@SX8`v};$BKWTR|YwTOCrL+3JSuTLNs@;BJ<$qgP&nI@=inb-{Vcfx;=}v;VAY z0-u^`s&O}CZT?m+7T!OZyq-Vv;(;(A3~X5jw;O1axD literal 0 HcmV?d00001 diff --git a/data/volcano.map b/data/volcano.map new file mode 100644 index 0000000000000000000000000000000000000000..fc53dabb889aff2a965ca9abbee85275fa80e3f8 GIT binary patch literal 114242 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 b then max:=a else max:=b; +end; + +function min(a,b:integer):integer; +begin + if a < b then min:=a else min:=b; +end; + +function OpenPicture(name: PChar) : PSDL_Texture; +var + image: PSDL_Surface; + texture: PSDL_Texture; +begin + image := IMG_Load(name); + texture := SDL_CreateTextureFromSurface(renderer, image); + SDL_FreeSurface(image); + OpenPicture := texture; +end; + +procedure CloseSound(var sound: PMix_Chunk); +begin + if sound <> nil then + Mix_FreeChunk(sound); + sound := nil; +end; + +procedure CloseMusic(var music: PMix_Music); +begin + if music <> nil then + Mix_FreeMusic(music); + music := nil; +end; + +procedure ClosePicture(var picture: PSDL_Texture); +begin + if picture <> nil then + SDL_DestroyTexture(picture); + picture := nil; +end; + +function GetTile(x, y: byte): byte; +// Entrada: coordenades en tiles relatives a la habitació actual +// Eixida: el valor del byte +var + room_x, room_y: byte; +begin + room_x := (map.room mod 12) * ROOM_WIDTH_IN_TILES; + room_y := (map.room div 12) * ROOM_HEIGHT_IN_TILES; + GetTile := map.tile[(room_x + x ) + (room_y + y) * map.w]; +end; + +function ReadMapTile(x, y: byte): byte; +begin + case GetTile(x,y) of + 000 .. 063: ReadMapTile := TILE_BACKGROUND; + 064 .. 143: ReadMapTile := TILE_PLATFORM; + 144 .. 175: ReadMapTile := TILE_TRAVESABLE_PLATFORM; + 176 .. 207: ReadMapTile := TILE_KILLING_PLATFORM; + 208 .. 255: ReadMapTile := TILE_ACTOR; + else ReadMapTile := TILE_BACKGROUND; + end; +end; + +function GetActor(x, y: byte): byte; +var + room_x, room_y : byte; +begin + room_x := (map.room mod 12) * ROOM_WIDTH_IN_TILES; + room_y := (map.room div 12) * ROOM_HEIGHT_IN_TILES; + GetActor := map.actor[(room_x + x) + (room_y + y) * map.w]; +end; + +Procedure SetActor(x, y, valor: byte); +var + room_x, room_y : byte; +begin + room_x := (map.room mod 12) * ROOM_WIDTH_IN_TILES; + room_y := (map.room div 12) * ROOM_HEIGHT_IN_TILES; + map.actor[(room_x + x) + (room_y + y) * map.w] := valor; +end; + +procedure SetMapGFX(zone: byte); +begin + case zone of + ZONE_SURFACE: + begin + map.sprite_tile := OpenPicture(FILE_TILES_SURFACE); + map.background := OpenPicture(FILE_BKG_SURFACE); + end; + + ZONE_VOLCANO: + begin + map.sprite_tile := OpenPicture(FILE_TILES_VOLCANO); + map.background := OpenPicture(FILE_BKG_SURFACE); + end; + end; +end; + +procedure SetMapMusic(zone: byte); +begin + case zone of + ZONE_SURFACE: + game.music := Mix_LoadMUS(FILE_MUSIC_SURFACE); + + ZONE_VOLCANO: + game.music := Mix_LoadMUS(FILE_MUSIC_VOLCANO); + end; +end; + +function CheckZoneChange(room: integer): boolean; +var + zone: byte; +begin + case room of + 0 .. 23: + zone := ZONE_SURFACE; + 24 .. 255: + zone := ZONE_VOLCANO; + end; + + if (zone = game.zone) then + CheckZoneChange := FALSE + else + CheckZoneChange := TRUE; +end; + +procedure SetZone(room: integer); +begin + case room of + 0 .. 23: + game.zone := ZONE_SURFACE; + + 24 .. 255: + game.zone := ZONE_VOLCANO; + end; + + SetMapGFX(game.zone); + SetMapMusic(game.zone); + Mix_PlayMusic(game.music, -1); +end; + +procedure SetPlayerAnimation(anim: byte); +begin + if (anim <> player.active_animation) then + begin + player.active_animation := anim; + player.src_rect.y := anim * player.src_rect.h; + player.animation[anim].index := 0; + player.animation[anim].timer := 0; + player.animation[anim].loops := FALSE; + end; +end; + +procedure Animate(var a:Tanimation; var s:TSDL_Rect); +begin + // Mirem si estem en el penultim frame per avisar de que anem a pintar el ultim + if (a.timer = (a.num_frames * a.speed) - 2) then + a.loops := TRUE + else + a.loops := FALSE; + + a.timer := (a.timer + 1) mod (a.num_frames * a.speed); + a.index := a.timer div a.speed; + s.x := (a.frame[a.index]) * s.w; +end; + +procedure AnimateIntroMenu(var a:Tanimation; var s:TSDL_Rect); +begin + // Mirem si estem en el penultim frame per avisar de que anem a pintar el ultim + if (a.timer = (a.num_frames * a.speed) - 2) then + a.loops := TRUE + else + a.loops := FALSE; + + a.timer := (a.timer + 1) mod (a.num_frames * a.speed); + a.index := a.timer div a.speed; + s.x := (a.frame[a.index] mod 4) * s.w; + s.y := (a.frame[a.index] div 4) * s.h; +end; + +procedure CreateActor(var a : Tactor; kind, id : byte; dstx, dsty, dstw, dsth, srcx, srcy, sx, sy, timer, frame : smallint; direction, parent : byte); +begin + a.kind := kind; + a.id := id; + a.dst_rect.x := dstx; + a.dst_rect.y := dsty; + a.dst_rect.w := dstw; + a.dst_rect.h := dsth; + a.src_rect.x := srcx; + a.src_rect.y := srcy; + a.src_rect.w := a.dst_rect.w; + a.src_rect.h := a.dst_rect.h; + a.direction := direction; + a.speed_x := sx; + a.speed_y := sy; + a.timer := timer; + a.frame := frame; + a.enabled := TRUE; + a.parent := parent; +end; + +procedure LoadMap(map:Pmap); +var + f: File; + numread: Word; + size: array[0..1] of byte; +begin + Assign(f, FILE_MAP_VOLCANO); + Reset(f, 1); + BlockRead(f, size, 2, numread); + map^.w := size[0]; + map^.h := size[1]; + SetLength(map^.tile, map^.w * map^.h); + SetLength(map^.actor, map^.w * map^.h); + BlockRead(f, map^.tile[0], map^.w * map^.h, numread); + BlockRead(f, map^.actor[0], map^.w * map^.h, numread); + Close(f); +end; + +procedure LoadRoom(num:integer); +var + i, j, k: integer; +begin + if (CheckZoneChange(num)) then + begin + SetZone(num); + end; + + // Coloquem el numero d'habitació corresponent al mapa + map.room := max(0, num); + + // Guardem les coordenades i el sentit que te el jugador al entrar a la habitació + player.respawn_x := player.dst_rect.x; + player.respawn_y := player.dst_rect.y; + player.respawn_direction := player.direction; + + // Esborrem la llista de tiles animats + for i:=0 to MAX_ANIMATED_TILES - 1 do + animated_tile[i].enabled := FALSE; + + // Escanejem la habitació en busca de tiles animats + k := 0; + for i:=0 to (ROOM_WIDTH_IN_TILES - 1) do + for j:=0 to (ROOM_HEIGHT_IN_TILES - 1) do + case GetTile(i, j) of + 48 .. 63, 128 .. 143, 160..175, 192..207: + begin + animated_tile[k].enabled := TRUE; + animated_tile[k].x := i * MAP_TILE_WIDTH; + animated_tile[k].y := j * MAP_TILE_HEIGHT; + animated_tile[k].index := GetTile(i, j); + animated_tile[k].frame := 0; + inc(k); + end; + end; + + // Esborrem la llista d'actors actius + for i:=0 to MAX_ACTORS - 1 do + actor[i].enabled := FALSE; + + // Escanejem la habitació en busca d'actors per afegirlos a la llista d'actors actius + k := 0; + for i:=0 to (ROOM_WIDTH_IN_TILES - 1) do + for j:=0 to (ROOM_HEIGHT_IN_TILES - 1) do + begin + case GetActor(i, j) of + CODE_ENEMY_V1U: + CreateActor(actor[k], KIND_FLYING_ENEMY, 0, i * MAP_TILE_WIDTH, j * MAP_TILE_HEIGHT, 16, 16, 0, 4 * 16, 0, 1, 0, 0, UP, k); + + CODE_ENEMY_V2U: + CreateActor(actor[k], KIND_FLYING_ENEMY, 0, i * MAP_TILE_WIDTH, j * MAP_TILE_HEIGHT, 16, 16, 0, 4 * 16, 0, 2, 0, 0, UP, k); + + CODE_ENEMY_V3U: + CreateActor(actor[k], KIND_FLYING_ENEMY, 0, i * MAP_TILE_WIDTH, j * MAP_TILE_HEIGHT, 16, 16, 0, 4 * 16, 0, 3, 0, 0, UP, k); + + CODE_ENEMY_V1D: + CreateActor(actor[k], KIND_FLYING_ENEMY, 0, i * MAP_TILE_WIDTH, j * MAP_TILE_HEIGHT, 16, 16, 0, 4 * 16, 0, 1, 0, 0, DOWN, k); + + CODE_ENEMY_V2D: + CreateActor(actor[k], KIND_FLYING_ENEMY, 0, i * MAP_TILE_WIDTH, j * MAP_TILE_HEIGHT, 16, 16, 0, 4 * 16, 0, 2, 0, 0, DOWN, k); + + CODE_ENEMY_V3D: + CreateActor(actor[k], KIND_FLYING_ENEMY, 0, i * MAP_TILE_WIDTH, j * MAP_TILE_HEIGHT, 16, 16, 0, 4 * 16, 0, 3, 0, 0, DOWN, k); + + CODE_ENEMY_H1L: + CreateActor(actor[k], KIND_FLYING_ENEMY, 0, i * MAP_TILE_WIDTH, j * MAP_TILE_HEIGHT, 16, 16, 0, 4 * 16, 1, 0, 0, 0, LEFT, k); + + CODE_ENEMY_H2L: + CreateActor(actor[k], KIND_FLYING_ENEMY, 0, i * MAP_TILE_WIDTH, j * MAP_TILE_HEIGHT, 16, 16, 0, 4 * 16, 2, 0, 0, 0, LEFT, k); + + CODE_ENEMY_H3L: + CreateActor(actor[k], KIND_FLYING_ENEMY, 0, i * MAP_TILE_WIDTH, j * MAP_TILE_HEIGHT, 16, 16, 0, 4 * 16, 3, 0, 0, 0, LEFT, k); + + CODE_ENEMY_H1R: + CreateActor(actor[k], KIND_FLYING_ENEMY, 0, i * MAP_TILE_WIDTH, j * MAP_TILE_HEIGHT, 16, 16, 0, 4 * 16, 1, 0, 0, 0, RIGHT, k); + + CODE_ENEMY_H2R: + CreateActor(actor[k], KIND_FLYING_ENEMY, 0, i * MAP_TILE_WIDTH, j * MAP_TILE_HEIGHT, 16, 16, 0, 4 * 16, 2, 0, 0, 0, RIGHT, k); + + CODE_ENEMY_H3R: + CreateActor(actor[k], KIND_FLYING_ENEMY, 0, i * MAP_TILE_WIDTH, j * MAP_TILE_HEIGHT, 16, 16, 0, 4 * 16, 3, 0, 0, 0, RIGHT, k); + + CODE_ENEMY_W1L: + CreateActor(actor[k], KIND_WALKING_ENEMY, 0, i * MAP_TILE_WIDTH, j * MAP_TILE_HEIGHT, 16, 16, 0, 1 * 16, 1, 0, 0, 0, LEFT, k); + + CODE_ENEMY_W2L: + CreateActor(actor[k], KIND_WALKING_ENEMY, 0, i * MAP_TILE_WIDTH, j * MAP_TILE_HEIGHT, 16, 16, 0, 1 * 16, 2, 0, 0, 0, LEFT, k); + + CODE_ENEMY_W3L: + CreateActor(actor[k], KIND_WALKING_ENEMY, 0, i * MAP_TILE_WIDTH, j * MAP_TILE_HEIGHT, 16, 16, 0, 1 * 16, 3, 0, 0, 0, LEFT, k); + + CODE_ENEMY_W1R: + CreateActor(actor[k], KIND_WALKING_ENEMY, 0, i * MAP_TILE_WIDTH, j * MAP_TILE_HEIGHT, 16, 16, 0, 0 * 16, 1, 0, 0, 0, RIGHT, k); + + CODE_ENEMY_W2R: + CreateActor(actor[k], KIND_WALKING_ENEMY, 0, i * MAP_TILE_WIDTH, j * MAP_TILE_HEIGHT, 16, 16, 0, 0 * 16, 2, 0, 0, 0, RIGHT, k); + + CODE_ENEMY_W3R: + CreateActor(actor[k], KIND_WALKING_ENEMY, 0, i * MAP_TILE_WIDTH, j * MAP_TILE_HEIGHT, 16, 16, 0, 0 * 16, 3, 0, 0, 0, RIGHT, k); + + CODE_ENEMY_SPL: + CreateActor(actor[k], KIND_SPEED_ENEMY, 0, i * MAP_TILE_WIDTH, j * MAP_TILE_HEIGHT, 16, 16, 0, 3 * 16, 1, 0, 0, 0, RIGHT, k); + + CODE_ENEMY_SPR: + CreateActor(actor[k], KIND_SPEED_ENEMY, 0, i * MAP_TILE_WIDTH, j * MAP_TILE_HEIGHT, 16, 16, 0, 2 * 16, 1, 0, 0, 0, RIGHT, k); + + CODE_ENEMY_DRP: + CreateActor(actor[k], KIND_DROP_GENERATOR, 0, i * MAP_TILE_WIDTH, j * MAP_TILE_HEIGHT, 16, 16, 0, 10 * 16, 0, 0, DROP_TIMER, 0, NONE, k); + + CODE_COIN: + CreateActor(actor[k], KIND_COIN, 0, i * MAP_TILE_WIDTH, j * MAP_TILE_HEIGHT, 16, 16, 0, 12 * 16, 0, 0, 0, 0, NONE, k); + + CODE_HEART: + CreateActor(actor[k], KIND_HEART, 0, i * MAP_TILE_WIDTH, j * MAP_TILE_HEIGHT, 16, 16, 0, 13 * 16, 1, 0, 0, 0, NONE, k); + + CODE_KEY_RED: + CreateActor(actor[k], KIND_KEY, 0, i * MAP_TILE_WIDTH, j * MAP_TILE_HEIGHT, 16, 16, 0, 14 * 16, 1, 0, 0, 0, NONE, k); + + CODE_LOCK_RED: + CreateActor(actor[k], KIND_LOCK, 0, i * MAP_TILE_WIDTH, j * MAP_TILE_HEIGHT, 16, 16, 0, 15 * 16, 1, 0, 0, 0, NONE, k); + + CODE_KEY_BLUE: + CreateActor(actor[k], KIND_KEY, 1, i * MAP_TILE_WIDTH, j * MAP_TILE_HEIGHT, 16, 16, 1 * 16, 14 * 16, 1, 0, 0, 0, NONE, k); + + CODE_LOCK_BLUE: + CreateActor(actor[k], KIND_LOCK, 1, i * MAP_TILE_WIDTH, j * MAP_TILE_HEIGHT, 16, 16, 1 * 16, 15 * 16, 1, 0, 0, 0, NONE, k); + + CODE_KEY_GREEN: + CreateActor(actor[k], KIND_KEY, 2, i * MAP_TILE_WIDTH, j * MAP_TILE_HEIGHT, 16, 16, 2 * 16, 14 * 16, 1, 0, 0, 0, NONE, k); + + CODE_LOCK_GREEN: + CreateActor(actor[k], KIND_LOCK, 2, i * MAP_TILE_WIDTH, j * MAP_TILE_HEIGHT, 16, 16, 2 * 16, 15 * 16, 1, 0, 0, 0, NONE, k); + + CODE_KEY_YELLOW: + CreateActor(actor[k], KIND_KEY, 3, i * MAP_TILE_WIDTH, j * MAP_TILE_HEIGHT, 16, 16, 3 * 16, 14 * 16, 1, 0, 0, 0, NONE, k); + + CODE_LOCK_YELLOW: + CreateActor(actor[k], KIND_LOCK, 3, i * MAP_TILE_WIDTH, j * MAP_TILE_HEIGHT, 16, 16, 3 * 16, 15 * 16, 1, 0, 0, 0, NONE, k); + + else + dec(k); + end; + inc(k); + end; +end; + +procedure IniMenu(); +begin + menu.enabled := TRUE; + menu.section := MENU_SECTION_ANIMATION; + + menu.music := Mix_LoadMUS(FILE_MUSIC_MENU); + menu.sound_logo := Mix_LoadWAV(FILE_SOUND_MENU_LOGO); + menu.sound_start := Mix_LoadWAV(FILE_SOUND_MENU_START); + + menu.sprite := OpenPicture(FILE_MENU); + menu.frame := 0; + menu.timer := 200; + + // Fondo + menu.src_rect_fondo.x := 0; + menu.src_rect_fondo.y := 0; + menu.src_rect_fondo.w := 320; + menu.src_rect_fondo.h := 240; + + menu.dst_rect_fondo.x := 0; + menu.dst_rect_fondo.y := 0; + menu.dst_rect_fondo.w := 320; + menu.dst_rect_fondo.h := 240; + + // Logo + menu.src_rect_logo.x := 0; + menu.src_rect_logo.y := 240; + menu.src_rect_logo.w := 260; + menu.src_rect_logo.h := 154; + + menu.dst_rect_logo.x := 30; + menu.dst_rect_logo.y := 30; + menu.dst_rect_logo.w := 260; + menu.dst_rect_logo.h := 154; + + menu.dst_rect_logo_zoom.x := 0; + menu.dst_rect_logo_zoom.y := 0; + menu.dst_rect_logo_zoom.w := 0; + menu.dst_rect_logo_zoom.h := 0; + + // PRESS RETURN TO START + menu.src_rect_text.x := 0; + menu.src_rect_text.y := 394; + menu.src_rect_text.w := 125; + menu.src_rect_text.h := 7; + + menu.dst_rect_text.x := (320 - 125) div 2; + menu.dst_rect_text.y := 195; + menu.dst_rect_text.w := 125; + menu.dst_rect_text.h := 7; + + // JAILGAMES 2016 + menu.src_rect_text2.x := 0; + menu.src_rect_text2.y := 394+7; + menu.src_rect_text2.w := 55; + menu.src_rect_text2.h := 5; + + menu.dst_rect_text2.x := (320 - 55) div 2; + menu.dst_rect_text2.y := 210; + menu.dst_rect_text2.w := 55; + menu.dst_rect_text2.h := 5; + + // Animació + menu.sprite_animation := OpenPicture(FILE_MENU_ANIMATION); + + menu.src_rect_animation.x := 0; + menu.src_rect_animation.y := 0; + menu.src_rect_animation.w := 320; + menu.src_rect_animation.h := 240; + + menu.dst_rect_animation.x := 0; + menu.dst_rect_animation.y := 0; + menu.dst_rect_animation.w := 320; + menu.dst_rect_animation.h := 240; + + menu.animation[0].num_frames := 29; + menu.animation[0].index := 0; + menu.animation[0].timer := 0; + menu.animation[0].speed := 9; + menu.animation[0].loops := FALSE; + + menu.animation[0].frame[ 0] := 0; + menu.animation[0].frame[ 1] := 1; + menu.animation[0].frame[ 2] := 0; + menu.animation[0].frame[ 3] := 1; + menu.animation[0].frame[ 4] := 2; + menu.animation[0].frame[ 5] := 3; + menu.animation[0].frame[ 6] := 4; + menu.animation[0].frame[ 7] := 5; + menu.animation[0].frame[ 8] := 6; + menu.animation[0].frame[ 9] := 7; + menu.animation[0].frame[10] := 8; + menu.animation[0].frame[11] := 9; + menu.animation[0].frame[12] := 10; + menu.animation[0].frame[13] := 11; + menu.animation[0].frame[14] := 12; + menu.animation[0].frame[15] := 13; + menu.animation[0].frame[16] := 14; + menu.animation[0].frame[17] := 15; + menu.animation[0].frame[18] := 16; + menu.animation[0].frame[19] := 17; + menu.animation[0].frame[20] := 18; + menu.animation[0].frame[21] := 19; + menu.animation[0].frame[22] := 20; + menu.animation[0].frame[23] := 21; + menu.animation[0].frame[24] := 22; + menu.animation[0].frame[25] := 23; + menu.animation[0].frame[26] := 24; + menu.animation[0].frame[27] := 25; + menu.animation[0].frame[28] := 26; + + menu.animation[1].num_frames := 23; + menu.animation[1].index := 0; + menu.animation[1].timer := 0; + menu.animation[1].speed := 9; + menu.animation[1].loops := FALSE; + + menu.animation[1].frame[ 0] := 18; + menu.animation[1].frame[ 1] := 26; + menu.animation[1].frame[ 2] := 18; + menu.animation[1].frame[ 3] := 26; + menu.animation[1].frame[ 4] := 18; + menu.animation[1].frame[ 5] := 26; + menu.animation[1].frame[ 6] := 18; + menu.animation[1].frame[ 7] := 26; + menu.animation[1].frame[ 8] := 18; + menu.animation[1].frame[ 9] := 26; + menu.animation[1].frame[10] := 18; + menu.animation[1].frame[11] := 26; + menu.animation[1].frame[12] := 18; + menu.animation[1].frame[13] := 26; + menu.animation[1].frame[14] := 18; + menu.animation[1].frame[15] := 19; + menu.animation[1].frame[16] := 20; + menu.animation[1].frame[17] := 21; + menu.animation[1].frame[18] := 22; + menu.animation[1].frame[19] := 23; + menu.animation[1].frame[20] := 24; + menu.animation[1].frame[21] := 25; + menu.animation[1].frame[22] := 26; +end; + +procedure EndMenu(); +begin + CloseSound(menu.sound_logo); + CloseSound(menu.sound_start); + CloseMusic(menu.music); + ClosePicture(menu.sprite); + ClosePicture(menu.sprite_animation); + menu.enabled:= FALSE; +end; + +procedure IniActors(); +var + i: byte; +begin + for i:=0 to MAX_ACTORS - 1 do + actor[i].enabled := FALSE; + map.sprite_actor := OpenPicture(FILE_ACTORS); +end; + +procedure IniAnimatedTiles(); +var + i: byte; +begin + for i:=0 to MAX_ANIMATED_TILES - 1 do + animated_tile[i].enabled := FALSE; +end; + +procedure IniMap(); +begin + map.src_rect.x := 0; + map.src_rect.y := 0; + map.src_rect.w := 320; + map.src_rect.h := 240; + + map.dst_rect.x := 0; + map.dst_rect.y := 0; + map.dst_rect.w := 320; + map.dst_rect.h := 240; + + LoadMap(@map); +end; + +procedure EndMap(); +begin + ClosePicture(map.sprite_tile); + ClosePicture(map.sprite_actor); + ClosePicture(map.background); +end; + +procedure IniPlayer(); +var + i: byte; +begin + player.sprite := OpenPicture(FILE_PLAYER); + player.dst_rect.x := MAP_TILE_WIDTH * STARTING_PLAYER_TILE_X; + player.dst_rect.y := MAP_TILE_HEIGHT * STARTING_PLAYER_TILE_Y; + player.dst_rect.w := 16; + player.dst_rect.h := 24; + player.src_rect.x := 0; + player.src_rect.y := 0; + player.src_rect.w := player.dst_rect.w; + player.src_rect.h := player.dst_rect.h; + player.direction := RIGHT; + player.respawn_x := player.dst_rect.x; + player.respawn_y := player.dst_rect.y; + player.respawn_direction := player.direction; + player.speed_x := BASE_SPEED; + player.speed_y := 0; + player.can_jump := TRUE; + player.jump_pressed_now := FALSE; + player.jump_pressed_before := FALSE; + player.standing := TRUE; + player.jumpforce := 10; + player.active_animation := 0; + player.enabled := TRUE; + player.cooldown := 0; + player.lifes := 10; + player.coins := 0; + for i:=0 to 5 do player.key[i] := FALSE; + player.sound_jump := Mix_LoadWAV(FILE_SOUND_JUMP); + player.sound_death := Mix_LoadWAV(FILE_SOUND_DEATH); + player.sound_coin := Mix_LoadWAV(FILE_SOUND_COIN); + + player.animation[0].num_frames := 33; + player.animation[0].index := 0; + player.animation[0].timer := 0; + player.animation[0].speed := 6; + player.animation[0].loops := FALSE; + player.animation[0].frame[ 0] := 0; + player.animation[0].frame[ 1] := 1; + player.animation[0].frame[ 2] := 2; + player.animation[0].frame[ 3] := 2; + player.animation[0].frame[ 4] := 1; + player.animation[0].frame[ 5] := 0; + player.animation[0].frame[ 6] := 0; + player.animation[0].frame[ 7] := 1; + player.animation[0].frame[ 8] := 2; + player.animation[0].frame[ 9] := 2; + player.animation[0].frame[10] := 1; + player.animation[0].frame[11] := 0; + player.animation[0].frame[12] := 0; + player.animation[0].frame[13] := 1; + player.animation[0].frame[14] := 2; + player.animation[0].frame[15] := 2; + player.animation[0].frame[16] := 1; + player.animation[0].frame[17] := 0; + player.animation[0].frame[18] := 0; + player.animation[0].frame[19] := 1; + player.animation[0].frame[20] := 2; + player.animation[0].frame[21] := 3; + player.animation[0].frame[22] := 4; + player.animation[0].frame[23] := 4; + player.animation[0].frame[24] := 5; + player.animation[0].frame[25] := 5; + player.animation[0].frame[26] := 4; + player.animation[0].frame[27] := 4; + player.animation[0].frame[28] := 5; + player.animation[0].frame[29] := 5; + player.animation[0].frame[30] := 6; + player.animation[0].frame[31] := 6; + player.animation[0].frame[32] := 7; + + player.animation[1] := player.animation[0]; + + player.animation[2].num_frames := 8; + player.animation[2].index := 0; + player.animation[2].speed := 4; + player.animation[2].loops := FALSE; + player.animation[2].frame[ 0] := 0; + player.animation[2].frame[ 1] := 1; + player.animation[2].frame[ 2] := 2; + player.animation[2].frame[ 3] := 3; + player.animation[2].frame[ 4] := 4; + player.animation[2].frame[ 5] := 5; + player.animation[2].frame[ 6] := 6; + player.animation[2].frame[ 7] := 7; + + player.animation[3] := player.animation[2]; + player.animation[4] := player.animation[2]; + player.animation[5] := player.animation[2]; + + player.animation[6].num_frames := 20; + player.animation[6].index := 0; + player.animation[6].speed := 6; + player.animation[6].loops := FALSE; + player.animation[6].frame[ 0] := 0; + player.animation[6].frame[ 1] := 1; + player.animation[6].frame[ 2] := 2; + player.animation[6].frame[ 3] := 3; + player.animation[6].frame[ 4] := 4; + player.animation[6].frame[ 5] := 5; + player.animation[6].frame[ 6] := 6; + player.animation[6].frame[ 7] := 7; + player.animation[6].frame[ 8] := 7; + player.animation[6].frame[ 9] := 7; + player.animation[6].frame[10] := 7; + player.animation[6].frame[11] := 7; + player.animation[6].frame[12] := 7; + player.animation[6].frame[13] := 7; + player.animation[6].frame[14] := 7; + player.animation[6].frame[15] := 7; + player.animation[6].frame[16] := 7; + player.animation[6].frame[17] := 7; + player.animation[6].frame[18] := 7; + player.animation[6].frame[19] := 7; + + player.animation[7] := player.animation[6]; +end; + +procedure EndPlayer(); +begin + ClosePicture(player.sprite); + CloseSound(player.sound_jump); + CloseSound(player.sound_death); + CloseSound(player.sound_coin); +end; + +procedure IniHud(); +begin + hud.sprite := OpenPicture(FILE_HUD); + hud.src_rect.x := 0; + hud.src_rect.y := 0; + hud.src_rect.w := 320; + hud.src_rect.h := 16; + + hud.dst_rect.x := 0; + hud.dst_rect.y := 224; + hud.dst_rect.w := 320; + hud.dst_rect.h := 16; + + hud.num_src_rect.x := 0; + hud.num_src_rect.y := 16; + hud.num_src_rect.w := 5; + hud.num_src_rect.h := 5; + + hud.num_dst_rect.x := 0; + hud.num_dst_rect.y := 16; + hud.num_dst_rect.w := 5; + hud.num_dst_rect.h := 5; + + hud.bignum_src_rect.x := 0; + hud.bignum_src_rect.y := 21; + hud.bignum_src_rect.w := 7; + hud.bignum_src_rect.h := 7; + + hud.bignum_dst_rect.x := 0; + hud.bignum_dst_rect.y := 21; + hud.bignum_dst_rect.w := 7; + hud.bignum_dst_rect.h := 7; +end; + +procedure EndHud(); +begin + ClosePicture(hud.sprite); +end; + +procedure IniGame(zone: byte); +begin + game.sound_drop_enemy := Mix_LoadWAV(FILE_SOUND_DROP_ENEMY); + game.sound_drop_splat := Mix_LoadWAV(FILE_SOUND_DROP_SPLAT); + game.enabled := TRUE; + game.zone := zone; + + // Inicialitzar jugador + IniPlayer(); + + // Inicialitza hud + IniHud(); + + // Establir el color d'esborrat + SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255); + + // Inicialitza actors + IniActors(); + + // Inicialitza tiles animats + IniAnimatedTiles(); + + // Inicialitza mapa + IniMap(); + SetMapGFX(zone); + SetMapMusic(zone); +end; + +procedure EndGame(); +begin + EndPlayer(); + EndHud(); + EndMap(); + CloseSound(game.sound_drop_enemy); + CloseSound(game.sound_drop_splat); + CloseMusic(game.music); + game.enabled := FALSE; +end; + +procedure KillPlayer(); +begin + player.enabled := FALSE; + player.cooldown := COOLDOWN_TIME; + + // Establir animació de mort + if (player.direction = LEFT) then + SetPlayerAnimation(PLAYER_ANIMATION_DYING_LEFT) + else + SetPlayerAnimation(PLAYER_ANIMATION_DYING_RIGHT); + + + Mix_PlayChannel(-1, player.sound_death, 0); +end; + +function OnFloor():boolean; +//[27/08/2016] [DOC] [BEGIN] +var + tile_on_right_foot, tile_on_left_foot, + tile_under_right_foot, tile_under_left_foot : byte; + + i_am_above_platform, i_am_above_travesable, + i_am_on_background : boolean; +begin + tile_under_left_foot := ReadMapTile((player.dst_rect.x + 3 ) div MAP_TILE_WIDTH, (player.dst_rect.y + player.dst_rect.h) div MAP_TILE_HEIGHT); + tile_under_right_foot := ReadMapTile((player.dst_rect.x + player.dst_rect.w - 4) div MAP_TILE_WIDTH, (player.dst_rect.y + player.dst_rect.h) div MAP_TILE_HEIGHT); + + i_am_above_platform := (tile_under_left_foot = TILE_PLATFORM) or (tile_under_right_foot = TILE_PLATFORM); + i_am_above_travesable := (tile_under_left_foot = TILE_TRAVESABLE_PLATFORM) or (tile_under_right_foot = TILE_TRAVESABLE_PLATFORM); + + tile_on_left_foot := ReadMapTile((player.dst_rect.x + 3 ) div MAP_TILE_WIDTH, (player.dst_rect.y + player.dst_rect.h-1) div MAP_TILE_HEIGHT); + tile_on_right_foot := ReadMapTile((player.dst_rect.x + player.dst_rect.w - 4) div MAP_TILE_WIDTH, (player.dst_rect.y + player.dst_rect.h-1) div MAP_TILE_HEIGHT); + + i_am_on_background := (tile_on_left_foot = TILE_BACKGROUND) and (tile_on_right_foot = TILE_BACKGROUND); + + if ( ( i_am_above_platform or i_am_above_travesable ) and i_am_on_background ) then + OnFloor := TRUE + else + OnFloor := FALSE; +//[27/08/2016] [DOC] [END] + + {if (ReadMapTile((player.dst_rect.x + 3 ) div MAP_TILE_WIDTH, (player.dst_rect.y + player.dst_rect.h) div MAP_TILE_HEIGHT) = TILE_PLATFORM) + or (ReadMapTile((player.dst_rect.x + player.dst_rect.w - 4) div MAP_TILE_WIDTH, (player.dst_rect.y + player.dst_rect.h) div MAP_TILE_HEIGHT) = TILE_PLATFORM) + or (ReadMapTile((player.dst_rect.x + 3 ) div MAP_TILE_WIDTH, (player.dst_rect.y + player.dst_rect.h) div MAP_TILE_HEIGHT) = TILE_TRAVESABLE_PLATFORM) + or (ReadMapTile((player.dst_rect.x + player.dst_rect.w - 4) div MAP_TILE_WIDTH, (player.dst_rect.y + player.dst_rect.h) div MAP_TILE_HEIGHT) = TILE_TRAVESABLE_PLATFORM) then + OnFloor := TRUE + else + OnFloor := FALSE;} +end; + +procedure MoveActors(); +var + i, k: byte; +begin + for i:=0 to MAX_ACTORS - 1 do + if actor[i].enabled then + case actor[i].kind of + KIND_FLYING_ENEMY: + begin + case actor[i].direction of + RIGHT: + begin + // Calculem la nova posició + actor[i].dst_rect.x := actor[i].dst_rect.x + actor[i].speed_x; + + // Si eix per la vora, canvi de sentit + if (actor[i].dst_rect.x + actor[i].dst_rect.w > GAME_WINDOW_WIDTH) then + actor[i].direction := LEFT; + + // Colisió amb el mapa, correcció a l'ultim pixel bo i canvi de sentit + if (ReadMapTile((actor[i].dst_rect.x + actor[i].dst_rect.w - 1) div MAP_TILE_WIDTH, actor[i].dst_rect.y div MAP_TILE_HEIGHT) <> TILE_BACKGROUND) + or (ReadMapTile((actor[i].dst_rect.x + actor[i].dst_rect.w - 1) div MAP_TILE_WIDTH, (actor[i].dst_rect.y + actor[i].dst_rect.h - 1) div MAP_TILE_HEIGHT) <> TILE_BACKGROUND) then + begin + actor[i].dst_rect.x := actor[i].dst_rect.x - ((actor[i].dst_rect.x + actor[i].dst_rect.w) mod MAP_TILE_WIDTH); + actor[i].direction := LEFT; + end; + end; + + LEFT: + begin + // Calculem la nova posició + actor[i].dst_rect.x := actor[i].dst_rect.x - actor[i].speed_x; + + // Si eix per la vora, canvi de sentit + if (actor[i].dst_rect.x) < 0 then + actor[i].direction := RIGHT; + + // Colisió amb el mapa, correcció a l'ultim pixel bo i canvi de sentit + if (ReadMapTile(actor[i].dst_rect.x div MAP_TILE_WIDTH, actor[i].dst_rect.y div MAP_TILE_HEIGHT) <> TILE_BACKGROUND) + or (ReadMapTile(actor[i].dst_rect.x div MAP_TILE_WIDTH, (actor[i].dst_rect.y + actor[i].dst_rect.h - 1) div MAP_TILE_HEIGHT) <> TILE_BACKGROUND) then + begin + actor[i].dst_rect.x := actor[i].dst_rect.x + (MAP_TILE_WIDTH - (actor[i].dst_rect.x mod MAP_TILE_WIDTH)); + actor[i].direction := RIGHT; + end; + end; + + DOWN: + begin + // Calculem la nova posició + actor[i].dst_rect.y := actor[i].dst_rect.y + actor[i].speed_y; + + // Si eix per la vora, canvi de sentit + if (actor[i].dst_rect.y + actor[i].dst_rect.h > GAME_WINDOW_HEIGHT) then + actor[i].direction := UP; + + // Colisió amb el mapa, correcció a l'ultim pixel bo i canvi de sentit + if (ReadMapTile(actor[i].dst_rect.x div MAP_TILE_WIDTH, (actor[i].dst_rect.y + actor[i].dst_rect.h - 1) div MAP_TILE_HEIGHT) <> TILE_BACKGROUND) + or (ReadMapTile((actor[i].dst_rect.x + actor[i].dst_rect.w - 1) div MAP_TILE_WIDTH, (actor[i].dst_rect.y + actor[i].dst_rect.h - 1) div MAP_TILE_HEIGHT) <> TILE_BACKGROUND) then + begin + actor[i].dst_rect.y := actor[i].dst_rect.y - ((actor[i].dst_rect.y + actor[i].dst_rect.h) mod MAP_TILE_WIDTH); + actor[i].direction := UP; + end; + end; + + UP: + begin + // Calculem la nova posició + actor[i].dst_rect.y := actor[i].dst_rect.y - actor[i].speed_y; + + // Si eix per la vora, canvi de sentit + if (actor[i].dst_rect.y < 0) then + actor[i].direction := DOWN; + + // Colisió amb el mapa, correcció a l'ultim pixel bo i canvi de sentit + if (ReadMapTile(actor[i].dst_rect.x div MAP_TILE_WIDTH, actor[i].dst_rect.y div MAP_TILE_HEIGHT) <> TILE_BACKGROUND) + or (ReadMapTile((actor[i].dst_rect.x + actor[i].dst_rect.w - 1) div MAP_TILE_WIDTH, actor[i].dst_rect.y div MAP_TILE_HEIGHT) <> TILE_BACKGROUND) then + begin + actor[i].dst_rect.y := actor[i].dst_rect.y + (MAP_TILE_WIDTH - (actor[i].dst_rect.y mod MAP_TILE_WIDTH)); + actor[i].direction := DOWN; + end; + end; + end; + + actor[i].frame := (actor[i].frame + 1) mod 24; + if (actor[i].direction = UP) then + actor[i].src_rect.y := 4 * 16; + if (actor[i].direction = DOWN) then + actor[i].src_rect.y := 5 * 16; + if (actor[i].direction = LEFT) then + actor[i].src_rect.y := 7 * 16; + if (actor[i].direction = RIGHT) then + actor[i].src_rect.y := 6 * 16; + actor[i].src_rect.x := (actor[i].frame div 4) * actor[i].dst_rect.w; + end; + + KIND_WALKING_ENEMY: + begin + case actor[i].direction of + RIGHT: + begin + // Calculem la nova posició + actor[i].dst_rect.x := actor[i].dst_rect.x + actor[i].speed_x; + + // Si eix per la vora, canvi de sentit + if (actor[i].dst_rect.x + actor[i].dst_rect.w > GAME_WINDOW_WIDTH) then + actor[i].direction := LEFT; + + // Colisió amb el mapa, correcció a l'ultim pixel bo i canvi de sentit + if (ReadMapTile((actor[i].dst_rect.x + actor[i].dst_rect.w - 1) div MAP_TILE_WIDTH, actor[i].dst_rect.y div MAP_TILE_HEIGHT) <> TILE_BACKGROUND) + or (ReadMapTile((actor[i].dst_rect.x + actor[i].dst_rect.w - 1) div MAP_TILE_WIDTH, (actor[i].dst_rect.y + actor[i].dst_rect.h - 1) div MAP_TILE_HEIGHT) <> TILE_BACKGROUND) then + begin + actor[i].dst_rect.x := actor[i].dst_rect.x - ((actor[i].dst_rect.x + actor[i].dst_rect.w) mod MAP_TILE_WIDTH); + actor[i].direction := LEFT; + end; + + // Arriba a la vora, correcció a l'ultim pixel bo i canvi de sentit + if (ReadMapTile((actor[i].dst_rect.x + actor[i].dst_rect.w - 3) div MAP_TILE_WIDTH, (actor[i].dst_rect.y + actor[i].dst_rect.h) div MAP_TILE_HEIGHT) <> TILE_PLATFORM) then + actor[i].direction := LEFT; + end; + + LEFT: + begin + // Calculem la nova posició + actor[i].dst_rect.x := actor[i].dst_rect.x - actor[i].speed_x; + + // Si eix per la vora, canvi de sentit + if (actor[i].dst_rect.x) < 0 then + actor[i].direction := RIGHT; + + // Colisió amb el mapa, correcció a l'ultim pixel bo i canvi de sentit + if (ReadMapTile(actor[i].dst_rect.x div MAP_TILE_WIDTH, actor[i].dst_rect.y div MAP_TILE_HEIGHT) <> TILE_BACKGROUND) + or (ReadMapTile(actor[i].dst_rect.x div MAP_TILE_WIDTH, (actor[i].dst_rect.y + actor[i].dst_rect.h - 1) div MAP_TILE_HEIGHT) <> TILE_BACKGROUND) then + begin + actor[i].dst_rect.x := actor[i].dst_rect.x + (MAP_TILE_WIDTH - (actor[i].dst_rect.x mod MAP_TILE_WIDTH)); + actor[i].direction := RIGHT; + end; + + // Arriba a la vora, correcció a l'ultim pixel bo i canvi de sentit + if (ReadMapTile((actor[i].dst_rect.x + 3) div MAP_TILE_WIDTH, (actor[i].dst_rect.y + actor[i].dst_rect.h) div MAP_TILE_HEIGHT) <> TILE_PLATFORM) then + actor[i].direction := RIGHT; + end; + end; + + // Animacio + actor[i].frame := (actor[i].frame + 1) mod 48; + if (actor[i].direction = LEFT) then + actor[i].src_rect.y := 1 * 16 + else + actor[i].src_rect.y := 0 * 16; + actor[i].src_rect.x := (actor[i].frame div 8) * actor[i].dst_rect.w; + end; + + KIND_SPEED_ENEMY: + begin + case actor[i].direction of + RIGHT: + begin + // Mirem si estem en la mateixa altura que el jugador i fem que es meneje més ràpid + if (actor[i].dst_rect.y + 8 > player.dst_rect.y) + and (actor[i].dst_rect.y + 8 < player.dst_rect.y + player.dst_rect.h - 1) + and (player.can_jump) then + actor[i].speed_x := 3 + else + actor[i].speed_x := 1; + + // Calculem la nova posició + actor[i].dst_rect.x := actor[i].dst_rect.x + actor[i].speed_x; + + // Si eix per la vora, canvi de sentit + if (actor[i].dst_rect.x + actor[i].dst_rect.w > GAME_WINDOW_WIDTH) then + actor[i].direction := LEFT; + + // Colisió amb el mapa, correcció a l'ultim pixel bo i canvi de sentit + if (ReadMapTile((actor[i].dst_rect.x + actor[i].dst_rect.w - 1) div MAP_TILE_WIDTH, actor[i].dst_rect.y div MAP_TILE_HEIGHT) <> TILE_BACKGROUND) + or (ReadMapTile((actor[i].dst_rect.x + actor[i].dst_rect.w - 1) div MAP_TILE_WIDTH, (actor[i].dst_rect.y + actor[i].dst_rect.h - 1) div MAP_TILE_HEIGHT) <> TILE_BACKGROUND) then + begin + actor[i].dst_rect.x := actor[i].dst_rect.x - ((actor[i].dst_rect.x + actor[i].dst_rect.w) mod MAP_TILE_WIDTH); + actor[i].direction := LEFT; + end; + + // Arriba a la vora, correcció a l'ultim pixel bo i canvi de sentit + if (ReadMapTile((actor[i].dst_rect.x + actor[i].dst_rect.w - 3) div MAP_TILE_WIDTH, (actor[i].dst_rect.y + actor[i].dst_rect.h) div MAP_TILE_HEIGHT) <> TILE_PLATFORM) then + actor[i].direction := LEFT; + end; + + LEFT: + begin + // Mirem si estem en la mateixa altura que el jugador i fem que es meneje més ràpid + if (actor[i].dst_rect.y + 8 > player.dst_rect.y) + and (actor[i].dst_rect.y + 8 < player.dst_rect.y + player.dst_rect.h - 1) + and (player.can_jump) then + actor[i].speed_x := 3 + else + actor[i].speed_x := 1; + + // Calculem la nova posició + actor[i].dst_rect.x := actor[i].dst_rect.x - actor[i].speed_x; + + // Si eix per la vora, canvi de sentit + if (actor[i].dst_rect.x) < 0 then + actor[i].direction := RIGHT; + + // Colisió amb el mapa, correcció a l'ultim pixel bo i canvi de sentit + if (ReadMapTile(actor[i].dst_rect.x div MAP_TILE_WIDTH, actor[i].dst_rect.y div MAP_TILE_HEIGHT) <> TILE_BACKGROUND) + or (ReadMapTile(actor[i].dst_rect.x div MAP_TILE_WIDTH, (actor[i].dst_rect.y + actor[i].dst_rect.h - 1) div MAP_TILE_HEIGHT) <> TILE_BACKGROUND) then + begin + actor[i].dst_rect.x := actor[i].dst_rect.x + (MAP_TILE_WIDTH - (actor[i].dst_rect.x mod MAP_TILE_WIDTH)); + actor[i].direction := RIGHT; + end; + + // Arriba a la vora, correcció a l'ultim pixel bo i canvi de sentit + if (ReadMapTile((actor[i].dst_rect.x + 3) div MAP_TILE_WIDTH, (actor[i].dst_rect.y + actor[i].dst_rect.h) div MAP_TILE_HEIGHT) <> TILE_PLATFORM) then + actor[i].direction := RIGHT; + end; + end; + + // Animacio + actor[i].frame := (actor[i].frame + 1) mod 48; + if (actor[i].direction = LEFT) then + actor[i].src_rect.y := 2 * 16 + else + actor[i].src_rect.y := 3 * 16; + actor[i].src_rect.x := (actor[i].frame div 8) * actor[i].dst_rect.w; + end; + + KIND_MOBILE_PLATFORM: + begin + case actor[i].direction of + RIGHT: + begin + // Calculem la nova posició + actor[i].dst_rect.x := actor[i].dst_rect.x + actor[i].speed_x; + + // Si eix per la vora, canvi de sentit + if (actor[i].dst_rect.x + actor[i].dst_rect.w > GAME_WINDOW_WIDTH) then + actor[i].direction := LEFT; + + // Colisió amb el mapa, correcció al ultim pixel bo i canvi de sentit + if (ReadMapTile((actor[i].dst_rect.x + actor[i].dst_rect.w - 1) div MAP_TILE_WIDTH, actor[i].dst_rect.y div MAP_TILE_HEIGHT) <> TILE_BACKGROUND) + or (ReadMapTile((actor[i].dst_rect.x + actor[i].dst_rect.w - 1) div MAP_TILE_WIDTH, (actor[i].dst_rect.y + actor[i].dst_rect.h - 1) div MAP_TILE_HEIGHT) <> TILE_BACKGROUND) then + begin + actor[i].dst_rect.x := actor[i].dst_rect.x - ((actor[i].dst_rect.x + actor[i].dst_rect.w) mod MAP_TILE_WIDTH); + actor[i].direction := LEFT; + end; + end; + + LEFT: + begin + // Calculem la nova posició + actor[i].dst_rect.x := actor[i].dst_rect.x - actor[i].speed_x; + + // Si eix per la vora, canvi de sentit + if (actor[i].dst_rect.x < 0) then + actor[i].direction := RIGHT; + + // Colisió amb el mapa, correcció al ultim pixel bo i canvi de sentit + if (ReadMapTile(actor[i].dst_rect.x div MAP_TILE_WIDTH, actor[i].dst_rect.y div MAP_TILE_HEIGHT) <> TILE_BACKGROUND) + or (ReadMapTile(actor[i].dst_rect.x div MAP_TILE_WIDTH, (actor[i].dst_rect.y + actor[i].dst_rect.h - 1) div MAP_TILE_HEIGHT) <> TILE_BACKGROUND) then + begin + actor[i].dst_rect.x := actor[i].dst_rect.x + (MAP_TILE_WIDTH - (actor[i].dst_rect.x mod MAP_TILE_WIDTH)); + actor[i].direction := RIGHT; + end; + end; + + DOWN: + begin + // Calculem la nova posició + actor[i].dst_rect.y := actor[i].dst_rect.y + actor[i].speed_y; + + // Si eix per la vora, canvi de sentit + if (actor[i].dst_rect.y + actor[i].dst_rect.h > GAME_WINDOW_HEIGHT) then + actor[i].direction := UP; + + // Colisió amb el mapa, correcció al ultim pixel bo i canvi de sentit + if (ReadMapTile(actor[i].dst_rect.x div MAP_TILE_WIDTH, (actor[i].dst_rect.y + actor[i].dst_rect.h - 1) div MAP_TILE_HEIGHT) <> TILE_BACKGROUND) + or (ReadMapTile((actor[i].dst_rect.x + actor[i].dst_rect.w - 1) div MAP_TILE_WIDTH, (actor[i].dst_rect.y + actor[i].dst_rect.h - 1) div MAP_TILE_HEIGHT) <> TILE_BACKGROUND) then + begin + actor[i].dst_rect.y := actor[i].dst_rect.y - ((actor[i].dst_rect.y + actor[i].dst_rect.h) mod MAP_TILE_WIDTH); + actor[i].direction := UP; + end; + end; + + UP: + begin + // Calculem la nova posició + actor[i].dst_rect.y := actor[i].dst_rect.y - actor[i].speed_y; + + // Si eix per la vora, canvi de sentit + if (actor[i].dst_rect.y < 0) then + actor[i].direction := DOWN; + + // Colisió amb el mapa, correcció al ultim pixel bo i canvi de sentit + if (ReadMapTile(actor[i].dst_rect.x div MAP_TILE_WIDTH, actor[i].dst_rect.y div MAP_TILE_HEIGHT) <> TILE_BACKGROUND) + or (ReadMapTile((actor[i].dst_rect.x + actor[i].dst_rect.w - 1) div MAP_TILE_WIDTH, actor[i].dst_rect.y div MAP_TILE_HEIGHT) <> TILE_BACKGROUND) then + begin + actor[i].dst_rect.y := actor[i].dst_rect.y + (MAP_TILE_WIDTH - (actor[i].dst_rect.y mod MAP_TILE_WIDTH)); + actor[i].direction := DOWN; + end; + end; + end; + end; + + KIND_DROP_GENERATOR: + begin + if (actor[i].timer > 0) then + dec(actor[i].timer) + else + // Si el contador arriba a 0, creem un actor KIND_DROP_ENEMY + begin + actor[i].timer := 32000; + k := 0; + while (actor[k].enabled) do inc(k); + CreateActor(actor[k], KIND_DROP_ENEMY, 0, actor[i].dst_rect.x, actor[i].dst_rect.y, 16, 16, 0, 8 * 16, 0, 2, 0, 0, DOWN, i); + Mix_PlayChannel(-1, game.sound_drop_enemy, 0); + end; + + // Animacio + actor[i].frame := (actor[i].frame + 1) mod 24; + if (actor[i].timer > (DROP_TIMER - 25)) then + // no el pintem. Posem el frame 6 que està buit + actor[i].src_rect.x := (6 * actor[i].dst_rect.w) + else + actor[i].src_rect.x := (actor[i].frame div 4) * actor[i].dst_rect.w; + end; + + KIND_DROP_ENEMY: + begin + // Calculem la nova posició + actor[i].dst_rect.y := actor[i].dst_rect.y + actor[i].speed_y; + + // Si eix per la vora, adios i avisa al pare + if (actor[i].dst_rect.y + actor[i].dst_rect.h > GAME_WINDOW_HEIGHT) then + begin + actor[i].enabled := FALSE; + actor[actor[i].parent].timer := DROP_TIMER; + end; + + // Colisió amb el mapa, correcció al ultim pixel bo, transforma en KIND_DROP_SPLAT + if (ReadMapTile(actor[i].dst_rect.x div MAP_TILE_WIDTH, (actor[i].dst_rect.y + actor[i].dst_rect.h - 1) div MAP_TILE_HEIGHT) <> TILE_BACKGROUND) + or (ReadMapTile((actor[i].dst_rect.x + actor[i].dst_rect.w - 1) div MAP_TILE_WIDTH, (actor[i].dst_rect.y + actor[i].dst_rect.h - 1) div MAP_TILE_HEIGHT) <> TILE_BACKGROUND) then + begin + actor[i].dst_rect.y := actor[i].dst_rect.y - ((actor[i].dst_rect.y + actor[i].dst_rect.h) mod MAP_TILE_WIDTH); + actor[i].kind := KIND_DROP_SPLAT; + actor[i].frame := 0; + actor[i].timer := 30; + actor[i].src_rect.y := 11 * 16; + Mix_PlayChannel(-1, game.sound_drop_splat, 0); + end; + + // Animacio + actor[i].frame := (actor[i].frame + 1) mod 24; + actor[i].src_rect.x := (actor[i].frame div 4) * actor[i].dst_rect.w; + end; + + KIND_DROP_SPLAT: + begin + //if (actor[i].timer > 0) then + if (actor[i].frame < 23) then + // Si encara te temps, pintem la animació + begin + dec(actor[i].timer); + actor[i].frame := (actor[i].frame + 1) mod 24; + actor[i].src_rect.x := ((actor[i].frame div 4) + 0) * actor[i].dst_rect.w; + end + else + begin + actor[i].enabled := FALSE; + actor[actor[i].parent].timer := DROP_TIMER; + end; + end; + + KIND_COIN: + begin + actor[i].frame := (actor[i].frame + 1) mod 32; + actor[i].src_rect.x := (actor[i].frame div 4) * actor[i].dst_rect.w; + end; + + KIND_HEART: + begin + actor[i].frame := (actor[i].frame + 1) mod 32; + actor[i].src_rect.x := (actor[i].frame div 4) * actor[i].dst_rect.w; + end; + + KIND_KEY: + begin + //actor[i].frame := (actor[i].frame + 1) mod 32; + //actor[i].src_rect.x := (actor[i].frame div 32) * actor[i].dst_rect.w; + end; + + KIND_LOCK: + begin + //actor[i].frame := (actor[i].frame + 1) mod 32; + //actor[i].src_rect.x := (actor[i].frame div 32) * actor[i].dst_rect.w; + end; + end; +end; + +procedure SetPlayerDirection(direction: integer); +begin + if (direction <> player.direction) then + begin + player.direction := direction; + player.speed_x := 0; + end; +end; + +procedure MovePlayer(direction: integer); +begin + case direction of + UP: + begin + // Si pot saltar, aleshores + if (OnFloor and player.can_jump) then + begin + // Salta i ja no pot saltar (fins que toque terra i/o soltes el botó) + player.can_jump := FALSE; + + // No estem quets + player.standing := FALSE; + + // Pilla velocitat negativa per a pujar cap amunt + player.speed_y := -(player.jumpforce); + + // Calculem la nova posició + player.dst_rect.y := player.dst_rect.y + player.speed_y; + + // Soroll de saltar + Mix_PlayChannel(-1, player.sound_jump, 0); + end; + + // Nou frame d'animació + if (player.direction = LEFT) then + SetPlayerAnimation(PLAYER_ANIMATION_JUMPING_LEFT) + else + if (player.direction = RIGHT) then + SetPlayerAnimation(PLAYER_ANIMATION_JUMPING_RIGHT); + end; + + RIGHT: + begin + // Per a poder dibuixar el bot en el sentit que toca + SetPlayerDirection(RIGHT); + + // No estem quets + player.standing := FALSE; + + // Incrementem la velocitat horitzontal + player.speed_x := min(player.speed_x + 1, MAX_SPEED); + + // Calculem la nova posició + player.dst_rect.x := player.dst_rect.x + ((player.speed_x div RATIO_SPEED) + 1); + + // Selecció de l'animació + if (player.speed_y = 0) then + // Animació de caminar + SetPlayerAnimation(PLAYER_ANIMATION_WALKING_RIGHT) + else + // Animació de saltar + SetPlayerAnimation(PLAYER_ANIMATION_JUMPING_RIGHT); + end; + + LEFT : + begin + // Per a poder dibuixar el bot en el sentit que toca + SetPlayerDirection(LEFT); + + // No estem quets + player.standing := FALSE; + + // Incrementem la velocitat horitzontal + player.speed_x := min(player.speed_x + 1, MAX_SPEED); + + // Calculem la nova posició + player.dst_rect.x := player.dst_rect.x - ((player.speed_x div RATIO_SPEED) + 1); + + // Selecció de l'animació + if (player.speed_y = 0) then + // Animació de caminar + SetPlayerAnimation(PLAYER_ANIMATION_WALKING_LEFT) + else + // Animació de saltar + SetPlayerAnimation(PLAYER_ANIMATION_JUMPING_LEFT); + end; + end; + + // Calcul del frame d'animació + Animate(player.animation[player.active_animation], player.src_rect); +end; + +procedure ApplyGravity(); +begin + // Si toca piso aleshores + if (OnFloor) then + begin + // Totes les forces verticals paren + player.speed_y := 0; + // Podem saltar + player.can_jump := TRUE; + end + else + begin + // Si no toca piso aleshores s'incrementa la velocitat vertical + player.speed_y := player.speed_y + GRAVITY; + + // La velocitat no pot ser mai superior a la altura d'un tile del mapa, per a que no els atravesse + //player.speed_y := max(min(player.speed_y, MAX_SPEED_Y), -(MAX_SPEED_Y)); + player.speed_y := min(player.speed_y, MAX_SPEED_Y); + + // Calculem la nova posició + player.dst_rect.y := player.dst_rect.y + player.speed_y; + end; +end; + +procedure DrawSprite (sprite:PSDL_Texture; src_rect, dst_rect: TSDL_Rect); +begin + SDL_RenderCopy(renderer, sprite, @src_rect, @dst_rect); +end; + +procedure DrawMap(map:Tmap); +var + i, j: byte; + src_rect1: TSDL_Rect; + dst_rect1: TSDL_Rect; +begin + src_rect1.w := MAP_TILE_WIDTH; + src_rect1.h := MAP_TILE_HEIGHT; + dst_rect1.w := MAP_TILE_WIDTH; + dst_rect1.h := MAP_TILE_HEIGHT; + + for i:=0 to (ROOM_WIDTH_IN_TILES - 1) do + for j:=0 to (ROOM_HEIGHT_IN_TILES - 1) do + begin + src_rect1.x := (GetTile(i, j) mod 16) * MAP_TILE_WIDTH; + src_rect1.y := (GetTile(i, j) div 16) * MAP_TILE_HEIGHT; + dst_rect1.x := i * MAP_TILE_WIDTH; + dst_rect1.y := j * MAP_TILE_HEIGHT; + SDL_RenderCopy(renderer, map.sprite_tile, @src_rect1, @dst_rect1); + end; + + i := 0; + while animated_tile[i].enabled do + begin + src_rect1.x := ((animated_tile[i].index mod 16) * MAP_TILE_WIDTH) + ((animated_tile[i].frame div 8) * MAP_TILE_WIDTH); + src_rect1.y := (animated_tile[i].index div 16) * MAP_TILE_HEIGHT; + dst_rect1.x := animated_tile[i].x; + dst_rect1.y := animated_tile[i].y; + animated_tile[i].frame := (animated_tile[i].frame + 1) mod 16; + SDL_RenderCopy(renderer, map.sprite_tile, @src_rect1, @dst_rect1); + inc(i); + end; +end; + +procedure DrawHud(); +begin + // Pinta el fondo del marcador + DrawSprite(hud.sprite, hud.src_rect, hud.dst_rect); + + // Pinta el numero de vides + hud.bignum_src_rect.x := ((player.lifes mod 100) div 10) * hud.bignum_src_rect.w; + hud.bignum_dst_rect.y := 229; + hud.bignum_dst_rect.x := 88; + DrawSprite(hud.sprite, hud.bignum_src_rect, hud.bignum_dst_rect); + + hud.bignum_src_rect.x := (player.lifes mod 10) * hud.bignum_src_rect.w; + hud.bignum_dst_rect.x := 96; + DrawSprite(hud.sprite, hud.bignum_src_rect, hud.bignum_dst_rect); + + // Pinta el numero de monedes + hud.bignum_src_rect.x := (player.coins div 100) * hud.bignum_src_rect.w; + hud.bignum_dst_rect.y := 229; + hud.bignum_dst_rect.x := 258; + DrawSprite(hud.sprite, hud.bignum_src_rect, hud.bignum_dst_rect); + + hud.bignum_src_rect.x := ((player.coins mod 100) div 10) * hud.bignum_src_rect.w; + hud.bignum_dst_rect.x := 258+8; + DrawSprite(hud.sprite, hud.bignum_src_rect, hud.bignum_dst_rect); + + hud.bignum_src_rect.x := (player.coins mod 10) * hud.bignum_src_rect.w; + hud.bignum_dst_rect.x := 258+16; + DrawSprite(hud.sprite, hud.bignum_src_rect, hud.bignum_dst_rect); + + if prog.debug then + begin + // Pinta el valor x,y del jugador + hud.num_src_rect.x := (player.dst_rect.x div 100) * hud.num_src_rect.w; + hud.num_dst_rect.y := 1; + hud.num_dst_rect.x := 1; + DrawSprite(hud.sprite, hud.num_src_rect, hud.num_dst_rect); + + hud.num_src_rect.x := ((player.dst_rect.x mod 100) div 10) * hud.num_src_rect.w; + hud.num_dst_rect.x := 5; + DrawSprite(hud.sprite, hud.num_src_rect, hud.num_dst_rect); + + hud.num_src_rect.x := (player.dst_rect.x mod 10) * hud.num_src_rect.w; + hud.num_dst_rect.x := 9; + DrawSprite(hud.sprite, hud.num_src_rect, hud.num_dst_rect); + + hud.num_src_rect.x := (player.dst_rect.y div 100) * hud.num_src_rect.w; + hud.num_dst_rect.x := 17; + DrawSprite(hud.sprite, hud.num_src_rect, hud.num_dst_rect); + + hud.num_src_rect.x := ((player.dst_rect.y mod 100) div 10) * hud.num_src_rect.w; + hud.num_dst_rect.x := 21; + DrawSprite(hud.sprite, hud.num_src_rect, hud.num_dst_rect); + + hud.num_src_rect.x := (player.dst_rect.y mod 10) * hud.num_src_rect.w; + hud.num_dst_rect.x := 25; + DrawSprite(hud.sprite, hud.num_src_rect, hud.num_dst_rect); + + // Pinta el valor de onfloor + if (OnFloor) then + hud.num_src_rect.x := 1 * hud.num_src_rect.w + else + hud.num_src_rect.x := 0 * hud.num_src_rect.w; + hud.num_dst_rect.y := 1; + hud.num_dst_rect.x := 33; + DrawSprite(hud.sprite, hud.num_src_rect, hud.num_dst_rect); + + hud.num_src_rect.x := (ReadMapTile((player.dst_rect.x + 3) div MAP_TILE_WIDTH, (player.dst_rect.y + player.dst_rect.h) div MAP_TILE_HEIGHT)) * hud.num_src_rect.w; + hud.num_dst_rect.x := 37; + DrawSprite(hud.sprite, hud.num_src_rect, hud.num_dst_rect); + + hud.num_src_rect.x := (ReadMapTile((player.dst_rect.x + player.dst_rect.w - 4) div MAP_TILE_WIDTH, (player.dst_rect.y + player.dst_rect.h) div MAP_TILE_HEIGHT)) * hud.num_src_rect.w; + hud.num_dst_rect.x := 41; + DrawSprite(hud.sprite, hud.num_src_rect, hud.num_dst_rect); + + // Pinta el numero d'habitació + hud.num_src_rect.x := (map.room div 100) * hud.num_src_rect.w; + hud.num_dst_rect.y := 1; + hud.num_dst_rect.x := 49; + DrawSprite(hud.sprite, hud.num_src_rect, hud.num_dst_rect); + + hud.num_src_rect.x := ((map.room mod 100) div 10) * hud.num_src_rect.w; + hud.num_dst_rect.x := 53; + DrawSprite(hud.sprite, hud.num_src_rect, hud.num_dst_rect); + + hud.num_src_rect.x := (map.room mod 10) * hud.num_src_rect.w; + hud.num_dst_rect.x := 57; + DrawSprite(hud.sprite, hud.num_src_rect, hud.num_dst_rect); + end; +end; + +procedure CheckPlayerCollisionWithMap(); +var + tile_on_left_foot, tile_on_right_foot : byte; // [27/05/2016] [DOC] + i_am_on_platform, i_am_on_travesable : boolean; // [27/05/2016] [DOC] +begin + // Si eix per baix, recalcula posició i canvi de pantalla + if (player.dst_rect.y > GAME_WINDOW_HEIGHT) then + begin + // Coloquem al jugador dalt de tot + player.dst_rect.y := 1; + + // Canvi de pantalla + LoadRoom(map.room + 12); + end; + + // Si eix per dalt, recalcula posició i canvi de pantalla + if ((player.dst_rect.y + player.dst_rect.h - 1) < 0) then + begin + // Recoloca el personat + player.dst_rect.y := GAME_WINDOW_HEIGHT - player.dst_rect.h; + + // Canvi de pantalla + LoadRoom(map.room - 12); + end; + + // Si eix per la vora, recalcula posició i canvi de pantalla + if (player.dst_rect.x > GAME_WINDOW_WIDTH) then + begin + // Coloquem al jugador en la entrada de la nova pantalla + player.dst_rect.x := 0; + + // Canvi de pantalla + LoadRoom(map.room + 1); + end; + + // Si eix per la vora, recalcula posició i canvi de pantalla + if ((player.dst_rect.x + player.dst_rect.w - 1) < 0) then + begin + // El posem al borde dret + player.dst_rect.x := GAME_WINDOW_WIDTH - player.dst_rect.w; + + // Canvi de pantalla + LoadRoom(map.room - 1); + end; + + // Mirem si colisionem cap avall i corregim + //[27/05/2016] [DOC] [BEGIN] + tile_on_left_foot := ReadMapTile((player.dst_rect.x + 3) div MAP_TILE_WIDTH, (player.dst_rect.y + player.dst_rect.h - 1) div MAP_TILE_HEIGHT); + tile_on_right_foot := ReadMapTile((player.dst_rect.x + player.dst_rect.w - 4) div MAP_TILE_WIDTH, (player.dst_rect.y + player.dst_rect.h - 1) div MAP_TILE_HEIGHT); + + i_am_on_platform := (tile_on_left_foot = TILE_PLATFORM) or (tile_on_right_foot = TILE_PLATFORM); + i_am_on_travesable := (tile_on_left_foot = TILE_TRAVESABLE_PLATFORM) or (tile_on_right_foot = TILE_TRAVESABLE_PLATFORM); + + if ( (player.was_on_background) and (player.speed_y > 0) and ( i_am_on_platform or i_am_on_travesable ) ) then + begin + // Corregim la posicio + player.dst_rect.y := player.dst_rect.y - ((player.dst_rect.y + player.dst_rect.h - 1) mod MAP_TILE_HEIGHT) - 1; + + // Ja podem saltar + player.can_jump := TRUE; + end; + + player.was_on_background := (tile_on_left_foot = TILE_BACKGROUND) and (tile_on_right_foot = TILE_BACKGROUND); + //[27/05/2016] [DOC] [END] + + {if player.speed_y > 0 then + if (ReadMapTile((player.dst_rect.x + 3) div MAP_TILE_WIDTH, (player.dst_rect.y + player.dst_rect.h - 1) div MAP_TILE_HEIGHT) = TILE_TRAVESABLE_PLATFORM) + or (ReadMapTile((player.dst_rect.x + player.dst_rect.w - 4) div MAP_TILE_WIDTH, (player.dst_rect.y + player.dst_rect.h - 1) div MAP_TILE_HEIGHT) = TILE_TRAVESABLE_PLATFORM) then + begin + // Corregim la posicio + player.dst_rect.y := player.dst_rect.y - ((player.dst_rect.y + player.dst_rect.h - 1) mod MAP_TILE_HEIGHT) - 1; + + // Ja podem saltar + player.can_jump := TRUE; + end; + + if (ReadMapTile((player.dst_rect.x + 3) div MAP_TILE_WIDTH, (player.dst_rect.y + player.dst_rect.h - 1) div MAP_TILE_HEIGHT) = TILE_PLATFORM) + or (ReadMapTile((player.dst_rect.x + player.dst_rect.w - 4) div MAP_TILE_WIDTH, (player.dst_rect.y + player.dst_rect.h - 1) div MAP_TILE_HEIGHT) = TILE_PLATFORM) then + begin + // Corregim la posicio + player.dst_rect.y := player.dst_rect.y - ((player.dst_rect.y + player.dst_rect.h - 1) mod MAP_TILE_HEIGHT) - 1; + + // Ja podem saltar + player.can_jump := TRUE; + end;} + + // Mirem si colisionem cap amunt i corregim + if (ReadMapTile((player.dst_rect.x + 3) div MAP_TILE_WIDTH, player.dst_rect.y div MAP_TILE_HEIGHT) = TILE_PLATFORM) + or (ReadMapTile((player.dst_rect.x + player.dst_rect.w - 4) div MAP_TILE_WIDTH, player.dst_rect.y div MAP_TILE_HEIGHT) = TILE_PLATFORM) then + // Corregim la posicio + player.dst_rect.y := player.dst_rect.y + (MAP_TILE_HEIGHT - (player.dst_rect.y mod MAP_TILE_HEIGHT)); + + // Una vegada em permes la colisió amunt o avall, al haver un marge de 3 pixels pot ser que estiguem dins d'una paret. S'ha de corregir aquest offset + // Mirem les colisions laterals + if (ReadMapTile(player.dst_rect.x div MAP_TILE_WIDTH, player.dst_rect.y div MAP_TILE_HEIGHT) = TILE_PLATFORM) + or (ReadMapTile(player.dst_rect.x div MAP_TILE_WIDTH, (player.dst_rect.y + (player.dst_rect.h div 2)) div MAP_TILE_HEIGHT) = TILE_PLATFORM) + or (ReadMapTile(player.dst_rect.x div MAP_TILE_WIDTH, (player.dst_rect.y + player.dst_rect.h - 1) div MAP_TILE_HEIGHT) = TILE_PLATFORM) then + player.dst_rect.x := player.dst_rect.x + (MAP_TILE_WIDTH - (player.dst_rect.x mod MAP_TILE_WIDTH)); + + if (ReadMapTile((player.dst_rect.x + player.dst_rect.w - 1) div MAP_TILE_WIDTH, player.dst_rect.y div MAP_TILE_HEIGHT) = TILE_PLATFORM) + or (ReadMapTile((player.dst_rect.x + player.dst_rect.w - 1) div MAP_TILE_WIDTH, (player.dst_rect.y + (player.dst_rect.h div 2)) div MAP_TILE_HEIGHT) = TILE_PLATFORM) + or (ReadMapTile((player.dst_rect.x + player.dst_rect.w - 1) div MAP_TILE_WIDTH, (player.dst_rect.y + player.dst_rect.h - 1) div MAP_TILE_HEIGHT) = TILE_PLATFORM) then + player.dst_rect.x := player.dst_rect.x - ((player.dst_rect.x + player.dst_rect.w) mod MAP_TILE_WIDTH); + + // Comprovar si toca alguna part del mapa de les que maten + if (ReadMapTile((player.dst_rect.x + 8) div MAP_TILE_WIDTH, (player.dst_rect.y + player.dst_rect.h - 12) div MAP_TILE_HEIGHT) = TILE_KILLING_PLATFORM) then + if player.enabled then + KillPlayer(); +end; + +{procedure CheckPlayerCollisionWithActors(); +var + i, collision: byte; + //collision_top, collision_bottom, collision_left, collision_right: boolean; +begin + for i:=0 to MAX_ACTORS - 1 do + if actor[i].enabled then + begin + collision := NO_COLLISION; + if ((actor[i].dst_rect.x + actor[i].dst_rect.w - ENEMY_HITBOX_REDUCTION > player.dst_rect.x) and (actor[i].dst_rect.x + actor[i].dst_rect.w - ENEMY_HITBOX_REDUCTION < player.dst_rect.x + player.dst_rect.w) and + (actor[i].dst_rect.y + actor[i].dst_rect.h - ENEMY_HITBOX_REDUCTION > player.dst_rect.y) and (actor[i].dst_rect.y + actor[i].dst_rect.h - ENEMY_HITBOX_REDUCTION < player.dst_rect.y + player.dst_rect.h)) then + collision := LEFT_COLLISION; + + if((actor[i].dst_rect.x + ENEMY_HITBOX_REDUCTION > player.dst_rect.x) and (actor[i].dst_rect.x + ENEMY_HITBOX_REDUCTION < player.dst_rect.x + player.dst_rect.w) and + (actor[i].dst_rect.y + actor[i].dst_rect.h - ENEMY_HITBOX_REDUCTION > player.dst_rect.y) and (actor[i].dst_rect.y + actor[i].dst_rect.h - ENEMY_HITBOX_REDUCTION < player.dst_rect.y + player.dst_rect.h)) then + collision := RIGHT_COLLISION; + + if ((actor[i].dst_rect.x + actor[i].dst_rect.w - ENEMY_HITBOX_REDUCTION > player.dst_rect.x) and (actor[i].dst_rect.x + actor[i].dst_rect.w - ENEMY_HITBOX_REDUCTION < player.dst_rect.x + player.dst_rect.w) and + (actor[i].dst_rect.y + ENEMY_HITBOX_REDUCTION > player.dst_rect.y) and (actor[i].dst_rect.y + ENEMY_HITBOX_REDUCTION < player.dst_rect.y + player.dst_rect.h)) then + collision := LEFT_COLLISION; + + if ((actor[i].dst_rect.x + ENEMY_HITBOX_REDUCTION > player.dst_rect.x) and (actor[i].dst_rect.x + ENEMY_HITBOX_REDUCTION < player.dst_rect.x + player.dst_rect.w) and + (actor[i].dst_rect.y + ENEMY_HITBOX_REDUCTION > player.dst_rect.y) and (actor[i].dst_rect.y + ENEMY_HITBOX_REDUCTION < player.dst_rect.y + player.dst_rect.h)) then + collision := RIGHT_COLLISION; + + if (collision <> NO_COLLISION) then + case actor[i].kind of + KIND_FLYING_ENEMY, KIND_WALKING_ENEMY, KIND_DROP_ENEMY, KIND_SPEED_ENEMY: + begin + if (player.enabled) then + KillPlayer(); + end; + + KIND_COIN: + begin + inc(player.coins); + actor[i].enabled := FALSE; + SetActor((actor[i].dst_rect.x div 16), (actor[i].dst_rect.y div 16), 0); + Mix_PlayChannel(-1, player.sound_coin, 0); + end; + + KIND_HEART: + begin + inc(player.lifes); + actor[i].enabled := FALSE; + SetActor((actor[i].dst_rect.x div 16), (actor[i].dst_rect.y div 16), 0); + Mix_PlayChannel(-1, player.sound_coin, 0); + end; + + KIND_KEY: + begin + player.key[0] := TRUE;; + actor[i].enabled := FALSE; + SetActor((actor[i].dst_rect.x div 16), (actor[i].dst_rect.y div 16), 0); + Mix_PlayChannel(-1, player.sound_coin, 0); + end; + + KIND_LOCK: + begin + // Si tenim clau + if (player.key[0]) then + begin + actor[i].enabled := FALSE; + SetActor((actor[i].dst_rect.x div MAP_TILE_WIDTH), (actor[i].dst_rect.y div MAP_TILE_HEIGHT), 0); + end + else + begin + if collision = LEFT_COLLISION then + begin + player.dst_rect.x := player.dst_rect.x + (MAP_TILE_WIDTH - (player.dst_rect.x mod MAP_TILE_WIDTH)); + end + else + begin + player.dst_rect.x := player.dst_rect.x - ((player.dst_rect.x + player.dst_rect.w) mod MAP_TILE_WIDTH); + end; + end; + end; + end; + end; +end;} + +procedure CheckPlayerCollisionWithActors(); +var + i: byte; +begin + for i:=0 to MAX_ACTORS - 1 do + if actor[i].enabled then + case actor[i].kind of + KIND_FLYING_ENEMY, KIND_WALKING_ENEMY, KIND_DROP_ENEMY, KIND_SPEED_ENEMY: + begin + if ((actor[i].dst_rect.x + actor[i].dst_rect.w - ENEMY_HITBOX_REDUCTION > player.dst_rect.x) and (actor[i].dst_rect.x + actor[i].dst_rect.w - ENEMY_HITBOX_REDUCTION < player.dst_rect.x + player.dst_rect.w) and + (actor[i].dst_rect.y + actor[i].dst_rect.h - ENEMY_HITBOX_REDUCTION > player.dst_rect.y) and (actor[i].dst_rect.y + actor[i].dst_rect.h - ENEMY_HITBOX_REDUCTION < player.dst_rect.y + player.dst_rect.h)) + or + ((actor[i].dst_rect.x + ENEMY_HITBOX_REDUCTION > player.dst_rect.x) and (actor[i].dst_rect.x + ENEMY_HITBOX_REDUCTION < player.dst_rect.x + player.dst_rect.w) and + (actor[i].dst_rect.y + actor[i].dst_rect.h - ENEMY_HITBOX_REDUCTION > player.dst_rect.y) and (actor[i].dst_rect.y + actor[i].dst_rect.h - ENEMY_HITBOX_REDUCTION < player.dst_rect.y + player.dst_rect.h)) + or + ((actor[i].dst_rect.x + actor[i].dst_rect.w - ENEMY_HITBOX_REDUCTION > player.dst_rect.x) and (actor[i].dst_rect.x + actor[i].dst_rect.w - ENEMY_HITBOX_REDUCTION < player.dst_rect.x + player.dst_rect.w) and + (actor[i].dst_rect.y + ENEMY_HITBOX_REDUCTION > player.dst_rect.y) and (actor[i].dst_rect.y + ENEMY_HITBOX_REDUCTION < player.dst_rect.y + player.dst_rect.h)) + or + ((actor[i].dst_rect.x + ENEMY_HITBOX_REDUCTION > player.dst_rect.x) and (actor[i].dst_rect.x + ENEMY_HITBOX_REDUCTION < player.dst_rect.x + player.dst_rect.w) and + (actor[i].dst_rect.y + ENEMY_HITBOX_REDUCTION > player.dst_rect.y) and (actor[i].dst_rect.y + ENEMY_HITBOX_REDUCTION < player.dst_rect.y + player.dst_rect.h)) then + if (player.enabled) then + KillPlayer(); + end; + + KIND_COIN: + begin + if ((actor[i].dst_rect.x + actor[i].dst_rect.w - ENEMY_HITBOX_REDUCTION > player.dst_rect.x) and (actor[i].dst_rect.x + actor[i].dst_rect.w - ENEMY_HITBOX_REDUCTION < player.dst_rect.x + player.dst_rect.w) and + (actor[i].dst_rect.y + actor[i].dst_rect.h - ENEMY_HITBOX_REDUCTION > player.dst_rect.y) and (actor[i].dst_rect.y + actor[i].dst_rect.h - ENEMY_HITBOX_REDUCTION < player.dst_rect.y + player.dst_rect.h)) + or + ((actor[i].dst_rect.x + ENEMY_HITBOX_REDUCTION > player.dst_rect.x) and (actor[i].dst_rect.x + ENEMY_HITBOX_REDUCTION < player.dst_rect.x + player.dst_rect.w) and + (actor[i].dst_rect.y + actor[i].dst_rect.h - ENEMY_HITBOX_REDUCTION > player.dst_rect.y) and (actor[i].dst_rect.y + actor[i].dst_rect.h - ENEMY_HITBOX_REDUCTION < player.dst_rect.y + player.dst_rect.h)) + or + ((actor[i].dst_rect.x + actor[i].dst_rect.w - ENEMY_HITBOX_REDUCTION > player.dst_rect.x) and (actor[i].dst_rect.x + actor[i].dst_rect.w - ENEMY_HITBOX_REDUCTION < player.dst_rect.x + player.dst_rect.w) and + (actor[i].dst_rect.y + ENEMY_HITBOX_REDUCTION > player.dst_rect.y) and (actor[i].dst_rect.y + ENEMY_HITBOX_REDUCTION < player.dst_rect.y + player.dst_rect.h)) + or + ((actor[i].dst_rect.x + ENEMY_HITBOX_REDUCTION > player.dst_rect.x) and (actor[i].dst_rect.x + ENEMY_HITBOX_REDUCTION < player.dst_rect.x + player.dst_rect.w) and + (actor[i].dst_rect.y + ENEMY_HITBOX_REDUCTION > player.dst_rect.y) and (actor[i].dst_rect.y + ENEMY_HITBOX_REDUCTION < player.dst_rect.y + player.dst_rect.h)) then + begin + inc(player.coins); + actor[i].enabled := FALSE; + SetActor((actor[i].dst_rect.x div 16), (actor[i].dst_rect.y div 16), 0); + Mix_PlayChannel(-1, player.sound_coin, 0); + end; + end; + + KIND_HEART: + begin + if ((actor[i].dst_rect.x + actor[i].dst_rect.w - ENEMY_HITBOX_REDUCTION > player.dst_rect.x) and (actor[i].dst_rect.x + actor[i].dst_rect.w - ENEMY_HITBOX_REDUCTION < player.dst_rect.x + player.dst_rect.w) and + (actor[i].dst_rect.y + actor[i].dst_rect.h - ENEMY_HITBOX_REDUCTION > player.dst_rect.y) and (actor[i].dst_rect.y + actor[i].dst_rect.h - ENEMY_HITBOX_REDUCTION < player.dst_rect.y + player.dst_rect.h)) + or + ((actor[i].dst_rect.x + ENEMY_HITBOX_REDUCTION > player.dst_rect.x) and (actor[i].dst_rect.x + ENEMY_HITBOX_REDUCTION < player.dst_rect.x + player.dst_rect.w) and + (actor[i].dst_rect.y + actor[i].dst_rect.h - ENEMY_HITBOX_REDUCTION > player.dst_rect.y) and (actor[i].dst_rect.y + actor[i].dst_rect.h - ENEMY_HITBOX_REDUCTION < player.dst_rect.y + player.dst_rect.h)) + or + ((actor[i].dst_rect.x + actor[i].dst_rect.w - ENEMY_HITBOX_REDUCTION > player.dst_rect.x) and (actor[i].dst_rect.x + actor[i].dst_rect.w - ENEMY_HITBOX_REDUCTION < player.dst_rect.x + player.dst_rect.w) and + (actor[i].dst_rect.y + ENEMY_HITBOX_REDUCTION > player.dst_rect.y) and (actor[i].dst_rect.y + ENEMY_HITBOX_REDUCTION < player.dst_rect.y + player.dst_rect.h)) + or + ((actor[i].dst_rect.x + ENEMY_HITBOX_REDUCTION > player.dst_rect.x) and (actor[i].dst_rect.x + ENEMY_HITBOX_REDUCTION < player.dst_rect.x + player.dst_rect.w) and + (actor[i].dst_rect.y + ENEMY_HITBOX_REDUCTION > player.dst_rect.y) and (actor[i].dst_rect.y + ENEMY_HITBOX_REDUCTION < player.dst_rect.y + player.dst_rect.h)) then + begin + inc(player.lifes); + actor[i].enabled := FALSE; + SetActor((actor[i].dst_rect.x div 16), (actor[i].dst_rect.y div 16), 0); + Mix_PlayChannel(-1, player.sound_coin, 0); + end; + end; + + KIND_KEY: + begin + if ((actor[i].dst_rect.x + actor[i].dst_rect.w - ENEMY_HITBOX_REDUCTION > player.dst_rect.x) and (actor[i].dst_rect.x + actor[i].dst_rect.w - ENEMY_HITBOX_REDUCTION < player.dst_rect.x + player.dst_rect.w) and + (actor[i].dst_rect.y + actor[i].dst_rect.h - ENEMY_HITBOX_REDUCTION > player.dst_rect.y) and (actor[i].dst_rect.y + actor[i].dst_rect.h - ENEMY_HITBOX_REDUCTION < player.dst_rect.y + player.dst_rect.h)) + or + ((actor[i].dst_rect.x + ENEMY_HITBOX_REDUCTION > player.dst_rect.x) and (actor[i].dst_rect.x + ENEMY_HITBOX_REDUCTION < player.dst_rect.x + player.dst_rect.w) and + (actor[i].dst_rect.y + actor[i].dst_rect.h - ENEMY_HITBOX_REDUCTION > player.dst_rect.y) and (actor[i].dst_rect.y + actor[i].dst_rect.h - ENEMY_HITBOX_REDUCTION < player.dst_rect.y + player.dst_rect.h)) + or + ((actor[i].dst_rect.x + actor[i].dst_rect.w - ENEMY_HITBOX_REDUCTION > player.dst_rect.x) and (actor[i].dst_rect.x + actor[i].dst_rect.w - ENEMY_HITBOX_REDUCTION < player.dst_rect.x + player.dst_rect.w) and + (actor[i].dst_rect.y + ENEMY_HITBOX_REDUCTION > player.dst_rect.y) and (actor[i].dst_rect.y + ENEMY_HITBOX_REDUCTION < player.dst_rect.y + player.dst_rect.h)) + or + ((actor[i].dst_rect.x + ENEMY_HITBOX_REDUCTION > player.dst_rect.x) and (actor[i].dst_rect.x + ENEMY_HITBOX_REDUCTION < player.dst_rect.x + player.dst_rect.w) and + (actor[i].dst_rect.y + ENEMY_HITBOX_REDUCTION > player.dst_rect.y) and (actor[i].dst_rect.y + ENEMY_HITBOX_REDUCTION < player.dst_rect.y + player.dst_rect.h)) then + begin + player.key[actor[i].id] := TRUE;; + actor[i].enabled := FALSE; + SetActor((actor[i].dst_rect.x div 16), (actor[i].dst_rect.y div 16), 0); + Mix_PlayChannel(-1, player.sound_coin, 0); + end; + end; + + KIND_LOCK: + // Les colisions amb aquest actor no tenen en compte el ENEMY_HITBOX_REDUCTION + begin + // El jugador colisiona amb el actor per l'esquerra del jugador + if ((actor[i].dst_rect.x + actor[i].dst_rect.w > player.dst_rect.x) and (actor[i].dst_rect.x + actor[i].dst_rect.w < player.dst_rect.x + player.dst_rect.w) and + (actor[i].dst_rect.y + actor[i].dst_rect.h > player.dst_rect.y) and (actor[i].dst_rect.y + actor[i].dst_rect.h < player.dst_rect.y + player.dst_rect.h)) + or + ((actor[i].dst_rect.x + actor[i].dst_rect.w > player.dst_rect.x) and (actor[i].dst_rect.x + actor[i].dst_rect.w < player.dst_rect.x + player.dst_rect.w) and + (actor[i].dst_rect.y > player.dst_rect.y) and (actor[i].dst_rect.y < player.dst_rect.y + player.dst_rect.h)) then + // Si tenim clau + if (player.key[actor[i].id]) then + begin + actor[i].enabled := FALSE; + SetActor((actor[i].dst_rect.x div MAP_TILE_WIDTH), (actor[i].dst_rect.y div MAP_TILE_HEIGHT), 0); + end + // Si no tenim clau + else + begin + player.dst_rect.x := player.dst_rect.x + (MAP_TILE_WIDTH - (player.dst_rect.x mod MAP_TILE_WIDTH)); + end; + + // El jugador colisiona amb el actor per la dreta del jugador + if ((actor[i].dst_rect.x > player.dst_rect.x) and (actor[i].dst_rect.x < player.dst_rect.x + player.dst_rect.w) and + (actor[i].dst_rect.y + actor[i].dst_rect.h > player.dst_rect.y) and (actor[i].dst_rect.y + actor[i].dst_rect.h < player.dst_rect.y + player.dst_rect.h)) + or + ((actor[i].dst_rect.x > player.dst_rect.x) and (actor[i].dst_rect.x < player.dst_rect.x + player.dst_rect.w) and + (actor[i].dst_rect.y > player.dst_rect.y) and (actor[i].dst_rect.y < player.dst_rect.y + player.dst_rect.h)) then + // Si tenim clau + if (player.key[actor[i].id]) then + begin + actor[i].enabled := FALSE; + SetActor((actor[i].dst_rect.x div MAP_TILE_WIDTH), (actor[i].dst_rect.y div MAP_TILE_HEIGHT), 0); + end + // Si no tenim clau + else + begin + player.dst_rect.x := player.dst_rect.x - ((player.dst_rect.x + player.dst_rect.w) mod MAP_TILE_WIDTH); + end; + end; + end; +end; + +procedure SetProgSection(section:byte); +begin + case section of + SECTION_MENU: + begin + prog.section := SECTION_MENU; + IniMenu(); + EndGame(); + end; + + SECTION_GAME: + begin + prog.section := SECTION_GAME; + IniGame(ZONE_VOLCANO); + EndMenu; + end; + + SECTION_QUIT: + begin + prog.section := SECTION_QUIT; + EndGame; + EndMenu; + end; + end; +end; + +procedure IniProgram(); +begin + prog.music_enabled := TRUE; + prog.filter := TRUE; + SetProgSection(SECTION_MENU); + prog.debug := FALSE; + + if (prog.music_enabled) then + Mix_VolumeMusic(100) + else + Mix_VolumeMusic(0); + + prog.sprite := OpenPicture(FILE_FILTER); + + prog.src_rect.x := 0; + prog.src_rect.y := 0; + prog.src_rect.w := 640; + prog.src_rect.h := 480; + + prog.dst_rect.x := 0; + prog.dst_rect.y := 0; + prog.dst_rect.w := 640; + prog.dst_rect.h := 480; +end; + +procedure EndProgram(); +begin + ClosePicture(prog.sprite); + EndGame(); + EndMenu(); +end; + +begin + // Inicialitzar SDL en general i el video en particular + fullscreen := false; + SDL_Init(SDL_INIT_EVERYTHING); + window := SDL_CreateWindow(WINDOW_TITLE + BUILD, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 640, 480, SDL_WINDOW_SHOWN); + renderer := SDL_CreateRenderer(window, -1, 0); + SDL_RenderSetLogicalSize(renderer, 320, 240); + + // Inicialitzar SDL_Image (càrrega de PNGs) + IMG_Init(IMG_INIT_PNG); + + // Inicialitzar audio + Mix_OpenAudio(MIX_DEFAULT_FREQUENCY, MIX_DEFAULT_FORMAT, 2, 1024); + Mix_AllocateChannels(8); + + // Inicialitzar el programa + IniProgram(); + + // Establir el color d'esborrat + SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255); + + // Inicialitza variables generals + quit := false; + delta_time := SDL_GetTicks(); + + // Bucle de programa + while not quit do + begin + case prog.section of + SECTION_GAME: + begin + // Inicialitza habitació + LoadRoom(STARTING_ROOM); + + // Conecta la musica + Mix_PlayMusic(game.music, -1); + + // Bucle de joc + while game.enabled do + begin + while SDL_PollEvent(@e) > 0 do + begin + // Si arriva el event de tancar la aplicació, eixim del bucle + if (e.type_ = SDL_QUITEV) then + begin + quit := true; + SetProgSection(SECTION_MENU); + break; + end + else + if ((e.type_ = SDL_KEYDOWN) and (e.key._repeat = 0)) then + case e.key.keysym.scancode of + SDL_SCANCODE_ESCAPE: + begin + SetProgSection(SECTION_MENU); + end; + + SDL_SCANCODE_F: + begin + if ( fullscreen ) then + begin + SDL_SetWindowFullscreen(window, 0); + SDL_ShowCursor(1); + fullscreen := false; + end + else + begin + SDL_SetWindowFullscreen(window, SDL_WINDOW_FULLSCREEN_DESKTOP); + SDL_ShowCursor(0); + fullscreen := true; + end; + end; + + SDL_SCANCODE_W: + begin + LoadRoom(map.room - 12); + end; + + SDL_SCANCODE_A: + begin + LoadRoom(map.room - 1); + end; + + SDL_SCANCODE_S: + begin + LoadRoom(map.room + 12); + end; + + SDL_SCANCODE_D: + begin + LoadRoom(map.room + 1); + end; + + SDL_SCANCODE_G: + begin + player.lifes := 255; + end; + + SDL_SCANCODE_M: + begin + prog.music_enabled := not(prog.music_enabled); + if (prog.music_enabled) then + Mix_VolumeMusic(100) + else + Mix_VolumeMusic(0); + end; + + SDL_SCANCODE_T: + begin + IniPlayer(); + LoadRoom(TEST_ROOM); + end; + + SDL_SCANCODE_F1: + begin + prog.debug := not(prog.debug); + end; + + SDL_SCANCODE_F2: + begin + prog.filter := not(prog.filter); + end; + end; + end; + + if ((SDL_GetTicks() - delta_time) > GAME_SPEED) then + begin + // Agafar el array de tecles + keys := SDL_GetKeyboardState(nil); + + // Mirem si esta apretant el botó de saltar. Per tal d'evitar repeticions en aquest boto + if (keys[SDL_SCANCODE_UP] = 0) then + player.jump_pressed_now := FALSE + else + player.jump_pressed_now := TRUE; + + // Si el jugador està deshabilitat, anem reduint el temps d'espera i canviant el frame de la animació de mort + if not(player.enabled) then + if (player.cooldown > 0) then + begin + dec(player.cooldown); + Animate(player.animation[player.active_animation], player.src_rect); + end + else + // Ha acabat el temps d'estar mort. Revivim al jugador + begin + player.enabled := TRUE; + + // Coloquem al jugador en el sentit que tenia quan va entrar a la habitació + if (player.respawn_direction = LEFT) then + begin + SetPlayerAnimation(PLAYER_ANIMATION_STANDING_LEFT); + player.direction := LEFT; + end; + if (player.respawn_direction = RIGHT) then + begin + SetPlayerAnimation(PLAYER_ANIMATION_STANDING_RIGHT); + player.direction := RIGHT; + end; + + // Coloquem al jugador en les coordenades per on va entrar + player.dst_rect.x := min(player.respawn_x, GAME_WINDOW_WIDTH - player.dst_rect.w); + player.dst_rect.y := player.respawn_y; + + // Recarreguem la habitació + LoadRoom(map.room); + + if (player.lifes > 0) then + // Descontem una vida + dec(player.lifes) + else + // Si no li queden vides, eixim al menu + SetProgSection(SECTION_MENU); + end; + + // Comprovem les tecles que ens interesen i actuem en consequència + if (keys[SDL_SCANCODE_RIGHT] = 1) and (player.enabled) then + MovePlayer(RIGHT); + if (keys[SDL_SCANCODE_LEFT] = 1) and (keys[SDL_SCANCODE_RIGHT] = 0) and (player.enabled) then + MovePlayer(LEFT); + if (keys[SDL_SCANCODE_UP] = 1) and (player.enabled) and not(player.jump_pressed_before) then + MovePlayer(UP); + player.jump_pressed_before := player.jump_pressed_now; + + // Mirem si no estem fent cap a cap costat i reduim la velocitat horitzontal + if ((keys[SDL_SCANCODE_RIGHT] = 0) and (keys[SDL_SCANCODE_LEFT] = 0) and (player.enabled)) then + begin + player.speed_x := 0; + + // Estem quets + player.standing := TRUE; + + // Posem la animació d'estar quet si no estem saltant + //if (player.speed_y = 0) then + if (player.can_jump) then + begin + if (player.direction = LEFT) then + SetPlayerAnimation(PLAYER_ANIMATION_STANDING_LEFT) + else + if (player.direction = RIGHT) then + SetPlayerAnimation(PLAYER_ANIMATION_STANDING_RIGHT); + Animate(player.animation[player.active_animation], player.src_rect); + end; + end; + + // Moure els actors + MoveActors(); + + // Apliquem la gravetat + if (player.enabled) then ApplyGravity(); + + // Comprovar colisions amb els actors + if (player.enabled) then CheckPlayerCollisionWithActors(); + + // Comprovar colisions amb el mapejat + CheckPlayerCollisionWithMap(); + + SDL_RenderSetLogicalSize(renderer, 320, 240); + + // Borrem pantalla + SDL_RenderClear(renderer); + + // Pintem el fondo + DrawSprite(map.background, map.src_rect, map.dst_rect); + + // Pinta el mapa + DrawMap(map); + + // Pintem el jugador + DrawSprite(player.sprite, player.src_rect, player.dst_rect); + + // Pintem els actors + for i:=0 to MAX_ACTORS - 1 do + if (actor[i].enabled) then + DrawSprite(map.sprite_actor, actor[i].src_rect, actor[i].dst_rect); + + // Pintem el marcador + DrawHud(); + + // Posem el filtro de pantalla + if prog.filter then + begin + SDL_RenderSetLogicalSize(renderer, 640, 480); + DrawSprite(prog.sprite, prog.src_rect, prog.dst_rect); + end; + + // Mostrem la pantalla + SDL_RenderPresent(renderer); + + delta_time := SDL_GetTicks(); + end; + end; + end; + + SECTION_MENU: + begin + // Establir el color d'esborrat + SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255); + + // Apaga la musica + Mix_HaltMusic(); + + while menu.enabled do + begin + // Bucle del menu + while SDL_PollEvent(@e) > 0 do + begin + // Si arriva el event de tancar la aplicació, eixim del bucle + if (e.type_ = SDL_QUITEV) then + begin + quit := true; + menu.enabled := FALSE; + break; + end + else + if ((e.type_ = SDL_KEYDOWN) and (e.key._repeat = 0)) then + case e.key.keysym.scancode of + SDL_SCANCODE_ESCAPE: + begin + quit := true; + SetProgSection(SECTION_QUIT); + break; + end; + + // (Des)Activa el mode de pantalla completa + SDL_SCANCODE_F: + begin + if ( fullscreen ) then + begin + SDL_SetWindowFullscreen(window, 0); + SDL_ShowCursor(1); + fullscreen := false; + end + else + begin + SDL_SetWindowFullscreen(window, SDL_WINDOW_FULLSCREEN_DESKTOP); + SDL_ShowCursor(0); + fullscreen := true; + end; + end; + + // (Des)Activa la musica + SDL_SCANCODE_M: + begin + prog.music_enabled := not(prog.music_enabled); + if (prog.music_enabled) then + Mix_VolumeMusic(100) + else + Mix_VolumeMusic(0); + end; + + // (Des)Activa les scanlines + SDL_SCANCODE_F2: + begin + prog.filter := not(prog.filter); + end; + + // Inicia el joc + SDL_SCANCODE_RETURN: + begin + if (menu.timer > 99) then + begin + menu.timer := 99; + Mix_HaltMusic(); + Mix_HaltChannel(-1); + Mix_PlayChannel(-1, menu.sound_start, 0); + menu.frame := 0; + end; + end; + end; + end; + + if ((SDL_GetTicks() - delta_time) > GAME_SPEED) then + begin + case menu.section of + {MENU_SECTION_MAIN: + begin + if menu.timer > 100 then + // Menu normal + begin + menu.frame := (menu.frame + 1) mod 30000; + + SDL_RenderSetLogicalSize(renderer, 320, 240); + // Borrem pantalla + SDL_RenderClear(renderer); + + // Pintem el fondo del menu + //DrawSprite(menu.sprite, menu.src_rect_fondo, menu.dst_rect_fondo); + + // Pintem el logo DESPLEGA + menu.dst_rect_logo_zoom.w := menu.dst_rect_logo.w; + menu.dst_rect_logo_zoom.h := min(menu.dst_rect_logo_zoom.h + 4, menu.dst_rect_logo.h); + menu.dst_rect_logo_zoom.x := menu.dst_rect_logo.x; + menu.dst_rect_logo_zoom.y := menu.dst_rect_logo.y; + + DrawSprite(menu.sprite, menu.src_rect_logo, menu.dst_rect_logo_zoom); + + if menu.frame = (154 div 4) then + Mix_PlayChannel(-1, menu.sound_logo, 0); + if menu.frame = (300 div 4) then + // Conecta la musica + Mix_PlayMusic(menu.music, -1); + + if menu.frame > (300 div 4) then + begin + // Pintem el text: PRESS RETURN TO START + if ((menu.frame mod 64) < 32) then + DrawSprite(menu.sprite, menu.src_rect_text, menu.dst_rect_text); + + // Pintem el text: JAILGAMES 2016 + DrawSprite(menu.sprite, menu.src_rect_text2, menu.dst_rect_text2); + end; + end + else + // Menu havent apretat START/RETURN + begin + dec(menu.timer); + menu.frame := (menu.frame + 1) mod 30000; + + // Borrem pantalla + SDL_RenderSetLogicalSize(renderer, 320, 240); + SDL_RenderClear(renderer); + + // Pintem el fondo del menu + //DrawSprite(menu.sprite, menu.src_rect_fondo, menu.dst_rect_fondo); + + // Pintem el logo + DrawSprite(menu.sprite, menu.src_rect_logo, menu.dst_rect_logo); + + // Pintem el text: PRESS RETURN TO START + if ((menu.frame mod 8) < 4) then + DrawSprite(menu.sprite, menu.src_rect_text, menu.dst_rect_text); + + // Pintem el text: JAILGAMES 2016 + DrawSprite(menu.sprite, menu.src_rect_text2, menu.dst_rect_text2); + + if menu.timer = 0 then + begin + //prog.section := SECTION_GAME; + //menu.enabled := FALSE; + //game.enabled := TRUE; + //menu.section := MENU_SECTION_ANIMATION; + //menu.timer := 100 + end; + end; + + // Posem el filtro de pantalla + if prog.filter then + begin + SDL_RenderSetLogicalSize(renderer, 640, 480); + DrawSprite(prog.sprite, prog.src_rect, prog.dst_rect); + end; + + // Mostrem la pantalla + SDL_RenderPresent(renderer); + + delta_time := SDL_GetTicks(); + end;} + + MENU_SECTION_ANIMATION: + begin + // No hem pulsat el botó d'start + if menu.timer > 100 then + // Animació inicial + if not(menu.animation[0].loops) then + begin + // Borrem pantalla + SDL_RenderSetLogicalSize(renderer, 320, 240); + SDL_RenderClear(renderer); + + AnimateIntroMenu(menu.animation[0], menu.src_rect_animation); + + // Pintem la animacio + DrawSprite(menu.sprite_animation, menu.src_rect_animation, menu.dst_rect_animation); + + // Posem el filtro de pantalla + if prog.filter then + begin + SDL_RenderSetLogicalSize(renderer, 640, 480); + DrawSprite(prog.sprite, prog.src_rect, prog.dst_rect); + end; + + // Mostrem la pantalla + SDL_RenderPresent(renderer); + + delta_time := SDL_GetTicks(); + end + else + // Animació segona en loop + begin + if Mix_PlayingMusic() = 0 then + Mix_PlayMusic(menu.music, -1); + + // Borrem pantalla + SDL_RenderSetLogicalSize(renderer, 320, 240); + SDL_RenderClear(renderer); + + AnimateIntroMenu(menu.animation[1], menu.src_rect_animation); + + // Pintem la animacio + DrawSprite(menu.sprite_animation, menu.src_rect_animation, menu.dst_rect_animation); + + // Pintem el text: PRESS RETURN TO START + if ((menu.animation[1].timer mod 64) < 32) then + DrawSprite(menu.sprite, menu.src_rect_text, menu.dst_rect_text); + + // Pintem el text: JAILGAMES 2016 + DrawSprite(menu.sprite, menu.src_rect_text2, menu.dst_rect_text2); + + // Posem el filtro de pantalla + if prog.filter then + begin + SDL_RenderSetLogicalSize(renderer, 640, 480); + DrawSprite(prog.sprite, prog.src_rect, prog.dst_rect); + end; + + // Mostrem la pantalla + SDL_RenderPresent(renderer); + + delta_time := SDL_GetTicks(); + end + else + // Hem pulsat el botó d'start + begin + Mix_HaltMusic(); + + // Borrem pantalla + SDL_RenderSetLogicalSize(renderer, 320, 240); + SDL_RenderClear(renderer); + + AnimateIntroMenu(menu.animation[1], menu.src_rect_animation); + + // Pintem la animacio + DrawSprite(menu.sprite_animation, menu.src_rect_animation, menu.dst_rect_animation); + + // Pintem el text: PRESS RETURN TO START + if ((menu.animation[1].timer mod 8) < 4) then + DrawSprite(menu.sprite, menu.src_rect_text, menu.dst_rect_text); + + // Pintem el text: JAILGAMES 2016 + DrawSprite(menu.sprite, menu.src_rect_text2, menu.dst_rect_text2); + + // Posem el filtro de pantalla + if prog.filter then + begin + SDL_RenderSetLogicalSize(renderer, 640, 480); + DrawSprite(prog.sprite, prog.src_rect, prog.dst_rect); + end; + + // Mostrem la pantalla + SDL_RenderPresent(renderer); + + delta_time := SDL_GetTicks(); + + dec(menu.timer); + if menu.timer = 0 then + begin + SetProgSection(SECTION_GAME); + menu.timer := 200; + end; + end; + end; + end; + end; + end; + end; + end; + end; + + // Finalitzar la música, els samples i el audio + CloseSound(player.sound_jump); + CloseSound(player.sound_death); + CloseSound(player.sound_coin); + CloseSound(menu.sound_logo); + CloseSound(menu.sound_start); + CloseSound(game.sound_drop_enemy); + CloseSound(game.sound_drop_splat); + + Mix_HaltMusic(); + + CloseMusic(game.music); + CloseMusic(menu.music); + + Mix_CloseAudio(); + + EndProgram(); + + // Finalitzar SDL_Image + IMG_Quit(); + + // Destruir els sprites + ClosePicture(prog.sprite); + ClosePicture(player.sprite); + ClosePicture(map.sprite_tile); + ClosePicture(map.sprite_actor); + ClosePicture(map.background); + ClosePicture(menu.sprite); + ClosePicture(menu.sprite_animation); + ClosePicture(hud.sprite); + + // Destruir la finestra + SDL_DestroyWindow(window); + + // Finalitzar SDL + SDL_Quit(); +end. diff --git a/sync.sh b/sync.sh new file mode 100755 index 0000000..b117b10 --- /dev/null +++ b/sync.sh @@ -0,0 +1,34 @@ +#!/bin/bash +readonly USAGE=" +USAGE: +$(basename "$0") [UPLOAD or DOWNLOAD]" + +function help_message() { + echo "$USAGE" +} + +PARAMETERS="UPLOAD DOWNLOAD upload download" + +# check if there are all the parameters +if [ "$#" -ne 1 ]; then + help_message + exit 0 +fi + +# check if the systems parameter is valid +if ! echo "$PARAMETERS" | grep -w "$1" >/dev/null; then + help_message + exit 0 +fi + +# UPLOAD +if [ "$1" = upload ] || [ "$1" = UPLOAD ]; then + printf "\n%s\n" "uploading volcano" + rsync -azmPu --delete -e 'ssh -p 4545' . sergio@sustancia.synology.me:/home/sergio/backup/code/volcano/ + rsync -azmPu -e 'ssh -p 4545' . sergio@sustancia.synology.me:/home/sergio/backup/code/volcano.all/ +fi + +if [ "$1" = download ] || [ "$1" = DOWNLOAD ]; then + printf "%s\n" "downloading volcano" + rsync -azmP --delete -e 'ssh -p 4545' sergio@sustancia.synology.me:/home/sergio/backup/code/volcano/* . +fi \ No newline at end of file