From 27afe594fe59c38651fa7959b63b561d2d9f829d Mon Sep 17 00:00:00 2001 From: Sander Schobers Date: Sat, 9 May 2020 13:55:37 +0200 Subject: [PATCH] Added renderer. Added props. Added map movement (dragging & hovering). --- cmd/tins2020/res/images/cactus_short_NE.png | Bin 0 -> 1791 bytes cmd/tins2020/res/images/cactus_short_NW.png | Bin 0 -> 1942 bytes cmd/tins2020/res/images/cactus_short_SE.png | Bin 0 -> 1934 bytes cmd/tins2020/res/images/cactus_short_SW.png | Bin 0 -> 1791 bytes cmd/tins2020/res/images/cactus_tall_NE.png | Bin 0 -> 2423 bytes cmd/tins2020/res/images/cactus_tall_NW.png | Bin 0 -> 2445 bytes cmd/tins2020/res/images/cactus_tall_SE.png | Bin 0 -> 2451 bytes cmd/tins2020/res/images/cactus_tall_SW.png | Bin 0 -> 2400 bytes cmd/tins2020/res/images/grass_NE.png | Bin 0 -> 1476 bytes cmd/tins2020/res/images/grass_NW.png | Bin 0 -> 1460 bytes cmd/tins2020/res/images/grass_SE.png | Bin 0 -> 1447 bytes cmd/tins2020/res/images/grass_SW.png | Bin 0 -> 1596 bytes cmd/tins2020/res/images/grass_leafs_NE.png | Bin 0 -> 1480 bytes cmd/tins2020/res/images/grass_leafs_NW.png | Bin 0 -> 1419 bytes cmd/tins2020/res/images/grass_leafs_SE.png | Bin 0 -> 1329 bytes cmd/tins2020/res/images/grass_leafs_SW.png | Bin 0 -> 1375 bytes .../res/images/plant_bushLarge_NE.png | Bin 0 -> 1640 bytes .../res/images/plant_bushLarge_NW.png | Bin 0 -> 1586 bytes .../res/images/plant_bushLarge_SE.png | Bin 0 -> 1591 bytes .../res/images/plant_bushLarge_SW.png | Bin 0 -> 1565 bytes .../res/images/plant_bushSmall_NE.png | Bin 0 -> 1418 bytes .../res/images/plant_bushSmall_NW.png | Bin 0 -> 1415 bytes .../res/images/plant_bushSmall_SE.png | Bin 0 -> 1415 bytes .../res/images/plant_bushSmall_SW.png | Bin 0 -> 1418 bytes .../res/images/{dirt.png => tile_dirt.png} | Bin .../res/images/{grass.png => tile_grass.png} | Bin .../res/images/{snow.png => tile_snow.png} | Bin cmd/tins2020/res/images/tree_fat_NE.png | Bin 0 -> 3210 bytes cmd/tins2020/res/images/tree_fat_NW.png | Bin 0 -> 3002 bytes cmd/tins2020/res/images/tree_fat_SE.png | Bin 0 -> 3002 bytes cmd/tins2020/res/images/tree_fat_SW.png | Bin 0 -> 3210 bytes .../res/images/tree_pineDefaultA_NE.png | Bin 0 -> 3992 bytes .../res/images/tree_pineDefaultA_NW.png | Bin 0 -> 3972 bytes .../res/images/tree_pineDefaultA_SE.png | Bin 0 -> 4012 bytes .../res/images/tree_pineDefaultA_SW.png | Bin 0 -> 3987 bytes cmd/tins2020/terrainrenderer.go | 41 ---- cmd/tins2020/tins2020.go | 77 ++++-- context.go | 25 +- game.go | 66 +++-- point.go | 16 +- renderer.go | 9 + terrainrenderer.go | 225 ++++++++++++++++++ 42 files changed, 373 insertions(+), 86 deletions(-) create mode 100644 cmd/tins2020/res/images/cactus_short_NE.png create mode 100644 cmd/tins2020/res/images/cactus_short_NW.png create mode 100644 cmd/tins2020/res/images/cactus_short_SE.png create mode 100644 cmd/tins2020/res/images/cactus_short_SW.png create mode 100644 cmd/tins2020/res/images/cactus_tall_NE.png create mode 100644 cmd/tins2020/res/images/cactus_tall_NW.png create mode 100644 cmd/tins2020/res/images/cactus_tall_SE.png create mode 100644 cmd/tins2020/res/images/cactus_tall_SW.png create mode 100644 cmd/tins2020/res/images/grass_NE.png create mode 100644 cmd/tins2020/res/images/grass_NW.png create mode 100644 cmd/tins2020/res/images/grass_SE.png create mode 100644 cmd/tins2020/res/images/grass_SW.png create mode 100644 cmd/tins2020/res/images/grass_leafs_NE.png create mode 100644 cmd/tins2020/res/images/grass_leafs_NW.png create mode 100644 cmd/tins2020/res/images/grass_leafs_SE.png create mode 100644 cmd/tins2020/res/images/grass_leafs_SW.png create mode 100644 cmd/tins2020/res/images/plant_bushLarge_NE.png create mode 100644 cmd/tins2020/res/images/plant_bushLarge_NW.png create mode 100644 cmd/tins2020/res/images/plant_bushLarge_SE.png create mode 100644 cmd/tins2020/res/images/plant_bushLarge_SW.png create mode 100644 cmd/tins2020/res/images/plant_bushSmall_NE.png create mode 100644 cmd/tins2020/res/images/plant_bushSmall_NW.png create mode 100644 cmd/tins2020/res/images/plant_bushSmall_SE.png create mode 100644 cmd/tins2020/res/images/plant_bushSmall_SW.png rename cmd/tins2020/res/images/{dirt.png => tile_dirt.png} (100%) rename cmd/tins2020/res/images/{grass.png => tile_grass.png} (100%) rename cmd/tins2020/res/images/{snow.png => tile_snow.png} (100%) create mode 100644 cmd/tins2020/res/images/tree_fat_NE.png create mode 100644 cmd/tins2020/res/images/tree_fat_NW.png create mode 100644 cmd/tins2020/res/images/tree_fat_SE.png create mode 100644 cmd/tins2020/res/images/tree_fat_SW.png create mode 100644 cmd/tins2020/res/images/tree_pineDefaultA_NE.png create mode 100644 cmd/tins2020/res/images/tree_pineDefaultA_NW.png create mode 100644 cmd/tins2020/res/images/tree_pineDefaultA_SE.png create mode 100644 cmd/tins2020/res/images/tree_pineDefaultA_SW.png delete mode 100644 cmd/tins2020/terrainrenderer.go create mode 100644 renderer.go create mode 100644 terrainrenderer.go diff --git a/cmd/tins2020/res/images/cactus_short_NE.png b/cmd/tins2020/res/images/cactus_short_NE.png new file mode 100644 index 0000000000000000000000000000000000000000..868501b0460c4f02876eba28fbd1a6c968736323 GIT binary patch literal 1791 zcmd6n|2NZn9LKjwIivJtVOwUH*%#7@(rLnVzw!V^?p2`=Y7tLLk{*`4@E#h zAkcb$KkrZw2m-VakdXmUlr@+>5C|+I2ZinTO$tKfBwJl)qiYK>k|JbI68u6OGCL7- zhl^lQEHY19@pF+E6Y(lBzE^~QEQT}Uv7Oa8Weu+T7MziQ`kiILOhT{{0I^lsMdENX zx-1U|D4$5N?E*qy12BkSQ*A_r2o@F2PPD$k0h9;q6V2we4p4nDaKlG z+5Y}bGs>~!RRLANFCI(_4L$_Ip`frM`LY#FY`!KeKSMAmlgZqmz51OQutDzRPBsO{ zcB3k|gArVjTdY8&6Z8tmdXZi+C>tEqX?;SDWKcCay{1b0*W6rl7)~;O(So|NH<*vP-MkGrf8Kv877T=L476==K9no=LdOWtew{UFTb&h}c zOjNEu)1H2}sUnsnS$u<}-~X=Fw@?g?Ji}=* z5{01oVGruj{mhO?{?`_eZ?qaiu#%Wab0Pgp#z|-E_1QtyDedILZBYYXpRRs?L7Vx; zW+!&iKK}W`N{xl;%zXlGRZ2u}h`uvjA7pb+bZZ%V_wH?Pq+=>@V}}S_A0M;NdKdqa zrcwTK@}y>w3V!+PmfVg2p{>xi^pTGOCCx5)Iq78JEJJ1=ErUFKD;bok=9iU}JLBa) z^s_5(XM22z_7yn3*icwn5D*eOlf+C+c4`1y8eUeav|8;EN@J)$VHiWCq6YeB4>+Ny zX`dT8LQtwYRV`P=mH%8C_shicIa=~@n(k=?(G%l-w9=TNe(o@3HaY!Rt|GIP;z| zUcP!9A1n75B^B&gjgvn=^8{rcZr(cnpDps#6 zz?gWz&6jKYuf)UwGWu$Z+|U z1Zc~=!gWR?$H3eDFgsnBphfD%5U?o}v%5EO%B+ee1e+RT+@1K_Vbedhumo#*r#MHa m+eiZ*pJy*r|JMs(MZE%!_3}0Sg6)j|m*u}d*jwrqbMYSm=j9Us literal 0 HcmV?d00001 diff --git a/cmd/tins2020/res/images/cactus_short_NW.png b/cmd/tins2020/res/images/cactus_short_NW.png new file mode 100644 index 0000000000000000000000000000000000000000..519219a50cc6d3c846b610b860cc3a2b2c5180cd GIT binary patch literal 1942 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 W2Hy-HbP#^7I;dD*hDsk|)nGK5$d z)>^|vVHQi1rJ*YoS>0p3+>9c$*0?`^#69Oe=Q-zj{eIq_bDj)8{JvEXCVYEV5OkU^fGPoUR6k`FX39-dE!GD)brY-Ak^mKKkBRE6!TfiXz1 zG!iTw=;vYA$%yJK3kC_Ab`CAM4P(S(WITI0AM>aZ)5Sx#aWS$Qdxg-x=MK7~(!TdD zy0hB4a0wG}JHzSK1IHI)0M>c59hw>sES+9IMDlY0USJanP^87%H5CJN$Ql;*ajpFm zzHKQJ$^eey9hCLf`BdzaI&2ruPF!r)QfB}3j^kfV7-+wt9^S%qR08EoPz^T@F0!GGNx?Qe=PNJ!jyNyecH02tdR(}JR)baY7G{Z&N%e;Pwr0^emm8xlHyt12L~@RZn#(wGk&GGX&D?kU zxMWr9#m_pjwd7;=Ty}IcpzeRr9@M3L?d&_*KHmgK&Q8*ldQZd3UmEGyPQrrvZ=Kos z#~*n-v3m3H;`<5Z_}Wt1go|9Enl#7~i>F46kl%h1-4>58P-{!CQd6|=W!>H3dLnVr zsRWCYv{61j|1op3MTcPecev|>-AAL=rMpexlBQ7=&wkY&Tg3MiNgW?eo@vbJs#nD| zUzKk=IZ7Md1gZb=7F4WjI9o|dO#C{e`K-Tr&|AIm)^FEIeYg5;pHzW{7#n*Tpy#8< zydAs@TNP~y<gw8z5x9H%(^0{Yn4X#Nbv@JL9&Y1G$fru3M#JF{@`ogpkA&UOK^Ns0a&Yo= z7~5g@@|0tD7k_r0n5BZNlj?3AqJRJHkx<~U`?poa_`)0WHrq1|*iO}_Tn@ZQF61rJ z`ZYV2dA`>QXb;b8_+k@MnK_Z}-*IzTHeL<$p(nPp3yAb|KiqOAn;5LCS3%XgOnsbE z%F7PXFMndCER+zBi*YG+8o)YK?>7QU0sZCh|j@V?)PGOJ$>){;t zdkD?!ATH&w(A?Kxo*+3PdL5gd{6=588XP_ydOtvjawi&MJ7P-d?NR!xz+N!*&trry8(JZ2P8np@(j}82v>jC3=m9g^ zUXyyMYrA_pCE{NpxGsn(Uh1lXfX>|`iOF;N;n@WHDfgi4i z4T;Qe)Tnvy8s_(e&nOx}Pv=r1cAm75Vsm>!9d@le?cN?FV3 ztToMeHhX|q;!;@HF{XO0A{?8EuM8(wg*c-hMP4|gBMG!o`c)a8AAHp;_7fq8@%|0h za;xF>J{yJmDb|RwOc*W7CvIZOKU7Wc^}DcR!j+)$Q=BN;A933 kdZ$wK#{U2HH=!b`KwsCQ=5vf~CYHFoz3`s*_JpPV3z@zG*8l(j literal 0 HcmV?d00001 diff --git a/cmd/tins2020/res/images/cactus_tall_NE.png b/cmd/tins2020/res/images/cactus_tall_NE.png new file mode 100644 index 0000000000000000000000000000000000000000..56f8228f4019d889743afcbb7dbd48a83c334669 GIT binary patch literal 2423 zcmc(g`9G9hAIGnmK@ztfS;pALKDLy^tA?63ayJhV5>hBj3}b5sgUcFeY?<5AFjIDl z7&MGwBB4@@+b(*NERChI+*zNiKjL{k*DvRKopZjQ@B8yP=k+=%m#r-V@Y07zI} zJZ}d8aOf8fh$5h&qg10C0AO2}@%9%iiFi#mT{$~ig`R*)A)(@l@{zs@@quVYl5!RW z6&oNQ?T6{A&}uGF$pMwKqm!|#zw0sGm6%s$n9ee2MuU}$E=q;;)haVFuPZbgAL+b#ii!)sbd;j$ ziCV3X(S=FcZBO(^*qSdMX|W41o#mR1`HEB$^6o8E3_-0jU9Z1RIU@qvto}4piAshb z)ymRU^5fA(DZ2c6G~*t`4{0JvUTS4&5E8TmHH8dnRA)nWR2j)iX(Wh8r>6?Sfb=1E zI^C59A6pKiF zBYm_u4DFZ2D)dB|JI)&QdCIhC`KUXxfo`${SDmg(xe#~7`(dg@_Z5>vk)+#@M`XCS zRtpndkf>grjU;=anaQfmWX!8lC_0E)^>K*pfv zX|IqFgaZB5s~_sTsj9;-$U?WlF4WHY3eZI|6SEliv|-FF6UG@fo(|H=%Hu2}3L~|v zLYhnF8ZEP&XD|%b^0nBm{{Cf)e!}w1uK-rpFSFR0UlzB1VOVBH{UmPc3@eqvpe?6f zQ*rA>1Axe=)%i2_A7b3I5K|Y z^#T8BTgf9x@#5(Zf)icV)m1TPcP2M(xAI!mJ4yDY>Con77T(ECOxQ*IeIYaa(BT@p>C+-ksyt`F%>%1mVceFCHY5AbF)~Y$6`ULlszyo5Ea$& zXte0lMb|$O$wCLSX3NTE2ZT&?JIkdEENE<9kO$ATStHoX71e{qW>OAQ9=fW+&#_G$ z>T z&b93sUx!_>UEkCWY8q+V-WA+?HC{Ei(agD4xnV z$?HjpCXBuYI68VqEKPB08%;R5+<1KKD5D|CO z>(tO=HdD59%s}k)VlD7K8lW!L#<+4PN1w{1TCLMWR$`4o$B;XZqs{}~=Aho7Kf;yU zf33!X=22^xQu#K-7YOt_zWgBYBpj+86=6pR_zBYOwXa?%Xj`j6ElpuDAh=Ob%?{J2Pq;S2-_2HraE}0N|qlcCBG} zIm|?kb%>eu+r=3Ycp2_QHtO%cX0r@Jn`QTfvS*nw_Z~a zfbVB|S4V{e)+;+?2^N9=g@}zW+czZnnBReM2gi4?=N1);ddqWfU1E;;oN5}03VM3{ zc&n*4RO+*8sPdv_IpD&m3w*!@R}{7~_vuqU0ACs1HjniM96zoO9LSI}=`+_?#f}Zt#XraBy?pmo}8MH6K_y?N1n#i!eRqeG*3g zu)VzV{}Z^d)qK$vX|6#1RJ!T>$>@=*7qJ z3%I*V@re)NVnHPyTJB1)rkB-cue#w}_4BQq6h2V_YeyWN(uZ#sV{$k}oXGW1M6obs z0w4FIWa-_!60^@?GdWY}Ym*#@CD9iaA==`vrmB@e09U2wHeXp%)w_jSf2`R=e?L%D iXuAJ@{6_3f?Z}x7fVce|g5!R-vbtb>zWVIVxc>q@k|1#a literal 0 HcmV?d00001 diff --git a/cmd/tins2020/res/images/cactus_tall_NW.png b/cmd/tins2020/res/images/cactus_tall_NW.png new file mode 100644 index 0000000000000000000000000000000000000000..3ce288d8687fa8038e268a9d3814d66ef269e508 GIT binary patch literal 2445 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 bFJ}YhZRwHxNq9~C$J*=<>+|)$d&c|={&q8t literal 0 HcmV?d00001 diff --git a/cmd/tins2020/res/images/cactus_tall_SW.png b/cmd/tins2020/res/images/cactus_tall_SW.png new file mode 100644 index 0000000000000000000000000000000000000000..4aa12fd8eca5b43e69ce42c9b2e7854e8c6a74be GIT binary patch literal 2400 zcmc(gi8oaJAII;^SSo7?nPChgGnN^WQyx6hQ%HFb^;k2aB4UPyvAal-L}@(yq#;X| ztYdAmjI7BvLdcRr_-Tfoi6Q)M=l3`K&hMV@x%YeSXL-Lq@9#b5CfZtCNE|>O002P3 z^4wWF0DwbVIIs@^J>C?mbprrw-PY=onFYm40i>wp-ABffkx8M*7=Jl`H^sYw_>LlZ ziaRpS|44)nGA;m<6{is8i;TVnEqSV^Mt2D&J07~DABUsj$e5>h)SGjmH%DtT(NChF zOjLXTuKBq_qz@9Rit$%}^-QC?6yNaz$IjP!UvsoROZ!8E)-V$iMa7aa*>_b-QlN#5 z_1EZq`75pEIaGBd_}Yu9BNb zn0$rrDuxKLx7HFH02e6dYe zNEf%M$;r=|+cjj2=Eg9GxZEzLKp>b8vF+me&6^kd7spI8>0Q6~QE&htGHiMF^reuA z)sGu)E{m|PtMvh#QOk{U7ABS()8SkV6(zOyN?`wfF_rWW9vR8(*?0>-;{u+;IZrD8_veeht_f=(fj?YHjODbiqt}>`6s(8a%V#!tG)VaBfi#^-mTH7Ee z?^Z6)%}YjX#iEoX2jX>> z(BQH%@N_Q)c&x>W94;+Q`8N7P?@DhyQC@g(d2FxCf)yS5T^mepnxK;W!nEwg5e*I! zd$Oh%w%_=8lCLj}=z?{1JXwt3Ry{e$vo>Jot9h=ki7NoB*#xX;vKJynl}%{hZu?z@ z`Sm34ERDoX471ruiMoK;;Bu71ao5EK zT-bXJ2n*X>`Z5y9$+J_Hj=C z*sU#*igo@SOs2r((yjvJUkSZu=oA=dsXcoE9wOqsBWxfs8`o0_>Vo{YKTKz`jaFB0 zkAL>PJOGsKiC60C+nemixPp&r-_8x1lD=Ott(%0mW5JF`!@~Q@E^Dp~Ai6_E63hVp z0{mxf=pNQLk1j8k`YL^$h>?Wp%g-WkV!RM);d;J8tLuqSf)~tVO`JDt24H=Yj4n9X z$mc{5<`tk+#U}&s4^G++70-yKXvL|&eVp2^!TPKL=6}-yW$Y{T5ee$< zQ6ZjT(Sg;MH2eEUU87e-ZJnl8hVEp4y1ZxknWn z9^>afwW4RW$Qm-8C$&z5g&&6}^j>J?(AV2Xa8l}M^9=@4g4=R3tLNHr!EDf?OcGFn zMVx$5ScpE+f~rF|Zwv$n1zp#>&EC$o=?y11gJ0reO6|#zpp66_nfZr`cn$`1+zdI~ z`bHNl4y*x+!>}$#P+5crvavOQ$Hi7oz;SR`xX6ojW3jVM=*I9;iea`v$k+w)Ykr=x z^_1dGVk_lpFp)8kGT+77A5Ad$%LdW&b=Q7JfXS9zSoee{OiJr>Pt{7li-!pb8ean* z3Z~Hpz|hPC$yjPzZo4LUsl;exYKrmD4bFilFw%f9&Z8m#)~*A7^M+aP$M^?MO*MXV z9T?vc!?-~_%y<)9od8mx z+Oh8(+^#R|r-`k$OvtV{uVcXIp`$vlj~mTpkwSM~r~QwA53_qyEimhKJL^y4r%1oF NEX}OXmjB@%`yXwC5G()y literal 0 HcmV?d00001 diff --git a/cmd/tins2020/res/images/grass_NE.png b/cmd/tins2020/res/images/grass_NE.png new file mode 100644 index 0000000000000000000000000000000000000000..df6feaa519fff10577f361d259f17a8eaea48612 GIT binary patch literal 1476 zcmd5)iBr=@7>zQH45QVlQ78!^=aV|*^f9%Ygb(1fktX_+ z7BJAcNwkq>Vtct;KA%3;MjgBdu$Y@!D6l`&NHaE*I&aY)tH3EyBLlNrJ`bIjg0C;a zR%8`3`nZPJQcCQ&g{{0o8*Bg! z)JJt*FZHO4iJ+dOk)kgrdp=WB`)a)=bnZ7rp1*0(Vjjhy03<*vPFVnoKMNkb2e72B zDle1P>v;!Oo{O(7#1v%!Ym^=(rCW*0N%|@+9xdhq!MNH&{N3y1`?o<80QR%%0s+W9 z$2HW!2Am?F_P7~%C$`I|1NESi*jE18?{Fjeel@_7^p&`p0@S5MKm}R~v=JI_;FMQ^ zaql{IC4gGtX!qj z*?OZHK0Z;97-NKBSl4S5LmXSQS!9E4B}PUZ4@UBAX6QLA>V-pMc?pM?4%Q+N4l%6V zyCV6fX_Gk#73#9~)i(p&1ad*;B-^F`R}hK%O%;T_J`Xtqm85vPS$13a=g|@4j$z5k z3EtdvTUzw=P&Uy0e~V9D=*%?U5vRcUzbzJeL|=8&#KlZ#A@m&E)mFY@+xF4%<`|50dpe{o>C+wW5Pg5QMwT*G{fBTJ=@IGUmMJv468`r*pb7t#~#xu#Lk#;}r8 zr|EN+afi9POT=R5(T;O>mk&A~m_8*iLza=(bEmD2q^<9=+B@3(t&@%$3WZ%Bc9#28%RqQ~ z)%GCMk)1RtBVgnD91)kg4>RqZC0+R5x&@023h-?V#LD%&ulwg0yW@+(c-mB?dw-36 zYKV2LIg<8*eoJU&AvYVE2rO;VayWWJ4zo37MZEFt${9ULuJ?Bdu09?|h0s&U;_yxv zVZt)Q&u&(OoSyhB__LT Q&%YP3g2Q&-V;;Nk4{E7nasU7T literal 0 HcmV?d00001 diff --git a/cmd/tins2020/res/images/grass_NW.png b/cmd/tins2020/res/images/grass_NW.png new file mode 100644 index 0000000000000000000000000000000000000000..1aaf9978f89557988c42c4ff760c7914f216bfd9 GIT binary patch literal 1460 zcmd5*`%}_c6lZfY$I6|Z$yo;>AG{yxEY|kY(k3y>MN-!-#_fq_wTh7fSz4(10-~BF zMMv>nn4*HHs9#Xb%r(m}Z44<*%{4W$wN}E%-gf_no!R@#IdkUR&*R*4v+1tVE=U=Q-AnzIW4OtQ}lI3b@D|9{yn!s^%uX=N?kXB|fQl zE6zgK=aCFbOj7}_vl6Q-bIwjgH|7H<{QWzC0x;q_%29Q8;7SmFM zRZEGFYJo6NL1bP)UcX2hP@z?MAjfJ;0J~FC3>GTEsHCV`38t~YttbN+aldmNfCD<9 z9LxcclL(X(4N8FHRv{z}G?1P(VB2Km;bylo0Rl`($RiCk0#(2}>fS9dD|FrMe|J zZajW7-pAg4Q%J1J%ol9tZ_-25&65-#ipt}Z#fL$eq(FR22$!ppP@l%}jj<969h$Vn zN+b-GoGLI{%<^tX!dFdNxN^CXN~a3AG6@y3JY`z=X7f`C9+Jz{ONB|+rfln%)u9Ui9DAFr z(D|aowObs%?BM_Gj9!UZsCHnVoxL`b=Knt2qV@k}!q71{!?G8 zXKifC%?OD&8&W>)r?K8hrNphO&#g0OnaM-1Qkoh*G2yl?>abJ9-y1JoIacjr^-7_? zg7a8WQF!0=R8p@v20uf4)+-YWSFO(dHEoWP1Jg?}iIe`z%$LWZ)~(+?{?sY;ic8pe zDE!CH&c3%cpL?`nra{5LSTM`y7$L!4gij(bkBXzWlorieqj#*Fz%F?fu9qA*?VD5d zt}ifuu!_STU0`31^4u_$+N%>4iCEng(F>PZtGx45N9HER0{kl8C)a)Zcx9wH5wm#4 z_vJb2v^3tGtW^~H9FC2&(~J7HYd;>0pXRhRSx>k49wF0+xNnH_O&ywoLnDh@FK&n= z&Cb57GX*G9?{P;mt$%o zY2!Z^bQSV^k(mx>aO<#)fu7GPWv!A2^CD5`SeSaE`)0&UJbTBBWVx*Kr>rKP|FmPg%OpuA2XNPnEB|Op%-qrtjISUw%VS0BxUQ@A1^X0jwEg A=l}o! literal 0 HcmV?d00001 diff --git a/cmd/tins2020/res/images/grass_SE.png b/cmd/tins2020/res/images/grass_SE.png new file mode 100644 index 0000000000000000000000000000000000000000..30793ddef2a6b1ee6b7dddc5e0e5bd2aa5039326 GIT binary patch literal 1447 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 literal 0 HcmV?d00001 diff --git a/cmd/tins2020/res/images/grass_leafs_NE.png b/cmd/tins2020/res/images/grass_leafs_NE.png new file mode 100644 index 0000000000000000000000000000000000000000..475ae3c36d2fb74f7d65b76eef5b389cf8a2f05c GIT binary patch literal 1480 zcmd6m`%@EF7>1+8j;7kFmO>JcY(h5KB%qc~t9Gak4i^y>1cK-fV2OxP0ZWKk6eEFP zfPfTixFm!?LbwG8WDz1DcMTUI1jbfn1QZ-?3sQ=;M5froAJLhf+1Wk2v)}uj_c`y$ z3_9+&4Nt=3aJX&$hrNSwxQ$@C5x4mx@aU_g4S*L;(9uvIzspB==Ae*TN=k`ETGh@n zAwh5!lA`M$r6^P=h6-47c5$++{wjXARcDtxD#IfoZNqdUPyHBcof(9BoAU zbc~KNxLr*%7Evp6ko#56*(gaIPq-3IE>5L27LZcnm;<#gw?!0f7Tj7wKx0TZE-?r6 zPHC4}qm7K73gkgGxI>0qq`!(Jx=2K0KrQj=d9osnT$JVz9|a+pJP$UrSv3HZS& zJ;7C<2Na-^bWjUqDVi+gK@FuMo1&EgU-Y(8Pz9CVWQ`c0QYq+8Da%0mD%TD6SJ9dZ zff}Pr!|2ko$1(P!JHQCNql}moLvK^N*5yNG8Pw`rf-oA`XLMIkYx7`}iqWZ|Va4=L zjjKMNs>^YIb`R;RLd-Sp&pO;5n*dcn#(lD#-d;v7N~L$G;T8q+VFSHgO+e4F#+qPL z3Gpf*bC#@>KqV5_`rGu*a$+(MQr%<@*AtU3kQEXDoFt9|=pdy8KqHARu_v0z$~2_E zl7b*Kj>k<%?!d6tjBTY&K6{TO3zxjgu|bSY?xwVzm`-J%x$6fif;?^^CQb zPhuWcn~W=yd$?d{PvM1#+$x-04B8$nb_W?A_V@M*MV~G_<|qp|gcPfgaOT|M4PHmK z+J_$DooL!5+p`kY`RkiEy*RtigYrJp!FE6S26s=t?9Tl26VtADr(>>>rz}0UkoD8? zzZ-ArpYO1Xoq09uv-wHI?gK>ap>E#>z5e=4gDTsPvt^*J?fPFnvug)G6bDxC82e)8 z{DLsjkuze8U$e}YG6MERcnUQlKi1MbAFIkXVM}iVuYDE0#XRho6&#)9q*f^R{V}&7 z2;&ZpdKo3Nay=)>wn^Fgb>hjGz{SXe-SZ&c2n$h+!#!VzlVLBq+fk1mo401LVtMvt^i)n zz4KjVz@G7`>jzJrnBd=AG@#$}cmX`OEAQu?J0@;1PhVWS+myhGe5G6Na&Ryk`F!q; zwFBV=mplHpO4*w8-TIeHdtG!)bFX9?}Yg|^= OJNf$@_ii|JCiP#{#z|uU literal 0 HcmV?d00001 diff --git a/cmd/tins2020/res/images/grass_leafs_NW.png b/cmd/tins2020/res/images/grass_leafs_NW.png new file mode 100644 index 0000000000000000000000000000000000000000..ba7a9f2ca2c8b7bedf26c7e9faf4c376e3961982 GIT binary patch literal 1419 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 J<}bd@`4^8;5-pP=9b)!W^*aIOxY@z zwcOGe!wfZF=|oG66iP(7bm2&7=i47~9*^_+;q!SvKA+F~{eHe)pT~zmAvb#|Iw~d%HxmXM5&4(&Sadj(t{qLqKIEawSSCGH$Xl7{`$fhbWk^nj zQ41GJF?m!;7-~Y^NXK^Z3@fh^OnRzOH!mY{M?%^m!y(nETMYf{sgPF?xluzgs+385C)G&_ z-*!ULc}gY0VMdDgHk%K7vSn)du>lJaJgcbgIN!GRP~}6d_*-s7=eUg7at_w~ zxvsajKy7e&kt`*{y*9Xy0WtC^)s~(W{?PMLwTnZ&nkVayG1H30N`JqSJRSIbo^>iS zToJ!MeJGfY)9P0$ew7FNymH>!O2K~9(jga~%=mf#NRg_)#7o`B-p~F?jcJoY7nBqo zXYXGbJ+^xX{@oYi>=-F3mKtj%^tN|jm`pf>$>Zk?df!cNTUyC_|7^BrdUnqNrI0bc zohi3M?z6QyDe_cERgz6)!>;u+;Q?R2ea_-snVa1CDXl$2DwD~E>&l0H%td>}wvs&w ziOs8Bl)lL$!8uW#0aZytiNvQmyU#K8a6lrR-kjTJZ4p&n-|Ar%7!kuy3QlPC8ky!? zj_Gq-_FKTSUbbp%R#Kz(uMw4aDPUZ+l|-;xlGjv1KsS>Vu4P)PW=o5$CY-6|rROt; z-r8G|_W1WL=Ey7X=>zNm*R`-x00Hy(B2nHPquJ+VVAn{CqE5_s)>CHYnXs$n@hYS^ zTj+c>DB_+V&gML(@Nt8}@J=dcT>Y!--oR-fK2?jdPkZLv!bYL3oPJs$lD2G8A>}yv z_}b=C`uF|g9Kvs$a}<`A{stt6*tF5Z173rJ1)^%pm9+NS!wqA7p{MtySR=710a`_H z5sfy^TlMwz-)O9{^}8^#hE%v|s(t)|vF+~IV3Z$s#Ao${MId{_MYdf@ksGf+@6*U! zx%3fzeQ>>@TEF)&#)8bbOD30Hl?54S_IX(vV{p!C+i_#rYO7op<~E-w3HEoZ;r!y# zov_UvvqR=+zT~oYw)|s>y#wi|Hkp+|=J{>?iL1eD|M8F32sfbPJ7`zqXqV^=M=g4q w=aWI$rttk3X6_5x+je|>h~0nukv`fjll&PYIx1sUML$}(93(r|I0U5p3+NuG5dZ)H literal 0 HcmV?d00001 diff --git a/cmd/tins2020/res/images/plant_bushLarge_NW.png b/cmd/tins2020/res/images/plant_bushLarge_NW.png new file mode 100644 index 0000000000000000000000000000000000000000..32602252645b8cf6c13c98f2d924bfba78ba65a1 GIT binary patch literal 1586 zcmd5*`#TeA93R!=(&=*)#n{{!0)cEf z8;TE~OaL4T0!2Q~Zv4dei(c^@Z3LK9o&|fT&K1&FGrHy$ai{?RBsUFNavcD?s*=!OM;dK{-%3VsQV7pw zc7JsdN92|jIVd5^X1vvIPKj$5+Ri*6jmWXB0^8RQ!Is^d$9B^l#Qr)|84KH31cXq+ zOkC$3=#4l+Uk&kjoppDm<=s4dSA}^R4XESVgqS)mEIYwcoCD2D03J}KnZ!XEX}Hm< zO<>i`C-h0J6hg2?=&uF*1oeHqQUtJNMJ|{m4AcR2C_5g?x=ec63}wZG$XIzXq9_eG zw_oT+6s96eZy@;@z&~lC6~Vhkd{GYy!K)-TlWlNL3QCk^Daivou$xz{duuE*E&=jy zw#C`jPpWLD6vUxMY(t^#oYJbT6jjbbaGBOms|nAfc5hX{Kgb0d#39Rwn(GdzUl<6n#P>Ob(EXMN0`NhTcpxJ zlY{nW%)wg*#svjXAr9~Xhp+G*Uyboz%=40Q#VVa?Ovh8Ebrgw8;H4WNOJoC*5GF_E zK$c17*pl%TSz!3U`IQI>oFa%AU~|~`6*^lWW9n2YvSL!33WGp4j2-g$`Dnt+#Zfxd z#K`QyDH3`Vb|6r?JjKu{#5l2u4=OF~p!*&45@nliwTrvgIabj5?qhE>Z|$R8H=Mr> zxceWSX+2udwS)T^N!rY)2*Y=C>pe@%b81(K=MM@O`eMlXs!pd<_l4%6Y20<+k>&YM z^A|K1{Qc@fQjE4cspTOns~)bJLbGW2Hq4n5KAzYm8{Xd@1(Bzw-JDg0#;)<%Fvo!@@ z?%pQJE6S?{(yZ&1C3;Hj2a%>R8L=;<@NB@+&O|CzL01p8j9m(s7X+r;k}>^xU$p94 z#$dLaSF+7dzMK0bk+CyMdN5ALzjRvWG(H$LnzYNG(<581$yuc}#mHVn@9`DM7oJYW zRgkG;hbR6C7M@C3yXeWD^Km}18hK!MO4H@og~u}%@?hK`uXAIxw)n`IQIWf1GJyoO ztH0PQg=#PKO557&$-HNgF8sr@)TE55M-#zek=D?ys<6p;MzTl|+uoi)OVRJS*yFhB z<=aZk48cIZSA`cXWOgOa&Mqca7X{Q@E-~leAg;W?`th~n2gz`2r}%ht$E8KZ=eH3K zgZr=n$l?>fB7h*eJ&Sw)QLUV^3ZCXtg(3vTRUV5_%%*p7fVJkEx=bD=Ey> zxUGAC%kHu?;H+c^$#_*(R?2w~qg$rV+_3y(>*4l0*&boFqoy}E_QtZ`|2=)27Sp`v z*Y0GjPk*tWZAN%QoCB{n(vh#;XjDv9y_%VeaG6B>(I9_qST?JAmF|w>^^vPRDc;ky kj=7)p4FBUlLw@shQzdNp_0s+9^lws!JOeyx+)rNn7yJ>K5dZ)H literal 0 HcmV?d00001 diff --git a/cmd/tins2020/res/images/plant_bushLarge_SE.png b/cmd/tins2020/res/images/plant_bushLarge_SE.png new file mode 100644 index 0000000000000000000000000000000000000000..a78294a014a638bae62d55d1304ebc2b016c5429 GIT binary patch literal 1591 zcmd6n`#0NX9LIyx3#;lmh?TfRz9N#KW1}@r=~PRV)SPxwWLj%l*BX-)OHh{pFxCXLFx5A)Eds~+ zZine7cKtO_{cjGh+n`#mRmrbl1PHzjro;8z2W~BSR{#zCP(4&v2tX0Xn*l2T5TL+y zhyX*2!gLER)3PWN85?HvkZ;#lZFxJx;uZtfRSEdmG~O}0nn;vOZ5r-a7G>GC3(fN{ z*|wGMWkg#Pq}sOKGcca_0(Tjl6cq41!pSHWx2ear(8G~^j0Ef6VEz&bpJ?FxMwmqmhZ(acgQW+esiMi`Q@@vRa|(9`99U zBM>?hzTRHJbosl9Q;DWjqx6VSAC`G{g7R33Mz%VYdcGyocPv?7J&IP=+=InRyojIK?aSHpE~&K|2DIwcI|+{p|3 z%#!EIal4LS3Jz8der(z2w#7dLAHc;tZ&FCkN6QQkbNz1V!bneTcjZE-Vcqa8E+w*57`$Ha3 z;iB`=8?*EB7g5cM1Et5E9?^eSQS3$&y|9KSXPaw7i`LJk+FJ%s3#KOR2R|x2oK4fM zdbUTLBM^O-ijp7c&mXJ^qO7Q{+iI=!|4oZxdpV$pFBUq_qHr}_>Je7Gc!Ju`-?ZY&TM}mm`}lsJjC$sr*V6VFcz)H$ z#GEo`#OUOHHftLm^AHF6WqY-nWkME0o(R2RnDi93<>E%sn-Q(+2RRi)r3 zk>Yo|xMsz>GWaCy0gm9Ygd9RyKq?0Mc)}pN)q&MA=$T^fYUXEOynK8FVYl2=-3h)U&E-dS3t*8ch4iT-{#s-l7nId3F`q7W8oJvr581oo#6rs-6eUqT5Ld>;yM3EfvTr4!W@v+g!dq=7c@K z2WxRXRfx(wD2omPoN#)liCldJo$v29>z3hoB6E$FvEt&qTQA z)yPLhh{{~>beQ%Bptb$u+n^CzS&o!)ZOhq6S)t;a|!S;+x3oTOcs5 zy9#u-6Xw|PuG-g?SaZ|C91x;>goHzQ{n&A$1)3F)0`6L-$G~riK` zF{(zW4Ubak$F=iXz7`(EPtY@n@OePX2YQKte6FHn9|W?#-<|xYA7gMfc<0B7LK$OYOTFYj(KxNL0TXR=M2)Fg#DSLYMs+Fg(Enu>r)ru=)iOGJM_jfK_E z$MrvIZ%og9erIZGr}$dHPn`R-qu;KS zu!ZacD?|PtKhsIN8T5rR_6-&gE$Iyq9dRf-GaQNq_A@;1uFbLiY(1Bb4TmZgqXF+3 znKlkctvedyKQMJ^>yqXNsXctLYb;z6v?d5XQB*t_^kHeLOg^?S9HCp#KJ=; zI2||nYrzC_n5}*n`qzV9jlAIiqAhJhvaiv0vrIL0A=qp4#C9h2G>&T+I;~leWSMQ= zl&?@n--CC~cRLaYH$6Bu0+Cpv+Cnko)P$f<5jcC`BC&XOD5hs)lh5e#)NGiN+>#!t zwQ8j=yy=;V(P*7tO@)r03|T{rebxI!M@E*f#Ga0ik8kiLbkhfPF82>zUOgK8K1#<` zj|JinaWoq8ykk$AY}JI-`mB19QagB9Hle$P3?*T8*N30%FJiiE69-N+ZM@?I#KH9k zcbgb}Gm~=)He{CMYyMf*`9D4DK%9}B^gd5=_8C#bmNz;{RZU@=sH7!P0r literal 0 HcmV?d00001 diff --git a/cmd/tins2020/res/images/plant_bushSmall_NE.png b/cmd/tins2020/res/images/plant_bushSmall_NE.png new file mode 100644 index 0000000000000000000000000000000000000000..d5c40252b6b4ff10b15a9f3ec6da2f72bb7dd36a GIT binary patch literal 1418 zcmd6l`%{u>6vxSRy0|%OZYPxJr*|geL8g2+( zyn+a7qD^S87?77x5ETQF%nFUv5QP+Tw|1D>^44UvksIyPAF(t0{BWMjoHNho`#ndr zmlGcxv^EHb!v!boWGCTp0pJ*bTly8)dNq-K-~#R4mAoVV*IkIagZa!%kYqzv3`Eu+ zR;Z?V|CBctsE2@e@IfE;8%hmPIBgU1mAWY>mY&qW4x_+lOj zE23GHkX22;dy{lMpJv9uBQm6q)K^jJOHp?xI&46lZS)>BStTJUMa;1~G)pb)XoY&z zcySgo+y+XR9uuRl5idSZQsluydiZfOMJ*xK7J&qOaW)w%B$V>;#pmHCdJqvuE67CM zMuuI>cyt>S0x(blH~}y`sAD{CCf_UuD$u8$(EVHJxQX7QLY!@=tAi-Nh>Wx|`kEkH z14UDUFUo`mTEeR?BTfTBc7a?cW=?#u1xNrG$VeMrltn1xBcmMv0QH!FMv6uXJ*bb= zRYo+GqoW;o2`^lc3pm3oFVXL+$Z82t%ILq%=x-v`6p+;=r0RUKQbf8@01vhR(?~Z8 zfiBi_EA#hm)}KAhNeg6aq%@Tg%5o5g0ri*}kG1q(HSh!;(xI+))MW%-k?TazgImx& zHPu*+xH{FRx-LDTTIERjP63cSX@jDUPt4xm>exjpyE2*6|bc-^gMNTu{ z&ynu2@Z^TnP_Dc;J)xH$`-J_PT7speqT`Y2-+Q5QI*PB_~ngn`fIm=b?9Y7IhDlxj+*7oD$6{2{C4E2L<%BcoEF22 zeDG%E&4Jxf@=dExos{l4JI=?nNmNoIUl@H&p=h2^tU4)WCp{2YQl^rZom^VKIr9i_ zP|-0fo=6>d89h@t|Gp)K8mZ5<+78Ej_BqrU`yvd?^weH<4c6N~fK1tuTgrxJ?dc^R`$ z{eqdx5iOI}ro*hnZNnS+PTA@Ga}$~K>@lgpY-)6;t*nThuZ(7*lU#xZ~HRmE%PhX<8v(SU_wo z!wWA$#hEmtgrcv9O0&r(2{NUJN;3T`E+AuF=!_AW&=5NW=xjIB(Z_t;ht6~dIQl4t zdd9dKoz$UoCSpewVmEy7^~V?x9HwHH)Nvq(WZRC5C|se^|V zw1H-j93Ji@tHsR6H$j8UN4-ROB@jjJMo<#a0yRS=S=h>4g0z&Z5i>@+pt1{$5v6}o zI$2jo?yA96=aW>`BxN=Ib}Ri}JN=G~dh-VTP8(K`2U??aU#H)d(Ff)D>pze>1lt;m z7*-`Rt*7=hk`z@WRSiiY4ESvzz}deJcFqi_0;IqTz>TC7qO&GI5+DTx;1Ly}>mwf_d7x~-uQm_^ptL8a%(x>|hw_rR2OXKh;G3q06PR@E>j zv=pPn8~0=a3{z<8VNN6_!O8N#Cit>^581IMu5YHqqT&ghDpnk~$f{bxW?1uSaVo2n zg>@!|IC+*3t3BLT;9+uc^JzSLg1}{3gm7RajqH7)M>3}uC;F8T*L#n3Qj=gen1{cJ zx92Jn?3(4XckoeChi7^4nfsiL8IsVW()F?af33B>!4cjX{^x=2yup5XnERK;y|0ds z3%12PUt2pS?%{tpZF`sETgP`;n$<7k{+{(1vTdgLdU>9Fe)^T@AMA@Bzg;;TVN7aG zeOYoKcInxI_m&3%OYFqtv(W|ChcS+?<5ylxUVi!sF6RpKM0e^RtM=Wg8!T53u&OqR zHw|tX%Seh1H0&_M&he>x_PiaQl0vWyZ~ls%NM|13ikj3XT`5s+EM-b$mVxBM9?CVe z%Q}i&?0Ez z2WMQTY%8gWsSztq`BYmF{}g&`=ee^{v3=W5TWrzu=SGK>HaV~SwkR*}(Y?j&Z}0k) zZ-~?6ASi0?ihruy74ft_xHG$zlJEC1a>jY>ov^U0XZ~XCXdCw-h3qv9iNptxo#%ee wO55Idq}f(GAX_cD?Eca-aO6K9kndiPZM3-(kA`k_V%NpkVVr&KpT-pY3zYmkX8-^I literal 0 HcmV?d00001 diff --git a/cmd/tins2020/res/images/plant_bushSmall_SE.png b/cmd/tins2020/res/images/plant_bushSmall_SE.png new file mode 100644 index 0000000000000000000000000000000000000000..5e58d5bfd1dcff122adfd9428e470e6efd300600 GIT binary patch literal 1415 zcmd6l`BPI@6vtEAX%U7IDRrdsl9)X&?}Zv^Q3hM7f~MG*5vev72c%|d1q5Ujfr3jb zi)9Oe1c-$S1QH+#*-1daMn%D}1qh4Qq_$-c9UN+q)?WUI&h-9rm$~PB&-r}MRW4`0 zm&f}a7!1aXePG{V48{!{-7xNNf~~)abQ@fPxd)Gg?N2&L>Z~HRmE%PhX<8v(SU_wo z!wWA$#hEmtgrcv9O0&r(2{NUJN;3T`E+AuF=!_AW&=5NW=xjIB(Z_t;ht6~dIQl4t zdd9dKoz$UoCSpewVmEy7^~V?x9HwHH)Nvq(WZRC5C|se^|V zw1H-j93Ji@tHsR6H$j8UN4-ROB@jjJMo<#a0yRS=S=h>4g0z&Z5i>@+pt1{$5v6}o zI$2jo?yA96=aW>`BxN=Ib}Ri}JN=G~dh-VTP8(K`2U??aU#H)d(Ff)D>pze>1lt;m z7*-`Rt*7=hk`z@WRSiiY4ESvzz}deJcFqi_0;IqTz>TC7qO&GI5+DTx;1Ly}>mwf_d7x~-uQm_^ptL8a%(x>|hw_rR2OXKh;G3q06PR@E>j zv=pPn8~0=a3{z<8VNN6_!O8N#Cit>^581IMu5YHqqT&ghDpnk~$f{bxW?1uSaVo2n zg>@!|IC+*3t3BLT;9+uc^JzSLg1}{3gm7RajqH7)M>3}uC;F8T*L#n3Qj=gen1{cJ zx92Jn?3(4XckoeChi7^4nfsiL8IsVW()F?af33B>!4cjX{^x=2yup5XnERK;y|0ds z3%12PUt2pS?%{tpZF`sETgP`;n$<7k{+{(1vTdgLdU>9Fe)^T@AMA@Bzg;;TVN7aG zeOYoKcInxI_m&3%OYFqtv(W|ChcS+?<5ylxUVi!sF6RpKM0e^RtM=Wg8!T53u&OqR zHw|tX%Seh1H0&_M&he>x_PiaQl0vWyZ~ls%NM|13ikj3XT`5s+EM-b$mVxBM9?CVe z%Q}i&?0Ez z2WMQTY%8gWsSztq`BYmF{}g&`=ee^{v3=W5TWrzu=SGK>HaV~SwkR*}(Y?j&Z}0k) zZ-~?6ASi0?ihruy74ft_xHG$zlJEC1a>jY>ov^U0XZ~XCXdCw-h3qv9iNptxo#%ee wO55Idq}f(GAX_cD?Eca-aO6K9kndiPZM3-(kA`k_V%NpkVVr&KpT-pY3zYmkX8-^I literal 0 HcmV?d00001 diff --git a/cmd/tins2020/res/images/plant_bushSmall_SW.png b/cmd/tins2020/res/images/plant_bushSmall_SW.png new file mode 100644 index 0000000000000000000000000000000000000000..d5c40252b6b4ff10b15a9f3ec6da2f72bb7dd36a GIT binary patch literal 1418 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 literal 0 HcmV?d00001 diff --git a/cmd/tins2020/res/images/tree_fat_SE.png b/cmd/tins2020/res/images/tree_fat_SE.png new file mode 100644 index 0000000000000000000000000000000000000000..66861e87bf5681b5f77f63ad1db4f49a0cb5c504 GIT binary patch literal 3002 zcmcgu`#;lt8~<+Hj!}wkhm|og=1{Saw2`(|TBD-ypmdj<8kKWxET`lU&6$au88Jr8 zbgP!=?r=L#j-~OTpYIQ!1QHRiAg3+| z0D!_Nf}JA(KtUG@$Vh;%&QhJX;N~L9{=!K-+1}to-2ry42JMzcG#Rw;vJ`kqD55$| zm9oA4=h3c7*PxNLD^gIsjfl#$bSDdL0Acw41@NnOc?xKeT~(-0^^Y8mz-Zf5dYz@H z0ro$&phbOdFdSg(cU2hJ&f2{w6R-zq=ZYgFcvv`dklo z1067K&|RY*eGApgLVapLR6a&jJ>HiRu3ec5FNg&plFyripoof8M0v_JcRbzMGLC4b zU74bpO-pn@gA51nolkT)5=l7tA%vtJP410wcpYS~RS=hU(Sl1RAm5a0<~{($>T!$y zfdd&DeQ5(}=(aNS+MnvR7wK}I>b4bb=YYoaAL-jQp4mRtyY88VAHLNV<-vK-X3u3 znFj`*`#|S;re-Gf@dfkGVWc2i!<@@jT2JFOv!f9;PvDF=B(DNN^=A?GC~xo`r$`*`+&< z#Pa|zs$xG!PR?I0@iHHI3|XO!L~{H?NF)JI`S4{g0VAX*%HJQy;2|qW^l5(LI{nx* zfBo7uK|?^m;V3~!gMcsK^P-MLaRe2(=_n+Jxc zram3ARgFy_;1aJ$m54e!i~pQz+!xbw-9kyvv&eGqNjOVo$LWnYJdcMDiSc?L<1Itj zU1#ksY3phu=5NLD)5Ygf=680^g&69b!20>=Lna=buu0}`l{SmIpd^1B1lbca;RwWD z=ku|u_X+tyd~s)Iw}?CAJ@U==_DvZ=Q`G0r+McRCE45r};8-RryxNj&CaE*I?D?0} z>vvZ+Fs&nE3!u1_-z~ay6MsYI?>uQEh^61w%!|2mN2u9keIPxCd=iM&l?yz4y!fi+ z?Wu)IaSGAs?B=IKo~2fjI8=B>Pn?nNm{^>hjR=151*mS8b2%iVe4ObWR$p-`GMLo> ze3x@Z_LvRKLl(mplFh4JlHJ@4n-opfw%X~UlvS#=K14M~#HySo99r^hlYB%>$;_>i zAmx1fA~ESdp8hUFLt_eH%@c`0C%zL6$+DO2c=hV+EeG~Uv!Nn3@X!!Y;QD3jhi>7= z25I||3rKpekvWq9CBbIhA+<8tnUd6tbGQCLf03Sf6B`WdnZ-)k)m?(s7*E7tN{sl_b1lyt`>W=fFj`^%j)l5j2VOq``m zMp|9O*5issu6U6D#Mr~sb8!*ZI9lGHrrKNC7cTT@*=;1d;zDxC%JXIVP@XO*m2}4> zavFqx)wQm5p*|DnjC-g+Ony3S1F;PSV)94feOYB*R_-OJWY7UM90t#%YzA z5?>O>;|yjY@q!1*r8Ph@ByiTV9xD3 zGH;uu;u*i#p*q@yDjii5B4&hAUZBD*0VJse5Hf*L+1U`VtiK7qd>Lyw$Y_U#qT9y& zkB*_S8-bp?siR^mDd9H3Kyf65Fa$k4D%w6Pej;)vU2Ts|4p*ciP>{avg1(U2P2HUw}_dBmh1;{<<%ey zKB0`(pOFJV*Hp*pgV{>dHG?b1nbAaay~Hl=o+bnW5C?>EUBh8_kiOFKu~eTH80@_a zRliQ)e`!q}E{naF4}|JH8~az|JQ`as-HWP#5OyyZseBI^cmoN&o)5eli#_|Bkn)ZV zxp!-7Ni*(kBMgauJN^d z8L{ct2R@d~x6W?hahvj!>-EpG`~{O!t^=&CK7$PN0hNJ<=CIt=nUNQeP{PJ-!MhbG z*=1u{ATcDuG@b>WufFv>?3`w5Lq~-15KC*_sj$zd1_ohK>fD4Y81a+`C9Ituj|b*7 z4`M9tFO0t|a~BJ^Tgx+C(aL)NSR0Ie~Km7RjgiP_mVDV1O z(h0O0a;#;#BR^0wxPUOc^_K+3DLrb5ZpwyP?5csX8~K#2=YmSG-%_^ejevy1lytYIwMOZ literal 0 HcmV?d00001 diff --git a/cmd/tins2020/res/images/tree_fat_SW.png b/cmd/tins2020/res/images/tree_fat_SW.png new file mode 100644 index 0000000000000000000000000000000000000000..f35a819de39828cba9ae1ef47499dd2d7212fed1 GIT binary patch literal 3210 zcmcgu`8!m78$ZmDwQS+Rj6vCkNLea0Av;Zk!q_4ng;8Xg88efTB}+7lOk;$UvSuCA zSRT(**0H3qgi0m*Lzc+Ar}zB_-s}D0J=eLebKjryz3=<;`Fy|Ux=sq(*+yJMK?DE* zaXVWp7XaV~Lw-OA0zNuQ54;AGe6-`a(>7Q~#Y8Op9syC9tWuH=%fhLaq^lIAB8pOn zaA$wVPcpQ7tF*eFYq6h!0f;DqO!97k6A{!TupyX&H#fl*IaCMB#)GrKRONBne{k*I zO0DjSw6lhz3Fk6gjNo_iEUc|&Td_)EO6OIFC;q743=5Or;axOXMM`PcIdN!moF`Zg za>#Zw86mi)oi$2wKFTGy=6W0hr-KfF62Q4&XK)0Zk^pK^DNKgn#lf@jpeW=(4T5$X z$*EB-%hc|#hGoRTa}wa$1W+0*D;|~^uiaA#yAuO4K|D%QeUbsvgJs4k-HAaI+|ufL zfuJRWx3nU|s%T{8`ZL0#8$t{b7QgzRvqb?fxpo zTalpuUD3`Bq1K>3$o`rlAM-N*Q&mBh>}!rX?;A8b%Ro;wI!a#zTCyVSXx?TY$nJR; zPDESj;%)Uy{7_@WbJ^}D8m+}@l@t|vic)H{a$cfx{*6P_MCJQrt+(avSbKu4e)DA; zW|(c3t8wHhWcfvl{#f+OkkeLot|r8J1>pP~2!UApBL@=04JmjHS`xv-%q`T_I3{2S z=i(FKV0jIrLQhsL%dkz{w+tRuzbF@HS73`h0}nG0A&aERFl9V7HPKJU48mxdWNS9( z6g=!=j3(tGy4EyiENyFv{EkU69jj$;!IwDXC33CjQ%-H*3@x0!MPn}2rpcfK(MwBg zCglv7y|o2rT9cXVna%0L^8g@x($4DCx!BS9@vk_g;r)C3vLzg)5VxQfwif*KRfz%I z5_7|dfqYR+@nF1r=HZpiNM}^1x21$u zjMa2)k&2{Ze}91g&ueFry2dnS+3z16F6v5XF|#ePDl}sdN4XatM)We>JVzzc>})sX={=#B>8@Q}ymiM?Dbh;!i+=;FpLQpG zW{IYd3MY^+rr-kimzx|3D_G!UxMFwEA-A?;H$vg<5WhqQa4KiFvIlvg$XoId&&FW& zm$L7%M;8e5yL!Gh_%FCmxtF?}PXdmx#(>?Yo(qvE`td%1Qhn@#2y5-`1ORv0%0OYrE~H2z@`3i^wYdR`U2_F#D5tLQ6+ECGCP`1W2<-6%qc~zJT4cwkn%j(H+49jFeb$uD@ z@4nrw{ND4mL*nx)g>_uaIeE2)nffd2RBN$=ShE?Q0^#OffaxZ~a z3uFDGrRDnoHArGph(L%esmTWf|9RTme2uh;z{WPdUqw6cfvgIgP`W^3lXrMgux0*X zL!F=oV=q923EJ`L@eIZ?K5$O&jj2+yN9H=rHknTUmGc?(Ys^*zAwBv$5#kAtwuw+JIq?|l2@O(J9xx6oh6hh&oR9!#S@IeJn z!MjPu^uj#%ojvfXj3oMj{Z72}azpzk;O3F3Wha=fXJ203uxy&T0@8LR~9pjfl-^C0aa!+d*Tl-BcijUP_*WF9onzOO7@%Sr@mhV}u zv(xphWlOB|YmC5L!M z%l)I;^6L=p$NUmZwLS#%M9b}?8g?SYa!k>?*f~ssZ1ecXtGN>VU;7g4ETIF@x|xZ~ z*pb`4tofHYvRY`IRiV70S-kMhkLt-^EBjbHdJfGft(C@rZ+D&C{k1{-wa|uJ2Cafx*$@f6kuh*qvMp0#V-!tb|{Grz^&I|CmF+ z=P^#w)fZ->BeXQ8wk|(neW4i>HtMtoawX66x}El!F1OB%PF6_9F1In3cAu^{L_!m` xL>Kn_kN+D}#Dz9KVX&A~$gA9z)c)_awJ1p+Yu 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 N40KH~Bpv6({{z1J>>&UE literal 0 HcmV?d00001 diff --git a/cmd/tins2020/res/images/tree_pineDefaultA_NW.png b/cmd/tins2020/res/images/tree_pineDefaultA_NW.png new file mode 100644 index 0000000000000000000000000000000000000000..5fd449a97bd36b318b20d55e8886ac51d56c84ec GIT binary patch literal 3972 zcmd5`ijMQGu0L&uq@mD%Y_HMH<}p}0L! z!q^niq!g*f*7@ho68K7P4{u(yf1$N5x2HF^2MShR!~Yyp<7@(NY%Q?T;db}x^fZ+y zuLiuNnut7}C}0AX(fUf2PKG2u>#-m^PA3;BLNkvS8cytlH@5+ifi=cJNhCEB*Z`KX z2Fel@HT@_Hz)YgF0*J}&;ROWY@$mz)11r3x9Y6xBCfp1Rk*sZq(pLf|tg2qRrDHPG zA=XfN$k&?diJL@8d7hKpUZZ4?xT1@>Dc4cP7m7rhm|4 zxHJE=2p(_rb8SV@^emzH#Mx&~lnB>STRotZVmbLDDLApLJmI8NjNW}fRbC%IKwj}; ze4(`tPzaH<4561vBFX98Pu=5;RCrLnITl)iFJ4ZEITqXKRyY`p2ipUZO4c^=g*`8` z*B6M23DLX*bW4JmT3^6(AX@(tPw=+C=xaVk+519um_oGeSkea|3oKcu!?6Y&rs`T%$(&;gH(9)p;) zuA4wJnV7CqGfi$nyQ`x}A(02xvKv&Z!}m&-!AjNFp_G$gDXmH4OlK07 z>Rd$ec9V^wXi-QlR4wl!rIr(viE$LF1&ej2RC}L)H-)!x z#jLEER^b7Y$@t76(Od0O%_`<5%UBNtNB zS!k;^33t8)6tMgK3EZh2(&&`y*YJ^>4Sfu5y$vbNJ5r|B38h4ZSxtoS73Uo(Q7uH( ztc8;~+}!v^@&bJi{HM)1bqG;?X_c49W_j$hR zH8eaS%RO-Uz1@zju3JKb+>WsyEq8m8^zf5a8B0Cf*Em;CEno8%CkJcNcj(6N*ehPK zmSOos8q&;#{FvD9u`IQz7QPxG*~aES@252f`iUdgz$l)xD{DO|^(t!gXOXC6E;!khgL9DV@;foh$irUjo?ZZmoL^{N;jYL_ zx>c6wxW4YN5QosFWkrB|6%DI~gx@rg*Cm^VA&hKh3|4qk*4JG$D1IF9?<4hfyWV;ADlEwOHZ`qn?`6 zO6I7vr`qzE%k)>L^l*oqU<_^zEt@OJo0~j)-)(*h9T@8-@G$DI;kIc8x3cy1 z^#|7)^P0UWEOzu%()v{QfP`ZCuj+QPM-r1J_jOT~ZgSF1lGw&~@(*;>Mp-rz|2OXX|m=36{VHn-tq0-5l%WogjYsnZrq+V8o@ zRNtOIc5Q9<;Dr4S`{sZ~$rv7wuU&doKNlqAdgMX;@OU18V6l|V$gkJ`dD1H==+E!P zv9XrT`neFLhItqxN%9>zGD7ODPkii5{S&zn3~p&~^wSb7jkcwBDQ04^-QYA(_z{j8 z>mTtV+~IC8W^2puW=E$=Ub|IX+tHy)$yEH7a55Q2iMfw--cY5E+a4^_*HA#+MQRJsG zz$zaRE7fh1>AFLMr9`E%KtEOe$<2u!t(+Z3e3?q_?cg5rU6=BG_58CljDB(KFSn{A&5K$OQk`K#M1mE&8@DD^1Y|qOdM`th$sq)CG&NaLXbt;_~r{a zSp8B1x#QJMzs~p3(%Ks7De-0u;U+s~wM+F5f;Q<%{jKz!0}g4R0k_5yF`O>l;NaI+ zDB?2|+qx3^!1bWq`?ZYWeP@?5(g+=XE$^*Eh(!@?0GTW(3tn%Btl!b_x}SG@`MJ1S za;(1YPTvk?)YI9NhyKT_1@Hrt%bW#^$Nfn(`~Bt2!}P}>O-9tjcSDq+hfT)Uw+ZoZWJ9cNExf@F(|$ zJ(RuG8S-=9z8PBriab9XW`4ql_YuXZMx5?9p#H!t5no4fxOZg}%J+Vmu|53t>)^m; zN}21DYPM#^Tm0^Ez+DcOU(NATU(oVgtfzm3(=;>M+F4mi|CHHwieNd$yy@{}k6?F- zGPGjGeJ)UlewCrr9(ln4cPq^JpHtTFNVn)1!&HT{_W=8wg_;* zAJr+9`j@M~)HouEyLn1Z`#*MnR29Mku)TH-9o?H!G73d3bR^Or$M&YS?)L82X9R?x zH7H&9>k({YZ+SV)!&2Bcv~mj7j!Q->}{ zT^X&+nGVb(pRNB`h@duoEYyJ6{rl7Ve>k2FsRqlfUX!y=hW*W=t7(KFs5?ae4_Bui A+5i9m literal 0 HcmV?d00001 diff --git a/cmd/tins2020/res/images/tree_pineDefaultA_SE.png b/cmd/tins2020/res/images/tree_pineDefaultA_SE.png new file mode 100644 index 0000000000000000000000000000000000000000..74678b280fa911d34c5aced6d6091f424f123fdd GIT binary patch literal 4012 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 Kr%|J36Y)Qm3>6Rn literal 0 HcmV?d00001 diff --git a/cmd/tins2020/terrainrenderer.go b/cmd/tins2020/terrainrenderer.go deleted file mode 100644 index bea8915..0000000 --- a/cmd/tins2020/terrainrenderer.go +++ /dev/null @@ -1,41 +0,0 @@ -package main - -import ( - "github.com/veandco/go-sdl2/sdl" - "opslag.de/schobers/tins2020" -) - -type terrainRenderer struct { - terrain *tins2020.Map - center tins2020.PointF - zoom float32 -} - -func newTerrainRenderer(terrain *tins2020.Map) *terrainRenderer { - return &terrainRenderer{terrain: terrain} -} - -func (r *terrainRenderer) Render(ctx *tins2020.Context) { - tempToTexture := func(temp float64) *tins2020.Texture { - if temp < .2 { - return ctx.Textures.Texture("snow") - } - if temp > .8 { - return ctx.Textures.Texture("dirt") - } - return ctx.Textures.Texture("grass") - } - - // horizontal: [191, 321) = 130 - // vertical: [267,332) = 65 - - for y := int32(0); y < 10; y++ { - left := -y * 65 - top := y * 32 - for x := int32(0); x < 10; x++ { - temp := r.terrain.Temp.Value(int(x), int(y)) - text := tempToTexture(temp) - text.Copy(ctx.Renderer, &sdl.Rect{X: left + x*65, Y: top + x*32, W: 512, H: 512}) - } - } -} diff --git a/cmd/tins2020/tins2020.go b/cmd/tins2020/tins2020.go index 56e67b5..49d77f9 100644 --- a/cmd/tins2020/tins2020.go +++ b/cmd/tins2020/tins2020.go @@ -28,7 +28,7 @@ func run() error { } defer sdl.Quit() - logSDLVersion() + // logSDLVersion() if err := ttf.Init(); err != nil { return err @@ -69,24 +69,66 @@ func run() error { return err } err = ctx.Textures.Load( - "dirt", "images/dirt.png", - "grass", "images/grass.png", - "snow", "images/snow.png", + "tile-dirt", "images/tile_dirt.png", + "tile-grass", "images/tile_grass.png", + "tile-snow", "images/tile_snow.png", + + "cactus-small-1", "images/cactus_short_NE.png", + "cactus-small-2", "images/cactus_short_NW.png", + "cactus-small-3", "images/cactus_short_SW.png", + "cactus-small-4", "images/cactus_short_SE.png", + + "cactus-tall-1", "images/cactus_tall_NE.png", + "cactus-tall-2", "images/cactus_tall_NW.png", + "cactus-tall-3", "images/cactus_tall_SW.png", + "cactus-tall-4", "images/cactus_tall_SE.png", + + "tree-fat-1", "images/tree_fat_NE.png", + "tree-fat-2", "images/tree_fat_NW.png", + "tree-fat-3", "images/tree_fat_SW.png", + "tree-fat-4", "images/tree_fat_SE.png", + + "tree-pine-1", "images/tree_pineDefaultA_NE.png", + "tree-pine-2", "images/tree_pineDefaultA_NW.png", + "tree-pine-3", "images/tree_pineDefaultA_SW.png", + "tree-pine-4", "images/tree_pineDefaultA_SE.png", + + "grass-small-1", "images/grass_NE.png", + "grass-small-2", "images/grass_NW.png", + "grass-small-3", "images/grass_SW.png", + "grass-small-4", "images/grass_SE.png", + + "grass-leafs-1", "images/grass_leafs_NE.png", + "grass-leafs-2", "images/grass_leafs_NW.png", + "grass-leafs-3", "images/grass_leafs_SW.png", + "grass-leafs-4", "images/grass_leafs_SE.png", + + "bush-small-1", "images/plant_bushSmall_NE.png", + "bush-small-2", "images/plant_bushSmall_NW.png", + "bush-small-3", "images/plant_bushSmall_SW.png", + "bush-small-4", "images/plant_bushSmall_SE.png", + + "bush-large-1", "images/plant_bushLarge_NE.png", + "bush-large-2", "images/plant_bushLarge_NW.png", + "bush-large-3", "images/plant_bushLarge_SW.png", + "bush-large-4", "images/plant_bushLarge_SE.png", ) if err != nil { return err } game := tins2020.NewGame() - tr := newTerrainRenderer(game.Terrain) + control := tins2020.NewTerrainRenderer(game.Terrain) + err = control.Init(ctx) + if err != nil { + return err + } - running := true - for running { + for { for event := sdl.PollEvent(); event != nil; event = sdl.PollEvent() { switch e := event.(type) { case *sdl.QuitEvent: - println("Quit") - running = false + ctx.Quit() break case *sdl.WindowEvent: switch e.Event { @@ -94,17 +136,22 @@ func run() error { x, y := window.GetPosition() ctx.Settings.Window.Location = &tins2020.Point{X: x, Y: y} } + case *sdl.KeyboardEvent: + switch e.Keysym.Sym { + case sdl.K_ESCAPE: + ctx.Quit() + } } + control.Handle(ctx, event) + } + + if ctx.ShouldQuit { + break } renderer.SetDrawColor(0, 0, 0, 255) renderer.Clear() - // renderer.SetDrawColor(255, 0, 0, 255) - // renderer.FillRect(&sdl.Rect{0, 0, 200, 200}) - // ctx.Textures.Texture("grass").Copy(renderer, &sdl.Rect{X: 200, Y: 100, W: 456, H: 356}) - // ctx.Textures.Texture("dirt").Copy(renderer, &sdl.Rect{X: 143, Y: 122, W: 456, H: 356}) - // ctx.Textures.Texture("snow").Copy(renderer, &sdl.Rect{X: 257, Y: 122, W: 456, H: 356}) - tr.Render(ctx) + control.Render(ctx) renderer.Present() } return nil diff --git a/context.go b/context.go index a903a74..b61b152 100644 --- a/context.go +++ b/context.go @@ -6,11 +6,12 @@ import ( ) type Context struct { - Renderer *sdl.Renderer - Fonts Fonts - Resources Resources - Textures Textures - Settings Settings + Renderer *sdl.Renderer + Fonts Fonts + Resources Resources + Textures Textures + Settings Settings + ShouldQuit bool } func NewContext(res *rice.Box) (*Context, error) { @@ -26,15 +27,17 @@ func NewContext(res *rice.Box) (*Context, error) { return ctx, nil } -func (c *Context) Init(renderer *sdl.Renderer) { - c.Renderer = renderer - c.Fonts.Init(c.Resources.Copy()) - c.Textures.Init(renderer, c.Resources.Copy()) -} - func (c *Context) Destroy() { c.Fonts.Destroy() c.Resources.Destroy() c.Textures.Destroy() c.Settings.Store() } + +func (c *Context) Init(renderer *sdl.Renderer) { + c.Renderer = renderer + c.Fonts.Init(c.Resources.Copy()) + c.Textures.Init(renderer, c.Resources.Copy()) +} + +func (c *Context) Quit() { c.ShouldQuit = true } diff --git a/game.go b/game.go index 1225279..61db4d8 100644 --- a/game.go +++ b/game.go @@ -13,33 +13,69 @@ type Game struct { } type Map struct { - Temp *NoiseMap - Humid *NoiseMap + Temp NoiseMap + Humid NoiseMap + Variant NoiseMap + PlaceX NoiseMap // displacement map of props + PlaceY NoiseMap } -type NoiseMap struct { +type NoiseMap interface { + Value(x, y int32) float64 +} + +func NewNoiseMap(seed int64) NoiseMap { + return &noiseMap{ + noise: noise.NewPerlin(seed), + alpha: 2, + beta: 4, + harmonics: 2, + } +} + +func NewRandomNoiseMap(seed int64) NoiseMap { + return &randomNoiseMap{noise.NewPerlin(seed)} +} + +type noiseMap struct { noise *noise.Perlin alpha, beta float64 harmonics int } -func NewNoiseMap(seed int64) *NoiseMap { - return &NoiseMap{ - noise: noise.NewPerlin(seed), - alpha: 2, - beta: 2.13, - harmonics: 4, +func clipNormalized(x float64) float64 { + if x < 0 { + return 0 } + if x > 1 { + return 1 + } + return x } -func (m *NoiseMap) Value(x, y int) float64 { - return m.noise.Noise2D(float64(x), float64(y), m.alpha, m.beta, m.harmonics) +// Value generates the noise value for an x/y pair. The range of the output is approximately [-1.325825214,1.325825214] (for 4 harmonics). +func (m *noiseMap) Value(x, y int32) float64 { + value := m.noise.Noise2D(float64(x)*.01, float64(y)*.01, m.alpha, m.beta, m.harmonics)*.565 + .5 + return clipNormalized(value) +} + +type randomNoiseMap struct { + *noise.Perlin +} + +// Value generates the noise value for an x/y pair. The range of the output is approximately [-1.325825214,1.325825214] (for 4 harmonics). +func (m randomNoiseMap) Value(x, y int32) float64 { + value := m.Noise2D(float64(x)*.53, float64(y)*.53, 1.01, 2, 2)*.5 + .5 + return clipNormalized(value) } func NewGame() *Game { terrain := &Map{ - Temp: NewNoiseMap(rand.Int63()), - Humid: NewNoiseMap(rand.Int63()), + Temp: NewNoiseMap(rand.Int63()), + Humid: NewNoiseMap(rand.Int63()), + Variant: NewRandomNoiseMap(rand.Int63()), + PlaceX: NewRandomNoiseMap(rand.Int63()), + PlaceY: NewRandomNoiseMap(rand.Int63()), } return &Game{ Terrain: terrain, @@ -48,10 +84,6 @@ func NewGame() *Game { } } -type PointF struct { - X, Y float32 -} - type Flower struct { Location PointF } diff --git a/point.go b/point.go index 66a5f0b..4eb3018 100644 --- a/point.go +++ b/point.go @@ -1,6 +1,18 @@ package tins2020 type Point struct { - X int32 - Y int32 + X, Y int32 } + +func (p Point) Add(q Point) Point { return Pt(p.X+q.X, p.Y+q.Y) } + +type PointF struct { + X, Y float32 +} + +func (p PointF) Add(q PointF) PointF { return PtF(p.X+q.X, p.Y+q.Y) } + +func (p PointF) Sub(q PointF) PointF { return PtF(p.X-q.X, p.Y-q.Y) } + +func Pt(x, y int32) Point { return Point{x, y} } +func PtF(x, y float32) PointF { return PointF{x, y} } diff --git a/renderer.go b/renderer.go new file mode 100644 index 0000000..7d35246 --- /dev/null +++ b/renderer.go @@ -0,0 +1,9 @@ +package tins2020 + +import "github.com/veandco/go-sdl2/sdl" + +type Control interface { + Init(*Context) error + Handle(*Context, sdl.Event) + Render(*Context) +} diff --git a/terrainrenderer.go b/terrainrenderer.go new file mode 100644 index 0000000..2971e67 --- /dev/null +++ b/terrainrenderer.go @@ -0,0 +1,225 @@ +package tins2020 + +import ( + "fmt" + "log" + + "opslag.de/schobers/geom" + + "github.com/veandco/go-sdl2/sdl" +) + +type terrainRenderer struct { + terrain *Map + hover PointF + project projection + + interact interaction +} + +type interaction struct { + mousePos Point + mouseLeftDown bool + mouseDrag *Point +} + +type projection struct { + center PointF + zoom float32 + zoomInv float32 + + tileScreenDelta PointF + tileScreenDeltaInv PointF + tileScreenOffset Point + tileScreenSize Point + windowCenter Point +} + +func newProjection() projection { + return projection{zoom: 1, tileScreenDelta: PtF(65, 32), tileScreenDeltaInv: PtF(1./65, 1./32)} +} + +func (p *projection) update(renderer *sdl.Renderer) { + p.zoomInv = 1 / p.zoom + + p.tileScreenOffset = Pt(int32(p.zoomInv*256), int32(p.zoomInv*300)) + p.tileScreenSize = Pt(int32(p.zoomInv*512), int32(p.zoomInv*512)) + + windowW, windowH, err := renderer.GetOutputSize() + if err != nil { + log.Fatal(err) + } + p.windowCenter = Pt(windowW/2, windowH/2) +} + +func (p *projection) mapToScreen(x, y int32) Point { + return p.mapToScreenF(float32(x), float32(y)) +} + +func (p *projection) mapToScreenF(x, y float32) Point { + translated := PtF(x-p.center.X, y-p.center.Y) + return Pt(p.windowCenter.X+int32((translated.X-translated.Y)*65*p.zoomInv), p.windowCenter.Y+int32((translated.X+translated.Y)*32*p.zoomInv)) +} + +func (p *projection) screenToMapRel(x, y int32) PointF { + normX := p.zoom * float32(x) + normY := p.zoom * float32(y) + return PtF(.5*(p.tileScreenDeltaInv.X*normX+p.tileScreenDeltaInv.Y*normY), .5*(-p.tileScreenDeltaInv.X*normX+p.tileScreenDeltaInv.Y*normY)) +} + +func (p *projection) screenToMap(x, y int32) PointF { + pos := p.screenToMapRel(x-p.windowCenter.X, y-p.windowCenter.Y) + return p.center.Add(pos) +} + +func (p *projection) screenToTileRect(pos Point) *sdl.Rect { + return &sdl.Rect{X: pos.X - p.tileScreenOffset.X, Y: pos.Y - p.tileScreenOffset.Y, W: p.tileScreenSize.X, H: p.tileScreenSize.Y} +} + +func NewTerrainRenderer(terrain *Map) Control { + return &terrainRenderer{terrain: terrain, project: newProjection()} +} + +func (r *terrainRenderer) Init(ctx *Context) error { + r.project.update(ctx.Renderer) + return nil +} + +func (r *terrainRenderer) Handle(ctx *Context, event sdl.Event) { + switch e := event.(type) { + case *sdl.MouseButtonEvent: + if e.Button == sdl.BUTTON_LEFT { + r.interact.mouseLeftDown = e.Type == sdl.MOUSEBUTTONDOWN + if r.interact.mouseLeftDown && r.interact.mouseDrag == nil { + r.interact.mouseDrag = &Point{e.X, e.Y} + fmt.Println("Drag start", r.interact.mouseDrag) + } else if !r.interact.mouseLeftDown && r.interact.mouseDrag != nil { + fmt.Println("Drag end", r.interact.mouseDrag) + r.interact.mouseDrag = nil + } + } + case *sdl.MouseMotionEvent: + r.hover = r.project.screenToMap(e.X, e.Y) + if r.interact.mouseDrag != nil { + fmt.Println("Dragging...", r.project.center) + r.project.center = r.project.center.Sub(r.project.screenToMapRel(e.X-r.interact.mouseDrag.X, e.Y-r.interact.mouseDrag.Y)) + r.project.update(ctx.Renderer) + r.interact.mouseDrag = &Point{e.X, e.Y} + } + case *sdl.MouseWheelEvent: + if e.Y > 0 { + r.project.zoom *= .5 + r.project.update(ctx.Renderer) + } else if e.Y < 0 { + r.project.zoom *= 2 + r.project.update(ctx.Renderer) + } + case *sdl.WindowEvent: + if e.Event == sdl.WINDOWEVENT_RESIZED { + r.project.update(ctx.Renderer) + } + } +} + +func (r *terrainRenderer) Render(ctx *Context) { + toTileTexture := func(temp, humid float64) *Texture { + if temp < .35 { + return ctx.Textures.Texture("tile-snow") + } + if temp > .65 { + return ctx.Textures.Texture("tile-dirt") + } + return ctx.Textures.Texture("tile-grass") + } + + variantToInt := func(variant float64) int { + if variant < .25 { + return 1 + } + if variant < .5 { + return 2 + } + if variant < .75 { + return 3 + } + if variant < 1 { + return 4 + } + return -1 + } + + variantToTexture := func(format string, variant float64) *Texture { + textName := fmt.Sprintf(format, variantToInt(variant)) + return ctx.Textures.Texture(textName) + } + + stretch := func(x, from, to float64) float64 { return (x - from) * 1 / (to - from) } + + toPropTexture := func(temp, humid, variant float64) *Texture { + if temp < .35 { + if humid < .2 { + return nil + } else if humid < .7 { + return variantToTexture("bush-small-%d", variant*5) + } + return variantToTexture("tree-pine-%d", variant*5) + } + if temp > .65 { + if humid < .2 { + return nil + } + if humid < .7 { + return variantToTexture("cactus-short-%d", variant*7) + } + return variantToTexture("cactus-tall-%d", variant*2) + } + if humid < .2 { + return nil + } + multiplier := 1 - stretch(humid, 0.2, 1) + if variant < .5 { + return variantToTexture("tree-fat-%d", stretch(variant, 0, .5)*multiplier*3) + } else if variant < .8 { + return variantToTexture("grass-small-%d", stretch(variant, .5, .8)*multiplier*2) + } + return variantToTexture("bush-large-%d", stretch(variant, .8, 1)*multiplier) + } + + // horizontal: [191, 321) = 130 + // vertical: [267,332) = 65 + + hover := Pt(int32(geom.Round32(r.hover.X)), int32(geom.Round32(r.hover.Y))) + for y := int32(-100); y < 100; y++ { + for x := int32(-100); x < 100; x++ { + if x == hover.X && y == hover.Y { + continue + } + temp := r.terrain.Temp.Value(x, y) + humid := r.terrain.Humid.Value(x, y) + text := toTileTexture(temp, humid) + pos := r.project.mapToScreen(x, y) + text.Copy(ctx.Renderer, r.project.screenToTileRect(pos)) + } + } + + for y := int32(-100); y < 100; y++ { + for x := int32(-100); x < 100; x++ { + variant := r.terrain.Variant.Value(x, y) + if variant < -1 || variant > 1 { + continue + } + + temp := r.terrain.Temp.Value(x, y) + humid := r.terrain.Humid.Value(x, y) + text := toPropTexture(temp, humid, variant) + if text == nil { + continue + } + + placeX, placeY := r.terrain.PlaceX.Value(x, y), r.terrain.PlaceY.Value(x, y) + pos := r.project.mapToScreenF(float32(x)-.2+float32(.8*placeX-.4), float32(y)-.2+float32(.8*placeY-.4)) + + text.Copy(ctx.Renderer, r.project.screenToTileRect(pos)) + } + } +}