From 3cccf804df5ad995e59d05eb3f86e51d0499d364 Mon Sep 17 00:00:00 2001 From: florianvazelle Date: Sat, 10 Feb 2024 15:36:44 +0100 Subject: [PATCH] feat: add speed boost areas in races (#43) * feat: add speed boost areas in races * chore: add changelog entry --- .reuse/dep5 | 10 +++ CHANGELOG.md | 1 + assets/sounds/boost.ogg | Bin 0 -> 19450 bytes assets/sounds/boost.ogg.import | 19 +++++ project.godot | 11 ++- scenes/blocks/forward_down.tscn | 6 +- scenes/blocks/turn_left_2.tscn | 6 +- scenes/blocks/turn_left_3.tscn | 6 +- scenes/blocks/turn_right_2.tscn | 7 +- scenes/blocks/turn_right_3.tscn | 6 +- scenes/boost.tscn | 53 +++++++++++++ scenes/race.tscn | 4 +- scripts/blocks/bumper.gd | 2 +- scripts/blocks/checkpoint.gd | 2 +- scripts/blocks/finish_line.gd | 2 +- scripts/blocks/piece.gd | 3 +- scripts/boost.gd | 34 ++++++++ scripts/constants/collision_layers.gd | 1 + scripts/gui/overlay.gd | 3 +- scripts/gui/participant.gd | 3 +- scripts/main.gd | 5 +- scripts/race.gd | 9 +++ shaders/energy_shield.gdshader | 107 ++++++++++++++++++++++++++ 23 files changed, 279 insertions(+), 21 deletions(-) create mode 100644 assets/sounds/boost.ogg create mode 100644 assets/sounds/boost.ogg.import create mode 100644 scenes/boost.tscn create mode 100644 scripts/boost.gd create mode 100644 shaders/energy_shield.gdshader diff --git a/.reuse/dep5 b/.reuse/dep5 index c585e57..3b4a989 100644 --- a/.reuse/dep5 +++ b/.reuse/dep5 @@ -65,6 +65,11 @@ Copyright: 2019 Zylann License: CC-BY-NC-ND-1.0 Source: https://github.com/Zylann/marbles +Files: assets/sounds/boost.ogg +Copyright: 2018 rubberduck +License: CC0-1.0 +Source: https://opengameart.org/content/50-cc0-retro-synth-sfx + # Fonts Files: assets/fonts/box_pixies.ttf @@ -78,3 +83,8 @@ Files: shaders/sky.gdshader Copyright: 2023 krzmig License: MIT Source: https://godotshaders.com/shader/stylized-sky-with-procedural-sun-and-moon/ + +Files: shaders/ernergy_shield.gdshader +Copyright: 2023 Daniel Bologna +License: MIT +Source: https://godotshaders.com/shader/energy-shield-with-impact-effect/ diff --git a/CHANGELOG.md b/CHANGELOG.md index 82e57a6..58d6db9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ Inspired from [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) ## [Unreleased] ### Added +- Add speed boost areas in races ([#43](https://github.com/MechanicalFlower/Marble/pull/43)) ### Changed ### Deprecated ### Removed diff --git a/assets/sounds/boost.ogg b/assets/sounds/boost.ogg new file mode 100644 index 0000000000000000000000000000000000000000..a6c235bb24df2f5d21b59bdc0a5e9201a29c7381 GIT binary patch literal 19450 zcmce-d0dj|_b_~eh+t@-XsBd>=7QRQqM=!Xifd>tU}(!AnhR#*-rnFwfaJI~WX#QDTJ+Q{Max36G92@6sjkMO7SE(-LEVD z&*i)@E)014MYBU=*sHVi`1~!|NqLFsX5h=7 z0kIGO0oI|i2s+{Qat;8X0f1-kY+98Z>fBo09kTGGqe$e{5*;p4MjiS$BhZp8 z000IEosebCk3t2b-YGc8vg}6hvD8hl+eth;Yv8_Jan5=3nG~Id4@;0r{-*PiQ?`HnqIC;s2lY8S%mTZ_R+4NgU0#5YL z_50qtzb#x}P$xiuMmz6=51bVwYsGzUg+Z~X6AC0Pkc5D&Bso_$hbof=-D!2lQ#+1l zTsi7`%Pq3)={em;9NRiKBQ|rbiFobG!#|a`uEdLvpS=$_Hpo?)m**l zkW~U$FKxWmsQnffY#VpI_L1ro7JQOa*E#l|V*lOWKWx#yxqfuO`ySXrGF_K`3b_e< z`Xj0S#RziY-T!1C1~_jCQ@EjqLc-oMI3G(?602-;zc;OFqz*f`*d8bg3TrQljJ9%Y z%`NA_r$%lzlK>l_Fvbv zSNJHi<={2u?iS;*n#1O-&(DbaA@BByl1)>2cW>^!d-K3IOGN*ZvHl}D04OxYUu3eH zFQZ$Eh5g#2_Tl5MBd=-e-q6O(1EXl+F&3M~Eb=BSx5RjD zn(*8*!P%nE-*W5tmJKKN#vT7hVEz`HyEpUxOL7)OgydcJAfyuZza*#8sq8+z%r3Oj zKCaSX=fM<7ZTq3akJ}Z-|3h+8rEPL)n^-z0E_0F`Oq0~APbs!u?tXgu|9bsLa)Pt% z!3&g}z-;^fk{k^c9{@_zQP=P{f8)4%3?yi7;FABI007XGqt<@WBT>S)L z`u{93V5y!KK0yNsTLS=AAphu$nq<*tRg>}02Dnlxq80v-T7oS)SbS0Le>o~bk!VbO zNNF4Q7Rf56`NoIb{o`J(&X*DQuf{d_&)dU6wFd*D0016J3bnuV+E)?$*7e#0i7!St zyOVZcF7$Bln;o`5=-VB(;Z?pBb7M4c;enWfx21m*(FH1`Lx58IowlK`eJjBR;aH;d zpi*Lc%{=h1gOoWzYpOk{+(`n#T1P1>$}^$%@cbc%iCm7dUA-~xAo0v$$6AL8_9hTa zT7Qsu1r&SNbspih$x_+~O`=G zIh?#uIjz>&EO4SYExtD8Z!q->xJx;&W=(JoDb&%MZk9aVrD#75b|q1&vpFCLE`irs zV|fxqhgl$JOKrEYUeBBW!6#op^&*Z1Cno=p@~M0H%~o~yqFWZ>`kH^h)7^{K!@<#i zNkUca(W|sgKct;rq0ifNvO87%FSx!21OY$@F#?2u`DF%3LWs}_07^jy-m=s7A}AVf zd_m5weYDg5(ov9{330U!((5#kfT^`}64JuT2N>hQpRL!cx%kEfCSZgBLS5EE^^rHs zFHF`P|H{;B!o^ih=Wx-YM8<}KJ9|62m}GM*0VJe;4S6~{868M(w(_%A~V zsbZ>5o?sm2yqqTWb6#GJ@DFKksSXWs>%Zad;wNGOmfSF&8Md?7^DmNby+3v|3PzAy(M5tWa>Q1HoVwtj)y9Q}V$1p>?< zO#z0XS7%vfG|iHmIvfTN3;-b&PE11i595j#%!*<(Xi!mRKr4yoZ{1kLdeqOUwLjUpwZ5n_I(;NM%-eB!>y27xtD?xTurALUcX(5E zb$t4$1nnQzrJJfZCl*)7m-c!)COSL!;}UZshN7bd)S*Z9G2Q)^i6fu^wlUppD1H&Z zNX-O*RXquL#Z`)44LDs;U?%{SM}q{!C9<4b7fdr{^#a}HF<~IxL3*}#w0ti}D3(Y{I1iHZBHi2G_I3#%iM>ME1aD&x3AX3X~jEO^p z+yyK+2#_?z;5gkt!w*5M1`!8Sgrh`lN zj~hz67RW%^nF$EPda^_{Eypg5&3vK5DF`3~5r6dW(jM9hau_(UFB4ZCwovf*6#6?^ zfdxi?7ZgW^J^oJtIQDVxIl@0v?eE;WfX_emqQm}u0($|O^9wh8$-s5{-xeSlqQj8? zv_ShiwN{(`Q*Sx=A<&El+cqs!ZdzFGLFz4JXz)W|e@U}Br`$J!b0e-v*oKH|Lg@7H|O&j6S?F$XYy0aK1qD~kv z4(g+TPEeRZl7pE^^uJGC{Xx!uzxz_q{+}ve!2kcVwF@Np7yJK@Pmn1?8&lz!d5~Fj zidC$2)&nGtRQ`ow(jcI8gA9YqMTdbBW=sTUKEj{erL#;dE(dwVX@Mn6sXI&;s68IN zl{&=rUErDp*2N{FjxMk`s0#VAe#=`6GXSzZ^+tRVD1RV#cj>u_ojRO(SO`cx{#Eea z)49BL5@hiqZaQ`7I5t}120k6=$0f)FT{>=JSMLo_5-!wO@}(fTbKHUui8)|@-1P2K zmI<=4Q#J8|17MZXuZD05>7AZKp!U$=?23E(k6WjYc-{n!wjso_L~u5L&RG!Z;&SSc zb^7QjK=?Dl2+$hZA={6kTn?Ok1w&y%nur~M5C;f}Kr#O)NCi;w0g%`pmt%c`=9BGJ zXXlGFj=9?8q~TWf)mi3sJI_h}@~I|^pJxnt3yU7$4glJ?5$}ujF0(EDQvz3uXj4$F z=MNJe+Uw%olh8$z{3lpV(6W)9@w9N!yph+G~5}z8vQo*It#{e&@fVd2B zr+JO9SkZU|SdyD{vjAO)E+$wSMKYkK5hw3SR{Gw9JI-Tke89~tm=M4Y(6;aric^yx z(S3Z^F#MT8Az`eD$Y?gW2!aU>tO0;Z3j(S3kawBs_lwKX6_`r1D)VYAXr?j1-P%GO z1^|VE0t2Q67z+J+ThBm!c?B$N>laGo@G}I+4Mm?ApXAwEtz->Duwz6`t{&xOYF5yu-}fa6Xew@z>0@H;#Os zZK+I*`t4oB@9Ur3f1Y0dLZR4slXPzEMc($D?(C;KlUMu8ep2To$Bn-E`1!NaO1Sdn zIcUrL<-)$7Xg)H}Q}<iquwtFu>VS_L2Sx%ArUowq(|1fDu3b?X&@6Q9$YV1A}xn&p|{H3(pDjBfNj zlzO2idgHxc@8rDt^YpE#gK#c2A=Rl9-vxgj+^wmx`|zgYQO#E$OV>JMymJri2`Zkk z`HJ}Z{cH6u62@Y4TP1JsR4ziJu%D%f&b_=KX-yopAaWS?NwCMv=4TcgXG|Y!Tb{L~ zT2-uiAD}>&D4>=bsBgF5`Yz|;Am>`1z9%4jXqi_KrSrJ5jeq{a$H5nacj|vvS%0p( zUBC5V_UXhW=)Wq)sKE(k($`N^`Mv69^9^aGo1Tw$bJ?ha%#`?h@+;qLvCr%I#*OYU za#MTn7v!J`0J^3i=lS|q=SOP;J}+q-Y7gE!pK~Yv!-J&ROZL@I_O+FsKKh~| zxAJHIO}|~flyT&b^>L+0c>YJj$atw zRL%#f$c?S)6(% zdt0y1IsFF?v;NuP7rVXux1UBY$w(}Ych#7|$_~CJ(^F`A zY8z}(bx1IzQDCC|BT30k*v(yZivHtOEW>0l-KfW+mtdLrjVK|pR{Zz`{+8L+wcmASsjzK{HWSiPIN@z^ru-dpKkzf2cUteNh6w&e@#%IeC}`vNPSD)=7EATVu+$*PR%%AV?qm4gR~`@>WKK`OZVwx`06%us&g*M% z)Z|4HiwW)I(T=o2Np1cFrN@Wd3xt?aDVRp|4I%CAkI7M`{x4qb(ft4&eDlP{t?UTt zVy|5_{%=^~Q@W@h4pELniG-BDQ-171VjOQdp zJGE_(@8IHZyhLV?Vh`OEq-@{>z4>kBSaf36bDCP6&`YHZu#5(sxxH4FHq`Jzwu5Wq zYAhqlEb4Vv(b%MSon-rS!Z!-I68BB;2^)(C-ln0CqgDiG?r~lHRD4f*sjD{x5X7In z`PT~Mr{d6nP0?SKA_~jbzsPHNHN-9rj!DEcC}21IEMtCNSt-zoCyKRjU1Z>pw@3Dpyq{Klwv3s1 zX%)6);=9$yeq(iXu>+0Wk+?EtctF2%8o_E&;CVzNh z{NwJ2jFm_B{!Djl{}@-hHms~}{i&f}Q(<^jXLBd+_@g!fea|v--GJd>8i#cXd+`N5bQ+9z0vWB z?3UwK@6EFO0t7w&KK-k?+-!MtZm{i2ZV2@7(vDi$L9$aCKo-bFX853Lx57NV1 zxZZn!_JHV=)5DR%jvvl0Jv@XpL?^urIez8S_>Y=r+xCXN>S6Er_$Kxb7UQep3uY(f zRA@Tv~HYsA}vCL>RpTed|!ZKq^n2oI9H`&AwHS00Y16^9lX3gKL zn+7TY;4Crk*x56xxLn9h(c7zg&b0foLE-G_=t|>EOxxityHHjaB6fdA-Q(&N+uOgf z)spSK@z?w-2GhLzHwib-C)aF|_C*ZQ)kW=S8yjA;$@$<#GrNk0dj-=9&w1C@spqFVcKo;zoj;~IwXdTAzt*Tl>W51Y zXDT8xHi!j*5&(@i>v~K>`xAi9g9vm1gb0O*p}1^jP+`W;SAIL5IcxGbNxAlNN9CQf z#D=cywPTBp-ZtfZUF#;Wn+{})`O1V^%Z~PrcoUngd#rTg6x?~Y4STkBwI9A`t?WvD z*mL5YM-(S$$*YyTMX?in{{92CBquMbmZVx5*$I!{wvX<6_>r-GEvZbqeqFqeTYkpg zcGw#DqNWee4nHzI?|P6~OVB+i^h*lHZaZ8o63OosjAuA)|1)p%cYmFu3rnUhPmQBH ztE}BDjqF08S{X{-~e9AI(`G@%<>jiI zm&4Yn|^& zFI#UqvN>)*KyA&u*%=3>Z`L2wa}x8y{|F3Rv{r0tS48HYZ5MqrSUvu7Ni)rlWAvxn z=g)jK=>vHlp^_)x=`8zYWh5UbQmK%tvk4z;n*Ut4?7LEDkrS6=Q5u+Ga;Es(ju9KE zN|na(3-8dAMVp@WGz#K5;hXY1^i1~U>KG-lnZc_}ya3f@k$gJBJfAsrBX8}UJDPuK2`=(QHqr%hD9G`p{kJTSo}Fp-U7J}G1iBl>Wl{?Bm58BGf0$FRt?e?O zh|Q}>j}jl>E4uhRQT)wObc(0#pfz8@z&xQXi95y$fguBmwIMwL9lcLX^`v(Zc1L|( z4?ey8SIfJbUVr^0+V}0sxFx55b73mBD=+6+o%{I5=q;n+nDuS3OJ5VK7hiesyX6|B z>7S4CMs#^S!!Pzd9Sl~#{$r+Db^go~%n#Dg6~FigwCx;Ozd}XwG77`3xI;@`^XZp{ z&>MoT%Wp4__^#_(yY9nZJDq=7anparxlJ9|MDmB$;7m28?6~>2M~`mR_~JVJgco>J zC)54V{j5Vp#M0%b@nw+j`TDEk>boaD?znVyd=TcDSG)V9vX_hX5Zu4M#ZqzN=AVgk zXV1skY&*BC8}E3i=H3)vPk)e3Y&nztM+#)-&lM*oU45T@IL%we`0XOMn6WG=vd?UlnETU_n9JpwRO>t&vn4QwGB2LLx6aK_&i&@oyRg9EulH_z-?LbBAp}Li8rlci6Ollp zlN35X7J#xn`15dN(M0~~yV#9qMOobJ=0Trld)q!M@7>R{YGaq)p_mNPSQ@@(5^=Fh zD>F%Uhi^?*H3@3@OAIYKtYb^>vGJ%OL4SOBASE)Y-zs($A4hs3!f}UQ%%oD?agQFB@UJ%`O^1+a|RoaZ=Id!b%SL#6FiA{pVRt)lQw%ixN{LbY5d z*3tB$=Cmmk$J1m$uq?QZ>+0nw0wbz^;aYyjU^11dqfl3o3)K*>j@qe}a_>HPZya-g zvh?akJAOQ?qrh6Aw%{=)X-{-CSHX0Kii1U&v$cKkXPTYCuq<52tIgf-n`BBh21IGS zx1V`+1nM+=f&ft+aChm475?e?d4YO_9}ltUozC4*^>&rg+SF9UQ{%`=-bxnQf`O{I zA)p$$2r!)9DQYLLRcjmMKxf_cft=G}b>OCCiW=UZ@9E}M8XgWzuuc0?tp)+~AitOA z!Kw>4(enGbZptQwl7pd6_9WDb3yH2)05?jENq{8HHVbbUbZ)l$i9FJoStjR}7NNEA z17~=IneJH`+A6Ugup(t9g=j0N{7Bqf?Bd^|s7_}czN&~SO<8d&2e$D5ef|G|M+8C<%O0g1mJUkZnwE$5tOyKMa5Jw=gC`>-)tXz zv}4JzEU}BR#v6!aC*>}+AbjO*Kr$LI7|SuOw+onIYLj;Pzht3M)(u0A1UM-b3x9yG zFfe<`c&M>5NCJxSNC@2tK6e%K00u(|vzY!tg~Tj?0G-u1)2WS6!Qj^d)N#3hVo$PmMT=Pu7RUTRPT_>>f)8{l|}`2)NJT`(rcl1->i zfbcPjTw?%nBn?%R1ITg=gbqh}C)$UO7cdbXNMlJTIe4}{hY^HA7WlV$AY`dDhZ;z3 zrL@35F0OFdbrfakHEu9kHP3noe= zWKk?Ehc(EDOiJy_$YtDTbd|o3%j#%$9-2axa(d!Xu9oITgHN15vj&u6+2*A&7Eu(9 zfZEHKhU@r&ol^Z}@g1@kHJl3TpYC$-DlI5^-LK;xvpPuKswhn3Y9l!Te$SM~v5d&( zjwzI@vX(#1LB-&`7Vqy4d}}V@Jo7T2V44I(T6wa9OVduMIGyJc0 z>4ci!3vjnucILN5gj2N?9SKgjL(%qd@%RNasGLmtS*qzB_4iju#(=6EGsL5Y0~8Y= zpcmA4335?jqt%`H3pB%tZBPMJrihJ%P+h$iDIce*!4MO>=TQ9E__C?#1LYSS+#@6s9f^ z-CR_ww1%tI0?!kx-l8L*ntjIj3NEq59@up@OfP@B+-5Pk4zn$6<8^_?dqU8C=9hKS zJwIYdlo?xkroFxWXd|ObqQMym8qDWp9%UMO;&3@Va|lsYO%H|aJ z5g~X80I2}m-j`)Thj7`WR+&Ru>#Lz6O+nVEgcv}Gkd=$=+(7~I7y`VB0sdw6xWU(p zS3nty0R{q(s35wRiHn6H_4GMrJ(a`=LTIfT20-lquYrmQi113RRzs`ww?l_+DW?H5 zD8LGNUo4j4pj5cFf{4i?@EOAeb}4u(qcWzPwtzIKn~!|{;7*ID zgy`qne!4!NN^3cCnKwTVNNu6OJSM)qV}5LXM|1Eumaf>6lIvp#PE3s97k{!jDEL*% z$s!Qg>~*KlVAZ?MH=;HJ3iw>KD(gt%U!U`ZW6(3Tq9$dUwJ6*I20?pv^5u!^saw73 zbZAaZP0d#)3fcv7%QM_gCDoFuXPXCvmrC2e`ZgoBwAs94>X}l6at{{*ivJmYC8Jeu#&6)qaaoj#dipk_Q=97X5O*HNqiwA{l2YkcyWY^s8yv z@2|V%cce9%Jq$M(q+Fy#QFJu7{0aU_lZkE9s58w{HF+vHJrzP!r}fv0#i{0ZL;)%M z6HT$Mlg^5vsV=^!o4{J7iq9a$4mvpS#R>hj?=exOd>oXUA(9Ks12};uo?ZD*kKUe? z#8a4fiWY4MFt3_*1eQtV#$vgWJE`_6O;d;<+{k`ufl6ACAh#SWHz11=5V0MFg=unu z!5}-T#HVw0@z@E|y&d{#2s`Q;W|1Ok+oSX@2ify+iN2>DNl>eO$Xqwm`;&d#Nj3(< z84#RMK-EhD25L}Anw}0g&diUbvdsH&v8;*m{b}B*o9`3MDQ?`%!U8qFy5b;he#5B^ z8hny3f>$Bbvu3er+CU^2YHrHV=Sn=~R1Y5>V7afJ>ZE%vKL)rmz@~dr+S> zgN0UMts7bB7( zGyn!+;>Fa6Z8lyco>rJ65;KO81w=7S>Weg1jXG9|0*LoAopd>1kVTwn* zqT?LQvY4_*-$6;m^VGX3X0QMpZjl{YwsNN4E>R|?6L=31%z82X0iJ*;3d{tG_P?Uo zGAI}zryfTIEf~KGk%1}WMW z_f%Bjg`{z0qem!<0mI{{Wx`>ES(SK*;0!Z~X=mV`M0~q^X%+1HJQmIaRa3Sp9)}@8 zhEK|i{cz^F);uTxX$Wc_r&6p~{+m2h2o)Cav511ucI8=|Qfx_w~OXUj734x8SFD|gt>rBxm&>9up;Y;~k6AR82ZZB8YBW-LHsWxpD-Ra{} zEKu-{_Nf~#->UScN_oDYUwFSyt>A=LG6t^3fy$;L-EMY{$cH+=^eTS3@ zY6x5{;ASYB)Uj+?6jiTO-bp?duXj)u=#Tf|lnGSepx9W2~-PBU_>d%ZO@)K&VGQj<5&_cjfD;m!o<}B0!iX zx9kYlb(7@eL{C(QDvgfg;k@b+y1RR&Q(6EMunOS!I~nKK<-MJcZ|3*P1?yb|I(6(s zUwrr~2RTXLu9V6}`s1H>#nv?&s7X>uU|gI!&jX$9ybw{9Z2g zx#8Qc$FcL-3=3vBiu$}!s?#vS2WXR7>t8Knp(fcZov%EXaOEef3$bgV7$B1m$P6%q zM23#&|BxY+?VtPk(}QE#KNbVRV}!#Op#|kx{^0tEs0T)ttf?z>$WB7kgG&phH`5+o zZx?HoTH+zXTlrIlyn}h5wLF8e0*q$s0o3D$gY! z@QcQnV~A#R42^fzjLaYf&rtL+cp8Gr{(zsOuz(Vph;|>s*}-92D@-sGmZU19W+G%c zOrF#7JO}zWOXYS6;4+AHLN`>QPNka1hGYVDBFtEGGA^hNS&_B9Rg;ED6;5zNh-y2v#U1~1kVHN0=Llhw$^xx#vLQ~StkN6+nU%cyup zs?OXrS#1fC+0O+D0a;7rMJ2i+hhe5_WU1||Wc5CCM+-R(8<7m3G6w1-7IFE|R{sNG z(5eD3k{Z4|R5)86`hspw7_cIO3d3W_ibw!$235!`Ju9dfhUm_mHAIJ08lxPlLV=>u zBnl4eQ`G1#XG7<6t<3>s1u>hC&;rJHI!kbWgnYk-0>-lof{d>EXN);9rf5b7Uidkd zCliZ;@PP1*HtZhKCBYfTmAvV@M&N4#3mQ@~Xpet_+qq-MNnfWGM!J#AiN~n- ze<@dZ$i-!$YNNKE>Q-2ZU-B`rF`yZ7@=+_=k2nM78h;CvuyGM_JUKo0-Proz4hoIe zzWzJ63%3G)r-+`yijOS<0NW+YA=o}f_p(R(g{7;lcvPc605JtXxUzMSCA-}H04Qu0byMMkP(_$? zr^x$?I*yxH7VGE68%Us*)g=t{Y+$qErVJ+{JM@KW(1&Pg6967KG{m+9-d*PahHjok z;2Y$Y7IBSAA8REjuVOu4tz!=|BVlC-shX(N_e5=&kR;R=8kWXTO_(;7v)`m2;^zo(`2+2SE+YTM4|%*qoT|33-@FfCfh4dn8XTj!8Ug4) zwyTo(VMly@JZlg}4eSH}wU>=XenTJV8rxw}7c(&?@iFYZ%^K{B>$2>y*1wB4jqlwQ z?D9%h-Ao~~rQ&HmE_MS7VEOr>IWEfH(m)g& z^kL|$N1JX==!N|qe3eR=dO~Qlb+fBIFiDuf1Lf5Fn({0F4#;xKQ1~qO2TvxK?M<%@ zcw4`6;0&xC#;7+>sW-5z+$iMLpF~&g#fNn~)$jYhJfza^n&Jn^-26t#w74;YOiFjiFGzz8D9U`k^&w z3eMNIG~guyK7gijfkA{w2wJg@uvsmp-JYO9`GDKkOZGS!(GDsywaOfI0%$1K)kdCm zl`*1F3_~3b5n@~m1AFK}GN8ho3L5Z|EL--;fCw$bpor%lS{Tvnfza4Pvl&1V-U^B) z5>tk~1NeBi9s6j>6d+;Z1*HL8RI`~N9rl==Ke*`_uGnw~ZY{txF7h`bmxS5f5@P&A z0C1xXZbbZ?ggk~O5rYpS%%I-~HB0bTKq9ID4G8JkP(HJDYpih=bT&i`;3WnrAucFeYD72^VMVFm#ci!Va(h5S^uu?2(& zpxD+*GzkrmjGzR2Bxum*I`CL%6ubcn+SLHVUCty45eNwHB^_FY()oAq$#v8q2!03W;^7V|nzs>e_3GMJeG!FBic-Y&BRECmx zxQau*-a%-n`9(r=*tT`n2Y}^t!`_U$%^-zTN{U0tVw#Zh= zPprx;`h`Pi5YU`WF-yLQ{2&)TE;1nX>gCn;-LPtt8cqRqnBHFtX9fAyD=I( zITeXCOGGg7rbUD31Xt7`&Xwp0S}F((E+!>*`_Ht(%PmmK<6I;JiL@dSNsfFJj2I9k zGp7>l2}9nQd~toZDXb=<>AH#=Iw&tJ5Yv5S!AK^_(h!F~B>H0q%65oIkwI}wP`|FB zqd`&2f|U(dco52%+;uwA0HTLWvLulxrUV!a4uh5<04V{mB0^J!g?5BY|0Dp^&E`}e zxP=5qvpz5YLm|LJtaK``-oq3TGmoptHTE;35rEQrJc6%jBii_06z&?P0GERDCM1gS z6?O)E8HB^-ZM4BXB{}bnlJFo;`4XHa&6D(ln%lsaa!;6Gs~FBC^p6IMz1P7 zDhi|Pn{qRLw5!a;vI8M33mg!5#KpOBc0Kngb;xPTSa*>?O&EQ*$ z5 zOJQ{+45&%Gywg4+U9v<&5+(G-x?DH+G%<%TC;O&SMs__#O;X%qwPaB{oF{+Ua#roE zc+*(u60TcpslHH(R2!&8oUIWiy*45wR6!z%nx4#11WW2v#$u_pNSszk zRO!{EAg?Yu-icth!3Yfv-~osiF2O-s&`E~C&<%#Xv)9$5y|ZBvz71E!I z_uaiqKU9>~eE0rx`?DydH{b}sHQo<|n(}hcPhgh=goW2&%luKsgDIq93q# zW|JER?9ml;_aR{pzjzqw9ZU*h45O(|_E44%RukG5jfCCTcw@2{HKr;44q;dd<-(Of z1$@oEj39@|8!F4D~>5Up6IpjS*K##5eM(BGRzj>x^}5KqE!NUlLUsV`R}$)XZhM zB+_wSr9v@6Y4}W(U=0Sh3KMFL24GPZo+h1^XY`Whkr%u`>>%4J%3?q;(8mo#b&R~w zN_A>WPaR2c{7^5ERd{%})zeomj%gnA}Tt?NOk)yk&Yqd#2T7l|F4dr+?KSqedQBtRJx2I|pO zO0l!z!tr&PzBt9{Wz`wqtvL=;jZ_^=blzRY3A#Fn0YEIqlDGG4U;&YVT|=rw?^eu2 zkM*?}15RD7GC@@+j&CfL^F6!Z1f@yo^WCZ7U(I$i0E!k2&Q+i#JZ` z3fE%0i_+pw90mirN&vg-bmE5<2P#l_#S(jn6Ma+yR6zLIqe6qM5JFOjxZo0?Y>D7I zggU0e3X<3yMlcgze+20}wC+#yhDcI?X-Ey^!7!ShX(|%~NL+9bqZ1m1&Mw2Dii;3j z6GkTR{XqGHO8Z%ch7Jh^Mj;X$WhivV0cmlTxv*ST*v!d?EHF^p`sD1tvaOP z=xpO-w;CI-bh1K;SrO(8vQX`?=$q05{y*5nI&!kH>oz1wnP<-W-Uw-=Ke0EOm3hEs zWFCwmu?MO3B|h#@$uOm3-~0XQ!uJI+KiMJ~tSkphDQeqs1D80eXcD zc0GRo*Sv@8&;I=Dx~!E+?RnkzfBDMAu_*TG1MeeF*X&|uN^GEfVgw%JZKQ!YSUlV} zuC3g%(ou2{)E1$d0dG@e3#J8Sg_sj6_)gfPW{Ad0SV<;8oO0zA_zxSyjm!X{2ct}z z6?Q1E9WA2+6w6<{N0NyNz2z?%03g55h{WAcP_APFn?$%*w|`l0&j;AP!RvZuuNu+z zMFUBs!jj1+R_-q`p6cJw{qEo60f>-ed(%TzqI-9qmf#h8`{K1j9rC-<4?U*aHz#9N z!w4vm(c%NQZtDAWj;}I*VtD~eHrEuD_0}32__NiOjXmx1ZU%vW6N}B|grH$-&7?eM zJCE!7aVTSn?ZeBSCO*r5Us8Eq{^4$3^Ttz3zc%K}uk8082EpLS0sczt;5KR?XjBJg zh}%VJICn0Swc&`5Jb!STly3?CGuc6)(#2o?#rf05#9FmNq%v7M|Ma;8|*`61ie5_Gzcf&9Tk* z9lyc#5J&NA}k?lch+;s8nC6Y_#kt1!cc?dvJ4K*sJ&}f{p@)be zuI{(#c@)EbE|tRsI1HBgf=l7zHn~EeN{H|D;?y~VgCUfef<^$})A;S)wbz~;(Dhk+ z_19XKwi9p;Vxl~jL){vmd+MC+(oHvggb92(Db|MURK29qrdL9tlPhj z{I2Q8h?`%rFXryrd)L4Q3Xa0w?13z6^wg=#JBY{)M~tq~33O3O?2+<~OC5)P$z?g^ zK$q|SwDfc6BfHQK(MUztFj&S7NEtDu{p```JzIb_ODIst96&&z15WT}apTVi zDLeEvd!QtA#au|(7Rn)>_tFUCk{61lzZ!nWX{!9G>XBsc4;5>^rY8MtU;x)PI)M@U zQ3;};DL!SfWB1-2kp1;Qd6sG89DuSd%OE7?!u`g77K@x=-r?pUnVXXu3I2QBAyOCi zo`*6h!^)UdCH$1R4Zoh0F$YZX9nni8GEF@ zT5J^b19n~Iyaru4M4noeD3C{91Wz)Q_%}yQ5>melx&N8HZEr5*czLneqOX_Uw%Q1W z>|ng%aw?O#KP1{etL!X{kEcIi)YCH=@OpHC$INB#EI!`KYz|K+2C$+La8ihcVHK9O zef%*ZMi|yir8q1V3+(B0GU09`xv@V914dQB9a3Ut0m8b3M@ggkH26{3)=&-GK?(Sc z`@zkG5zAAt))&O~B0L(ju<*#oups+ON#)xB*<+RrCuphkZ;MGo#6ZR#+mmp|Sz%)D zu&tF5pPX%z z6q5-HUB>regV+g8edh4U_h9G5JXYg`CmJJ&D+1ved>m(3(kT3 z=!(aIoBPKDP0UfC**>yDR8uyHC%@er()g4e+}7M29M54vsBZb71eYi$>bALodmW6{ zxKMCodv8^(Z7x6%Sc78~1M`oK_ulomBbvuH*cP4tHE$x4YU0Uud;i028tcT^yZDvbe;{iMKc}e&vjxLJB1rUG}UR9cpl@~H0If0Z*aJ95x z-Ze>OZ&qc?*wMoPkI29q+7%Q^P+4(EsFv0Oq{`-tY#E2zWdPJ$N><+k`l=CH4hYdT<)MXAj6qarB{J6(hek4b$_ZlXen04~mb!+JmAVms z%W>zei!J#{w^2r+kqwp-3PC2kPws!zwrg*zMw}$6nr&Hb;7(sTbpdgkCrfS*5&{4X z30b|%4+uG8Ya`mlh{~H_3hAoOEq;j7-P{!xefJ0UX)$C#9_DR%H+L?6Uw_&7L%Ap}8+$8&;5_}} z)nnyTRcXS?Bz;DPi1Rnc#*jiK#QxpKRj6qBs93>~Btv^3~ z(`uL^rp4;-m=?1QUR*gx+cUpU$!8a$&szC;j#gQbO5`3j;0lh*^GSqv0@de0-!=)d#KP=%Uh#1Eo&^bT|xk=TA=HrQ&0h8%~}%>x{4^$vc64B zLaGP`AWQZG9yAX$4V> z)ip&-XRFZw?;_2bQew8M>snVz3IO`v7NFNpLXBSbtR8eB$O^=lSd`FS4+_ws2L=ED z1fv(rv+jDp+tt3}MJ~zeeci4MFLwM5T-7Wb%Le26Q%)t`G{>1wj9l32@&dc)Ou^#% zau!%=&`rWy^_jU~2$JLis=s=9a~Rf_oj2T36%j3ca0L$i zqp|E^D0cv5NUO_zS(s8mye(Ki@53+aC?VQob--7&4W)% z+en~7S=J#agYfQ%YHDwH_Jb=54|_H7dqGb=!1_K`2CqJ*A9hRR?@;CUFgrb;0u&T6 zRHBTN+{!&qgY6Xm|HUbi{|TFfk9yB>A9m%_;hd%J9aa3@+g8H|fnIWF>VI>8>bX`= z4PM3MX_oSq%Ep*m&z&|{mJn)q`Rg>L&Vil1-S^@7;xq2%wK^7CS&va_=@`3q^un~g z!3t~eRoB{vPXxg@gGRSW%7 zMm$#dr+5B(vA*M5HO$_M{Vx=R$KCA=DP|lxZFZSPQ^0tOoh!{U9>#@MOg8H2N@|S<<7lRd1Y`*`M23Ggw-a(n8r*_wc6E#iZn0&S;R2wTT>n9c(fP5LA-F zhN!`SSu{z0`xd~*=Vtr(&Q+4DW!n6?|4Vd+YtIw?9y@8c!gR7f;8;Ib9tzvh)h4f7 z0Z(UVQvd|$Gynhq0001gh?;!`0001cloe0{|8L%7dma4?1}Na%V|yL_2M#FU3_>)p zVWSREfD1qg18}YsbRKph!2~iKS_1?es zf!$Jn*ScoEPxY9+O}#L6gb*P_;Bm`a-cy>=l=7Chyk|}`r@7@VZ+SKIYP{2Ur}0kX zz2t#Ca6EVnhyfgqzQxz^c>Mw>)aIeKKaDk`tDJeQ&b;}YefNXC{h@YUNx)Su08yle z9*why-UIdx`_}s#?{B-mxo_?UH#i`*_Y1MJ>BDd@Z+Xjm=GDxrnOAebYFLzFQF>ih z1wME@RNN{~+Gly?x673_?pYzR8$nZxMQP?$dmn}eo5P{wpX;kD+1Ke8>$Q#7VZ1)X j*CG1b?v void: + set_visible(val) + area.set_monitoring(val) + + +func is_activated() -> bool: + return is_visible() + + +func _on_area_3d_body_entered(body): + if body.is_in_group(Group.MARBLES): + body.linear_velocity *= 2 + audio.play() diff --git a/scripts/constants/collision_layers.gd b/scripts/constants/collision_layers.gd index ec49a83..4fcfdc9 100644 --- a/scripts/constants/collision_layers.gd +++ b/scripts/constants/collision_layers.gd @@ -1,3 +1,4 @@ const PROPS := 0 const CONNECTION_AREAS := 1 const MARBLES := 2 +const BOOSTS := 3 diff --git a/scripts/gui/overlay.gd b/scripts/gui/overlay.gd index aaadf58..24349d2 100644 --- a/scripts/gui/overlay.gd +++ b/scripts/gui/overlay.gd @@ -3,8 +3,7 @@ class_name Overlay extends Control const Participant := preload("res://scenes/gui/participant.tscn") - -var Group := load("res://scripts/constants/groups.gd") +const Group := preload("res://scripts/constants/groups.gd") @onready var _ranking := get_node(^"%Ranking") as Ranking @onready var _marble_pool = get_tree().get_nodes_in_group(&"marble_pool")[0] diff --git a/scripts/gui/participant.gd b/scripts/gui/participant.gd index 217ad0f..4a04806 100644 --- a/scripts/gui/participant.gd +++ b/scripts/gui/participant.gd @@ -6,8 +6,7 @@ const IconConfetti := preload("res://assets/icons/icons8-confetti-100.png") const IconTrophy := preload("res://assets/icons/icons8-trophy-100.png") const IconBang := preload("res://assets/icons/icons8-bang-100.png") const IconSkull := preload("res://assets/icons/icons8-skull-100.png") - -var Group := load("res://scripts/constants/groups.gd") +const Group := preload("res://scripts/constants/groups.gd") var _marble: Marble = null var _last_rank := -1 diff --git a/scripts/main.gd b/scripts/main.gd index 8b38dd4..1a449ac 100644 --- a/scripts/main.gd +++ b/scripts/main.gd @@ -6,12 +6,11 @@ enum State { MODE_START, MODE_PAUSE, MODE_MARBLE } const RotationCamera := preload("res://scenes/camera/rotation_camera.tscn") const CinematicCamera := preload("res://scenes/camera/marble_camera.tscn") const Race := preload("res://scenes/race.tscn") +const Group := preload("res://scripts/constants/groups.gd") +const NameGenerator := preload("res://scripts/utils/name_generator.gd") const TIME_PERIOD := 5 # 500ms -var Group := load("res://scripts/constants/groups.gd") -var NameGenerator := load("res://scripts/utils/name_generator.gd") - var _rotation_camera = null var _cinematic_camera = null var _mode: int = State.MODE_START diff --git a/scripts/race.gd b/scripts/race.gd index 0239bd9..2e5c2a5 100644 --- a/scripts/race.gd +++ b/scripts/race.gd @@ -107,6 +107,8 @@ func place_piece(piece_index: int) -> void: rotate_piece(piece) translate_piece(piece) + randomize_boost(piece) + # Store data for next piece and positions for the race path store_piece_data(piece, piece_data) store_piece_positions(piece) @@ -152,6 +154,13 @@ func calculate_translation_offset(piece: Piece) -> Vector3: return offset +# Function to enable randomly boost on the piece +func randomize_boost(piece: Piece) -> void: + var boost = piece.get_node_or_null("Boost") + if boost and randf() > 0.5: + boost.activate(true) + + # Function to store data for the next piece func store_piece_data(piece: Piece, piece_data: Dictionary) -> void: _previous_piece = piece diff --git a/shaders/energy_shield.gdshader b/shaders/energy_shield.gdshader new file mode 100644 index 0000000..d6a5e48 --- /dev/null +++ b/shaders/energy_shield.gdshader @@ -0,0 +1,107 @@ +shader_type spatial; +render_mode shadows_disabled, specular_disabled, ambient_light_disabled, + unshaded; + +group_uniforms Shield_Color; +uniform vec3 _shield_color : source_color = vec3(0.0, 0.0, 1.0); +uniform float _shield_color_brightness : hint_range(0.25, 20.0, 0.05) = 10.0; +uniform float _shield_intensity : hint_range(0.25, 5.0, 0.05) = 2.0; + +group_uniforms Shield_Transform; +uniform vec3 _rotation = vec3(0.1, 0.0, 0.0); +uniform float _shield_size : hint_range(0.0, 0.5, 0.01) = 0.0; + +group_uniforms Shield_Pulse; +uniform float _shield_pulse_frequency = 1.0; +uniform float _shield_pulse_density = 1.0; +uniform float _shield_pulse_amplitude = 1.0; +uniform float _shield_pulse_blend = 1.0; +uniform float _shield_pulse_radius = 1.0; + +group_uniforms Impact_Shape; +uniform vec3 _impact_origin = vec3(1.0, 0.0, 0.0); +uniform float _impact_frequency = 5.0; +uniform float _impact_density = 5.0; +uniform float _impact_amplitude = 6.0; +uniform float _impact_blend = 0; +uniform float _impact_radius = 1.1; +uniform float _impact_anim = 0.0; + +// === IMPACT === + +float _GetRippleOrigin(vec3 vert, vec3 orig) { + // distance of each vertex from the origin + return length(orig - vert); +} + +float _FadeRipple(float orig, float blend, float radius) { + // create a radius + float b = clamp(blend, 0.0, radius); + return smoothstep(b, -radius, orig); +} + +float _ComputeRipple(vec3 vert, vec3 orig, float blend, float radius, + float freq, float dens, float ampl, float anim) { + // calculate the intensity of the impact + float o = _GetRippleOrigin(vert, orig); + float i = sin(anim * freq - o * dens) / ampl; + return i * _FadeRipple(o, blend, radius); +} + +// === SHIELD === + +float saturate(float x) { return max(0, min(1, x)); } + +float ComputeFresnel(vec3 norm, vec3 view_dir, float intensity) { + // dot product between mesh normals and view direction + float fresnel = saturate(1.0 - dot(norm, view_dir)); + // modulate fresnel intensity + fresnel = pow(fresnel, intensity); + return fresnel; +} + +vec3 Rotate(vec3 vert, vec3 speed) { + // build the 3 rotation matrices + speed = speed * TIME * 5.0; + + mat4 xrot = mat4( + vec4(1.0, 0.0, 0.0, 0.0), vec4(0.0, cos(speed.x), -sin(speed.x), 0.0), + vec4(0.0, sin(speed.x), cos(speed.x), 0.0), vec4(0.0, 0.0, 0.0, 1.0)); + + mat4 yrot = mat4( + vec4(cos(speed.y), 0.0, -sin(speed.y), 0.0), vec4(0.0, 1.0, 0.0, 0.0), + vec4(sin(speed.y), 0.0, cos(speed.y), 0.0), vec4(0.0, 0.0, 0.0, 1.0)); + + mat4 zrot = mat4(vec4(cos(speed.z), -sin(speed.z), 0.0, 0.0), + vec4(sin(speed.z), cos(speed.z), 0.0, 0.0), + vec4(0.0, 0.0, 1.0, 0.0), vec4(0.0, 0.0, 0.0, 1.0)); + + return (xrot * yrot * zrot * vec4(vert, 1.0)).xyz; +} + +void vertex() { + // rotate VERTICES in local space + VERTEX = Rotate(VERTEX, _rotation); + // ...and relative NORMALS for the fresnel effect to work + NORMAL = Rotate(NORMAL, _rotation); + + // Local to World conversion to add impact ripple + vec3 w_pos = (MODEL_MATRIX * vec4(VERTEX, 1.0)).xyz; + + // normalize impact origin vector + vec3 imp_or = normalize(_impact_origin); + + float impact_ripple = _ComputeRipple( + w_pos, _impact_origin, _impact_blend, _impact_radius, _impact_frequency, + _impact_density, _impact_amplitude, _impact_anim); + + VERTEX += NORMAL * (impact_ripple + _shield_size); +} + +void fragment() { + // add fresnel + float f = ComputeFresnel(NORMAL, VIEW, _shield_intensity); + // set color and alpha + ALBEDO = f * _shield_color_brightness * _shield_color; + ALPHA *= f; +}