From fb352043099de9f8e683acc4f453d0ab60d8fb77 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mi=C5=82osz=20Sm=C3=B3=C5=82ka?= Date: Wed, 22 Nov 2023 09:43:18 +0100 Subject: [PATCH] Add source --- assets/assets.go | 72 ++++++++++++++++ assets/font.ttf | Bin 0 -> 24612 bytes assets/laser.png | Bin 0 -> 318 bytes assets/meteors/meteorBrown_big1.png | Bin 0 -> 1804 bytes assets/meteors/meteorBrown_big2.png | Bin 0 -> 2323 bytes assets/meteors/meteorBrown_big3.png | Bin 0 -> 1713 bytes assets/meteors/meteorBrown_big4.png | Bin 0 -> 1990 bytes assets/meteors/meteorBrown_med1.png | Bin 0 -> 982 bytes assets/meteors/meteorBrown_med3.png | Bin 0 -> 881 bytes assets/meteors/meteorGrey_big1.png | Bin 0 -> 1786 bytes assets/meteors/meteorGrey_big2.png | Bin 0 -> 2310 bytes assets/meteors/meteorGrey_big3.png | Bin 0 -> 1699 bytes assets/meteors/meteorGrey_big4.png | Bin 0 -> 1967 bytes assets/meteors/meteorGrey_med1.png | Bin 0 -> 966 bytes assets/meteors/meteorGrey_med2.png | Bin 0 -> 864 bytes assets/player.png | Bin 0 -> 2698 bytes game/bullet.go | 71 ++++++++++++++++ game/game.go | 126 ++++++++++++++++++++++++++++ game/meteor.go | 93 ++++++++++++++++++++ game/player.go | 102 ++++++++++++++++++++++ game/rect.go | 32 +++++++ game/timer.go | 33 ++++++++ game/vector.go | 13 +++ go.mod | 18 ++++ go.sum | 50 +++++++++++ main.go | 16 ++++ 26 files changed, 626 insertions(+) create mode 100644 assets/assets.go create mode 100644 assets/font.ttf create mode 100644 assets/laser.png create mode 100644 assets/meteors/meteorBrown_big1.png create mode 100644 assets/meteors/meteorBrown_big2.png create mode 100644 assets/meteors/meteorBrown_big3.png create mode 100644 assets/meteors/meteorBrown_big4.png create mode 100644 assets/meteors/meteorBrown_med1.png create mode 100644 assets/meteors/meteorBrown_med3.png create mode 100644 assets/meteors/meteorGrey_big1.png create mode 100644 assets/meteors/meteorGrey_big2.png create mode 100644 assets/meteors/meteorGrey_big3.png create mode 100644 assets/meteors/meteorGrey_big4.png create mode 100644 assets/meteors/meteorGrey_med1.png create mode 100644 assets/meteors/meteorGrey_med2.png create mode 100644 assets/player.png create mode 100644 game/bullet.go create mode 100644 game/game.go create mode 100644 game/meteor.go create mode 100644 game/player.go create mode 100644 game/rect.go create mode 100644 game/timer.go create mode 100644 game/vector.go create mode 100644 go.mod create mode 100644 go.sum create mode 100644 main.go diff --git a/assets/assets.go b/assets/assets.go new file mode 100644 index 0000000..15d3307 --- /dev/null +++ b/assets/assets.go @@ -0,0 +1,72 @@ +package assets + +import ( + "embed" + "image" + _ "image/png" + "io/fs" + + "github.com/hajimehoshi/ebiten/v2" + "golang.org/x/image/font" + "golang.org/x/image/font/opentype" +) + +//go:embed * +var assets embed.FS + +var PlayerSprite = mustLoadImage("player.png") +var MeteorSprites = mustLoadImages("meteors/*.png") +var LaserSprite = mustLoadImage("laser.png") +var ScoreFont = mustLoadFont("font.ttf") + +func mustLoadImage(name string) *ebiten.Image { + f, err := assets.Open(name) + if err != nil { + panic(err) + } + defer f.Close() + + img, _, err := image.Decode(f) + if err != nil { + panic(err) + } + + return ebiten.NewImageFromImage(img) +} + +func mustLoadImages(path string) []*ebiten.Image { + matches, err := fs.Glob(assets, path) + if err != nil { + panic(err) + } + + images := make([]*ebiten.Image, len(matches)) + for i, match := range matches { + images[i] = mustLoadImage(match) + } + + return images +} + +func mustLoadFont(name string) font.Face { + f, err := assets.ReadFile(name) + if err != nil { + panic(err) + } + + tt, err := opentype.Parse(f) + if err != nil { + panic(err) + } + + face, err := opentype.NewFace(tt, &opentype.FaceOptions{ + Size: 48, + DPI: 72, + Hinting: font.HintingVertical, + }) + if err != nil { + panic(err) + } + + return face +} diff --git a/assets/font.ttf b/assets/font.ttf new file mode 100644 index 0000000000000000000000000000000000000000..33c1fd603d1f7630dbbbccc9a79705d46226eb62 GIT binary patch literal 24612 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 Q?f?J)07*qoM6N<$g3)z?{Qv*} literal 0 HcmV?d00001 diff --git a/assets/meteors/meteorBrown_big1.png b/assets/meteors/meteorBrown_big1.png new file mode 100644 index 0000000000000000000000000000000000000000..31e06a4895c2f2b958aa13b664b40a385b3507a4 GIT binary patch literal 1804 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

6hYj}Y z@my*E_|NOp?8Dk5dvh}^(2zyK!HLDgoA8Zv--!+20zeVCqWJM>wgY-7pvmf?fN|PL z_nFur118`mq^>g!e$g?${^D>;|pAs8+FZQRe&jUY$8m6Hk*Bb91`3ln*p}&?}i`Oxj!_PwAf62 z2p2^LbPkVSNN|&klzDAY;5EAajV_y2nnx}`&Kq2x$x{@_VbrDb3UXGJR-^z?Ov~*| zHk*R%%Z}w0U+-TtZXRW_nbzfWo9-^Ewb(+pCjvHe<@QzuvO=JEF)g>Ht%Jg2BkMgKN-kac^^!sZdN*`!IN z!bX|4nf88TZWsxgM=h@)%h=4XqLj_b@d>bN=X`;z`q;%NA2#D*{5oLQ%J~F2ixDPk zaxv>MUzA{u(5gvfQ&z|9H1K(BC-_sFMZQ56u{kz9R>>jCP5j}$P3v~2E(75t@S2z% zh3zQUe@9WYXmdzA&YK+jbN!Z*nO@OxgjGKq# zAbjb&ZP}c(Y)E$6JE8W^4BE5Z^{=YWNIvLzC4DM@@X~bd+ zm}siQt~SA^u0lIF(`_%NQ(2&?x=GPR*?eF#j?PBOQ2Oke)v8I+cEwp>*>-wdUq1BN zMIb54z;;nKJF#p<)MrsrB{xF@<}ME-v9@eQ)#uO$idb8=qUv+Vqj7?rgcz$n`wH51 z>ddm0MW0=s4@XaK@RJS?i#{8l(o*TOzGchxpzAX0v(i@H(E7|DZ-)5;$OvY_ig<=6 zZ`qXy7dNdu^;PnJo|-%+tuZU{ruVW6@nhwk1;Es$?h+S<>>(|Go}Xs001p?MObuGZ)S9N zVRB^vVtFoNY;SL5WO*)Qa(QrcZ!T$VVP|D7P)Z)9b1s0M%T00000NkvXX Hu0mjfZlqIp literal 0 HcmV?d00001 diff --git a/assets/meteors/meteorBrown_big4.png b/assets/meteors/meteorBrown_big4.png new file mode 100644 index 0000000000000000000000000000000000000000..e643572633e8a4fe8c7dd309ada259b6ccc85b7b GIT binary patch literal 1990 zcmV;%2RZnOP)B@ow?;kN(^b{e-7~XNJvj01j;ngUufD44o~5Opzjnu~YkQOByW6K< zcz$VkwfEY2rnY&Of?(W@K#Jef#AP2MtaQv0Y@_$w5UqAPXxv}x; z{AUDe@S3jU52yCD>iBDCSIzAUubXc#kIj!)-!VU5-xCdD?t)Y0dnwcXsahs{M5B-2Bc!Fb2*DAXt~$gJp^z)77U*t*OHxjdzmDIM<%Mv;P#G8-4c+K#t# z`CJVdSTVs^M6h-)UxMRZmaX8k33id=Lv#5d7$LAT4S*}9?3&|UW~=Yy8iO*On7Mqe zmW}$xElFjBJ_R7VV1STu0f3>t1|kc=M>?RC?B}-|=gs|3-!p&SzGxob**1TFeR=kC z(ZN8bM9Mcur~mTNhWY)IP4maCE%WHhZS&Xu2Q$aJ48NoCo#4p1`ktaitFVOfL$0em z#PGf%)i?EdQ>Lg`^}f}fIvA*#_M+quB?2cKP- zIRvX6kW=@&T6aR#0BuDC16cvS0HtXSTtE1Hs}|ScY*#Swz8FE!4hA&VaVGUtU1Lx^ ziM!&l(nFkrVBmfB=REo9Qq(|b1tXf^1NlhQG$4oT7|Qt(l-NP=-I3g2pcSCQ50lXW zJ`kA!=c1&zj$nk|Q8@$yqE}V$QIU_+J-c^vvsDM?77R7@O+`MgnwG#)F2TTJ(h3G! z@DVI=i+r)t&9+TipAxHYD)MpEbjh$3Js9KFwcsKjS521=OD==(lmr9Kv|zy}De@r~ z?^+PF>Qlk$n?_+c?acPDeK*AD`XQK6V2OGUoROIvVaYeKA*ldx z`C;BXs+;_f6!~(5CEwjZ@WlOmaE%0(YImz4>oXN ziPJD@2usg;51f%1X)fM&KLK|Eh*t7>oYDrtQf+gHdJmkD8A;ZWA{dgpK%%B?SgNhK zQjw1{G6QAVmm;4;O`pKhg3}BnMZOYXN!vJT+6zn6d*G<)l3*!iwY3o}QIU_Mruzs> z95vk(me@tUKEe`5O?zR`PabHKni^k{uvQM@u_ZT0HO+#hnB*N}#IXc5&4#5| z5A@{V!VQj_r+iO399)APM?F^-kfB=5G!8W~zOb8ACQ(+LC79*v_#-fcCK zT#yplHwjhKQDG?tdB+|&STu?s!c(DYnqaA|0~S@tJ7$&EC%~FyQXDl+u+-Yg$QtAw zvr6kD*e01&sG2^3r52w_WRtg~*BwJwG|l?~JILZ-G!NT!FGX@#s**PagL|@B3~eEC zro>u@C2jHsOoSE#0V}|Hzz0?|$X~jmC6)x1>U!Rg^<46{b9@8^P6osfbdZxZjslJO zq?P2)AEHxiI2+`cQ-(%jP9K;-=9Q zU#a9>idpAr!`z_ri@!w|#Y0z;-0tsPn#d6R>I*KjaCn^rMZ zLz^0|&vNoz*z76vb6G#=MtN7Uy=BG|xU)i5MaX#dr^e(+@@+Jq{ zt2orb=oB8W;3HbajrwS7YVy{KQKGBibQ YV{c?-a;OG>?f?J)07*qoM6N<$f_^K%Jpcdz literal 0 HcmV?d00001 diff --git a/assets/meteors/meteorBrown_med1.png b/assets/meteors/meteorBrown_med1.png new file mode 100644 index 0000000000000000000000000000000000000000..14fa6f5c662c47c759a54d05285bef0837c5ad5d GIT binary patch literal 982 zcmV;{11bE8P)W*-@mVS5{;W>t z%`otepi#{3x3Mdz74j9?WbNXq)2R`y7xR0NS)V;?Hs{X=SeuzJaU0N}QOqA&n>=7c zUPOrq3qtH=W5&E$pBsqRYqRD>y%gZ-(v)ddF9)zU$)@8r;4HD}+=*i=#q3}H`Pp(I zl4w%co7`Tw(2aI>*Gs2c<;m2DhVi^s4D_!i%FaZm9Pzlw5?#@;PN(f`73~buX{*V{gm3Gm$ zx97}{ooWwJ8$TZ}nJ-(F&W3y(VW53UIo+5$=d>ut9z`?^-bF5&b#b7s3|f)p^wsKB zHPO%a7t}<<(e|=0>aR~Z{kU27BI-i6&%S8m_yhG=OO$L6CzK0FJ{SAq~)Y{{Z zODL^&T^u2>FL3~^1in4Ik%%b39W>vf#q5&Z?u8Jc}N>=N?efC9yi4-&yD@kGr zwDyHGJ7n7iVD$oSQXrd?kaZ~#efCwqa^{vxLEspZkaa0KaO!DjD77xGfFt-?m)2t= z?aOWp$w18_dk-q9+E%1}`A7lXxfTL#V%Z>%x?~S}x-QoOq48W_lCj;Fs}vwHiVkZS zu+xF}F;^*oaOs7lYwtRYsC8p#^)=wGQV<&(B}qAcdur3;2EI~|WE&MpqA3#@nH@yl za77C2YTP$kCNcJ)Pc=T0W_(=34J0S#FPX0%%1J}+a&hzpa+7EhB)UMa5oelG;MDAB zk}D**-;_JWF{hMJiRQpecX?!jC=o^yE;rvOJCZI+1{mJa9OMk)-x2s2(RLXv+2$?= z?>&Z(d&tc0j~FfaAW4BA#*LYBQHY?(Nl`%ygD5V|Dlqh9+TGo)^Bip-Ia0000jbVXQnQ*UN;cVTj6 z0AhJAVr*}3WMp|RV{&KQKGBibQV{c?-a;OG>?f?J)07*qoM6N<$ Ef~vIA2mk;8 literal 0 HcmV?d00001 diff --git a/assets/meteors/meteorBrown_med3.png b/assets/meteors/meteorBrown_med3.png new file mode 100644 index 0000000000000000000000000000000000000000..5ec2d1ecd7d5f623cba428dd93aa42cb0f22fad4 GIT binary patch literal 881 zcmV-%1CIQOP){GcSMVtuLEw3gVksi`F-Ewx&!wc18Ogd$i$MMbfqqWGyt=n*`E zNAL(9Vch@3XBan|*=J^Fr(JkRX~OJpX8zCHOsRATPq#KU(Y} zFU*45XpW11`?7f2iNv$slz6$?P_{LHNr7X0FOalyS#Vgj&AAIB;Y@}}VT@i>{goRU zgP7oUx^?k<`6?T3l)YG)mOC;4FYh}8!>cjK%G8)QIFn&#@Gc1+%g=F@%ljArt6C(i zZde=@QDWb*h9(U|pP`^(j~6DCW46an9(R&PNMJJTE;%MUq8x@a432qlq@|GrSB@En z-9n}D>Q+O%z0;KT{_d>!xY3gKx$Wm-*Lf#4{(xRNn&yO^<}jx>dvVcvOep`YIdm&^9`O_4EcKC z7)5}qGitpUDhfPr_DmK-Ue2aX;FLW9j&zHcBV5_Ub^Vky$i0i6_R|b7*mk-BNSlZ)9b1s0M%T00000NkvXX Hu0mjfyCb4} literal 0 HcmV?d00001 diff --git a/assets/meteors/meteorGrey_big1.png b/assets/meteors/meteorGrey_big1.png new file mode 100644 index 0000000000000000000000000000000000000000..74371c312858f0a6f125815701f0a6d7fafce22b GIT binary patch literal 1786 zcmVtWS2!?1O*gJDNn!=JOW4X2xI@dcvG<_ zy(D?*B;7MrudGsQdOH8SU-Fht4-GMVUQV^1jx}dzs%p5up^!e~&GzWT^!skrExOM? z;fT^||HY43Fxy_uPhg@M<2FUYIL^fUa}cMGfCwS$w&+U)vv&tqOpww`z`%2;Ez zgC9D#u~TVLU{mueVPK5VwX%O)c~O>k5B z8e@bm{J1)b;w8oiU2x^PisBWSxpc6h3EU+*{f++i$2*QN=& zfECk06AftE|9TUPg+IBz7r!$YjG3ZKh3~En9_c;COwon)ArwJiK&$r{GesA+pCO3? z0}{Q)m?^qA7GW2L$>b%*2wiX6i`rY>qB|`gF{ZjTF9lub&(;^6@?XJrs&cgxFYQ4PHx&3g#}|A z=+a586bjZ3Pn`s#CZe!lj00Udsg)wtKUaA)Q&C{erFDIbnW9T4wSx7>=Mn&iD8Lx# zql_^^7Z_;LpkSjEo7`f<8)^N*zfr-<#&(%Q6xhPnzB_NCxx|$Y8)s+ z`BHM$>4c%6vd>$_odos>lAGJPgKq^^1&yhNz2+(`pQmS^Ily?LE?Un*XLp6o0y8Rb6CBh+T@GQA`- z=f#CC9~v7%@e;9#V!Y8F?h}Pv$i_4AAwH8*hL_-Aw+BJ)(~cXwqbIa%oU@W83^oSv zC?xQZGYd8FRDFhpQYum}p`sR@AYmHKX9blQaLg#IH@Jyp88_4zN7YLxrGhapRBf~= zjE{X>F1@5sCktGOgfZ#$a-9hP4(V_N>TaP97itW5{D7USaEewa3#GNFHMJ3gVL*k*BrgOlKn0PGgC9*?t zVE8g$y+p@5Tv@NOm`u;>2!kNUq;=I+kZIjJn9l}Ft-<>$j7pFhl6SCri7X9cE4UPe z$wOI4-XW$`*dIp4qEwbJ6l7MxJNi;8$@Dz8Ft(2q?Ca4D%sXU>M=P)Uh=sA7j!D*K zLiLWmlnS?(l$|H5l2J+phoM?O_e*?d%3$zwyd*6>Z|hW}I-Yf}e3*1vdfw6@I>Q5D zvQsLhc}bcuHiJvf!J=0>A!BRnHw#CukGeXic({zH-z3F>BNl1Vl^OmG1BsFa{x8JS zEss-5MJYXR^N=>5gaK0N=#9i%=KQK cGBibQV{c?-a;OG>?f?J)07*qoM6N<$f^;iANB{r; literal 0 HcmV?d00001 diff --git a/assets/meteors/meteorGrey_big2.png b/assets/meteors/meteorGrey_big2.png new file mode 100644 index 0000000000000000000000000000000000000000..bcc8dc75474a9d3d8a5fa4135f19ec1245083212 GIT binary patch literal 2310 zcmV+h3HkPkP)%xV#&%V97`Q_z}*~RbHuYI+WuQac( zudII#ATMofZ(Um7J}CkHaCvj~-<50E3)Aqo^55s*tZjag-&%whfWb@zkl%0Yya$kV z5bL(KbGx{D<8JZe?ABSZ*Jq#bJs2GM%?^B3ZgqXO3IM9vxH0?K2P8n;xV>9!-J2IT z9~=~S9vv0;51*bf{2ib9Ve7_Ou*>g<8_!?|ijQ!c6_Dku>H-nK0LaZdd&Tzd!wRsw z2gm1tl-Tw8;|lEhZ&aS499+1+jFQLr*yL6*8+Z2hDqR0Bay;Crd%jwDHk&t6lLiHp4vv>_&1{hLp+0YmDA5 z*NPWGx9S=nV>5Ub4A666Pl=q70Kt9Ht%i<|Fod1duDl1lpaykkT$TpkSZkkQmJp53|z)Wz3T1H z(ux`Y$o2uu9M4wro2pd}fQkY?15N|I7hBV^KEA3$9L zV~Vp^D^H4w`()12P7NDTLpmz!F|}=AOm+5}eO}&*`xG{$^=%geUoTO znRM>E8c&{Fs8^EWe!b8jZEVk#pYh~LqqslUtUIb!>?5}d$)vM2o2LI+T-r9ua7K_P7sY+)(i9ga4L3a%c@Zp@ zagZCPfoEWL+3d9?Rjw-aN?3@oUb$bFEHz6+@iJ0o)F!af{kkx)34B*)3sOmZ2A{=X z!Az~HW0q@ztyk{XB}*xjrmB@`jNR1g zm8)c#QmT|Pu+}U0yNH%#!C4BaQtH53uiWpGEG0}jmZ}oM1UD&V9E^2aU|UnK-0zbt zLpI>~26xCksK(lRQnhklB3VioeUC}9kcNcbb1H^iWa*x*HWqD@ETv3(tQ@#%FP)eh zHn;Kzs15r-udevGC|Sn3Wy93Kg$stb)O50`c_4@Pa~LEWuMAx_)JS_VpP9rn80s5% zo7?k4cnWgL3MEVFX5T1Q584y*hk7z5(kRE-QL?l>=nBl%=enU(z=g+aI@HQ=yC=ciu8m{~cj9_l3SzWNDy8Wa z9*Z2Yg|*S`#(HiriI%TpaS*4qRVPg&+K^`!wUQ&a-I5$deTryZvJ`J&sMw@bLdaqP zw=E|%-ENWxKAYzv`39MUtSL^zosS7F&mU?dM|8VU9slYui|1^_3w7u-2^oMLLs#z2 zNmFvWma5h&7l;QvX{C(QL+Q%QN!!Q~-ENfRC{)@+`4X`xwPR$NlQtdIx{v~=;&xq% z5ZucHFDdquzL}FYlA}|%JJ=b#NyX(;88gN+gWClA!KJ{|FAxsKWyG=3&ki;gWSMRk zgK??duFHj)09O|>m6EdH#bW4k&_yE!P9-i=5YcSn;uBnBDaWTgTLY$21R1V!2$y{Z z+|rZeSv#Rr3gKYUWthPo)@8FufmABQ>EHmDxh#GwgFB+c={uD&!F6r`&zIW;HtRE$ z0)flm#u%49q*7cq>9n#gU&EwQ+T&?WaJ{yU=F4*`by{E6q*CnY&)_B~aUzxKa@mv~ z@%apHda2aMu2jkdH>*<rc$R8XOKQKGBibQV{c?-a;OG>?f?J)07*qoM6N<$f;OR4!~g&Q literal 0 HcmV?d00001 diff --git a/assets/meteors/meteorGrey_big3.png b/assets/meteors/meteorGrey_big3.png new file mode 100644 index 0000000000000000000000000000000000000000..0bb867420be538f657f0563d8156763c1ba15fe8 GIT binary patch literal 1699 zcmV;U23+}xP)}Aa>888te(4O;XHK7c@5xPOVj_X-*3`_E$!_oN%?F*!6Yb^qx^ZLb(*5rI$%7|P z1;u2icXqEc*9Y(|Ld*-yot)|Y1+Wii7sT|!vXH^f03ZDO0Py`gohR4ug|w*INy8rk z65uXv?uyl&cUe5`Z;9^nwG8+?=wSVT>DOCX(OmbsbF%~(Km?!!Zc!|5?1-7Ab@8aT zIL`8J?-cLX%F6J%Jw0<3T1x-{xaI9VEx`Ez+vnC^iK+SLy=zrtNL)?rmv4sxO@j_XF zj@P|B%qKQH(y_qR>3CUrSj)tQN7pv7g$`NAYgHZ&6IYd^ zfA?9e?!J!-G-Q!*@KWO8O=KfIbYcUz08j<4Dt3>4WuV6bno2!1FkX%Hkcka4-~w(w z*4})G0x}vI7Mq7g`nkjw%5MND&|5CJ6nHP)--En>@pxjmpPkA&Yc`|MmJ?f$BT`Kc#O*L6j?-5z7Ji%Dbxl!_IpgUnghQkqAhKvuP?se^2580Fba z?e;kxZL33#%~?Afwc9eALx7ysoQgIT{%z_Y+j`6@^Jv6o7n8_@jXG^}^?p+} zjEdNd@rs}z>)0%>qBO0PlM~>moC^iA>0_6od~n9YOsp+vv4lyG*xuW2Xa!K{^sTWTf zB~FtJdsp|ZwA165M7C2pO>Lv|CEKVj_T?!fq17E=5QRH_tM!t(AU9z&z;@n3Te9g^ ztT`Yf8`pKf#dYD-dbQfe;9(v0IV&rfdr!`lY$h{t-09A`>9dbrRoaqGHw?}hJgkd8 z``FM^TC(Z3HQvO@txQhYfW0}fF+iX4f9ZR2m?xX?}U3J*kCiuctXzmFC zKJ?jVKvQj#qK~#YKOJPXQ8Jc3`)0LiQsk~U7nN-64eYV>*+(EL>cIBVHhU@AYN^kP zq)OEc4Ve2pjD%gX)m5KkA1J~u*=noL5s$`+b`oN$`Wz}oyH0(TY)#Q;pXbBTlN3KIhI2C8fO9xl00^q|JAof?O@s*Wqz7i#v0r0b5PLPfUE@MA# zoY)`oYDO=WiC)oM=~@;Zewp`Wpbznf9?PP002ovPDHLkV1gLNJv#sZ literal 0 HcmV?d00001 diff --git a/assets/meteors/meteorGrey_big4.png b/assets/meteors/meteorGrey_big4.png new file mode 100644 index 0000000000000000000000000000000000000000..6b7e708515c816a8faebbb73872d8a97960d98ef GIT binary patch literal 1967 zcmV;g2T=HlP)@A`3Vu5W)oc_`3@l@15P@v9r#|5ly<>-G(^wsW)m8iAU;rs((!>su$q zzhA13|7G)qi7>w)OxwSJtuU|P^IDTG0&gVME z|91V3+1kBlZtNeHj<4G7gX8kaKrklG@F3Va$HTff-WiPIvk~OU+cgAR*lC^PFJHTD zHt)>M^}7dNj&BMEo}wujmCUA&U^N|IXLyn*7`TUtV3!8C*toT4uFfAUR%{68w*>?D zHGG0i#PM~8%!=*_oHQJQZOCkp%Tr3(r{i70$WriGnaydN-{#S~PYcJ_8NNs3cY-5JjZvUQR9Hg!A=TCHWB9o&)i?EddreV`RqtBu zeFp<|w4jALDo^zJ6aZ2*0`OHZiU4OJ_(;UzmuWi}xPI^C^}-=o?SP!7@6~z|ss?Dw zA{fXD@C#6y*1+}q&)+uUI-Fe>4E$V(AZP~z8f(cHU(_`Q)swg@9xL6)DF_CB&i)OZL+cqU(oX27x8&J#a>5QiLVf#D=5-z~zUsdDJxdAu94E2urS~f#8Yz z`QRD}EH&<4r6M0kO{WM;UFVm$#LX#_(|!wxIcM*IQ{+n#ma6Sm&3j)wZIX#{7c8;V zbfVc(r{+#^@0>tzl(jA58exfwd>l2Ma&4(@5Wya7;KCB8Vbl$lmc0kg$c!`>kKRux zo&pf9jvW`B2A$bZUYTAaS#)>Ny`8XppP?lpU@=4S*!BXpK z29hFQ4zQ$c95wBPCF(tJ)O1d;)MvG|6D(1YkE5o?2umC_-3gW?MZPh@5=TutVaYD? zany9|QOG1}S4>!fpPd87+>se@#88IFLaAwjrPh&4Ns(_X6B|-BjYaO<(nUo+=?0WB zOl@$~G~nI|OLlKsyg{+J!J$JGM@<81I!%HTG=bHnhgJ=3)>T7IcY>vAu}|ZCjUhvn zubM7lsjV+vRo0ZkVn}v^C>=Fz!P4A&Ly87*$K3ChvYIAX^4{i46AqZH_5;*i#(?AdBxJ=*V9pbE|PUABIk?E_Z zt-W#j$I5AvcPz3-hE~noVyJ04VIbJ6akR)gRwJnnQhfU+zG^xsEQKKN&;ti;qxe2N z<*TMkSc-ALq853FtkSv!SeHzSqoxU#qMeMaLf!$Zv`&KUkV*NfX@aGw?^*k!%{LY4b&p<+>AD^2R)d*@3MIguej+n#g{92=VEl8MzZfR9SeCU2}@%m z?-G_Y`qC45tH9EHCG~4)MVycFAc5rcjrITk{n=oWUIKw*| z_|YbB?82~&E3kS?3N$-(w2W;pmW9E|catzvR;cCgVGdAB;a zcyg*Rfgp~06^FQhz2snf75Dz4?jEoI0Gu4>xlaN=f&c&jEp$a#bW?9;ba!ELWdLG% zE@EtNZ)9Y7E@N_eaCC1jX>DO=WiC)oM=~@;Zewp`Wpbznf9?PP002ovPDHLkV1j2) Bs%roM literal 0 HcmV?d00001 diff --git a/assets/meteors/meteorGrey_med1.png b/assets/meteors/meteorGrey_med1.png new file mode 100644 index 0000000000000000000000000000000000000000..910474658eecb7fed8732f2dbd7427be173cfb01 GIT binary patch literal 966 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 Ef&*|u*#H0l literal 0 HcmV?d00001 diff --git a/game/bullet.go b/game/bullet.go new file mode 100644 index 0000000..c2be9cc --- /dev/null +++ b/game/bullet.go @@ -0,0 +1,71 @@ +package game + +import ( + "math" + + "github.com/hajimehoshi/ebiten/v2" + + "github.com/ThreeDotsLabs/meteors/assets" +) + +const ( + bulletSpeedPerSecond = 350.0 +) + +type Bullet struct { + position Vector + rotation float64 + sprite *ebiten.Image +} + +func NewBullet(pos Vector, rotation float64) *Bullet { + sprite := assets.LaserSprite + + bounds := sprite.Bounds() + halfW := float64(bounds.Dx()) / 2 + halfH := float64(bounds.Dy()) / 2 + + pos.X -= halfW + pos.Y -= halfH + + b := &Bullet{ + position: pos, + rotation: rotation, + sprite: sprite, + } + + return b +} + +func (b *Bullet) Update() { + speed := bulletSpeedPerSecond / float64(ebiten.TPS()) + + b.position.X += math.Sin(b.rotation) * speed + b.position.Y += math.Cos(b.rotation) * -speed +} + +func (b *Bullet) Draw(screen *ebiten.Image) { + bounds := b.sprite.Bounds() + halfW := float64(bounds.Dx()) / 2 + halfH := float64(bounds.Dy()) / 2 + + op := &ebiten.DrawImageOptions{} + op.GeoM.Translate(-halfW, -halfH) + op.GeoM.Rotate(b.rotation) + op.GeoM.Translate(halfW, halfH) + + op.GeoM.Translate(b.position.X, b.position.Y) + + screen.DrawImage(b.sprite, op) +} + +func (b *Bullet) Collider() Rect { + bounds := b.sprite.Bounds() + + return NewRect( + b.position.X, + b.position.Y, + float64(bounds.Dx()), + float64(bounds.Dy()), + ) +} diff --git a/game/game.go b/game/game.go new file mode 100644 index 0000000..9756784 --- /dev/null +++ b/game/game.go @@ -0,0 +1,126 @@ +package game + +import ( + "fmt" + "image/color" + "time" + + "github.com/hajimehoshi/ebiten/v2" + "github.com/hajimehoshi/ebiten/v2/text" + + "github.com/ThreeDotsLabs/meteors/assets" +) + +const ( + screenWidth = 800 + screenHeight = 600 + + meteorSpawnTime = 1 * time.Second + + baseMeteorVelocity = 0.25 + meteorSpeedUpAmount = 0.1 + meteorSpeedUpTime = 5 * time.Second +) + +type Game struct { + player *Player + meteorSpawnTimer *Timer + meteors []*Meteor + bullets []*Bullet + + score int + + baseVelocity float64 + velocityTimer *Timer +} + +func NewGame() *Game { + g := &Game{ + meteorSpawnTimer: NewTimer(meteorSpawnTime), + baseVelocity: baseMeteorVelocity, + velocityTimer: NewTimer(meteorSpeedUpTime), + } + + g.player = NewPlayer(g) + + return g +} + +func (g *Game) Update() error { + g.velocityTimer.Update() + if g.velocityTimer.IsReady() { + g.velocityTimer.Reset() + g.baseVelocity += meteorSpeedUpAmount + } + + g.player.Update() + + g.meteorSpawnTimer.Update() + if g.meteorSpawnTimer.IsReady() { + g.meteorSpawnTimer.Reset() + + m := NewMeteor(g.baseVelocity) + g.meteors = append(g.meteors, m) + } + + for _, m := range g.meteors { + m.Update() + } + + for _, b := range g.bullets { + b.Update() + } + + // Check for meteor/bullet collisions + for i, m := range g.meteors { + for j, b := range g.bullets { + if m.Collider().Intersects(b.Collider()) { + g.meteors = append(g.meteors[:i], g.meteors[i+1:]...) + g.bullets = append(g.bullets[:j], g.bullets[j+1:]...) + g.score++ + } + } + } + + // Check for meteor/player collisions + for _, m := range g.meteors { + if m.Collider().Intersects(g.player.Collider()) { + g.Reset() + break + } + } + + return nil +} + +func (g *Game) Draw(screen *ebiten.Image) { + g.player.Draw(screen) + + for _, m := range g.meteors { + m.Draw(screen) + } + + for _, b := range g.bullets { + b.Draw(screen) + } + + text.Draw(screen, fmt.Sprintf("%06d", g.score), assets.ScoreFont, screenWidth/2-100, 50, color.White) +} + +func (g *Game) AddBullet(b *Bullet) { + g.bullets = append(g.bullets, b) +} + +func (g *Game) Reset() { + g.player = NewPlayer(g) + g.meteors = nil + g.bullets = nil + g.score = 0 + g.meteorSpawnTimer.Reset() + g.baseVelocity = baseMeteorVelocity + g.velocityTimer.Reset() +} + +func (g *Game) Layout(outsideWidth, outsideHeight int) (int, int) { + return screenWidth, screenHeight +} diff --git a/game/meteor.go b/game/meteor.go new file mode 100644 index 0000000..6d82a02 --- /dev/null +++ b/game/meteor.go @@ -0,0 +1,93 @@ +package game + +import ( + "math" + "math/rand" + + "github.com/hajimehoshi/ebiten/v2" + + "github.com/ThreeDotsLabs/meteors/assets" +) + +const ( + rotationSpeedMin = -0.02 + rotationSpeedMax = 0.02 +) + +type Meteor struct { + position Vector + rotation float64 + movement Vector + rotationSpeed float64 + sprite *ebiten.Image +} + +func NewMeteor(baseVelocity float64) *Meteor { + target := Vector{ + X: screenWidth / 2, + Y: screenHeight / 2, + } + + angle := rand.Float64() * 2 * math.Pi + r := screenWidth / 2.0 + + pos := Vector{ + X: target.X + math.Cos(angle)*r, + Y: target.Y + math.Sin(angle)*r, + } + + velocity := baseVelocity + rand.Float64()*1.5 + + direction := Vector{ + X: target.X - pos.X, + Y: target.Y - pos.Y, + } + normalizedDirection := direction.Normalize() + + movement := Vector{ + X: normalizedDirection.X * velocity, + Y: normalizedDirection.Y * velocity, + } + + sprite := assets.MeteorSprites[rand.Intn(len(assets.MeteorSprites))] + + m := &Meteor{ + position: pos, + movement: movement, + rotationSpeed: rotationSpeedMin + rand.Float64()*(rotationSpeedMax-rotationSpeedMin), + sprite: sprite, + } + return m +} + +func (m *Meteor) Update() { + m.position.X += m.movement.X + m.position.Y += m.movement.Y + m.rotation += m.rotationSpeed +} + +func (m *Meteor) Draw(screen *ebiten.Image) { + bounds := m.sprite.Bounds() + halfW := float64(bounds.Dx()) / 2 + halfH := float64(bounds.Dy()) / 2 + + op := &ebiten.DrawImageOptions{} + op.GeoM.Translate(-halfW, -halfH) + op.GeoM.Rotate(m.rotation) + op.GeoM.Translate(halfW, halfH) + + op.GeoM.Translate(m.position.X, m.position.Y) + + screen.DrawImage(m.sprite, op) +} + +func (m *Meteor) Collider() Rect { + bounds := m.sprite.Bounds() + + return NewRect( + m.position.X, + m.position.Y, + float64(bounds.Dx()), + float64(bounds.Dy()), + ) +} diff --git a/game/player.go b/game/player.go new file mode 100644 index 0000000..d81ddb3 --- /dev/null +++ b/game/player.go @@ -0,0 +1,102 @@ +package game + +import ( + "math" + "time" + + "github.com/hajimehoshi/ebiten/v2" + + "github.com/ThreeDotsLabs/meteors/assets" +) + +const ( + shootCooldown = time.Millisecond * 500 + rotationPerSecond = math.Pi + + bulletSpawnOffset = 50.0 +) + +type Player struct { + game *Game + + position Vector + rotation float64 + sprite *ebiten.Image + + shootCooldown *Timer +} + +func NewPlayer(game *Game) *Player { + sprite := assets.PlayerSprite + + bounds := sprite.Bounds() + halfW := float64(bounds.Dx()) / 2 + halfH := float64(bounds.Dy()) / 2 + + pos := Vector{ + X: screenWidth/2 - halfW, + Y: screenHeight/2 - halfH, + } + + return &Player{ + game: game, + position: pos, + rotation: 0, + sprite: sprite, + shootCooldown: NewTimer(shootCooldown), + } +} + +func (p *Player) Update() { + speed := rotationPerSecond / float64(ebiten.TPS()) + + if ebiten.IsKeyPressed(ebiten.KeyLeft) { + p.rotation -= speed + } + if ebiten.IsKeyPressed(ebiten.KeyRight) { + p.rotation += speed + } + + p.shootCooldown.Update() + if p.shootCooldown.IsReady() && ebiten.IsKeyPressed(ebiten.KeySpace) { + p.shootCooldown.Reset() + + bounds := p.sprite.Bounds() + halfW := float64(bounds.Dx()) / 2 + halfH := float64(bounds.Dy()) / 2 + + spawnPos := Vector{ + p.position.X + halfW + math.Sin(p.rotation)*bulletSpawnOffset, + p.position.Y + halfH + math.Cos(p.rotation)*-bulletSpawnOffset, + } + + bullet := NewBullet(spawnPos, p.rotation) + p.game.AddBullet(bullet) + } +} + +func (p *Player) Draw(screen *ebiten.Image) { + bounds := p.sprite.Bounds() + halfW := float64(bounds.Dx()) / 2 + halfH := float64(bounds.Dy()) / 2 + + op := &ebiten.DrawImageOptions{} + op.GeoM.Translate(-halfW, -halfH) + op.GeoM.Rotate(p.rotation) + op.GeoM.Translate(halfW, halfH) + + op.GeoM.Translate(p.position.X, p.position.Y) + + screen.DrawImage(p.sprite, op) +} + +func (p *Player) Collider() Rect { + bounds := p.sprite.Bounds() + + return NewRect( + p.position.X, + p.position.Y, + float64(bounds.Dx()), + float64(bounds.Dy()), + ) +} diff --git a/game/rect.go b/game/rect.go new file mode 100644 index 0000000..0ee8972 --- /dev/null +++ b/game/rect.go @@ -0,0 +1,32 @@ +package game + +type Rect struct { + X float64 + Y float64 + Width float64 + Height float64 +} + +func NewRect(x, y, width, height float64) Rect { + return Rect{ + X: x, + Y: y, + Width: width, + Height: height, + } +} + +func (r Rect) MaxX() float64 { + return r.X + r.Width +} + +func (r Rect) MaxY() float64 { + return r.Y + r.Height +} + +func (r Rect) Intersects(other Rect) bool { + return r.X <= other.MaxX() && + other.X <= r.MaxX() && + r.Y <= other.MaxY() && + other.Y <= r.MaxY() +} diff --git a/game/timer.go b/game/timer.go new file mode 100644 index 0000000..b90fe2a --- /dev/null +++ b/game/timer.go @@ -0,0 +1,33 @@ +package game + +import ( + "time" + + "github.com/hajimehoshi/ebiten/v2" +) + +type Timer struct { + currentTicks int + targetTicks int +} + +func NewTimer(d time.Duration) *Timer { + return &Timer{ + currentTicks: 0, + targetTicks: int(d.Milliseconds()) * ebiten.TPS() / 1000, + } +} + +func (t *Timer) Update() { + if t.currentTicks < t.targetTicks { + t.currentTicks++ + } +} + +func (t *Timer) IsReady() bool { + return t.currentTicks >= t.targetTicks +} + +func (t *Timer) Reset() { + t.currentTicks = 0 +} diff --git a/game/vector.go b/game/vector.go new file mode 100644 index 0000000..f05f3cb --- /dev/null +++ b/game/vector.go @@ -0,0 +1,13 @@ +package game + +import "math" + +type Vector struct { + X float64 + Y float64 +} + +func (v Vector) Normalize() Vector { + magnitude := math.Sqrt(v.X*v.X + v.Y*v.Y) + return Vector{v.X / magnitude, v.Y / magnitude} +} diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..e3d815d --- /dev/null +++ b/go.mod @@ -0,0 +1,18 @@ +module github.com/ThreeDotsLabs/meteors + +go 1.21 + +require ( + github.com/hajimehoshi/ebiten/v2 v2.6.0 + golang.org/x/image v0.12.0 +) + +require ( + github.com/ebitengine/purego v0.5.0 // indirect + github.com/jezek/xgb v1.1.0 // indirect + golang.org/x/exp/shiny v0.0.0-20230817173708-d852ddb80c63 // indirect + golang.org/x/mobile v0.0.0-20230922142353-e2f452493d57 // indirect + golang.org/x/sync v0.3.0 // indirect + golang.org/x/sys v0.12.0 // indirect + golang.org/x/text v0.13.0 // indirect +) diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..8551e30 --- /dev/null +++ b/go.sum @@ -0,0 +1,50 @@ +github.com/ebitengine/purego v0.5.0 h1:JrMGKfRIAM4/QVKaesIIT7m/UVjTj5GYhRSQYwfVdpo= +github.com/ebitengine/purego v0.5.0/go.mod h1:ah1In8AOtksoNK6yk5z1HTJeUkC1Ez4Wk2idgGslMwQ= +github.com/hajimehoshi/bitmapfont/v3 v3.0.0 h1:r2+6gYK38nfztS/et50gHAswb9hXgxXECYgE8Nczmi4= +github.com/hajimehoshi/bitmapfont/v3 v3.0.0/go.mod h1:+CxxG+uMmgU4mI2poq944i3uZ6UYFfAkj9V6WqmuvZA= +github.com/hajimehoshi/ebiten/v2 v2.6.0 h1:nh09FUhjNGFVcUUPsx6oTMbD1pHerNvTKPE+494y3cU= +github.com/hajimehoshi/ebiten/v2 v2.6.0/go.mod h1:TZtorL713an00UW4LyvMeKD8uXWnuIuCPtlH11b0pgI= +github.com/jezek/xgb v1.1.0 h1:wnpxJzP1+rkbGclEkmwpVFQWpuE2PUGNUzP8SbfFobk= +github.com/jezek/xgb v1.1.0/go.mod h1:nrhwO0FX/enq75I7Y7G8iN1ubpSGZEiA3v9e9GyRFlk= +github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/exp/shiny v0.0.0-20230817173708-d852ddb80c63 h1:3AGKexOYqL+ztdWdkB1bDwXgPBuTS/S8A4WzuTvJ8Cg= +golang.org/x/exp/shiny v0.0.0-20230817173708-d852ddb80c63/go.mod h1:UH99kUObWAZkDnWqppdQe5ZhPYESUw8I0zVV1uWBR+0= +golang.org/x/image v0.12.0 h1:w13vZbU4o5rKOFFR8y7M+c4A5jXDC0uXTdHYRP8X2DQ= +golang.org/x/image v0.12.0/go.mod h1:Lu90jvHG7GfemOIcldsh9A2hS01ocl6oNO7ype5mEnk= +golang.org/x/mobile v0.0.0-20230922142353-e2f452493d57 h1:Q6NT8ckDYNcwmi/bmxe+XbiDMXqMRW1xFBtJ+bIpie4= +golang.org/x/mobile v0.0.0-20230922142353-e2f452493d57/go.mod h1:wEyOn6VvNW7tcf+bW/wBz1sehi2s2BZ4TimyR7qZen4= +golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= +golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E= +golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.12.0 h1:CM0HF96J0hcLAwsHPJZjfdNzs0gftsLfgKt57wWHJ0o= +golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k= +golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= +golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git a/main.go b/main.go new file mode 100644 index 0000000..bf15741 --- /dev/null +++ b/main.go @@ -0,0 +1,16 @@ +package main + +import ( + "github.com/hajimehoshi/ebiten/v2" + + "github.com/ThreeDotsLabs/meteors/game" +) + +func main() { + g := game.NewGame() + + err := ebiten.RunGame(g) + if err != nil { + panic(err) + } +}