From 2d1b8472e1aed994c88b9200a926a8332cb44103 Mon Sep 17 00:00:00 2001 From: sigonasr2 Date: Sun, 11 Jun 2023 19:38:58 -0500 Subject: [PATCH] Player animations and states implemented. --- Crawler/Crawler.vcxproj | 1 + Crawler/Crawler.vcxproj.filters | 3 + Crawler/assets/nico-warrior.png | Bin 9576 -> 10869 bytes Crawler/assets/nico-warrior.xcf | Bin 17853 -> 20395 bytes Crawler/main.cpp | 172 ++++- Crawler/olcUTIL_Animate2D.h | 2 +- Crawler/olcUTIL_Geometry2D.h | 1046 +++++++++++++++++++++++++++++++ 7 files changed, 1220 insertions(+), 4 deletions(-) create mode 100644 Crawler/olcUTIL_Geometry2D.h diff --git a/Crawler/Crawler.vcxproj b/Crawler/Crawler.vcxproj index 9c6368ef..a47757da 100644 --- a/Crawler/Crawler.vcxproj +++ b/Crawler/Crawler.vcxproj @@ -133,6 +133,7 @@ + diff --git a/Crawler/Crawler.vcxproj.filters b/Crawler/Crawler.vcxproj.filters index ea59ed75..69ac8a8b 100644 --- a/Crawler/Crawler.vcxproj.filters +++ b/Crawler/Crawler.vcxproj.filters @@ -27,6 +27,9 @@ Header Files + + Header Files + diff --git a/Crawler/assets/nico-warrior.png b/Crawler/assets/nico-warrior.png index 03428b2e39c4c64ff1a93c2a549df30dfbff9dcc..9b84f38aa232bbd22c85c50d87e017f5cd3aadaa 100644 GIT binary patch delta 6458 zcmV-A8O7%4O7&EbBYzO(dQ@0+Qek%>aB^>EX>4U6ba`-PAZ2)IW&i+q+U=QJk{dY= zMgO^qSppvbK`w{Sh}pp`e-2V|xm@jbw4;A*g{3MC*GyhZbM|`tzKkJkQU+`~HaEe|SH9e2{so@LFEK+JAU||J(cN;{>ml!B6_> zMBgr+=8qq=_XoLsIZ=MS6kn15yx%A4@6StqeURk6tMhuD?*pIhzW+=6adrNC_~8ws zN?SQ!$@!F2BG0Ad*M*AzFJ86u*;D?nKYm|Jl z@tX6><$13a%RR5+y%B$;n~g5*(&*oMIw~cA6UrbRenb%_6gu zQt3_0et&5Wv5=ncX3ekn;UhYsOq0{!Z_dW*K9GrP@@MvN1&djq+nL6vV*=C<( z0iPvHS6#N+>TB%0%Z3_u-L~8Adz^HD(vhR59)Am`oqomzYqwmvdh4~@ZolKBYwxc9 z+vsP%9AmVc*n!CUt)I``4HaO~Z;pLA`zwymdQuPO8y zjDO|2Or~~<^`XLRntg}e@@N-e&#~KF3{cy3=#e>F&$bw!5{I9W_!k|vyQ%x?!^LM48dH5%(OsFdN|bbqXl-7oV^MM|vW7F`6vH1|`J&MU2WFo7KbYbwcQ( z?wK^H(X|O`<#0L{-OoCSH%0-g;p|gkwbf#S+s`uka%*X4g3-C@LP=-nWcOZIow>tE zKEQ)hLttm7S*cOyYb>v)g@>#4(*hitcH@uGaLE_HGS-atK`)PJNNrxCO| z?JYM}4#a&>Ue<4r1LH7QPfdftrwUY+A=QSQ<4H=Q3KNjoK3q8ksm+gd*ZI$0r=Pk( z99?ZEJ-g{zy#_}k4WrjSh--Eb8t;yswlK2VDLd;}yUR?Vh{aOWo}oiv&}}hV*WjZW z^Q;vb9#pL;jQ0CyHRC5D_?(KvJ+>DZUy zHD-fxT)P}bR~kCnhI4jL)V4#tu>mD^317lk!cI>M%}Q0w0ko3WoZ2x=5C=v8!*&?2 zbK7Ezkn1Tt+numJ0N995!jv^HMpB9`_Y~&EE+sHX8>mgVm@e(1oqv57t4nbePE%Mt zenli81Xc@cporL`85C}?Gx^f#mTp%Dg{8&Y`=Q@rok5#24p^lEJyF`R&ghj%9tOUf zfb0|sOp}h_cvtu4ZUcvDYXyyc)H<12)TRmS4fv1yLMT-&7Fxl`FV4yGk)!!Aj;kvh zh{y5Ev@+l?bmqUlmVd2A6)q@B+YU&b5-v5VxKl$NQ{GG9QMk5vylJ$V!C9Cp$~>xz z)_B8no@N^&q;*tuS%4un=b_`BQ8p*pD!U`&>?PsOi=(MZM$X_+#^IK>SP|=is-;q1 zcAns)={l#7FoQLEWNES=zwXWznScwrPt%!*GN)gVImk$NpMM1+0r6gS1Zob!@@=P| z+SVYbG{iRQD#Lf!Rz_YhHJidCUMPFNjR`MI5ayzz&InPU9>>d&;6(`O?tKNWZ0jim zZXn(UGl5bjM`reyy-TVGCOa#6j#&_E=z^MI`7_m^Oa=aCNKia_aT?bJBN;+ZsTZkR zk0TWVXeH5W#(&UI1r86<&`z@OWS_-ZNhl-JMm>i?&P9M+MxJtlAWOslVuMaRYb{~J z$Y>teodBIKM)kt2i)h_YSBM4GuV~gn+ECJrfhdGIcp)_kI&d;OJ0q^EiT^R*VAo>~ zX4K6JK?=KdA%TYRfQXLybmInGbd+i3*r$6!uk*sPq<=V@vtGDQjKdL8RiVJE{SBP4 zx44-oJ7Fp;9^l{QBDx*T;zUy&*%cZpz`CNjN2!d18i*Y9P3qveoZ)o9`_;V|csX}c z_Q_B)eI;yyJ;kM4dPc_Z&B4Zi;(?RV?=h^CKir=6>>~j%C?Q;_NHaJ^{V_x>9AM^y z=DH46nSU=nLFN!8Jl)MSNI{*k3tYs;F~A70HQr-iWJKMla?a2I5cOxP%k2ub4g~7~ zuZSa(_0Ue~PIGwCyAX|t2^Oy&z{@z%8QD)@^d5!Aj2e0x&vwy?>Aj*P<6})Y_95y*jSMy66`pA~h z4dJ)W%I64IS)bvYWWl%qExMS|ANYwuJs3}QAs)9^Y?ERb(OBG=Lv#3CInlMp`A>v# zWBuWfHkBPvL#Cm_r?>`;aVc;Lo=vRMiQ;&6#8DK1CJLiN?x(Z3SgP2NNvy%6N$^wI z*ne>R1u>#vV|>el4qdpE_vd22*z|$MzIfSecbmWendUK9^K_>Llsd3q<3XQ zL~`Ry5uo$|!ZUfTxsyUL;|;LX19V~s1_m3%FgwrqN)olhOT~3;yJMhrT&$etfg+zx zl)5m5LY6%gnwtjNiQOd(kG5U-M3yw40eZ`u%S$bx~$>wrGKMV6d{Jw z7uJk3{K8=m2nU^H$O{{q^odSFx+!)|E{Hp8U|7wqKW-%h?5JT91d;3vg>Qxf<#|UzY zhlqa9x?p>tMtxG(xAaBqXGVRbpk<0^kQfw8s6js-8Tliz%dMfhj>#xuh=;hWhPw=q|iW$8*aY= zA(?;s z;DRfXA}^j6QE=iK-Y}})r-XCnbWMkKfJG7);^Tkv8BV;b{~F!jQ9g)`sd_x>+Ko{+ zd^Z;k@IXQBTyZ*LPay1mV?dpnsca#WVK4~;*MD!=_@V)u!ZpRsR`L5N{x_QBW(IqYjZo4n z(tlRBO!9Cqw=ag#eLU2Yp724iBlr8QLA!)g&kmpx;yXhTs+$oWG^T6AGho^XMwack z)AAb@Bf_Bg+qHfEEciV+i_k^Yj@%t=Cti&-Gn=k~rS;ow1Hi6gPly>TQI6k$VlpwE zWO4R~_HUNYhTSePz>DfGq{dMEQ9Qr11Akgo6yx0FlCBO1ZvXouIgUAqvXsOb5F>C& z`cWZzo1sb2x%;b5uvW-(^Pkwt3xd`g5W`C;D@uUlE+h z?#02x82%6W`d8E=@@mkto()F^Br#((Ha9UgG%YhVVP-8fWH)3jVK+H5EiyGQGdMIj zGiEknFp~)sA0%NpGB;r{VP!2jW@ch7G%+_hEjeU4GA&^ zI59b4HexqpWo9#zSr$+SIXW{iIy5k|uoh?t1bwN4PLmuTGJgyJ9w_7YT&Dm42a`!e zK~#9!?cF_cqevJA;O?ynIL98ya}~mgHeH80i*L2*Mr6Ig3QZd!2|+gk^gLCru{~0Q zB;Ni(_)`b~0KgOC6SqwZ?)why!zKfqLI|O4+i$--old2Ku=n<1vjI-S1Apiogt;Nu zd;75206#qV7k`Fe@9o3O{oyHqV+J^8>%W+0`F8xNr;*4$J861PN&dy zT?iqBrfI^|_2s*?Kl>y^j3K2IVvNZ;93$}lrn0dQv5}b40lusw^AW56e(760SsOLl zpS1tyQ91Sh9x=q}+%RuADz$B!&Ii?_uczDYx~@jMV}BjR&9AQOE?*lM0gLZLI;*^n z*FkJCy!}Dlwr%?7DgXZk2me+3h1wl`4Eg@|9n;1FTs*{UgiC;5=f|A` z|MJ7>bPAzuL-_UU|6lz1`-b`LmaIAd{`248?JsNhre7ob-!x6=x-K+Lvvj&%Y&xBV zIF<@njDIoqL5nfw+o~PjRBBsKp2K*H6N0zaz_DqX{-CaTpyq4cD%-gA81ijyD7^V| zQ*?jMAr9GEd$mz`%@cGfrF?sbpBX&77J7K%XBdD2qu1z@TzFJW3!a00uY=CP&4SdA zz_E02V>Yyp-K^wxAHCLt$9mY;IxY-AEHu>{n}252d|x!ZLwJW7D>-$(HS*pF@oE7c zStf**M1igb>2l*Vk2u^X)unKc0)>e+%)wyBsmZj{+P|r&F!>foo6ilJJ&kw}13; z|Mm5C$$yM7e0+SQudlB-BXIG2yL6+3&f&#J0chLyX3@Fq|K>bvDXV)`x`X)EcBKwz za{;dScxts>y3Mp$7*hZxgzxT;s8G^{aWaH;@X|Wntz?p+XwgR zAQR-51b9+e)&c>p-ASy~302EQt$iD-9aW;Ov2r^?T*s?xVx`J;nbXeeKKB(Xiidb? zv`i_br9tcOUn8)l=GRoEeAlU0R+2TZ+PI|F@*2Ss-su6p)K#8RUzvKxYpoj3!>n#O z97p_Ag;hr2&(F`AYscE1#D5Vwp=!Cx+AZ=KMRPwMh00Ut+SM#7brNZ%PH3$WsPrgY z?J@VW@lyM1?R(q9y3kG2TuQX|L9TJo7w#nbeZJcFJ%%@AMa*loTjE4no~^;B7}h$A z-tYHYhx(6+K?q&fU8bR3*OeR%V$(F2QL^Ne_q?B@qwo%=)Ui?!`hOExi^AJ~%*i0U z#X88rNjBkqVkG-kI<{gp$8S|A2X&o`?02}XP)Xs}FD$QAdUI_(2(Z_0P7o@*Kv!jC zN47V6-^1h5xNLv@pPw8{>PVMa1NY%ud==Kj+daFT*fdQVPM7nw@cH*OKavDCIW;Od zf?c&)c(hLwzu5Q)Y=86}KQS_Aw5;`4LUAzSmfGg6QMTq|qHu^q@S$Y@000000011D zy3la&0IyM!RXu2^5a2YS9P5%ms0R(N3h*Eh&xWCT=TNzQc)87%m2KO$A34(=+lRLf zFi2wOG)9F$xy5y90*g14vS7aM^Iv>+#-om%itOZKG z<{iVWcE?K0&T2mlO4qh+yQEFnUw}iUij-qDoAaLw1np|SD;B4RRZYGYdboBhbs6QY zwdr8myXeEs?jN+f^fADG0=%G&Iqhz}eR#PaPafd4>L}l;*Bp1!K9jK|ix;o(AKFwW USdaynNB{r;07*qoM6N<$f>gzRqW}N^ delta 5136 zcmV+r6z}WxROm{OBYzEXdQ@0+Qek%>aB^>EX>4U6ba`-PAZ2)IW&i+q+U=NImK!+^ zME|*pSpr`m$mNg(dCu%$mOmFMxw^`3cel^XrzKmdO63Ct0ug}>=Rg0x;a|LJlpd;R zZ=O(`^*0D@k3@;VOw5*>VJG6|80NzxWH>O`6iz( z^zG(pef^=of5`p23+30Qctrl)-WMA0-%Eb|km`F?=e1q$6QAY2|JVLCI{!O-*`Z{~ zgzJ@@Pe~>6SxSE0sQCXwACsE>G=a`+u=NeEuQHcPEsO+vLv?<@s^r{3W6}qYa(yLfG?zthcHMzPYV-+n4uOMZnCswZ+h?|=Q=t#fBf9GVjsOPunL-r=7f z_-F5Xx2Gtv_!QpBBChPfBMh&ce{vWVN%x&pc@q5X{r!sz0Z&ROPntUmoN>J_u_XP0 zt@0GQaGbDxwNX-gfZ>IzfqM(V0Qj0>OGQ#kQFGRmNMxr#lhAXic~OBRl8qp9r7NgS z&wgu8(SMMhW3%Mfe)xz=2;HRAW|T>>Y8CLKwS%E4MXHE2QRy;dw$f^o)qlGk?y!VC|M$uiSR^_B-zUsM@=#KfHgT zYUy3I{8Y-1(~qjLSM}Y{z$N%ayk=A^*F?pY5+nefy=JkeTC-QqYZiwyn`D9%uZ<V|mJ@v&>;fY!g5dv#}~o*vx6SZ;E|dJ0x538oTMbGGiM> z7kC|$Yu7uQoMO}V?8K!|Da~tCtW6u2{(mMTCAN8sYzfzfn9M#-g(Jyy>;f!=3Zx5= zs`?*RW9O_oZxpcudiqcxMZAl3&ol#>QbjXKE>vynmbr&Dt(Byud{QopH13sKrPL^S zPj`3fvd=QV&FQP^f<}%hBs8Y>lUHqO)_T7MWms(x%jo2j?(wo{tSo)?a?>7b+<#+U zl9S^Ky=!vGTP3Gzwg;vumVHqCeo>NGKw|cP)a!@sJZ%VhZ6ny6HK`UG+cRC8-C}F+ za%8~ko?gP+>1<8lLQQA3+(`NYfrG5n)g;dlscDv)Nn^3S%ZwH=DYwT+b#IMTbu$n@gOxo*w7+LEDeppiJn%A*0xL9jdQ!YO2utlhB(ow5xV(e@UQXpJVUMdNC{5^O!JwtqL;o6HmY zxileVm@_zfZnJ!rcyB9b#9C(twQ%X}G-`4*tk#Hj>ZY=^0HM_hw`5Ok#xn#sb_|vY zFV)*S0tta08oI?<2y19txi^@iqJ}44^Cr1zu*6ADVU6RQ5E=;q0yIp{P-pUdWWN^? zk4&wL^xGCht_sPC6UYK2yMG<)vtn&XGF=$j*|ehw6zcGw?wd<{!0aabueVoVe6q^) z5L7PwdcfAs*0&|Iv_WkuaETNc2bCd8bvfELR1P$}_MC5&Qq5bZg@~5izR*EBej7m_ zh7-FoEDgX_d4|OA?BnE}A z^X!9g6gZ zPdEa~ppO$}GWrPczcAWS`+g#Lv5Ba!@~B-nRZ$60J+Bs=_9@Ox5dDb)E7?hFK{v?H z8F4w~L0+j5hDHPkb?&)Bi~;_J#yA9=FGA7lfG4Y)JtPwke1B-%L07Q8=?le3nxFer zFB@8lNQ8~!_i=>c`T&ZQQ)j2@{4+SKcWH%4G$VCBzcu7F96EH-HQ6f2wyER{f5iN; zAR>AxZL+KI3k}IvUj?B3g7K)_+j&J7kr?n5FGt%_c+-tjr2Rx~{r6Yln#zGNs`tNa=2}g{Hg>o~zDI zU=ntR7NFW8Bs2*#FaXNTVu$Gp(G_)KRo9;?Be|o1^Nu?xB{1rksNR(LSf5h^9;|Je zfYw{EIjjm)r|1nGO>>24Vr zqm-k%wSvSB8g;f0l9)h05pp-pZ~!g=qzZmu&}(H+g3oRVa3oHqCAs*mN;48sgHSdd z4O7EL41DWAngxw?8BJF!;LPD^En2!I*A+;$G?~bF&Ln4a$eVt^ymF65(`;uIthYN1 z?g^L?i+_U434g<>2>ia41p<1!a$5q77%-u8W?D!dN!^56g4Y$MKWO6P+{Wnz9&9Uq zW#PtL#ExFZtQNx5!TW{0WN@Hn`&e3CQ^m{n$0lX zUKEO~#v~05<9jC&2|WO_VNd&H1VKYFv$!v#w||@SyU*7dzORe4WiZ(ASG1{%?(m}- zU>G5!V?-gsN$Mzghs&Wx+I|rO4(2j2*6W;z5N^_1<~$u17x$IvVblpaacn8!0fphn ztv8rouCtaw-6oEHA?bxrEP1=OL$IY9K8~xyWea5O8SiDvrpnlICnfYL!kUERu9T!> zrhib>g#hGo5fOgC0?`PE*#fCy7n4LwlqoXoq=57q{1M1#Q%`(_vs z+W`=cEV9xJ2BaE_Ck5Nu$&nNFt#l5TT_@o?YLWUUkMK!P|vLn=176Twcg_1 zYzSEwREu!~U8_L4GiW)qR|z$a=G{G?XFM1hJad9O;Tpt^-bnfJ<oG55a=Fg{#6>Ht|oX-v8R45#OFDV^Wkix*}?|B^gxvvj9^Jf3;GEzFFp(+MBHXliPC8u8<3C3qUCmT zv&8~0XAlWBoS04I3UK=PM&mXgvwtccm?0W7wf*@Ys>GPq+U&1I6DVMJWD34zw`P)o zGmXRmD>O_6EfU}e#&G74p3EPW9vT-|AcX!b4iVr((B88bgn4le$bose7#B_I9b|FR z{c%MSbHtxZpk>#PHE794Erxiv#F(VX7y@HulG@-5^U+!|uu~733BGEOgMS_(M;MRl zUDfN*fy6qzOJkha%*C5=p88FfZ5uU@fxC%}t%M&roCO8I6}KBYaE$4h&>%2CGzqw& z3p6C~V-`g!V`o@0S1-_k`ogrGQfxG4hCu@kMgV+XuI?wvuR=~(72y&dhP;P0h8f09 zCKL=442e`D>vKSH6fF4PxPLghn{XShGsQW@S(!yb9d}1)B4evaz84&J!mPB^G^2?b zGtx3vG0-?n<#rf#%3q=HG(MzSnlqVdWPI5PK4Gmj0{fd!w6(R;Kd)qq5T*EI($QE zgQ1zxkBXuDg{hQ?)F-Uz1PVibD*lh#@UtI&b^H55zc2LrLKeR-^!q~prwjQb7#rcg zMuOV9NqGV^vl0G-WX}EjeU0HZ3zWWHMxBV=ypbV`7ti z7at@xV>V_uHZ?gdH!(LdEi^DSW-U24Ib$t3IWc5oGi5YnH)Uj#z!xVZWH>i5H)b?4 zEiyGRWGyr?H#aRfVr4WfVL4`GVq;`9V`F1xlM5JO3Nkr2H#svgGcYuhb{KRAH###m zIx#kr@faruH###mIx#kr9~p`yVK*>hV>M$kEjBh{WGysiV>2x|I5{&dF=I10GcqwY zW-u~llg$}W2RAx1Haamkvm_d52n3CKr#X|5A~Jsq79J24HEb7d}T0M6Tjxud!lB*e`2G4+o7{XTSE7eWZ3X__!~ z|N1KJzp5BxNGXLFW3tc347|z=M>8>10({!1<}+gd_ebAC%G#*Wz7T&c(+v#oxCA_D9?DzW++BSsG&%ZbP__||$zd1|j-oHQo`)dEOc2~cg z&O#hZ1uVuG`=G@b^JCQxZz^@Hd-~IxY`re-fn(D&p=p}h9W~$U^8L9f+5wLt4%vTR zd$Cz~$rE%brTloCUm1K%mZ9=H|_}3QT zxbVJ)LQChGuh+E@=Yd)}#4oY}d5M1jv*HXd9hghY_|gIHPtMH=^0l86VBU9~zEFTm zymhsO5c?=4WoCjKVd%qK>WuVOW>5j$9>gph7|^Qsk+VS z!2t#Yco?eMb)oyeDC`bp16;i>^jL5U4-gbw8RegyDDgH-{$Y$q+new~l1+d1p{KqN zJY|45-p3clpPAs1Y|Q*5R0>~3Lej9kIn_g^{>&1UNnS0$>Nam==Bya(G-oilH5pC} zTbgfi1t#K1#XK@YeduT!B!W zLj3dR&$(@%+8CSB$G+aU)gXU==v30NAZWlrb;cz&dg*ZRXjrL<+ zePj5Y-;1e#vjE5aeqZZ-U?-;5G4rO<{r+$`XZQFkP6W+5f^uw>$%G&NvM5U7L6>f9AoguFa-L~ziE_8n$vJy3+gW~S5 z9Nwz!R|=Z|_hAi#;_H8QzrKZTaKE`v^jY!v0t1BbuH+bI%z7`_*pjy7EP1hg0fyV+ zjSzOvO?@KS@sYI9NRv5(b` zD$&+hxg8;{j%hv1yvKfRzew*L6z_5@z8AmgxPS zI=^B<<;%O6>BH@_(5dUX&@|1rpdD{3a%Qw|zw5g2`T02vFZE~4hX;pj5Ez?@W659g zc&5C+8iT=oLV#;WYeW|qSx+To^YXR%aa5#SS6>O0>Urn;>b?Z6+4s%>S9*cQuJTZN zpkV#`|8G}ZP)GW{W!c#$r3#jO9W7mZVfk#i^u_@mF4t>aeQ~n^uDCZ#1%FpI9AM#n yEEK6?n9_xIlK?XevA&bxDSeahDI^%Mu>S!LHafQ&cDI`V00006|L^+o|&HaV`tYM@7lZGEMaYvZ0s1@;9bYNMnNcefqW1`K#76{D8y=s z#~0e-@fRX+QW6pm#R*>{WfU-r_~2y_mW7-k!SI2E$Om5$5&|0`xdYy9&b@WJrza#? z%o09msrppiTaSCIPTj7qAAiYt_Pld$*}4D1%6h5QzO49JIAw9=dr$nj?OZdHhR^)12g3T|3#*93P9-ez&J zy(EIuf*%$Dq5A&lb!Ts@5P2J+^kwF4)wY_~J>VC~RHf(50A zY5mdGQO6zoi>X(-y0gpjeBprL(S-Lv+OU-HbY$c0`;;y3mwmEd_R0R|to-)32|h0P zO~Jn4j|5*}oK?5~UIc#*Z7-%qgemsEwY2EJk@#^{OQ9 zxhe=<6{C^|MG#h1F(Y-ApGrN{EugLg%x61E6fP80U3zy5p&9GUl&i`K|E{7)g`qjp zxpk!cU}rw4LGMIP7@NmBCrVYW8AX2#&6Un{%a+~8_OWjxY2v+7k%ypwo@u0!7H=(J6q;tLF`~)$ zHdW}W%@8W8lH+Pl&pPqLi79VP#i9A##2jYiI%bD_R!{Dj#1tTC(u##<_l|M+3jfy+ z?`Sw@+Pr#XL=nd1*%gll4;z^Ip?p(Cw3@}RCbL7;3os~hQQL~Cb;#>ggnc(KqA1K$ zJG$jsBBIkRi_mV}wghe5QwG?s_4hz(BPF7q?HuCK~A>~E+( znE5i^eQazWwP>TTHGW?R+#ew@N=#sAhqN{?PVQvid{KL%PJ1);DeHX!HJF?KQe$yy z$D6EOe*bUS2_e`QhRAq*ur`l{!H25P1pV~Xkf5hSWxg>rIX7fzo`>+!E@tOx0%AB% zl>OCI!||E2<`26&nkkBEOkE6uJR}^EhZ?Ie zKik`xp$X3q(g2Ks(*P`+qa{*9&2(oUGm$!#k8T4I7hrjI8;~Wu+(itV-3HPvW&(=rHYmtG zFjsFGzb|3E?G?-#Y@hW?t1IT2qZ2x>0vw7d6>-Qd$7N2zNIqNV-^mwLf%~ijseT2C z^3*@&X)I4wlaeEJ_zimt|E-dr8c< z!;(7zn~=EpTIQ3x((gA8PpZu~W=g~MH2QV9CSQBWb$fXiSqg5H^Wx1>(&of5TNz+`wfw{Y|*V@sG{=hVnGk3rOyU zafA(#zDp3|m`36@zsrb(sNBSvoDK&#qqaC6M$=H>Lk}06u#BqYP76r~m++7F`tIpB z*uSmZ({HeUTe%1S?OOha>$jDETe+vPjIXzTHk8>ALHRm|wF0(0{r@{Lt~3w=2(ba& zl0>A2M5I7!Q*bRH@=&a!;F;$<^{TT48(k|Lssc19N`Ma#2LPnHedi^7K;pYk+Thzfx+)7XgL$IQES#McRHaQ|n zE*nm?bCG5xh|MpXzc9HszvSL=ith~Wz{!H175TSc!Jl~gTt$u&o`V+DLBtJuj)-9S ztSv9go!he9B`km6%2(vqe`Qk22Lz8Z&Z?DrMDT#%Cj>t$`1pEn{!+_5b=jOf-qol6 zYQ?KY@VrHSlTPe?#}};p?vGh~=VKP%eNynf7EhlMykK!PC)gI86+FZ^t5)T=jBJc5xtg@kNTG3CSNo zo>o_vJXIpxZu{+YpuMl~G`<~E)!`hB$F$-T%u`zi;;WqI8<@fl$|R@zR5*1XqL>@Q cD^#Sga!G0bWI7`>D||5;Y}~Be{Nz;pPuw+W7LGqW>$XPuoH-PzgMan;scHFZB+X>~9`-9jo25s3<-lKZEA zSa>O@KSm!MqCcUKNCOR(Oi({c1cRa^Y9bPpq<(}yL_}7c%9-2qp8L*tT@r*GIOjR% zIq!Mj_nh5 zZ4*(ady6+7Kgf8yaI$3%Q7 z6Jw0CjJp{3dnkkxcuQXC*%t~A-?2F_4@K66y7mf3KOpx<`x8asx_zSI3U^v)?k4nR zWhAyX`2GL4*iAkL$)obD!@E}!;Fg1nql}{TqQ4RtLvcmG-6%pRL3dIZ?iA+CVBG2a z28()FPV^oQ>UV5yh(Dw0^7*-(JiR(A$L9@sY-Lm)o{QbqzqOKsT|`ZMv>bjxu%;Q^VrP zkftc7i1YxqR>u}M$+TavV;p5UEL_AL7EQa3=M2&E%C~JPs86!Xet9vy0qag@2KGQS z6&6j!Cz>{QOEd;JQi}#`?O_EXVp<2bLOotn2V*Vu$i~tXiH(O09%3&c zbd^$Wr%hNZrQA-3Dop`3G;I-529!EMY~1Fb}bxpd$xwKnUQ8j~iHXiH7n zIm@9a-gK-Q@fJyo?3HJngN4P>{cd8Oq(!OB7c9I9LtvG{7LC4Au+lWz zRusI`gP;^u!vj!IZ=-VsdK-mDGI~Uq13wae!i7EG8YiRlFHEg4$i5y(7NEKX?KqCrmervQ%`qJt!H`<#wT@ z88ggh{~H}lG}T0M(2bJCM8dS_aXUq)a@Z}xDnJBRh8(U8y|_XYQ1Gm|j`k1In1q*J zTqKsMFk$7Ti)T|hltworrP)fyX*DQ~2oFTi_NU>cLupYu9k2@{5Ty}v2RRM8snE`3FpE5=fjuZKR6DayxeUXQw$8-mh*nCjO}K7_2;veIQXy$PDJK#`xbpN* zJJIu^1J7|E%Hp;O4-t6J0?GR_T(J^JG5~a0=?qo}u&27l{8AoUHj zv)qpYhf(m?Q+JGC)trK=6R<3xD3op~eeXRw_cTZ3+J{wSgcJUqKTZsHNVWR#Eay-X zj8Hg6jE$~^uY_TA=o`i{9#h6xKE7A~LMSad;j b(sud~j}^X{T$jF_oakr5iHTN`m0j+?UI^pm diff --git a/Crawler/main.cpp b/Crawler/main.cpp index 29d6e38d..84793f09 100644 --- a/Crawler/main.cpp +++ b/Crawler/main.cpp @@ -3,18 +3,51 @@ #include "olcUTIL_Camera2D.h" #define OLC_PGEX_TRANSFORMEDVIEW #include "olcPGEX_TransformedView.h" +#include "olcUTIL_Animate2D.h" using namespace olc; using namespace olc::utils; const vi2d WINDOW_SIZE={24*8,24*8}; +enum AnimationState{ + WALK_S,WALK_E,WALK_N,WALK_W, + IDLE_S,IDLE_E,IDLE_N,IDLE_W +}; + struct Player{ vf2d pos; float moveSpd; + AnimationState animState=AnimationState::IDLE_S; + private: + Animate2D::Animationanimation; + Animate2D::AnimationState internal_animState; + Key lastReleasedMovementKey; + public: Player(){}; Player(vf2d pos,float moveSpd): - pos(pos),moveSpd(moveSpd){}; + pos(pos),moveSpd(moveSpd){ + }; + void Update(float fElapsedTime){ + animation.UpdateState(internal_animState,fElapsedTime); + } + void AddAnimation(AnimationState state,Animate2D::FrameSequence frame){ + animation.AddState(state,frame); + }; + void UpdateAnimation(AnimationState animState){ + animation.ChangeState(internal_animState,animState); + } + + Animate2D::Frame GetFrame(){ + return animation.GetFrame(internal_animState); + } + + void SetLastReleasedMovementKey(Key k){ + lastReleasedMovementKey=k; + } + Key GetLastReleasedMovementKey(){ + return lastReleasedMovementKey; + } }; class Crawler : public olc::PixelGameEngine @@ -23,6 +56,7 @@ class Crawler : public olc::PixelGameEngine Camera2D camera; TileTransformedView view; Player player=Player{{},100}; + Renderable GFX_Pl_sheet; public: Crawler() @@ -33,35 +67,167 @@ public: public: bool OnUserCreate() override { + //Initialize Camera. camera=Camera2D{WINDOW_SIZE}; camera.SetMode(olc::utils::Camera2D::Mode::LazyFollow); camera.SetTarget(player.pos); camera.SetWorldBoundary({0,0},WORLD_SIZE*24); camera.EnableWorldBoundary(false); + + //Graphics + GFX_Pl_sheet.Load("assets/nico-warrior.png"); + + //Animations + Animate2D::FrameSequence pl_walk_s{0.2}; + pl_walk_s.AddFrame({&GFX_Pl_sheet,{vi2d{0,0}*24,{24,24}}}); + pl_walk_s.AddFrame({&GFX_Pl_sheet,{vi2d{1,0}*24,{24,24}}}); + pl_walk_s.AddFrame({&GFX_Pl_sheet,{vi2d{0,0}*24,{24,24}}}); + pl_walk_s.AddFrame({&GFX_Pl_sheet,{vi2d{2,0}*24,{24,24}}}); + Animate2D::FrameSequence pl_walk_e{0.2}; + pl_walk_e.AddFrame({&GFX_Pl_sheet,{vi2d{0,3}*24,{24,24}}}); + pl_walk_e.AddFrame({&GFX_Pl_sheet,{vi2d{1,3}*24,{24,24}}}); + pl_walk_e.AddFrame({&GFX_Pl_sheet,{vi2d{0,3}*24,{24,24}}}); + pl_walk_e.AddFrame({&GFX_Pl_sheet,{vi2d{2,3}*24,{24,24}}}); + Animate2D::FrameSequence pl_walk_w{0.2}; + pl_walk_w.AddFrame({&GFX_Pl_sheet,{vi2d{0,2}*24,{24,24}}}); + pl_walk_w.AddFrame({&GFX_Pl_sheet,{vi2d{1,2}*24,{24,24}}}); + pl_walk_w.AddFrame({&GFX_Pl_sheet,{vi2d{0,2}*24,{24,24}}}); + pl_walk_w.AddFrame({&GFX_Pl_sheet,{vi2d{2,2}*24,{24,24}}}); + Animate2D::FrameSequence pl_walk_n{0.2}; + pl_walk_n.AddFrame({&GFX_Pl_sheet,{vi2d{0,1}*24,{24,24}}}); + pl_walk_n.AddFrame({&GFX_Pl_sheet,{vi2d{1,1}*24,{24,24}}}); + pl_walk_n.AddFrame({&GFX_Pl_sheet,{vi2d{0,1}*24,{24,24}}}); + pl_walk_n.AddFrame({&GFX_Pl_sheet,{vi2d{2,1}*24,{24,24}}}); + Animate2D::FrameSequence pl_idle_s; + pl_idle_s.AddFrame({&GFX_Pl_sheet,{vi2d{0,0}*24,{24,24}}}); + Animate2D::FrameSequence pl_idle_e; + pl_idle_e.AddFrame({&GFX_Pl_sheet,{vi2d{0,3}*24,{24,24}}}); + Animate2D::FrameSequence pl_idle_w; + pl_idle_w.AddFrame({&GFX_Pl_sheet,{vi2d{0,2}*24,{24,24}}}); + Animate2D::FrameSequence pl_idle_n; + pl_idle_n.AddFrame({&GFX_Pl_sheet,{vi2d{0,1}*24,{24,24}}}); + + + player.AddAnimation(WALK_N,pl_walk_n); + player.AddAnimation(WALK_E,pl_walk_e); + player.AddAnimation(WALK_S,pl_walk_s); + player.AddAnimation(WALK_W,pl_walk_w); + player.AddAnimation(IDLE_N,pl_idle_n); + player.AddAnimation(IDLE_E,pl_idle_e); + player.AddAnimation(IDLE_S,pl_idle_s); + player.AddAnimation(IDLE_W,pl_idle_w); view=TileTransformedView{GetScreenSize(),{1,1}}; + + player.UpdateAnimation(IDLE_S); + return true; } bool OnUserUpdate(float fElapsedTime) override { HandleUserInput(fElapsedTime); + player.Update(fElapsedTime); UpdateCamera(fElapsedTime); RenderWorld(); return true; } void HandleUserInput(float fElapsedTime){ + bool setIdleAnimation=true; if(GetKey(RIGHT).bHeld){ player.pos.x+=fElapsedTime*player.moveSpd; + player.UpdateAnimation(WALK_E); + setIdleAnimation=false; } if(GetKey(LEFT).bHeld){ player.pos.x-=fElapsedTime*player.moveSpd; + if(setIdleAnimation){ + player.UpdateAnimation(WALK_W); + } + setIdleAnimation=false; } if(GetKey(UP).bHeld){ player.pos.y-=fElapsedTime*player.moveSpd; + if(setIdleAnimation){ + player.UpdateAnimation(WALK_N); + } + setIdleAnimation=false; } if(GetKey(DOWN).bHeld){ player.pos.y+=fElapsedTime*player.moveSpd; + if(setIdleAnimation){ + player.UpdateAnimation(WALK_S); + } + setIdleAnimation=false; + } + + if(GetKey(UP).bReleased){ + player.SetLastReleasedMovementKey(UP); + if(GetKey(RIGHT).bHeld){ + player.UpdateAnimation(WALK_E); + } else + if(GetKey(DOWN).bHeld){ + player.UpdateAnimation(WALK_S); + } else + if(GetKey(LEFT).bHeld){ + player.UpdateAnimation(WALK_W); + } + } + if(GetKey(RIGHT).bReleased){ + player.SetLastReleasedMovementKey(RIGHT); + if(GetKey(UP).bHeld){ + player.UpdateAnimation(WALK_N); + } else + if(GetKey(DOWN).bHeld){ + player.UpdateAnimation(WALK_S); + } else + if(GetKey(LEFT).bHeld){ + player.UpdateAnimation(WALK_W); + } + } + if(GetKey(LEFT).bReleased){ + player.SetLastReleasedMovementKey(LEFT); + if(GetKey(RIGHT).bHeld){ + player.UpdateAnimation(WALK_E); + } else + if(GetKey(DOWN).bHeld){ + player.UpdateAnimation(WALK_S); + } else + if(GetKey(UP).bHeld){ + player.UpdateAnimation(WALK_N); + } + } + if(GetKey(DOWN).bReleased){ + player.SetLastReleasedMovementKey(DOWN); + if(GetKey(RIGHT).bHeld){ + player.UpdateAnimation(WALK_E); + } else + if(GetKey(UP).bHeld){ + player.UpdateAnimation(WALK_N); + } else + if(GetKey(LEFT).bHeld){ + player.UpdateAnimation(WALK_W); + } + } + + if(setIdleAnimation){ + switch(player.GetLastReleasedMovementKey()){ + case UP:{ + player.UpdateAnimation(IDLE_N); + }break; + case DOWN:{ + player.UpdateAnimation(IDLE_S); + }break; + case LEFT:{ + player.UpdateAnimation(IDLE_W); + }break; + case RIGHT:{ + player.UpdateAnimation(IDLE_E); + }break; + default:{ + player.UpdateAnimation(IDLE_S); + } + } } } @@ -71,13 +237,13 @@ public: } void RenderWorld(){ - Clear(BLACK); + Clear({100,180,100}); for (int x = view.GetTopLeftTile().x/24-1; x <= view.GetBottomRightTile().x/24; x++){ for (int y = view.GetTopLeftTile().y/24-1; y <= view.GetBottomRightTile().y/24; y++){ view.DrawRect(vi2d{x,y}*24,{24,24},VERY_DARK_GREY); } } - view.DrawCircle(player.pos,8); + view.DrawPartialDecal(player.pos-vi2d{12,12},player.GetFrame().GetSourceImage()->Decal(),player.GetFrame().GetSourceRect().pos,player.GetFrame().GetSourceRect().size); } }; diff --git a/Crawler/olcUTIL_Animate2D.h b/Crawler/olcUTIL_Animate2D.h index 0fe2fc29..5fd8c01f 100644 --- a/Crawler/olcUTIL_Animate2D.h +++ b/Crawler/olcUTIL_Animate2D.h @@ -55,7 +55,7 @@ David Barr, aka javidx9, �OneLoneCoder 2019, 2020, 2021, 2022 #pragma once #include "olcPixelGameEngine.h" -#include "utilities/olcUTIL_Geometry2D.h" +#include "olcUTIL_Geometry2D.h" namespace olc::utils::Animate2D { diff --git a/Crawler/olcUTIL_Geometry2D.h b/Crawler/olcUTIL_Geometry2D.h new file mode 100644 index 00000000..1b7d1be9 --- /dev/null +++ b/Crawler/olcUTIL_Geometry2D.h @@ -0,0 +1,1046 @@ +/* +OneLoneCoder - Geometry 2D v1.01 +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +A collection of 2D Geometric primitives and functions to work with +and between them. + + +License (OLC-3) +~~~~~~~~~~~~~~~ + +Copyright 2018 - 2022 OneLoneCoder.com + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + +1. Redistributions or derivations of source code must retain the above +copyright notice, this list of conditions and the following disclaimer. + +2. Redistributions or derivative works in binary form must reproduce +the above copyright notice. This list of conditions and the following +disclaimer must be reproduced in the documentation and/or other +materials provided with the distribution. + +3. Neither the name of the copyright holder nor the names of its +contributors may be used to endorse or promote products derived +from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +Links +~~~~~ +YouTube: https://www.youtube.com/javidx9 +Discord: https://discord.gg/WhwHUMV +Twitter: https://www.twitter.com/javidx9 +Twitch: https://www.twitch.tv/javidx9 +GitHub: https://www.github.com/onelonecoder +Homepage: https://www.onelonecoder.com + +Author +~~~~~~ +David Barr, aka javidx9, �OneLoneCoder 2019, 2020, 2021, 2022 + +Changes: +v1.01: +Made constants inline ++Header guards (lol... sigh...) + +*/ + +#pragma once +#include "olcPixelGameEngine.h" + +namespace olc::utils::geom2d +{ + // Lemon Meringue + inline const double pi = 3.141592653589793238462643383279502884; + + // Floating point error margin + inline const double epsilon = 0.001; + + //https://stackoverflow.com/questions/1903954/is-there-a-standard-sign-function-signum-sgn-in-c-c + template + constexpr int sgn(T val) { return (T(0) < val) - (val < T(0)); } + + // Defines a line segment + template + struct line + { + olc::v2d_generic start; + olc::v2d_generic end; + + inline line(const olc::v2d_generic& s = { T(0), T(0) }, + const olc::v2d_generic& e = { T(0), T(0) }) + : start(s), end(e) + { } + + + // Get length of line + inline constexpr T length() + { + return (end - start).mag(); + } + + // Get length of line^2 + inline constexpr T length2() + { + return (end - start).mag2(); + } + + inline constexpr olc::v2d_generic vector() const + { + return (end - start); + } + + // Given a real distance, get point along line + inline constexpr olc::v2d_generic rpoint(const T& distance) const + { + return start + (end - start).norm() * distance; + } + + // Given a unit distance, get point along line + inline constexpr olc::v2d_generic upoint(const T& distance) const + { + return start + (end - start) * distance; + } + + // Return which side of the line does a point lie + inline constexpr int32_t side(const olc::v2d_generic& point) const + { + double d = (end - start).cross(point - start); + if (d < 0) + return -1; + else + if (d > 0) + return 1; + else + return 0; + } + }; + + template + struct ray + { + olc::v2d_generic origin; + olc::v2d_generic direction; + }; + + template + struct rect + { + olc::v2d_generic pos; + olc::v2d_generic size; + + inline rect(const olc::v2d_generic& p = { T(0), T(0) }, + const olc::v2d_generic& s = { T(1), T(1) }) + : pos(p), size(s) + { } + + inline olc::v2d_generic middle() const + { + return pos + (size * double(0.5)); + } + + // Get line segment from top side of rectangle + inline line top() const + { + return { pos, {pos.x + size.x, pos.y } }; + } + + // Get line segment from bottom side of rectangle + inline line bottom() const + { + return { {pos.x, pos.y + size.y}, pos + size }; + } + + // Get line segment from left side of rectangle + inline line left() const + { + return { pos, {pos.x, pos.y + size.y} }; + } + + // Get line segment from right side of rectangle + inline line right() const + { + return { {pos.x + size.x, pos.y }, pos + size }; + } + + // Get a line from an indexed side, starting top, going clockwise + inline line side(const size_t i) const + { + if (i & 0b11 == 0) return top(); + if (i & 0b11 == 1) return right(); + if (i & 0b11 == 2) return bottom(); + if (i & 0b11 == 3) return left(); + } + + // Get area of rectangle + inline constexpr T area() const + { + return size.x * size.y; + } + + // Get perimeter of rectangle + inline constexpr T perimeter() const + { + return T(2) * (size.x + size.y); + } + }; + + + template + struct circle + { + olc::v2d_generic pos; + T radius = T(0); + + inline circle(const olc::v2d_generic& p = { T(0), T(0) }, const T r = T(0)) + : pos(p), radius(r) + { } + + // Get area of circle + inline constexpr T area() const + { + return T(pi) * radius * radius; + } + + // Get circumference of circle + inline constexpr T perimeter() const + { + return T(2.0 * pi) * radius; + } + + // Get circumference of circle + inline constexpr T circumference() const + { + return perimeter(); + } + }; + + + template + struct triangle + { + std::array, 3> pos; + + inline triangle( + const olc::v2d_generic& p0 = { T(0), T(0) }, + const olc::v2d_generic& p1 = { T(0), T(0) }, + const olc::v2d_generic& p2 = { T(0), T(0) }) + : pos{ p0,p1,p2 } + { } + + // Get a line from an indexed side, starting top, going clockwise + inline line side(const size_t i) const + { + return line(pos[i % 3], pos[(i + 1) % 3]); + } + + // Get area of triangle + inline constexpr T area() const + { + return double(0.5) * std::abs( + (pos[0].x * (pos[1].y - pos[2].y)) + + (pos[1].x * (pos[2].y - pos[0].y)) + + (pos[2].x * (pos[0].y - pos[1].y))); + } + + // Get perimeter of triangle + inline constexpr T perimeter() const + { + return line(pos[0], pos[1]).length() + + line(pos[1], pos[2]).length() + + line(pos[2], pos[0]).length(); + } + }; + + + template + struct polygon + { + std::vector> vPoints; + }; + + + // ========================================================================================================================= + // Closest(shape, point) =================================================================================================== + + // Returns closest point to point + template + inline olc::v2d_generic closest(const olc::v2d_generic& p1, const olc::v2d_generic& p2) + { + return p1; + } + + // Returns closest point on line to point + template + inline olc::v2d_generic closest(const line& l, const olc::v2d_generic& p) + { + auto d = l.vector(); + double u = std::clamp(double(d.dot(p - l.start)) / d.mag2(), 0.0, 1.0); + return l.start + u * d; + } + + // Returns closest point on circle to point + template + inline olc::v2d_generic closest(const circle& c, const olc::v2d_generic& p) + { + return c.pos + olc::vd2d(p - c.pos).norm() * c.radius; + } + + // Returns closest point on rectangle to point + template + inline olc::v2d_generic closest(const rect& r, const olc::v2d_generic& p) + { + // This could be a "constrain" function hmmmm + // TODO: Not quite what i wanted, should restrain to boundary + return olc::v2d_generic{ std::clamp(p.x, r.pos.x, r.pos.x + r.size.x), std::clamp(p.y, r.pos.y, r.pos.y + r.size.y) }; + + } + + // Returns closest point on triangle to point + template + inline olc::v2d_generic closest(const triangle& t, const olc::v2d_generic& p) + { + olc::utils::geom2d::line l{t.pos[0], t.pos[1]}; + auto p0 = closest(l, p); + auto d0 = (p0 - p).mag2(); + + l.end = t.pos[2]; + auto p1 = closest(l, p); + auto d1 = (p1 - p).mag2(); + + l.start = t.pos[1]; + auto p2 = closest(l, p); + auto d2 = (p2 - p).mag2(); + + if((d0 <= d1) && (d0 <= d2)) { + return p0; + } else if((d1 <= d0) && (d1 <= d2)) { + return p1; + } else { + return p2; + } + } + + + + + + + + + + + + // ================================================================================================================ + // POINT ========================================================================================================== + + // Checks if point contains point + template + inline constexpr bool contains(const olc::v2d_generic& p1, const olc::v2d_generic& p2) + { + return (p1 - p2).mag2() < epsilon; + } + + // Checks if line contains point + template + inline constexpr bool contains(const line& l, const olc::v2d_generic& p) + { + double d = ((p.x - l.start.x) * (l.end.y - l.start.y) - (p.y - l.start.y) * (l.end.x - l.start.x)); + if (std::abs(d) < epsilon) + { + // point is on line + double u = l.vector().dot(p - l.start) / l.vector().mag2(); + return (u >= double(0.0) && u <= double(1.0)); + } + + return false; + } + + // Checks if rectangle contains point + template + inline constexpr bool contains(const rect& r, const olc::v2d_generic& p) + { + return !(p.x < r.pos.x || p.y < r.pos.y || + p.x > (r.pos.x + r.size.x) || p.y > (r.pos.y + r.size.y)); + } + + // Checks if circle contains a point + template + inline constexpr bool contains(const circle& c, const olc::v2d_generic& p) + { + return (c.pos - p).mag2() < (c.radius * c.radius); + } + + // Checks if triangle contains a point + template + inline constexpr bool contains(const triangle& t, const olc::v2d_generic& p) + { + // http://jsfiddle.net/PerroAZUL/zdaY8/1/ + T2 A = T2(0.5) * (-t.pos[1].y * t.pos[2].x + t.pos[0].y * (-t.pos[1].x + t.pos[2].x) + t.pos[0].x * (t.pos[1].y - t.pos[2].y) + t.pos[1].x * t.pos[2].y); + T2 sign = A < T2(0) ? T2(-1) : T2(1); + T2 s = (t.pos[0].y * t.pos[2].x - t.pos[0].x * t.pos[2].y + (t.pos[2].y - t.pos[0].y) * p.x + (t.pos[0].x - t.pos[2].x) * p.y) * sign; + T2 v = (t.pos[0].x * t.pos[1].y - t.pos[0].y * t.pos[1].x + (t.pos[0].y - t.pos[1].y) * p.x + (t.pos[1].x - t.pos[0].x) * p.y) * sign; + return s > T2(0) && v > T2(0) && (s + v) < T2(2) * A * sign; + } + + + + + // Check if point overlaps with point (analagous to contains()) + template + inline constexpr bool overlaps(const olc::v2d_generic& p1, const olc::v2d_generic& p2) + { + return contains(p1, p2); + } + + // Checks if line segment overlaps with point + template + inline constexpr bool overlaps(const line& l, const olc::v2d_generic& p) + { + return contains(l, p); + } + + // Checks if rectangle overlaps with point + template + inline constexpr bool overlaps(const rect& r, const olc::v2d_generic& p) + { + return contains(r, p); + } + + // Checks if circle overlaps with point + template + inline constexpr bool overlaps(const circle& c, const olc::v2d_generic& p) + { + return contains(c, p); + } + + // Checks if triangle overlaps with point + template + inline constexpr bool overlaps(const triangle& t, const olc::v2d_generic& p) + { + return contains(t, p); + } + + + + + // Get intersection points where point intersects with point + template + inline std::vector> intersects(const olc::v2d_generic& p1, const olc::v2d_generic& p2) + { + if (contains(p1, p2)) + return { p1 }; + else + return {}; + } + + // Get intersection points where line segment intersects with point + template + inline std::vector> intersects(const line& l, const olc::v2d_generic& p) + { + if (contains(l, p)) + return { p }; + else + return {}; + } + + // Get intersection points where rectangle intersects with point + template + inline std::vector> intersects(const rect& r, const olc::v2d_generic& p) + { + std::vector> vPoints; + if (contains(r.top(), p)) vPoints.push_back(p); + if (contains(r.bottom(), p)) vPoints.push_back(p); + if (contains(r.left(), p)) vPoints.push_back(p); + if (contains(r.right(), p)) vPoints.push_back(p); + return vPoints; + } + + // Get intersection points where circle intersects with point + template + inline std::vector> intersects(const circle& c, const olc::v2d_generic& p) + { + if (std::abs((p - c.pos).mag2() - (c.radius * c.radius)) <= epsilon) + return { p }; + else + return {}; + } + + // Get intersection points where triangle intersects with point + template + inline std::vector> intersects(const triangle& r, const olc::v2d_generic& p) + { + // TODO: + return {}; + } + + + + + + + + + + + + + // ================================================================================================================ + // LINE =========================================================================================================== + + // Check if point contains line segment + template + inline constexpr bool contains(const olc::v2d_generic& p, const line& l) + { + return false; // It can't! + } + + // Check if line segment contains line segment + template + inline constexpr bool contains(const line& l1, const line& l2) + { + // TODO: Check if segments are colinear, and l1 exists within bounds of l2 + return false; + } + + // Check if rectangle contains line segment + template + inline constexpr bool contains(const rect& r, const line& l) + { + return contains(r, l.start) && contains(r, l.end); + } + + // Check if circle contains line segment + template + inline constexpr bool contains(const circle& c1, const line& l) + { + return contains(c1, l.start) && contains(c1, l.end); + } + + // Check if triangle contains line segment + template + inline constexpr bool contains(const triangle& t, const line& l) + { + return contains(t, l.start) && contains(t, l.end); + } + + + + + // Check if point overlaps line segment + template + inline constexpr bool overlaps(const olc::v2d_generic& p, const line& l) + { + return contains(l, p); + } + + // Check if line segment overlaps line segment + template + inline constexpr bool overlaps(const line& l1, const line& l2) + { + // TODO: + return false; + } + + // Check if rectangle overlaps line segment + template + inline constexpr bool overlaps(const rect& r, const line& l) + { + return contains(r, l.start) + || contains(r, l.end); + + // TODO: This method is no good, it cant detect lines whose start and end + // points are outside the rectangle + } + + // Check if circle overlaps line segment + template + inline constexpr bool overlaps(const circle& c, const line& l) + { + // TODO: + return false; + } + + // Check if triangle overlaps line segment + template + inline constexpr bool overlaps(const triangle& t, const line& l) + { + return overlaps(t, l.start) || overlaps(t, l.end); + + // TODO: This method is no good, it cant detect lines whose start and end + // points are outside the triangle + } + + + + + // Get intersection points where point intersects with line segment + template + inline std::vector> intersects(const olc::v2d_generic& p, const line& l) + { + // TODO: + return {}; + } + + // Get intersection points where line segment intersects with line segment + template + inline std::vector> intersects(const line& l1, const line& l2) + { + // TODO: + return {}; + } + + // Get intersection points where rectangle intersects with line segment + template + inline std::vector> intersects(const rect& r, const line& l) + { + // TODO: + return {}; + } + + // Get intersection points where circle intersects with line segment + template + inline std::vector> intersects(const circle& c, const line& l) + { + // TODO: + return {}; + } + + // Get intersection points where triangle intersects with line segment + template + inline std::vector> intersects(const triangle& t, const line& l) + { + // TODO: + return {}; + } + + + + + + + + + + + + + // ================================================================================================================ + // RECTANGLE ====================================================================================================== + + // Check if point contains rectangle + template + inline constexpr bool contains(const olc::v2d_generic& p, const rect& r) + { + return false; // It can't! + } + + // Check if line segment contains rectangle + template + inline constexpr bool contains(const line& l, const rect& r) + { + return false; // It can't + } + + // Check if rectangle contains rectangle + template + inline constexpr bool contains(const rect& r1, const rect& r2) + { + return (r2.pos.x >= r1.pos.x) && (r2.pos.x + r2.size.x < r1.pos.x + r1.size.x) && + (r2.pos.y >= r1.pos.y) && (r2.pos.y + r2.size.y < r1.pos.y + r1.size.y); + } + + // Check if circle contains rectangle + template + inline constexpr bool contains(const circle& c, const rect& r) + { + return contains(c, r.pos) + && contains(c, olc::v2d_generic{ r.pos.x + r.size.x, r.pos.y }) + && contains(c, olc::v2d_generic{ r.pos.x, r.pos.y + r.size.y }) + && contains(c, r.pos + r.size); + } + + // Check if triangle contains rectangle + template + inline constexpr bool contains(const triangle& t, const rect& r) + { + return contains(t, r.pos) + && contains(t, r.pos + r.size) + && contains(t, olc::v2d_generic{ r.pos.x + r.size.x,r.pos.y }) + && contains(t, olc::v2d_generic{ r.pos.x, r.pos.y + r.size.y }); + } + + + + + // Check if point overlaps rectangle + template + inline constexpr bool overlaps(const olc::v2d_generic& p, const rect& r) + { + return overlaps(r, p); + } + + // Check if line segment overlaps rectangle + template + inline constexpr bool overlaps(const line& l, const rect& r) + { + return overlaps(r, l); + } + + // Check if rectangle overlaps rectangle + template + inline constexpr bool overlaps(const rect& r1, const rect& r2) + { + return (r1.pos.x < r2.pos.x + r2.size.x && r1.pos.x + r1.size.x >= r2.pos.x && + r1.pos.y < r2.pos.y + r2.size.y && r1.pos.y + r1.size.y >= r2.pos.y); + } + + // Check if circle overlaps rectangle + template + inline constexpr bool overlaps(const circle& c, const rect& r) + { + // Inspired by this (very clever btw) + // https://stackoverflow.com/questions/45370692/circle-rectangle-collision-response + // But modified to work :P + T2 overlap = (olc::v2d_generic{ std::clamp(c.pos.x, r.pos.x, r.pos.x + r.size.x), std::clamp(c.pos.y, r.pos.y, r.pos.y + r.size.y) } - c.pos).mag2(); + if (std::isnan(overlap)) overlap = T2(0); + return (overlap - (c.radius * c.radius)) < T2(0); + } + + // Check if triangle overlaps rectangle + template + inline constexpr bool overlaps(const triangle& t, const rect& r) + { + return contains(t, r.pos) + || contains(t, r.pos + r.size) + || contains(t, olc::v2d_generic{ r.pos.x + r.size.x, r.pos.y }) + || contains(t, olc::v2d_generic{ r.pos.x, r.pos.y + r.size.y }); + + // TODO: This method is no good, consider rectangle with all vertices + // outside of triangle, but edges still crossing + } + + + + + // Get intersection points where point intersects with rectangle + template + inline std::vector> intersects(const olc::v2d_generic& p, const rect& r) + { + return intersects(r, p); + } + + // Get intersection points where line segment intersects with rectangle + template + inline std::vector> intersects(const line& l, const rect& r) + { + // TODO: + return {}; + } + + // Get intersection points where rectangle intersects with rectangle + template + inline std::vector> intersects(const rect& r1, const rect& r2) + { + // TODO: + return {}; + } + + // Get intersection points where circle intersects with rectangle + template + inline std::vector> intersects(const circle& c, const rect& r) + { + // TODO: + return {}; + } + + // Get intersection points where triangle intersects with rectangle + template + inline std::vector> intersects(const triangle& t, const rect& r) + { + // TODO: + return {}; + } + + + + + + + + + + + + + + // ================================================================================================================ + // CIRCLE ========================================================================================================= + + // Check if point contains circle + template + inline constexpr bool contains(const olc::v2d_generic& p, const circle& c) + { + return false; // It can't! + } + + // Check if line segment contains circle + template + inline constexpr bool contains(const line& l, const circle& c) + { + return false; // It can't! + } + + // Check if rectangle contains circle + template + inline constexpr bool contains(const rect& r, const circle& c) + { + // TODO: + return false; + } + + // Check if circle contains circle + template + inline constexpr bool contains(const circle& c1, const circle& c2) + { + return (c1.pos - c2.pos).mag2() <= (c1.radius - c2.radius) * (c1.radius - c2.radius); + } + + // Check if triangle contains circle + template + inline constexpr bool contains(const triangle& t, const circle& c) + { + // TODO: + return false; + } + + + + + // Check if point overlaps circle + template + inline constexpr bool overlaps(const olc::v2d_generic& p, const circle& c) + { + return overlaps(c, p); + } + + // Check if line segment overlaps circle + template + inline constexpr bool overlaps(const line& l, const circle& c) + { + return overlaps(c, l); + } + + // Check if rectangle overlaps circle + template + inline constexpr bool overlaps(const rect& r, const circle& c) + { + return overlaps(c, r); + } + + // Check if circle overlaps circle + template + inline constexpr bool overlaps(const circle& c1, const circle& c2) + { + return (c1.pos - c2.pos).mag2() <= (c1.radius + c2.radius) * (c1.radius + c2.radius); + } + + // Check if triangle overlaps circle + template + inline constexpr bool overlaps(const triangle& t, const circle& c) + { + // TODO: + return false; + } + + + + + // Get intersection points where point intersects with circle + template + inline std::vector> intersects(const olc::v2d_generic& p, const circle& c) + { + // TODO: + return {}; + } + + // Get intersection points where line segment intersects with circle + template + inline std::vector> intersects(const line& l, const circle& c) + { + // TODO: + return {}; + } + + // Get intersection points where rectangle intersects with circle + template + inline std::vector> intersects(const rect& r, const circle& c) + { + // TODO: + return {}; + } + + // Get intersection points where circle intersects with circle + template + inline std::vector> intersects(const circle& c1, const circle& c2) + { + // TODO: + return {}; + } + + // Get intersection points where triangle intersects with circle + template + inline std::vector> intersects(const triangle& t, const circle& c) + { + // TODO: + return {}; + } + + + + + + + + + + + + + + // ================================================================================================================ + // TRIANGLE ======================================================================================================= + + // Check if point contains triangle + template + inline constexpr bool contains(const olc::v2d_generic& p, const triangle& t) + { + return false; // It can't! + } + + // Check if line segment contains triangle + template + inline constexpr bool contains(const line& l, const triangle& t) + { + return false; // It can't + } + + // Check if rectangle contains triangle + template + inline constexpr bool contains(const rect& r, const triangle& t) + { + // TODO: + return false; + } + + // Check if circle contains triangle + template + inline constexpr bool contains(const circle& c, const triangle& t) + { + // TODO: + return false; + } + + // Check if triangle contains triangle + template + inline constexpr bool contains(const triangle& t1, const triangle& t2) + { + // TODO: + return false; + } + + + + + // Check if point overlaps triangle + template + inline constexpr bool overlaps(const olc::v2d_generic& p, const triangle& t) + { + return overlaps(t, p); + } + + // Check if line segment overlaps triangle + template + inline constexpr bool overlaps(const line& l, const triangle& t) + { + return overlaps(t, l); + } + + // Check if rectangle overlaps triangle + template + inline constexpr bool overlaps(const rect& r, const triangle& t) + { + return overlaps(t, r); + } + + // Check if circle overlaps triangle + template + inline constexpr bool overlaps(const circle& c, const triangle& t) + { + return overlaps(t, c); + } + + // Check if triangle overlaps triangle + template + inline constexpr bool overlaps(const triangle& t1, const triangle& t2) + { + // TODO: + return false; + } + + + + + // Get intersection points where point intersects with triangle + template + inline std::vector> intersects(const olc::v2d_generic& p, const triangle& t) + { + // TODO: + return {}; + } + + // Get intersection points where line segment intersects with triangle + template + inline std::vector> intersects(const line& l, const triangle& t) + { + // TODO: + return {}; + } + + // Get intersection points where rectangle intersects with triangle + template + inline std::vector> intersects(const rect& r, const triangle& t) + { + // TODO: + return {}; + } + + // Get intersection points where circle intersects with triangle + template + inline std::vector> intersects(const circle& c, const triangle& t) + { + // TODO: + return {}; + } + + // Get intersection points where triangle intersects with triangle + template + inline std::vector> intersects(const triangle& t1, const triangle& t2) + { + // TODO: + return {}; + } + +} \ No newline at end of file