From 359c3f37ba7d227bec199ca7edb162ef9430be6c Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Tue, 17 Aug 2010 01:20:21 +0200 Subject: [PATCH] initial import from svn without history --- .gitignore | 5 + bin/Balls.class | Bin 0 -> 1465 bytes .../controller/Game$BorderBehaviour.class | Bin 0 -> 1296 bytes .../steffenvogel/balls/controller/Game.class | Bin 0 -> 5675 bytes .../balls/controller/Loader.class | Bin 0 -> 3261 bytes .../balls/controller/mode/AirHockey.class | Bin 0 -> 4133 bytes .../balls/controller/mode/Billiard.class | Bin 0 -> 2680 bytes .../balls/controller/mode/ChainRxn.class | Bin 0 -> 2578 bytes .../balls/controller/mode/Demo.class | Bin 0 -> 7420 bytes .../balls/controller/mode/Dodge.class | Bin 0 -> 4392 bytes .../balls/controller/mode/Golf.class | Bin 0 -> 2566 bytes .../balls/controller/mode/InkBall.class | Bin 0 -> 2578 bytes .../balls/controller/mode/Pong.class | Bin 0 -> 2592 bytes bin/de/steffenvogel/balls/model/Ball.class | Bin 0 -> 5889 bytes .../steffenvogel/balls/model/BallList.class | Bin 0 -> 1884 bytes bin/de/steffenvogel/balls/model/Barrier.class | Bin 0 -> 1044 bytes .../balls/model/BarrierList.class | Bin 0 -> 2479 bytes .../steffenvogel/balls/model/HighScore.class | Bin 0 -> 362 bytes bin/de/steffenvogel/balls/model/Hole.class | Bin 0 -> 2358 bytes .../steffenvogel/balls/model/HoleList.class | Bin 0 -> 1247 bytes .../balls/model/Level$VirtualDimension.class | Bin 0 -> 1164 bytes bin/de/steffenvogel/balls/model/Level.class | Bin 0 -> 5382 bytes .../steffenvogel/balls/model/Renderable.class | Bin 0 -> 129 bytes .../balls/model/ServerHighScore.class | Bin 0 -> 347 bytes .../balls/model/State$Status.class | Bin 0 -> 1260 bytes bin/de/steffenvogel/balls/model/State.class | Bin 0 -> 972 bytes bin/de/steffenvogel/balls/view/Field.class | Bin 0 -> 4901 bytes bin/de/steffenvogel/balls/view/Gui.class | Bin 0 -> 2662 bytes bin/de/steffenvogel/balls/view/MenuBar.class | Bin 0 -> 1468 bytes bin/de/steffenvogel/balls/view/Sound.class | Bin 0 -> 3060 bytes .../steffenvogel/balls/view/StatusBar.class | Bin 0 -> 2002 bytes bin/de/steffenvogel/util/Vector2d.class | Bin 0 -> 3053 bytes icons/InkBall_Vista_Icon.png | Bin 0 -> 45435 bytes icons/icons.svg | 1218 +++++++++++++++++ levels/billiard/level.xml | 3 + server/config.php | 21 + server/get.php | 30 + server/init.php | 15 + server/submit.php | 5 + sounds/click1.wav | Bin 0 -> 24128 bytes src/Balls.java | 17 + .../steffenvogel/balls/controller/Game.java | 189 +++ .../steffenvogel/balls/controller/Loader.java | 230 ++++ .../balls/controller/mode/AirHockey.java | 128 ++ .../balls/controller/mode/Billiard.java | 113 ++ .../balls/controller/mode/ChainRxn.java | 110 ++ .../balls/controller/mode/Demo.java | 224 +++ .../balls/controller/mode/Dodge.java | 134 ++ .../balls/controller/mode/Golf.java | 114 ++ .../balls/controller/mode/InkBall.java | 170 +++ .../balls/controller/mode/Pong.java | 110 ++ src/de/steffenvogel/balls/model/Ball.java | 152 ++ src/de/steffenvogel/balls/model/BallList.java | 48 + src/de/steffenvogel/balls/model/Barrier.java | 26 + .../steffenvogel/balls/model/BarrierList.java | 66 + .../steffenvogel/balls/model/HighScore.java | 6 + src/de/steffenvogel/balls/model/Hole.java | 42 + src/de/steffenvogel/balls/model/HoleList.java | 25 + src/de/steffenvogel/balls/model/Level.java | 126 ++ .../steffenvogel/balls/model/Renderable.java | 5 + .../balls/model/ServerHighScore.java | 5 + src/de/steffenvogel/balls/model/State.java | 83 ++ src/de/steffenvogel/balls/view/Field.java | 146 ++ src/de/steffenvogel/balls/view/Gui.java | 56 + src/de/steffenvogel/balls/view/MenuBar.java | 29 + src/de/steffenvogel/balls/view/Sound.java | 61 + src/de/steffenvogel/balls/view/StatusBar.java | 57 + .../balls/view/images/airhockey.png | Bin 0 -> 2252 bytes .../steffenvogel/balls/view/images/balls.png | Bin 0 -> 2716 bytes .../balls/view/images/billiard.png | Bin 0 -> 4607 bytes .../balls/view/images/chainrxn.png | Bin 0 -> 2879 bytes .../steffenvogel/balls/view/images/demo.png | Bin 0 -> 2658 bytes .../steffenvogel/balls/view/images/dodge.png | Bin 0 -> 4934 bytes .../steffenvogel/balls/view/images/golf.png | Bin 0 -> 3124 bytes .../balls/view/images/inkball.png | Bin 0 -> 10147 bytes .../steffenvogel/balls/view/images/pong.png | Bin 0 -> 1242 bytes src/de/steffenvogel/util/Vector2d.java | 81 ++ 77 files changed, 3850 insertions(+) create mode 100644 .gitignore create mode 100644 bin/Balls.class create mode 100644 bin/de/steffenvogel/balls/controller/Game$BorderBehaviour.class create mode 100644 bin/de/steffenvogel/balls/controller/Game.class create mode 100644 bin/de/steffenvogel/balls/controller/Loader.class create mode 100644 bin/de/steffenvogel/balls/controller/mode/AirHockey.class create mode 100644 bin/de/steffenvogel/balls/controller/mode/Billiard.class create mode 100644 bin/de/steffenvogel/balls/controller/mode/ChainRxn.class create mode 100644 bin/de/steffenvogel/balls/controller/mode/Demo.class create mode 100644 bin/de/steffenvogel/balls/controller/mode/Dodge.class create mode 100644 bin/de/steffenvogel/balls/controller/mode/Golf.class create mode 100644 bin/de/steffenvogel/balls/controller/mode/InkBall.class create mode 100644 bin/de/steffenvogel/balls/controller/mode/Pong.class create mode 100644 bin/de/steffenvogel/balls/model/Ball.class create mode 100644 bin/de/steffenvogel/balls/model/BallList.class create mode 100644 bin/de/steffenvogel/balls/model/Barrier.class create mode 100644 bin/de/steffenvogel/balls/model/BarrierList.class create mode 100644 bin/de/steffenvogel/balls/model/HighScore.class create mode 100644 bin/de/steffenvogel/balls/model/Hole.class create mode 100644 bin/de/steffenvogel/balls/model/HoleList.class create mode 100644 bin/de/steffenvogel/balls/model/Level$VirtualDimension.class create mode 100644 bin/de/steffenvogel/balls/model/Level.class create mode 100644 bin/de/steffenvogel/balls/model/Renderable.class create mode 100644 bin/de/steffenvogel/balls/model/ServerHighScore.class create mode 100644 bin/de/steffenvogel/balls/model/State$Status.class create mode 100644 bin/de/steffenvogel/balls/model/State.class create mode 100644 bin/de/steffenvogel/balls/view/Field.class create mode 100644 bin/de/steffenvogel/balls/view/Gui.class create mode 100644 bin/de/steffenvogel/balls/view/MenuBar.class create mode 100644 bin/de/steffenvogel/balls/view/Sound.class create mode 100644 bin/de/steffenvogel/balls/view/StatusBar.class create mode 100644 bin/de/steffenvogel/util/Vector2d.class create mode 100644 icons/InkBall_Vista_Icon.png create mode 100644 icons/icons.svg create mode 100644 levels/billiard/level.xml create mode 100644 server/config.php create mode 100644 server/get.php create mode 100644 server/init.php create mode 100644 server/submit.php create mode 100755 sounds/click1.wav create mode 100644 src/Balls.java create mode 100644 src/de/steffenvogel/balls/controller/Game.java create mode 100644 src/de/steffenvogel/balls/controller/Loader.java create mode 100644 src/de/steffenvogel/balls/controller/mode/AirHockey.java create mode 100644 src/de/steffenvogel/balls/controller/mode/Billiard.java create mode 100644 src/de/steffenvogel/balls/controller/mode/ChainRxn.java create mode 100644 src/de/steffenvogel/balls/controller/mode/Demo.java create mode 100644 src/de/steffenvogel/balls/controller/mode/Dodge.java create mode 100644 src/de/steffenvogel/balls/controller/mode/Golf.java create mode 100644 src/de/steffenvogel/balls/controller/mode/InkBall.java create mode 100644 src/de/steffenvogel/balls/controller/mode/Pong.java create mode 100644 src/de/steffenvogel/balls/model/Ball.java create mode 100644 src/de/steffenvogel/balls/model/BallList.java create mode 100644 src/de/steffenvogel/balls/model/Barrier.java create mode 100644 src/de/steffenvogel/balls/model/BarrierList.java create mode 100644 src/de/steffenvogel/balls/model/HighScore.java create mode 100644 src/de/steffenvogel/balls/model/Hole.java create mode 100644 src/de/steffenvogel/balls/model/HoleList.java create mode 100644 src/de/steffenvogel/balls/model/Level.java create mode 100644 src/de/steffenvogel/balls/model/Renderable.java create mode 100644 src/de/steffenvogel/balls/model/ServerHighScore.java create mode 100644 src/de/steffenvogel/balls/model/State.java create mode 100644 src/de/steffenvogel/balls/view/Field.java create mode 100644 src/de/steffenvogel/balls/view/Gui.java create mode 100644 src/de/steffenvogel/balls/view/MenuBar.java create mode 100644 src/de/steffenvogel/balls/view/Sound.java create mode 100644 src/de/steffenvogel/balls/view/StatusBar.java create mode 100644 src/de/steffenvogel/balls/view/images/airhockey.png create mode 100644 src/de/steffenvogel/balls/view/images/balls.png create mode 100644 src/de/steffenvogel/balls/view/images/billiard.png create mode 100644 src/de/steffenvogel/balls/view/images/chainrxn.png create mode 100644 src/de/steffenvogel/balls/view/images/demo.png create mode 100644 src/de/steffenvogel/balls/view/images/dodge.png create mode 100644 src/de/steffenvogel/balls/view/images/golf.png create mode 100644 src/de/steffenvogel/balls/view/images/inkball.png create mode 100644 src/de/steffenvogel/balls/view/images/pong.png create mode 100644 src/de/steffenvogel/util/Vector2d.java diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..f16baa8 --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +.settings +.cproject +.project +.classpath + diff --git a/bin/Balls.class b/bin/Balls.class new file mode 100644 index 0000000000000000000000000000000000000000..e5927676a7b28fb1661852e8db9c73232fb219d3 GIT binary patch literal 1465 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 LbiP)X5CQcOeTNOH literal 0 HcmV?d00001 diff --git a/bin/de/steffenvogel/balls/controller/Loader.class b/bin/de/steffenvogel/balls/controller/Loader.class new file mode 100644 index 0000000000000000000000000000000000000000..3a02d7d44a88b614e41abcc40472051940f80cd7 GIT binary patch literal 3261 zcmai0YgZFj6y293jKByQd6-tk7XslC#aAV0K~%(sXB0(S+aVcnbeKse6R3T^pFgCZ zb(PpvSG)STf2iNOy6;R#CKAkI!OYxy&ffbx?z#N)-yeSg7{MAh4tY@8)Mzn5pA33^~6^N!P z+HQMm+zqd3>m=^og*Xu86b&WZm|+?26@lr#U3`48KK*M={CN78sA7@p6p+e)`wNJK$UOZDw@zN z-;SwJut%URWmx)bVSPn+Zc7)LB|D>;OPXWI@6uw}ePrYX`gaK@kR`trn5R85v2z>S z)pcAcw_ims+M6(dAq9g1eRa!yQYNX8S22u)fHI$&Se~Ap5{U02CD17)*JKmU;H-iX zMqQUq#W~5-nDscv6D=8JEG;Q`SD>eMdsRxBkTawS5AlJ5_p8o! z`YC&1U4@1f9)8_ntQ~%&hMkyaQ@JdbuB|hgELIgz+5xXD)!Qo8@Q9_!Ne|O{r8~Ff zvpXMe`+M2oWU)8>;~$n?S3N8JHsO&DWlRo%{W~haX3A-f`!uI>JG!$%JS%?rx&y8? zDnJTFbJk2=3zQecDJd5a)K*GNwQ~A)R!=U6+kSyVK3i=o0oBKyH0`_u-COzO zKw;AT?`yiYO)O!*QE^`07Uf-oy=JT$5}_n?y0TKDnB(M-2F+=^;AHe0hMf8>{@fmx zJw-9o7O!P5RkEaw{tU)3Qik{&K^P74{@_0e4f00up1foDq;$0Msq(E2`}lW1zf5|B z_&gGSfoS|CI+o+Vq3Z==TR0RS*y8%&7LGonMFWoWZznl`c6xQ-0J?CHKZg;+39cUX zk#G_{{352OKzMIbQvPhKgDo!!X-T-2>jK~5JM<(G?39-e8x=;nx%uOK9Tn+?aTFNk&FzUmI zZjv_A_WnyGm!p?o;O&7TCW^TJJEmtMf8y5cP$)W=9tua#qz8wJSQrg+H8dKDMM7jg zl8!~fQb9T%3&$cw-1!?1w$Sw}T4tW(y}=?f&%D5Au>ga)l=T?#YMWpvr&)zF%=rja zo~7P%TshC1@dCziksg<@NTtgd^P;%P)KF=;R`>CQy}%m>m$43uF~{g@BgdHHOyGxb z$atEamWRt8Sfqae8?@UbPA8wf=SO_=?Vr;AW9~Jf;a@B$FciXnf=~Tqkw(xIh{TKd ztWr2X+vD_|@N`OK8kKcM$oe^51->Xlou`Gg+R;f<0f_BRl0CHz@nwC8nK}?(l_7!w zef?@c3k+y6097lXZ_7}-26Qg~Q7fSD>O(xN1Mz)*i0o@28t{Wxk00?9pK=%uurGfe GkNpozkl1bj literal 0 HcmV?d00001 diff --git a/bin/de/steffenvogel/balls/controller/mode/AirHockey.class b/bin/de/steffenvogel/balls/controller/mode/AirHockey.class new file mode 100644 index 0000000000000000000000000000000000000000..ae40d09b5ea1de2f7a431e5f36de158277a7b2e4 GIT binary patch literal 4133 zcma)8`%@EF6#i}!Sb{4eq81fJ1PeipV6APjs5~VGi()~suT63ZtD9ZASx~gCw$(nh z@0Wes$MokqMw~j+KcLgj^dIR=|AN|c@1}VW!ZtH3clVt0-ShnJ{q3J$eg)8l9~Jl* z!U-NuJA7)2n{!r@8{wE{80m1_G9BA83~q;07O5Q4?Za05ET2~pU}*I;8q!jnp)z45 zlH6u!jxKE>u#IppZQ0GRGG)!C`KXoF9o;e+wv-snI=T@a=W)lfyAotkxnDPRr-xy< ztwh(2!`&dt=eW_mtjd_9IlQ}loFULhPF2H?l`4X$RYZduhjasY` zko61|ZIMX(cm>sge#)OgJb(=f8W?KMXmeUvJLiP^EW@%@Y{Vu8zs(a2wb5c>cQtCT zSs-p<7%R;{(e9Yje6YPv*nod#6ebx`&}ErJWy} z;Uan#5rVxc9+n0|pkLsX2mbzD{QeNa$5eD;;fhTF!Y|TtqDTblaPAi?YcFzq6d;+HwoMdQO&VA8V!Wk8lI8CFVC8!x% zm-j)~bhl4Zo};?SkItrI+&-bj45FmEs1?_Yan07nd-h|%nbxUwJIgp-P+5_nJQ)%N zRTzR>XgbQ+7Sup!rv=S;X}erREw2+P(o6j8h&Cf#Rgmoow2PrPg79-HZjOG zIIF@y6%EHsmS6=RnJO&IkWzX!#&EDStHmTyTGe8?*oOutE%sSq(WsjgF42Qv(^(bM zpnz1#@_mL*rwLVZb6cKwD3hiW9ucR&fLKa8W|Xdt%jo=vIAA(l(&P%c!N7Ul5%}(Q zqc-J2yt-%1ac*!;zPsXnTT3Q|xLVqdSaUp4jhFGNf>#(CaJPAh*`?AyL(g7XqzF4PtbWspuk74t$B{;!@(Y!YhFz($!z!GOqOWfse zJ<^Cy^_V6P#e#q%rE@57)AA~oy)JnKEFq;!N*13;^MBb;ZpP@?i}OKU$RT=ovvBJ=aqJYv?9Jh-komY``J9kqu!JqG-f1Y{p4!!Lw)rM>CSxhBIivd9>mp ztuLb;*U0*5LJGOT;u+Ewzw3Ao8l^(4Vu(|^l60v`AWZvn`dSa)eF6(8UXc3r!R zZ1NdWmCurcDpfh;klgZRe9ASI?pg6D8)*&}rPa=K_piIBr<;HN`{PdlckwiXlt6w@ zx=}2vRp~c_n$&LD(>ii1fggu~)-rS(0jU&}*2)X_GDr(tx7w_D4JnYW9%wBvT|8T# z!P+g5zoLrbInu9tx+>87s;*)(zh<=~o8GeaD*FO`^U7E81A(=fu4YBqlzOhKN-6eY zId@}+0$QXH2hoFJ2j}1nK;T0MS$rgrtNznwHMsN_xMXf6Pd~y>rNrv95*d?ca>~64pnO{wb1(7dz(K#Y6`>_m} zc+NOjeoa@DR*Ac|G#YQQ(}y&W(n>1oFDtTEi~GsYMRjFdgoyQdOffB%FH(u9<0 z^J%hn?TA7W26fP2DL4o#@}c6h89Hk4JU270Qk&C|K^iIaqL1EE$h3d^F<{n%=69Gh zX{^z6h<1M=E4It$Zr=JGALP<4jPT=pE_<LrX|jOHMXIQpB!IE|+(GUe?$LgVzT(7LpHcqQz%C@hW0=6#_=e;Hb9O||f|$1>W-W+s?TGsp!~;8G-hx=L zBMKJ8cXq_81@S!!wxVu!L@b)3E@9b**zSmUXb>xQ#4`(G)sA@46_Lgo*4v3J(BLv40Q=z>wuK)J>@i9<5 literal 0 HcmV?d00001 diff --git a/bin/de/steffenvogel/balls/controller/mode/ChainRxn.class b/bin/de/steffenvogel/balls/controller/mode/ChainRxn.class new file mode 100644 index 0000000000000000000000000000000000000000..fc4335a77bfd75032534a216097e7ce90d10bc72 GIT binary patch literal 2578 zcmbuA=~5Fx5Xb)$B1vEojDR8@2p$-f^}bLMLpXy6v82i>KWyTVjBa+R%@V<9@L8<# zL&_>Y_yE3zPv9F^cF%^Rlw>}TRJOLKyMNQi^yKHC?>_+CKp}ycz{ERg*Fw3rCcU~} zmabiNT(@SId@l@q*Oh@?^~oe#ag?{R=_L>sIB)csbE;CH^P%!o_*h_JJiosSvt2tc z>(ZTUYf=cEP)=TYEfCL=PZv6nvTz8UDF}31u+SrrE>Xm)rhIQzg_WnAh=6#*CcPH= z*ks@zlORwssC7UbS!c7O7Wy$DkSGUEU4>iZzQF6pEF8y>K(gv=7S^SFM~X#O3|ly< z9ay10$z|<#tku9M_m)Js{TezW?e-YQ|V5RM;SUFLz_1BLVKC@IeyhW z7DOIyW3x@nd7%uL*sV9nZK{x^XuB7ItkqcT(aII+N=M6)dM0qnWmb1-^|D`Qp;rs5 z6)D~3%GmzFYLnfFNA`_&j}h%d-QJ1m3sDF?FP&HH>z4;%$!qRD40O-V&_+lQl_ z1p11Op71?YSv+`EG*X9@X!7Y!G*l<@q1qJuji4lF71yR``&ymgiKoj#(7nc=UV5X; zjh+dTKGQ0%Ph>7%`G#aB-ar>W4rkIw8c1hS4Gd;F8aR>Z$EgO+WYS{|oc~H5F=|^5f=@JJ7&aH1LCe3anpdfXGYvNAnuzH zQwGEXGa_d|OyZ%bsY@*pk91QXW6Feh*%I+YBc{!WRRiLw8S%C)B91I(nu$!&Ddy4p z?|_#yBAOPl=YZ!hORnUAIeLpBj(IGYV5$XdaR;`9yoN2~nF;0_VbAe`U;-~G&KOqy E0=jMe^8f$< literal 0 HcmV?d00001 diff --git a/bin/de/steffenvogel/balls/controller/mode/Demo.class b/bin/de/steffenvogel/balls/controller/mode/Demo.class new file mode 100644 index 0000000000000000000000000000000000000000..4e2b102ddc7fa00dbb9da8ac0d7775dcd98991ee GIT binary patch literal 7420 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 literal 0 HcmV?d00001 diff --git a/bin/de/steffenvogel/balls/controller/mode/Golf.class b/bin/de/steffenvogel/balls/controller/mode/Golf.class new file mode 100644 index 0000000000000000000000000000000000000000..e3288a20e3a0f1b5ff6f26858623c5860bc861a7 GIT binary patch literal 2566 zcmbuA=~5Fx5Xb)$A|bGfMh+1V6j5A(Rq;keg%FN_M=Ytb$`6}3gwf3|wOOL@3_goh zen?s62Oq$<@Ckea%kEjOLX!DFQrX&`?*2_5)01C+fBXb+6NMBK0``09R3o{vBK=xW zmY!2|J+JDN0zV1^&y%533CJWDcq=I+1%{0FIkzGOS|2K3MUMsMhVuuzFxPYPvL?NW zrY42RjpW4DHv-8i@@Yp4(iV=OH4T9d3l@$FWJ(mRs;aEa-ZY%UJIwtC(u@LKNr@dd{2sbR`gpqqa9eG zHf8JNpRZk;zjI$%Ibh)eE|S+us7euqMPAcwxFnE%s>0cz^igiG-DL|`FiffWx@?*J z2e;-rp6i#LLKG^$JV6QMl`ogpD@7T;c8eZWH)^W!KtV*z6l~bOgY^iMLhU4tqPmx2L`jNB9`YgZd{t6=Z zH?i3!X8lNpOzhAbWIwBjrFgp+p{!O}JgSwiq$gc1$Li_OEtgr{uGNb{jfGAvEU!xG zZLJI*9IQ6kjdHo!UPB z0=ecB$FtFV;IswLTcUVF;9}E*p>5gnCS}Tj%=xncAJIcc!I*gJ8A}tgs=3X>(M|%# zi>{vTJyn@Md{s13hm_jl(|u^DPV7UqDFo|bNzN#)O`5OMF`jg~Bm~`O{OP1Oy42{I zBIygQ^7@#4ZR9)J>|`D7{5WQ3PSlaH({=RNEp?o>yKuIS^LA#ij-hYlk-$}YUPhXp z8RB)J1Ko53_RzN%{dAcPppPz{(-rN9v6vzKlDy6W9R6r3gD56k>^?n0IgbIb?twa(NKWytzMz_0Ucd5cN_$(%V zXiWUz1Nas`fp1_uXSM=S+WBCcZuZPM=QrmvXZrou*KYu>p_oEKVB(Fm!$_{LORwfv zq-&QP*A4Bm??r*{x-zhKLdAU{?(*oD!qU63{D zPPH^CMouKB#$O5~=g6lMZAe=9ktMhet}daaB3>rCigtAAG2^Ag905@=R$qtGR@L7M<(#W1VXEBeu{c5JePq+7USzMZKF6<={OMKWM$m);}yK}9UZJ3b3!7_!){l`o_#9WBS|`M{}ESly}BD}IfI9xbeG zNa;3KMh=cwo9qQWd|&bTvh@E|(MTOqs==pQ(NLY(hiX&ww}P^KthhE-<6fQQk*C{2(8b1|9(tqO zjh-ozKGG_$Pi8M&{(_EdvW`xE9L{EX>&Rr&bqr+N>Nt_@!>KyXWHTdmjD9AM1jgxk z0cm<>h}VZM^wU*1K;L5+qFZekgLM0xzywKIvKo$e!X;cLiS{JTB*npRHm(p+;41xl z#F5>k^#uLI-ew#$C>4ec#L8Wmz;)apy}(T~;-Ud@%Z!*XAa0ux*A0j}X2e|s;;tDn zV?f+9BXS1B6sAp0U2clFubcV+GbY6Irih0cF>6Mw84!=mh}SIX}DqAzte}B{6Gd=wH{p~w|ajd405U}4!rxMBab?H}w zlJuN{>v6Rg5TD@|tPG1xk%8%#w>1Y+RxR zU)M2{d+SzR$8-IXlaE5>mnJBqobu(^0jnHrRphj%ito5$r$*!K-1m_~oBENn#P%!? z^??f_4>r;45VL+HLne0U4YD6p#Itz2BZ1mR*qAq9LT&s7w{GR?=Ui>`gQx#*jKdK$r{@EbJ))G)R3`TYUsDqH4O0Rq}_|58qV68^EHfq zA-4p^=xd{$zC8pzf)0A_y3vPz`WwVi4AC<;f&tPUr~eLvxJ=5ScuQP?Lo?bOS8h%LtSi$c&HEc5gwZm&l@79HDbn$STi89X2k2Jh$Nn1 zww}lo-D2*+e=c}YBjRom`!4t#=E;>Dut1{(l2}B}1XB%QOS`bAc&1^?cy59PM%WAF M2_~>YaVGHc4_9vfRR910 literal 0 HcmV?d00001 diff --git a/bin/de/steffenvogel/balls/model/Ball.class b/bin/de/steffenvogel/balls/model/Ball.class new file mode 100644 index 0000000000000000000000000000000000000000..005753044e36ced65949bfb51957b6cd9f33766a GIT binary patch literal 5889 zcma)A33yyp75?w+nZ71%nubXzC2eVwnIwd6K$}uZGNesRT5W0|trcD-ugSENnRMn& z7X;KosEy)+N-LY_C*XpLnw2V|pdz?}8@MkB?x?sT)c?FUlgwoDwNU!rz31I~mj9gd z-#dN$l?NXJuu7ffg+rmL*JwzY#-2S!{6M15h&A-+u~@2MAkoWl6USb-6z1*K59kds zJ>J)_t!J+hF}?68tT^4??MA%UNa{T?L&24bUc;Aa<8VMvr8o>L%t<7pM%>iRXd&hTg;bN>)(E1GX zGSf^(d(tM0ZbglqMyq%`DUSCw1`9=gtVE+ku|Z+sY+D%TN^I0{DK@bbqj9rKkEN-f z`ET{2DX&Mui8K@ELy;esp-~I1YKn$68TOt-RD+oLJ7aSl51dM|cRS1xeb?;5&r1#L%7 zV?e@h4Hl?j6xHY!Cok|}4#Pe)z#J~jTbE6tba~36#krrNNZcd*j9-lO-v591uJX(yyAfHVO1F z-sHtKZ0*w-vmDZJtpufs7ah@f=b&NqipJ|TyjkkR6Eos{X1^GItA-;Y@{3`+vc%Gj z8iuA-=!d3M9M$kP9HXPDNJlzmGN`3B;llXy`%*N%UBf$YGi%gxiW+UwW)=?PUBYDV zR#xw4Lv>ppb+0Q9*dt(u9!TY>;ufnP`0#mSC!}}#n_rYkd;1R)bsgx5^ zA>m+~sJ>0Z?XtwvZ$$h0O>y^54R=k4LVOvDV0pJB@k6q=HQ4IeRJ7!!9pUz| z{uA~0Y4|8U#sVKqSeXrngJD1E`V$)N$0u1KY)0#>X-OsqY={;z{cRaenLdhS)2F3C z=F|I_RH4GMGs8#vb|$3*N^O$LsYQNrn~5u>@#^!*Gn|N|ZT6hCA$@3=g9$w7#pDbI z$Zphd5})V65lI@lX=EB%A$UfL$@aV-58+`izL;&H9JfdJ41c5Y^uh0HH_d%g-d61C6`mPh>~)0#aWyr%I|6TK7PPP(+3B6OKR?q#+Yv& zRJj|3n`h{-L@bZqL`0!HZ}pT_3Gf*WKgLg}p8;;^Y_h6VVryw>DX3EBWgy$?-T}K) z$jy;{BeIVhV^QhgS9ulKDGc^24Zp^3ctrN{;L+m|9s_5-6@vG4fR(?&*v2fCR zxkl~hU)F-+k>VKSM#mrndbK%|yK~A+aIe2JkxoX8mZg5*#^{?P~H5{jy zY>yYpi)#Mwa(da=oTyV&HB;`OTyU9(+Dx2B>7p2FwBkI8>h9VRl#heKmWMLafHe(- z_@z?9=X;R=z;{(9YDZ4gXH(@OMtcrrixI-PScNLAXHq2Ua@*Wg)QxCh{45qabwS3d zrx=|$bu{DD%I@0I)stA`z&O^A;gTWo;v_DkxH%&ZkKuCqLTRx3BxFNt&W3TciNjVr zr5%&l>VR_++Z}iqYsYcrRIH^tXZaS8wB`o5i~*j9v+4FqCSfb_--{aDMBJwXJUSKN zQS8DStN?f8jhO)VGm#SD+7Q9+9>G<72lzU+Z0`hmhV)TOB47ILFa6VB`lsC~wko3z zm8^+1I6uey+9~sEu@5ntEy4iewt2OS)g`U)#7QK&$FaZN0%i=!p;~#2Bi&I)yN8DB z#&BJNvbS({gGh|weU>aThMPKM7lp&JOIEyd1n+T+pnr(#CUC1h&jgLPlazBpITp3 zQS`u6j#e;KFf%?vQprPfBY*83!8#mg3EqoFme3`5jK9t#SKF-~e*zCcK=t7fd={T0 zNR^!1EqDa2R$Dr`e~rZ?E^1kBafyez%B*JeQKQo;Wck59f>9f2>T+2r+Fe^ZHi>Zu zI_gSSGmgp$d|?ugI8j&H%xTpGzLuG`a=K^?k5Ay6wuJNY(heg0ok=|9z!j31Kon83FnQ*37G?_r-;6eFVG*`jAy?TBP1VP4{188)yG7Vx6{>?H-d{5Tv@-x< zsp7@uF5_6$vACv9;OS|L9EqUBBQyFdga?v z2~ap^48P>CQb)CBCR|}n__zmf9&A&1=|ggQnIxSf3IUhM(gFlQNN7(qr)=KRHk^F zEz(GiTvli0eX=Vv5q-1C^Yl#MAM0Fo^<(%?dN|;UaPac6n-l9imPjNAvm#%>Q+)g` z_yeAj6Srf2z$dds0bj|9JFrl=`MG;ASKcqogmEcR0FzxpURpvek(WTtP)OvNv*d3AN(0waGLN$VGT0qS3Mt~m!%oW#F zk&f28>gp<71Ws7%<>7>g-1YUgNIazUph_AHpVexGr)r|PCgoBQ|`wVNby&b)X;77LyMCDW2+so6O3x>PsVt!#;q+NjItH;h= z;UVNiWja)wbq?{`beJJs!(;GTY`}HchU>AD|4Jd;V3*RasW5kCN~sjBnJ|~(;!K!9 z{P-QQ|PDC|J5`dTyYTo^GnA2gBN5 zVYXSM%F04Fq;O&B)}N7bqd!9YZqI|k(i&^3?&I8h&iT%FzT5NLUqAf};3huP5D~ah zl}0^~4<1PO*gKGpv2Qv~-Kcq0u5WW)w(Eh0m_YWSd2AYuz;+DFbFGH&OE)k|-qFdn zyXV`1-0*$#L|qpctxMlFon7hIZO{E;^NxVHFECW{+AIJD~m z3+4Y)RFT=tYE@u9)AN2Y`_&)>QaWD2xWKS=D6K~&&v9&3pF%pNV+_**6Pa?zlViFE z#`gY0X$5p<`TGLt-g(H;PGDM(w#=ijCYALy9kaMD&`*wiGw^%@$z+>p!gg%7?8OA; zFt6bT>A7fD`&7pQUMIJ%e9R7wweY-pp4F&P zWyS0z^Ib=V)_%N4*HEwt6tSjZm4*FV03GXipWIr$Gy~c4r=+`^wG;TZd+;BrRLvVY z-o`r#lyFxA6+PCSsTEVlJ$xvTFprL;TP+>h4h6PwxvC1q{f{)EiF&Mh7Mpvi*bWC2 zz~h>uo+Kqcap_K*5XJ455+XG^xZ^c^OWw29YZ+?4!0D zY)A zUXsNqC{3oWC@B4i5=s-s2p4=HE#AIoXvNz~KKbq$Zbh)wrf<57zQQ6QeQ<``5$tsc zd|CLRgDe#W$zXtl%pi{}=VdH)k+;$zZv`J=lj#RgzZz$r{=0=1Wvzs(ZF~~WpZ*QDhKR%f literal 0 HcmV?d00001 diff --git a/bin/de/steffenvogel/balls/model/Barrier.class b/bin/de/steffenvogel/balls/model/Barrier.class new file mode 100644 index 0000000000000000000000000000000000000000..dbcf3f6ecd20a9df0c9272b8855c01f7a68abd4d GIT binary patch literal 1044 zcmah|+foxj5Ivm>o6Cm8KqB4)NX#aIReZ$q0ld6Ks1hr}<76|0r8c|NWP^T|R*4oq z_yK;DWzQx;VkxPu?VaxF?$dM5?9X4{e*oCTrhyn?wJYsGD36Y$e-`wlXLp3>4eWl< z<@L5u%9YAMf>1aSXTtV`-?R5RC(;QG%n_>BmA{pKS1Qr*Bq2Eng$fBPt?Meb8GMTn z=R(5VGuL;+=Y-d_*+sK6tTrLB!{^E%j(HOqVm?goAPMc@qk z(hs++sqjlrM$r`R5RA@9jV$irfr0yk#ecOhQNc1H=O`&cIqpEPYON~)_e16Sz5jq^ zu!=PU4+)i7Qkhu7tt=kFGEigcCg&L=o2a8f$cocb7Io*?^;p^J^yzn5l)r|FLM%@= za0uloQZBjT?T?zv($w}J&IptHL=s3Sg#MrX({6~=1oxeJg zL6)t_-XZ&O{^sl7kgGS&QK&c1QT!YwF0w5m!8XfQUz{A~`6+RvGActEH`(I`5e!8u z4Wwb1y)n#yvo(y>DBixn-5B09>t9f4e8tKIsxiFRZgIl>#K|#S4Y0uAC2m+|HI^m@ Yur3F%(8M~!rFpas*wFxwqb^T=139Gk8~^|S literal 0 HcmV?d00001 diff --git a/bin/de/steffenvogel/balls/model/BarrierList.class b/bin/de/steffenvogel/balls/model/BarrierList.class new file mode 100644 index 0000000000000000000000000000000000000000..6e295bc5e9afe9332eb420503aec695b3058fe40 GIT binary patch literal 2479 zcma)8-%}G;6#i}?EP+KK1zSXcsAztGQE9a$NGl+f8n6`wr9X6&thjcw>ufeur!Rf% zL*M#Ro#~4+)fdNUXDp2EOsCJC>GTijLtpz;`rW%rh@C>1Om6OvbI6 z1;8oX)DRIkRx+~{-@J9pbXMIJ)6NzQ+pc8GZi(|r!}BcD%Ucy+L$g5Yj_0wdY0v0%$-fwiFtojP=M z2{a{Bi!lhiqN5G%0(7wLuLdOWwGWrwLt7w~s*T($6uHy}y7HDM^dxr0N0{fDwfT}9^*>FGC zjyEx;;Vo9iRy%B->d0Z7W#*Xon1=365B0%Hv4Sq#PX! zzES*i&bS*ET-0~3m2H8MWZv~wvY(9>vn98jopy`WGMg}$dTIN-ZK~Z?yvvY6Wh?EN z#YGM5!tVd`p(BquA{RZ=@XgSLYOk$?E%=`0tZaiOMeSt9OKy?sy+o+SQ=t7`*$y8T zc2LhtW}CbP^pNzVe2y4{ZB%?Y7ig@2Zw3a#W7O@m-E!KcZ;iN>i&= zj(nIn$~_$&9QSZFL(7OfORr;ZI`bpqKX4U6H^)87(_S>A6ESq5hkN@1YyQ5pZ)3Qh-aQ-{~89D!ugPzXV#H?%G>og-DK56FZ=3n`fE7-$Y5CEu;4?S z8zIg>n*Oqz2t+%%IVal5rLBPC3PaU2l&<1wmtM1i4k=!x3>(`jG_jnLrcm;T?^(MiK2A) zT9QyRfB5^FB$F&9;3#7_#!!=#=>$?Zi3$EAaS@}q%Ga}i)39*{s|^1OjNvPc;~UyM zqU}?@aop0e2WE^rcA{{T)_ZypTd15b(DC^#2Tg- zDf$DnY_JqGimqW+!=i?ShHF6rHs~PspA!vzGC3+i8#uJhd1!_72GhT@i`X{co#*6V myCC_bAM|Q0onhInVR@^CWK)A*sf}#s2tHEd$M{73-uM^L!6!2S literal 0 HcmV?d00001 diff --git a/bin/de/steffenvogel/balls/model/HighScore.class b/bin/de/steffenvogel/balls/model/HighScore.class new file mode 100644 index 0000000000000000000000000000000000000000..3fd364530f62ac5a15ac30a49ee8550245d8a60f GIT binary patch literal 362 zcmaJ-O-sW-5Pg&8Lt|{U|3FauIJn?d@gj(apod5=o;K+;-LlO>vhDx!BzW)#_@l&0 zDLs~jxAWdGGjHbi@B0V99mWX)!o`$T=Xo~cX6m}9 z*IHTK)atEVaODZ1HJyCtANjsEh1Z_%3GstzjDI8yuC6Ci{3JtC3~-bo!2w~En}%Ok z%aYr7U0NoLb606Q(XHwERt){zbcD;jGk4ZyZd$liTk*5$TMl=b+kPLMLHx);NM3|^ o8;Kv`hr-k*14K7pNIyjgkO{^jLkf=tvrQafh>Yr=*=pX< z1VZbUqr19g3Y^LAcdEF$k;*ZqWltB=0v(S2oIYZf!?Nl)9A*SMuj;1mUK1FL9TH(S z6VK80HY3A-PGXlMPyv~}g zR?_Sc!d)1}SPa{pqhW*MtcsfpIsFN9k}u)?d-g$(Wnac3XchQET(a8IDSU~8(Y)zb>Z z4`ri)P--(LE173P*6NA1pkNXADVA&1bZ7Qh8|kGkUnqEhB_1B9>#Dy7sFekm_@6= zTig=i`$yPUXmsEQ(_n+J5yLyW~FHJtf_yNa)P!DN~(p+*;P*4P;N1Ue_9#+*X za58#We~QmZ-;#nA=q$piU5yjw6;x&d`*FY5b3mRojpdC4OgZz6UzDkMwYCKUC{38^0N_^-=9g@*Kn3y+RtCWd$NJ^6Gj6>yf>RS-yK}( z#t}YyI5TJ&;QLr&2S*dhZS*CEx6z-7Z)5OJuKO^==YVH(guXqDc9h<|=tC4IxR>B6 z{c#e*e9Mu{E4-1+?DIx4w?xMNQqR1}m~!v3m-#JDKS@SMc5&8+9bBj)AyK@=Bv+?) z@qrKiU3}=n-x%FNnlSgkMe6`M&`&@EY=wg!uz_0mcfc;=Q(R+m-b&o4gLvUl#qWGF zdUF@IeOQ=?jz}zt*XZBDY!%sEeD22t=Y7$sWEBs0@yLfq6MqnTjhtHk6C~y&&X9yD z_8&>i2n&|~AR5F><7<4wykW#WBtDM6#dmciZ@At``>f2Ae2wp`$p1RW$za^-8GdE` z_B&?wwwA91k~CT!3JkyM846TUw$`e6S~KUMipn-tB}e`y0mn%HdEyyI3>Pp@91`ax vPu%P~oLM}>7Euuko_hjzld&H?0b@9a7nC=EpSa%%@h|43tUq(+!^{5xsJ$|6 literal 0 HcmV?d00001 diff --git a/bin/de/steffenvogel/balls/model/HoleList.class b/bin/de/steffenvogel/balls/model/HoleList.class new file mode 100644 index 0000000000000000000000000000000000000000..d8a886dd21ec7273771aa7a465daef8060bf598e GIT binary patch literal 1247 zcma)5%Tg0T6g`~>Lz0QS!c$Q|gd{vhiTEIhS^-O}5EfCeEH|A=lMGH~QZpTdU-1L9 z%9U=gaACRjGu-y3a8E&iVY)0dSBkwoVI9~N zVQM9Anyyx}%d~!In<8(xQbC9zwa*W@){us&>9(ae97kAE%h~m#ZEM#tq`2=m{KyMu z=yio-aC1jEu3=kGHrE;0BZhd+wp__Axx>wd2!}UbM|z)s8)WEOH7rA}F$9yT9fnYj z;G+oQoQf!73_W?n5`{*sB%H^*WD17@E~>bM35IT>*x}N47>1ImpBa2LHk0{nAp}$I=3|U4toc@6Ldq1Ry z{!t181%z-8z5dD%LLd5RM-n2@Oz@Uq!sJ_?>mNM9Z~$BBV~nqa-e7Drbb?8S&zLRD zFU%byb%MD7c0KnshF7Ow=ikxAAUwb!KS>`VlzN0(8ZKzzY8X;bwyJrt=%d`Dm>rH1*Zbt$W`>qpp1w>OI z-IeZcmxt-7>xN4!0*kE+l{N_9bbU8^Az&Dnz&D%awm@o&$xcFGTE`VkYDglhL&G(J zq)~3Go9j9zkXBJaM+RwunU?Fz*MnY1_TSkZPYUE(!M5$S?Y^t_&5VR< zGLX%xf#5#H6Ae>bb?!b9sZa&8a)_(u5oXNNA#!Fhb%^{oUL;WDn&UHIg_O%AsbU%y zW_ePI#R|BAIqpakizebo$&SQsj>YOcQFr+hF>~@Gg{XLuf&YXm5%Y7r&2GC6%sV0P^);#zeb$EGv*`y E0(4UCIsgCw literal 0 HcmV?d00001 diff --git a/bin/de/steffenvogel/balls/model/Level.class b/bin/de/steffenvogel/balls/model/Level.class new file mode 100644 index 0000000000000000000000000000000000000000..2e8f4d6f8536bd1b2b47a6220f32824adc3220f6 GIT binary patch literal 5382 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 Be!Ktx literal 0 HcmV?d00001 diff --git a/bin/de/steffenvogel/balls/model/Renderable.class b/bin/de/steffenvogel/balls/model/Renderable.class new file mode 100644 index 0000000000000000000000000000000000000000..3a97d3d9fd29db63c81a5391ae86f6133bd2542f GIT binary patch literal 129 zcmX^0Z`VEs1_mPrc6J6PMh3N%RQ=+T)U>qJyt4fC)Exb!#GIUB{oMQ%AUh~EFD11o zF)1gNoq>gsK_Dx!EKxrvF)v-;KPf9UxrC8{D>%QjC^^+FGbfdifghn>52Tchk%5tc Q8E6>@FfyJ{d z@ClEX1gB9#`&}2h8WUPi&ohEQk&O{rxauN6o6t*i!JnIT#_mgHh6(qH&6SxcryG7O z`qfI8gh6uY?3vFIAxiDWT@LSaieTX;t1SC@9NiY-^A2<-a?9kat!9yh2 Vv>}3P!R{dsB;E)k+zNW=?E$GkRgC}u literal 0 HcmV?d00001 diff --git a/bin/de/steffenvogel/balls/model/State$Status.class b/bin/de/steffenvogel/balls/model/State$Status.class new file mode 100644 index 0000000000000000000000000000000000000000..92c82ac1c590c8ffb8df72b3da4c57d976a773a4 GIT binary patch literal 1260 zcmb7ET~pIQ6g_L&rVWvgiXdMiirSWsiVA+T!@ywCj-_-a(3y-+X$dtr5-lalb93c%WGr{UZ*LbR!Zw;vHVsbQ@U!UoItFyzH1cT z5Z~C@u2eXRZx+i%;~j^6h4Sv!Y<0b~TQCIXK3u1AJYRPm&k0rqlvKJZ5ZNFpaYQu; z4CzSX7HyyJrHrIXmx_$Qcf3Zfn64%$_qL8GVsWSp?&we%#2HNJh%-nqxT_<97)SSX zXy_9dC^?>8?lfz*zhl*0TOe6#)h)Mb`3_?_sX@UIH5Ytz+SJdX<#uce7E9Z*>7cJ08f2f1QM{@*FmPv;^#+TIsf4bys` zD1G%4VWCfSEMQ4sIb3SPwc71mX#b1ams;3kF~$Yq$w9UiS!vx!y|Y4 zw2%+gVq*U4O|H@=deQT2Uv_1a*#*oi&4Xjb}??4u`Z^JV@!Xgx;HRGZ;eLKzR#(*`*N07=t}guSRxIqLe0!gp5VbH zF-8eAElGMWo@F^?{)c$fqpy&3rjK+nZN67BXJ(!|+fpV@@p%3Vt(>=UUQJxIkRW?3 o_G)A(hxgKwB6EuDPl$i>6#9#C&1WQt$7QTAllTHJ@M>-B4>|@MI{*Lx literal 0 HcmV?d00001 diff --git a/bin/de/steffenvogel/balls/model/State.class b/bin/de/steffenvogel/balls/model/State.class new file mode 100644 index 0000000000000000000000000000000000000000..17ea4039103542de7c2699029cb48bb5e90d3972 GIT binary patch literal 972 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 Zq!e$mfhsA@`&`F7DMJklRMdgD{sTH}TnqpJ literal 0 HcmV?d00001 diff --git a/bin/de/steffenvogel/balls/view/Sound.class b/bin/de/steffenvogel/balls/view/Sound.class new file mode 100644 index 0000000000000000000000000000000000000000..15b6333505789dc85c6a5b93e7bceadde3852499 GIT binary patch literal 3060 zcma)8X?GM=5WO#%(8fxJGo6!e&a{)ghHV#;CoS_-vePX(Sq(9T>Bo$dM$$H%Tyk&kF*D<9n50mBXLWzk zag1KuRG3uoJ=5q{c%WUjPbUjJ|RGO#FOwo5eh5A4)S@bPCnQ@&=(eq5lPj(%pkJ%2_ zwRc3KRGYNbax8zF!i+?yWx2_nmTji$yJ@$@&6;tPW2TO2n59sjsPEP=TVZ8@!gvc! zo@Wd++ivE#<>dAi%_5a+Fjti4@w7x*v=>aI{a^p8un4sp7Aq_&X|K!bHxJN#9ZRrO zLF?SnvUg8wr$X%n2t@L!IOb!yxK*c+PNdUq_mD5WJtk5DRs|-2jwzTLM*
gmaZ z`OrDQ6ztd0h*b(RbEZE&OB6Pazmvd^duEsTu||i6$~YdxIt^L&E#uDsOo5Y{VH z(V3mD*Khbt&_tL`C5?tcL~|n^*0AaSq76lLY{nJ^T?}|ezu9S>Vf8Sp(&Fh>9gl#i zICW&Z-E?yP(LkV0!=nmIOGPoJS~N5(%q=A*brQ#Rw938jxC3rb;4QXMD5NHaH;R-A zEZ{z-qY80xIjy4&k2ANWw3va3L(S>5M3ca79ec2sYm7#USs@i(=XfaZRC;NsWj`fm z_vx4neKMNRsiO-AXx7b}jzXgJ!9hYro(Fz)$8iun8lGUn2}B{e?Kqt=^Seawn`-W%-|f>cv!nlOZpse6d2qG+oov=t=6C>Zo{ z_Shf?@*{z6xew>I-gW3mqeyMzsZ#=EcN_TtH4XGc4=y7DLBk1R7_5xv*D-{{nDVwU zAXG*IEJ|HXW~vFlOIgYKDIKRVz!VI714Eq?F-j2Ys9TcN&*FIv&yDGNBMfyGFR%vP zBIzK4imrBqNg{18rQt;$eJ7*X<=6n4iyX3dp*MMp~UV;!GJcbi^_IIY7i zSW->0`I(N-rKBnfzTx?@@}-WiWF=PcUAFW%pBrArl#Uxtoa`FGk&&kz$MgbTG7B2M zW2CY%o;*g#k0;7wLBkJGvm7rt$}$>$nt&li1WQRY<@{A3#upQN2>&5;7mVZ|j%Cv0 zIEvgfOy~a$Kpm#kB(7d=7)JGN)bz~2pTn55yWuwG_e@{RS^PQ{t{TR&8(7iMcoQpc zV0FVUSUrT~9{z2(7*0~w;Ko=@?6=A-6;$2cQ{A+>CN_+g8`voV^D4?~Vnf(dbbbzZ7hn|@Vm%)l ztyoMxuO$yIK@Q7URm-Vahe51h+O5P>)Zax=7$gqkX^!%B1kVIOoP~j2g0mi-$RJC2 zTG0X%eYDla)|SIj!aB&Ag=5@3PHlZu)23!WS7xK^9~v#!pford@-iNbQO?6G{u64P z;2DbJI!3)>2nAw$1(RjcFocuWappG8^;Dl9#)VMe(hy!9!W%<)=Nh%j101S(2GGE( zY~&+t4b~zV#3vrfQ#p)JJmNLiaPh-Y^XKVm88=o4=;gQYQ5odx7Cu$c#}`U&puI7= z0TAC>-au%1evl^XnNk}tlW&JwY$D#9iE}FOfC$Lpkq1j6yi|Y=-|t5PILh!fh01UR U-*Bwv*LHl1@0o*F@uQ6Y0!#QPvj6}9 literal 0 HcmV?d00001 diff --git a/bin/de/steffenvogel/balls/view/StatusBar.class b/bin/de/steffenvogel/balls/view/StatusBar.class new file mode 100644 index 0000000000000000000000000000000000000000..ebcda5196b57eeb7b4da993848b434203c672377 GIT binary patch literal 2002 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 F{~!Aj72f~= literal 0 HcmV?d00001 diff --git a/icons/icons.svg b/icons/icons.svg new file mode 100644 index 0000000..6dac920 --- /dev/null +++ b/icons/icons.svg @@ -0,0 +1,1218 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/levels/billiard/level.xml b/levels/billiard/level.xml new file mode 100644 index 0000000..fabe3ce --- /dev/null +++ b/levels/billiard/level.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/server/config.php b/server/config.php new file mode 100644 index 0000000..3d935d2 --- /dev/null +++ b/server/config.php @@ -0,0 +1,21 @@ + \ No newline at end of file diff --git a/server/get.php b/server/get.php new file mode 100644 index 0000000..d2dee57 --- /dev/null +++ b/server/get.php @@ -0,0 +1,30 @@ +createElement('highscores'); +$highScores->setAttribute('game', $_REQUEST['game']); +$doc->appendChild($highScores); + +$rank = 1; +while ($row = mysql_fetch_assoc($result)) { + $highScore = $doc->createElement('highscore'); + $highScore->setAttribute('id', $row['id']); + $highScore->setAttribute('rank', $rank++); + $highScores->appendChild($highScore); + + foreach (array('date', 'nick', 'score', 'time') as $tagName) { + $highScore->appendChild($doc->createElement($tagName, $row[$tagName])); + } +} + +?> \ No newline at end of file diff --git a/server/init.php b/server/init.php new file mode 100644 index 0000000..188f3fc --- /dev/null +++ b/server/init.php @@ -0,0 +1,15 @@ + \ No newline at end of file diff --git a/server/submit.php b/server/submit.php new file mode 100644 index 0000000..9d299e8 --- /dev/null +++ b/server/submit.php @@ -0,0 +1,5 @@ + \ No newline at end of file diff --git a/sounds/click1.wav b/sounds/click1.wav new file mode 100755 index 0000000000000000000000000000000000000000..f9f01ec3a7857a845f8092349777d1ed0a7b27db GIT binary patch literal 24128 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 CaG@3e literal 0 HcmV?d00001 diff --git a/src/Balls.java b/src/Balls.java new file mode 100644 index 0000000..d13c14f --- /dev/null +++ b/src/Balls.java @@ -0,0 +1,17 @@ +import de.steffenvogel.balls.controller.Loader; +import de.steffenvogel.balls.controller.mode.Demo; +import de.steffenvogel.balls.model.Level; +import de.steffenvogel.balls.model.State; +import de.steffenvogel.balls.view.Gui; + +public class Balls { + public static void main(String[] args) { + + State state = new State(); // Model + Level level = new Level(); // Model + Gui gui = new Gui(level, state); // View + Loader loader = new Loader(level, state, gui); // Controller + + loader.load(Demo.class); + } +} diff --git a/src/de/steffenvogel/balls/controller/Game.java b/src/de/steffenvogel/balls/controller/Game.java new file mode 100644 index 0000000..77b2972 --- /dev/null +++ b/src/de/steffenvogel/balls/controller/Game.java @@ -0,0 +1,189 @@ +package de.steffenvogel.balls.controller; + +import java.awt.event.KeyListener; +import java.awt.event.MouseListener; +import java.awt.event.MouseMotionListener; +import java.awt.event.MouseWheelListener; +import java.util.ListIterator; +import java.util.TimerTask; + +import de.steffenvogel.balls.model.Ball; +import de.steffenvogel.balls.model.Barrier; +import de.steffenvogel.balls.model.Hole; +import de.steffenvogel.balls.model.Level; +import de.steffenvogel.balls.model.State; +import de.steffenvogel.balls.model.State.Status; +import de.steffenvogel.util.Vector2d; + +public abstract class Game extends TimerTask implements MouseListener, MouseMotionListener, MouseWheelListener, KeyListener { + public enum BorderBehaviour { + REFLECT, BEAM, REMOVE + } + + protected Level level; + protected State state; + + public BorderBehaviour borderBehaviour = BorderBehaviour.REMOVE; + + public boolean collisionWithBalls, collisionWithBarriers; + public boolean beamBalls; + public boolean resizable; + public int gravity = 150000; + public double friction; + + public Game(Level level, State state) { + this.level = level; + this.state = state; + } + + protected abstract void ballCollision(Ball b1, Ball b2); + + protected abstract void ballInHole(Ball ball, Hole hole); + + protected abstract void barrierCollision(Ball ball, Barrier barrier); + + synchronized protected void process() { + for (Ball b : level.balls) { + if (b.orientation.length() > Ball.getMaxSpeed()) { + b.orientation = b.orientation.scMultp(Ball.getMaxSpeed() / b.orientation.length()); + } + + if (b.position.x < -b.size || b.position.x > level.size.width + b.size || b.position.y < -b.size || b.position.y > level.size.height + b.size) { + level.balls.remove(b); + System.out.println("ball lost!"); + } else { + b.move(1f); + } + } + + for (Ball b : level.balls) { + processBall(b); + } + } + + protected void processBall(Ball b) { + // border behaviour + switch (this.borderBehaviour) { + case BEAM: + if (b.position.x < 0) + b.position.x += level.size.width; + else if (b.position.x > level.size.width) + b.position.x = 0; + + if (b.position.y < 0) + b.position.y += level.size.height; + else if (b.position.y > level.size.height) + b.position.y = 0; + break; + + case REFLECT: + if (b.position.x < b.size) { + float back = 1 - ((b.size - b.position.x) / (float) b.orientation.x); + b.move(-back); + b.orientation.x *= -1; + b.move(back); + } + else if (b.position.x > level.size.width - b.size) { + float back = 1 - ((b.size - level.size.width + b.position.x) / (float) b.orientation.x); + b.move(-back); + b.orientation.x *= -1; + b.move(back); + } + + if (b.position.y < b.size) { + float back = 1 - ((b.size - b.position.y) / (float) b.orientation.y); + b.move(-back); + b.orientation.y *= -1; + b.move(back); + } + else if (b.position.y > level.size.height - b.size) { + float back = 1 - ((b.size - level.size.height + b.position.y) / (float) b.orientation.y); + b.move(-back); + b.orientation.y *= -1; + b.move(back); + } + break; + + case REMOVE: + // std behavior. ball already has been removed! + break; + } + + // Collision with other balls + if (collisionWithBalls) { + for (ListIterator it = level.balls.listIterator(level.balls.indexOf(b) + 1); it.hasNext();) { + Ball b2 = it.next(); + + if (b.checkCollision(b2)) { + // backsteppin + int i = 0; + float backStepSize = (float) 1 / 10; + while (b.checkCollision(b2) && i <= 10) { // TODO check for infinity loop + b.move(-backStepSize); + b2.move(-backStepSize); + i++; + } + b.collide(b2); // collision + ballCollision(b, b2); // hook for gamemodes + b.move(backStepSize * i); // undo backsteppin + b2.move(backStepSize * i); // undo backsteppin + + + // alternative + Vector2d v = b2.orientation.sub(b.orientation); + Vector2d bp = v.scMultp(v.length() / b.orientation.Multp(v)); + Vector2d b2p = v.scMultp(v.length() / b2.orientation.Multp(v)); + Vector2d n = b2p.sub(bp); + + float back = s + + } + } + } + + // Collision with barriers + if (collisionWithBarriers) { + for (Barrier barrier : level.barriers) { + if (b.checkCollision(barrier)) { + + // TODO check for infinity loop + int i = 0; + float backStepSize = (float) 1 / 10; + while (b.checkCollision(barrier) && i <= 10) { + b.move(-backStepSize); + i++; + } + + b.collide(barrier); //collision + barrierCollision(b, barrier); // hook for gamemodes + b.move(backStepSize * i); // undo backsteppin + } + } + } + + // Collision with holes + for (Hole hole : level.holes) { + if (hole.position.distance(b.position) < (hole.size - b.size)) { + level.balls.remove(b); + ballInHole(b, hole); + } else if (this.gravity != 0) { + hole.gravitate(b, this.gravity); + } + } + + // Reibung + if (b.orientation.length() < 5) { + b.stop(); + } else { + b.orientation = b.orientation.scMultp(friction); + } + } + + public void run() { + synchronized (state) { + if (state.status == Status.RUNNING) { + process(); + } + } + } +} diff --git a/src/de/steffenvogel/balls/controller/Loader.java b/src/de/steffenvogel/balls/controller/Loader.java new file mode 100644 index 0000000..20455ce --- /dev/null +++ b/src/de/steffenvogel/balls/controller/Loader.java @@ -0,0 +1,230 @@ +package de.steffenvogel.balls.controller; + +import java.awt.Image; +import java.awt.event.ActionEvent; +import java.awt.event.ComponentEvent; +import java.awt.event.ComponentListener; +import java.awt.event.KeyListener; +import java.awt.event.MouseListener; +import java.awt.event.MouseMotionListener; +import java.awt.event.MouseWheelListener; +import java.awt.event.WindowEvent; +import java.awt.event.WindowListener; +import java.lang.reflect.Constructor; +import java.util.Timer; + +import javax.swing.AbstractAction; +import javax.swing.Action; +import javax.swing.ImageIcon; +import javax.swing.JOptionPane; + +import de.steffenvogel.balls.controller.mode.AirHockey; +import de.steffenvogel.balls.controller.mode.Billiard; +import de.steffenvogel.balls.controller.mode.ChainRxn; +import de.steffenvogel.balls.controller.mode.Demo; +import de.steffenvogel.balls.controller.mode.Dodge; +import de.steffenvogel.balls.controller.mode.Golf; +import de.steffenvogel.balls.controller.mode.InkBall; +import de.steffenvogel.balls.controller.mode.Pong; +import de.steffenvogel.balls.model.Level; +import de.steffenvogel.balls.model.State; +import de.steffenvogel.balls.view.Gui; + +public class Loader implements WindowListener, ComponentListener { + private State state; + private Level level; + private Gui gui; + private Timer timer; + public Game game; // Sub-Controller + + private abstract class StateAction extends AbstractAction { + private static final long serialVersionUID = -3159579754353760125L; + protected State state; + + public StateAction(State state, String title) { + super(title); + this.state = state; + } + } + + private class LoadAction extends AbstractAction { + private static final long serialVersionUID = 5692117074325799909L; + Class game; + Loader loader; + + public LoadAction(Loader loader, Class game) { + super(game.getSimpleName()); + + try { + ImageIcon ico = new ImageIcon(Gui.class.getResource("images/" + game.getSimpleName().toLowerCase() + ".png")); + ico.setImage(ico.getImage().getScaledInstance(16, 16, Image.SCALE_DEFAULT)); + + this.putValue(Action.SMALL_ICON, ico); + } catch (Throwable t) { + t.printStackTrace(); + } + + this.game = game; + this.loader = loader; + } + + @Override + public void actionPerformed(ActionEvent arg0) { + this.loader.load(this.game); + } + + } + + public Loader(Level level, State state, Gui gui) { + this.level = level; + this.state = state; + this.gui = gui; + + gui.field.addComponentListener(this); + gui.addWindowListener(this); + + this.loadActions(); + } + + private void loadActions() { + gui.menuBar.mnGame.add(new StateAction(this.state, "Starten") { + @Override + public void actionPerformed(ActionEvent arg0) { + this.state.start(); + } + }); + gui.menuBar.mnGame.add(new StateAction(this.state, "Pausieren") { + @Override + public void actionPerformed(ActionEvent e) { + this.state.pause(); + } + }); + gui.menuBar.mnGame.addSeparator(); + gui.menuBar.mnGame.add(new AbstractAction("Beenden") { + @Override + public void actionPerformed(ActionEvent arg0) { + System.exit(0); + } + }); + gui.menuBar.smLoad.add(new LoadAction(this, AirHockey.class)); + gui.menuBar.smLoad.add(new LoadAction(this, Billiard.class)); + gui.menuBar.smLoad.add(new LoadAction(this, ChainRxn.class)); + gui.menuBar.smLoad.add(new LoadAction(this, Demo.class)); + gui.menuBar.smLoad.add(new LoadAction(this, Dodge.class)); + gui.menuBar.smLoad.add(new LoadAction(this, Golf.class)); + gui.menuBar.smLoad.add(new LoadAction(this, InkBall.class)); + gui.menuBar.smLoad.add(new LoadAction(this, Pong.class)); + } + + public void load(Class game) { + // remove listeners + for (MouseListener listener : gui.field.getListeners(MouseListener.class)) gui.field.removeMouseListener(listener); + for (MouseMotionListener listener : gui.field.getListeners(MouseMotionListener.class)) gui.field.removeMouseMotionListener(listener); + for (MouseWheelListener listener : gui.field.getListeners(MouseWheelListener.class)) gui.field.removeMouseWheelListener(listener); + for (KeyListener listener : gui.getListeners(KeyListener.class)) gui.removeKeyListener(listener); + + + // create timer thread + if (this.timer != null) { + this.timer.cancel(); + this.timer.purge(); + } + this.timer = new Timer("controller"); + + // reset level and state + this.level.load(); + this.state.reset(); + this.state.game = game; + this.state.nick = JOptionPane.showInputDialog("Bitte gebe deinen Namen an", this.state.nick); + + try { + Class partypes[] = new Class[2]; + partypes[0] = Level.class; + partypes[1] = State.class; + Constructor ctor = game.getConstructor(partypes); + Object arglist[] = new Object[2]; + arglist[0] = level; + arglist[1] = state; + this.game = (Game) ctor.newInstance(arglist); + } + catch (Throwable e) { + e.printStackTrace(); + } + + // add listeners + gui.field.addMouseListener(this.game); + gui.field.addMouseMotionListener(this.game); + gui.field.addMouseWheelListener(this.game); + gui.addKeyListener(this.game); + + this.gui.setIconImage(new ImageIcon(Gui.class.getResource("images/" + game.getSimpleName().toLowerCase() + ".png")).getImage()); + this.gui.setTitle("2DBalls - " + game.getSimpleName()); + + // start + this.timer.scheduleAtFixedRate(this.game, 0, 30); + state.start(); + + System.out.println("game loaded"); + } + + @Override + public void windowActivated(WindowEvent e) { + this.state.start(); + } + + @Override + public void windowClosed(WindowEvent e) { + // TODO Auto-generated method stub + } + + @Override + public void windowClosing(WindowEvent e) { + // TODO Auto-generated method stub + } + + @Override + public void windowDeactivated(WindowEvent e) { + this.state.pause(); + } + + @Override + public void windowDeiconified(WindowEvent e) { + // TODO Auto-generated method stub + + } + + @Override + public void windowIconified(WindowEvent e) { + // TODO Auto-generated method stub + + } + + @Override + public void windowOpened(WindowEvent e) { + // TODO Auto-generated method stub + + } + + @Override + public void componentHidden(ComponentEvent e) { + // TODO Auto-generated method stub + + } + + @Override + public void componentMoved(ComponentEvent e) { + // TODO Auto-generated method stub + + } + + @Override + public void componentResized(ComponentEvent e) { + this.level.size.set(gui.field.getSize()); + } + + @Override + public void componentShown(ComponentEvent e) { + // TODO Auto-generated method stub + + } +} diff --git a/src/de/steffenvogel/balls/controller/mode/AirHockey.java b/src/de/steffenvogel/balls/controller/mode/AirHockey.java new file mode 100644 index 0000000..5727ff3 --- /dev/null +++ b/src/de/steffenvogel/balls/controller/mode/AirHockey.java @@ -0,0 +1,128 @@ +package de.steffenvogel.balls.controller.mode; + +import java.awt.Color; +import java.awt.event.KeyEvent; +import java.awt.event.MouseEvent; +import java.awt.event.MouseWheelEvent; + +import de.steffenvogel.balls.controller.Game; +import de.steffenvogel.balls.model.Ball; +import de.steffenvogel.balls.model.Barrier; +import de.steffenvogel.balls.model.Hole; +import de.steffenvogel.balls.model.Level; +import de.steffenvogel.balls.model.State; +import de.steffenvogel.balls.view.Field; +import de.steffenvogel.util.Vector2d; + +public class AirHockey extends Game { + + private Ball dodger = null; + private Vector2d mousePosition; + + public AirHockey(Level level, State state) { + super(level, state); + + collisionWithBalls = true; + collisionWithBarriers = false; + gravity = 70000; + friction = 0.978; + borderBehaviour = BorderBehaviour.REFLECT; + + for (int i = 0; i < 6; i++) + level.balls.add(Ball.random(level)); + } + + protected void process() { + if (this.dodger != null) { + dodger.orientation = mousePosition.sub(dodger.position); + super.process(); + } + } + + @Override + public void mouseClicked(MouseEvent e) { + // TODO Auto-generated method stub + + } + + @Override + public void mouseEntered(MouseEvent e) { + // TODO Auto-generated method stub + + } + + @Override + public void mouseExited(MouseEvent e) { + // TODO Auto-generated method stub + + } + + @Override + public void mousePressed(MouseEvent e) { + // TODO Auto-generated method stub + + } + + @Override + public void mouseReleased(MouseEvent e) { + // TODO Auto-generated method stub + + } + + @Override + public void mouseDragged(MouseEvent e) { + this.mouseMoved(e); + } + + @Override + public void mouseMoved(MouseEvent e) { + mousePosition = Field.point2Vector(e.getPoint()); + if (this.dodger == null) { + this.dodger = new Ball(mousePosition, new Vector2d(0, 0), 20 * Field.VIRTUAL_RESOLUTION, 0, Color.red); + while (!level.balls.add(this.dodger)); + } + } + + @Override + public void mouseWheelMoved(MouseWheelEvent e) { + // TODO Auto-generated method stub + + } + + @Override + public void keyPressed(KeyEvent e) { + // TODO Auto-generated method stub + + } + + @Override + public void keyReleased(KeyEvent e) { + // TODO Auto-generated method stub + + } + + @Override + public void keyTyped(KeyEvent e) { + // TODO Auto-generated method stub + + } + + @Override + protected void ballCollision(Ball b1, Ball b2) { + // TODO Auto-generated method stub + + } + + @Override + protected void ballInHole(Ball ball, Hole hole) { + // TODO Auto-generated method stub + + } + + @Override + protected void barrierCollision(Ball ball, Barrier barrier) { + // TODO Auto-generated method stub + + } + +} diff --git a/src/de/steffenvogel/balls/controller/mode/Billiard.java b/src/de/steffenvogel/balls/controller/mode/Billiard.java new file mode 100644 index 0000000..24854b3 --- /dev/null +++ b/src/de/steffenvogel/balls/controller/mode/Billiard.java @@ -0,0 +1,113 @@ +package de.steffenvogel.balls.controller.mode; + +import java.awt.event.KeyEvent; +import java.awt.event.MouseEvent; +import java.awt.event.MouseWheelEvent; + +import de.steffenvogel.balls.controller.Game; +import de.steffenvogel.balls.model.Ball; +import de.steffenvogel.balls.model.BallList; +import de.steffenvogel.balls.model.Barrier; +import de.steffenvogel.balls.model.Hole; +import de.steffenvogel.balls.model.Level; +import de.steffenvogel.balls.model.State; +import de.steffenvogel.balls.view.Gui; + +public class Billiard extends Game { + private BallList full, half; + private Ball white, black; + + public Billiard(Level level, State state) { + super(level, state); + + collisionWithBalls = true; + collisionWithBarriers = true; + gravity = 50000; + friction = 0.98; + } + + @Override + public void mouseClicked(MouseEvent e) { + // TODO Auto-generated method stub + + } + + @Override + public void mouseEntered(MouseEvent e) { + // TODO Auto-generated method stub + + } + + @Override + public void mouseExited(MouseEvent e) { + // TODO Auto-generated method stub + + } + + @Override + public void mousePressed(MouseEvent e) { + // TODO Auto-generated method stub + + } + + @Override + public void mouseReleased(MouseEvent e) { + // TODO Auto-generated method stub + + } + + @Override + public void mouseDragged(MouseEvent e) { + // TODO Auto-generated method stub + + } + + @Override + public void mouseMoved(MouseEvent e) { + // TODO Auto-generated method stub + + } + + @Override + public void mouseWheelMoved(MouseWheelEvent e) { + // TODO Auto-generated method stub + + } + + @Override + public void keyPressed(KeyEvent e) { + // TODO Auto-generated method stub + + } + + @Override + public void keyReleased(KeyEvent e) { + // TODO Auto-generated method stub + + } + + @Override + public void keyTyped(KeyEvent e) { + // TODO Auto-generated method stub + + } + + @Override + protected void ballCollision(Ball b1, Ball b2) { + // TODO Auto-generated method stub + + } + + @Override + protected void ballInHole(Ball ball, Hole hole) { + // TODO Auto-generated method stub + + } + + @Override + protected void barrierCollision(Ball ball, Barrier barrier) { + // TODO Auto-generated method stub + + } + +} diff --git a/src/de/steffenvogel/balls/controller/mode/ChainRxn.java b/src/de/steffenvogel/balls/controller/mode/ChainRxn.java new file mode 100644 index 0000000..4d067d6 --- /dev/null +++ b/src/de/steffenvogel/balls/controller/mode/ChainRxn.java @@ -0,0 +1,110 @@ +package de.steffenvogel.balls.controller.mode; + +import java.awt.event.KeyEvent; +import java.awt.event.MouseEvent; +import java.awt.event.MouseWheelEvent; + +import de.steffenvogel.balls.controller.Game; +import de.steffenvogel.balls.model.Ball; +import de.steffenvogel.balls.model.Barrier; +import de.steffenvogel.balls.model.Hole; +import de.steffenvogel.balls.model.Level; +import de.steffenvogel.balls.model.State; +import de.steffenvogel.balls.view.Gui; + +public class ChainRxn extends Game { + + public ChainRxn(Level level, State state) { + super(level, state); + + collisionWithBalls = true; + collisionWithBarriers = true; + gravity = 70000; + friction = 0.99; + } + + @Override + public void mouseClicked(MouseEvent e) { + // TODO Auto-generated method stub + + } + + @Override + public void mouseEntered(MouseEvent e) { + // TODO Auto-generated method stub + + } + + @Override + public void mouseExited(MouseEvent e) { + // TODO Auto-generated method stub + + } + + @Override + public void mousePressed(MouseEvent e) { + // TODO Auto-generated method stub + + } + + @Override + public void mouseReleased(MouseEvent e) { + // TODO Auto-generated method stub + + } + + @Override + public void mouseDragged(MouseEvent e) { + // TODO Auto-generated method stub + + } + + @Override + public void mouseMoved(MouseEvent e) { + // TODO Auto-generated method stub + + } + + @Override + public void mouseWheelMoved(MouseWheelEvent e) { + // TODO Auto-generated method stub + + } + + @Override + public void keyPressed(KeyEvent e) { + // TODO Auto-generated method stub + + } + + @Override + public void keyReleased(KeyEvent e) { + // TODO Auto-generated method stub + + } + + @Override + public void keyTyped(KeyEvent e) { + // TODO Auto-generated method stub + + } + + @Override + protected void ballCollision(Ball b1, Ball b2) { + // TODO Auto-generated method stub + + } + + @Override + protected void ballInHole(Ball ball, Hole hole) { + // TODO Auto-generated method stub + + } + + @Override + protected void barrierCollision(Ball ball, Barrier barrier) { + // TODO Auto-generated method stub + + } + +} diff --git a/src/de/steffenvogel/balls/controller/mode/Demo.java b/src/de/steffenvogel/balls/controller/mode/Demo.java new file mode 100644 index 0000000..f7c93fb --- /dev/null +++ b/src/de/steffenvogel/balls/controller/mode/Demo.java @@ -0,0 +1,224 @@ +package de.steffenvogel.balls.controller.mode; + +import java.awt.Color; +import java.awt.event.KeyEvent; +import java.awt.event.MouseEvent; +import java.awt.event.MouseWheelEvent; +import java.io.File; + +import de.steffenvogel.balls.controller.Game; +import de.steffenvogel.balls.model.Ball; +import de.steffenvogel.balls.model.Barrier; +import de.steffenvogel.balls.model.Hole; +import de.steffenvogel.balls.model.Level; +import de.steffenvogel.balls.model.State; +import de.steffenvogel.balls.view.Field; +import de.steffenvogel.balls.view.Sound; +import de.steffenvogel.util.Vector2d; + +public class Demo extends Game { + private Ball pressed, moved; + private Barrier barrier; + + public Demo(Level level, State state) { + super(level, state); + + collisionWithBalls = true; + collisionWithBarriers = true; + resizable = true; + gravity = 15000; + friction = 1; + borderBehaviour = BorderBehaviour.REFLECT; + + for (int i = 0; i < 6; i++) + this.level.balls.add(Ball.random(this.level)); + } + + @Override + protected void ballCollision(Ball b1, Ball b2) { + state.addPoints((int) (b1.size + b2.size)/Field.VIRTUAL_RESOLUTION); + } + + @Override + protected void ballInHole(Ball ball, Hole hole) { + state.addPoints(5000); + } + + @Override + protected void barrierCollision(Ball ball, Barrier barrier) { + //level.barriers.remove(barrier); + + state.addPoints(300); + } + + @Override + public void keyPressed(KeyEvent e) { + // TODO Auto-generated method stub + + } + + @Override + public void keyReleased(KeyEvent e) { + // TODO Auto-generated method stub + + } + + @Override + public void keyTyped(KeyEvent e) { + switch (e.getKeyChar()) { + case 'r': + level.balls.clear(); + level.barriers.clear(); + level.holes.clear(); + break; + case 's': + for (Ball ball : level.balls) + ball.stop(); + break; + case 'f': + level.save(new File("level.xml")); + break; + case 'l': + level.load(new File("level.xml")); + break; + case 'n': + for (int i = 0; i < 6; i++) + level.balls.add(Ball.random(level)); + break; + default: + break; + } + } + + @Override + public void mouseClicked(MouseEvent e) { + // TODO Auto-generated method stub + + } + + @Override + public void mouseDragged(MouseEvent e) { + if (pressed != null) { + moved.position = Field.point2Vector(e.getPoint()); + + // Snapping + if (barrier != null) { + Ball snap = null; + Vector2d mouse = Field.point2Vector(e.getPoint()); + + for (Ball b : level.balls) { + if (b.position.distance(mouse) < 2000 && b != moved && b != barrier.start) { + snap = b; + break; + } + } + + if (snap != null) { + if (level.balls.contains(moved)) { + level.balls.remove(moved); + } + barrier.end = snap; + } else { + if (level.balls.contains(moved) == false) { + level.balls.add(moved); + } + barrier.end = moved; + } + + if (pressed.position.distance(moved.position) > 100 && e.getModifiersEx() == MouseEvent.BUTTON2_DOWN_MASK) { + level.barriers.add(new Barrier(pressed, moved)); + pressed = moved; + moved = new Ball(moved); + } + } + } + } + + @Override + public void mouseEntered(MouseEvent e) { + // TODO Auto-generated method stub + + } + + @Override + public void mouseExited(MouseEvent e) { + // TODO Auto-generated method stub + + } + + @Override + public void mouseMoved(MouseEvent e) { + // TODO Auto-generated method stub + + } + + @Override + public void mousePressed(MouseEvent e) { + long size; + double mass; + Color color; + + if (e.getButton() == MouseEvent.BUTTON3 || e.getButton() == MouseEvent.BUTTON2) { + size = 1 * Field.VIRTUAL_RESOLUTION; + mass = 0; + color = Color.green; + } else { + size = 20 * Field.VIRTUAL_RESOLUTION; + mass = Math.round(Math.PI * Math.pow(10 * Field.VIRTUAL_RESOLUTION, 2)); + color = Ball.getColorFromSize(20 * Field.VIRTUAL_RESOLUTION); + } + + // Snapping + if (e.getButton() == MouseEvent.BUTTON3 || e.getButton() == MouseEvent.BUTTON2) { + Vector2d mouse = Field.point2Vector(e.getPoint()); + for (Ball b : level.balls) { + if (b.position.distance(mouse) < 2000) { + pressed = b; + break; + } + } + } + + if (pressed == null) { + pressed = new Ball(Field.point2Vector(e.getPoint()), new Vector2d(0, 0), size, mass, color); + } + moved = new Ball(pressed); + + // TODO check collision between start and endpoint of barrier + if (level.balls.checkCollision(pressed) == false) { + if (e.getButton() == MouseEvent.BUTTON3 || e.getButton() == MouseEvent.BUTTON2) { + barrier = new Barrier(pressed, moved); + level.barriers.add(barrier); + } else if (e.getButton() == MouseEvent.BUTTON1) { + level.balls.add(pressed); + } + } else { + pressed = null; + moved = null; + } + } + + @Override + public void mouseReleased(MouseEvent e) { + if (pressed != null) { + if (barrier == null) { + pressed.orientation = pressed.position.sub(moved.position).scMultp(0.1); + } + } + + pressed = null; + moved = null; + barrier = null; + } + + @Override + public void mouseWheelMoved(MouseWheelEvent e) { + if (pressed != null) { + if (pressed.size + 2 * Field.VIRTUAL_RESOLUTION * e.getWheelRotation() > Ball.minSize && pressed.size + 2 * Field.VIRTUAL_RESOLUTION * e.getWheelRotation() < Ball.maxSize) { + pressed.size += 2 * e.getWheelRotation() * Field.VIRTUAL_RESOLUTION; + pressed.mass = Math.PI * Math.pow(pressed.size, 2); + pressed.color = Ball.getColorFromSize(pressed.size); + } + } + } +} diff --git a/src/de/steffenvogel/balls/controller/mode/Dodge.java b/src/de/steffenvogel/balls/controller/mode/Dodge.java new file mode 100644 index 0000000..aa0a25f --- /dev/null +++ b/src/de/steffenvogel/balls/controller/mode/Dodge.java @@ -0,0 +1,134 @@ +package de.steffenvogel.balls.controller.mode; + +import java.awt.Color; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.KeyEvent; +import java.awt.event.MouseEvent; +import java.awt.event.MouseWheelEvent; + +import javax.swing.Timer; + +import de.steffenvogel.balls.controller.Game; +import de.steffenvogel.balls.model.Ball; +import de.steffenvogel.balls.model.Barrier; +import de.steffenvogel.balls.model.Hole; +import de.steffenvogel.balls.model.Level; +import de.steffenvogel.balls.model.State; +import de.steffenvogel.balls.model.State.Status; +import de.steffenvogel.balls.view.Field; +import de.steffenvogel.util.Vector2d; + +public class Dodge extends Game implements ActionListener { + + private Ball dodger; + long lastAdded = System.currentTimeMillis(); + + public Dodge(Level level, State state) { + super(level, state); + + collisionWithBalls = true; + collisionWithBarriers = false; + gravity = 70000; + friction = 1.00002; + borderBehaviour = BorderBehaviour.REFLECT; + + dodger = new Ball(new Vector2d(0, 0), new Vector2d(0, 0), 20 * Field.VIRTUAL_RESOLUTION, 0, Color.red); + level.balls.add(dodger); + + new Timer(3000, this).start(); + } + + @Override + public void mouseClicked(MouseEvent e) { + // TODO Auto-generated method stub + + } + + @Override + public void mouseEntered(MouseEvent e) { + // TODO Auto-generated method stub + + } + + @Override + public void mouseExited(MouseEvent e) { + // TODO Auto-generated method stub + + } + + @Override + public void mousePressed(MouseEvent e) { + // TODO Auto-generated method stub + + } + + @Override + public void mouseReleased(MouseEvent e) { + // TODO Auto-generated method stub + + } + + @Override + public void mouseDragged(MouseEvent e) { + // TODO Auto-generated method stub + + } + + @Override + public void mouseMoved(MouseEvent e) { + dodger.position = Field.point2Vector(e.getPoint()); + } + + @Override + public void mouseWheelMoved(MouseWheelEvent e) { + // TODO Auto-generated method stub + + } + + @Override + public void keyPressed(KeyEvent e) { + // TODO Auto-generated method stub + + } + + @Override + public void keyReleased(KeyEvent e) { + // TODO Auto-generated method stub + + } + + @Override + public void keyTyped(KeyEvent e) { + // TODO Auto-generated method stub + + } + + @Override + protected void ballCollision(Ball b1, Ball b2) { + if (b1 == dodger || b2 == dodger) { + state.gameOver(); + } + } + + @Override + protected void ballInHole(Ball ball, Hole hole) { + // TODO Auto-generated method stub + + } + + @Override + protected void barrierCollision(Ball ball, Barrier barrier) { + // TODO Auto-generated method stub + + } + + @Override + public void actionPerformed(ActionEvent e) { + if (state.status == Status.RUNNING) { + level.balls.add(Ball.random(level)); + state.addPoints(100); + } + } + +} diff --git a/src/de/steffenvogel/balls/controller/mode/Golf.java b/src/de/steffenvogel/balls/controller/mode/Golf.java new file mode 100644 index 0000000..01096b5 --- /dev/null +++ b/src/de/steffenvogel/balls/controller/mode/Golf.java @@ -0,0 +1,114 @@ +package de.steffenvogel.balls.controller.mode; + +import java.awt.event.KeyEvent; +import java.awt.event.MouseEvent; +import java.awt.event.MouseWheelEvent; + +import de.steffenvogel.balls.controller.Game; +import de.steffenvogel.balls.model.Ball; +import de.steffenvogel.balls.model.Barrier; +import de.steffenvogel.balls.model.Hole; +import de.steffenvogel.balls.model.Level; +import de.steffenvogel.balls.model.State; +import de.steffenvogel.balls.view.Gui; + +public class Golf extends Game { + + public Golf(Level level, State state) { + super(level, state); + + collisionWithBalls = true; + collisionWithBarriers = true; + borderBehaviour = BorderBehaviour.REMOVE; + gravity = 70000; + friction = 0.99; + + for (int i = 0; i < 6; i++) + level.balls.add(Ball.random(level)); + } + + @Override + public void mouseClicked(MouseEvent e) { + // TODO Auto-generated method stub + + } + + @Override + public void mouseEntered(MouseEvent e) { + // TODO Auto-generated method stub + + } + + @Override + public void mouseExited(MouseEvent e) { + // TODO Auto-generated method stub + + } + + @Override + public void mousePressed(MouseEvent e) { + // TODO Auto-generated method stub + + } + + @Override + public void mouseReleased(MouseEvent e) { + // TODO Auto-generated method stub + + } + + @Override + public void mouseDragged(MouseEvent e) { + // TODO Auto-generated method stub + + } + + @Override + public void mouseMoved(MouseEvent e) { + // TODO Auto-generated method stub + + } + + @Override + public void mouseWheelMoved(MouseWheelEvent e) { + // TODO Auto-generated method stub + + } + + @Override + public void keyPressed(KeyEvent e) { + // TODO Auto-generated method stub + + } + + @Override + public void keyReleased(KeyEvent e) { + // TODO Auto-generated method stub + + } + + @Override + public void keyTyped(KeyEvent e) { + // TODO Auto-generated method stub + + } + + @Override + protected void ballCollision(Ball b1, Ball b2) { + // TODO Auto-generated method stub + + } + + @Override + protected void ballInHole(Ball ball, Hole hole) { + // TODO Auto-generated method stub + + } + + @Override + protected void barrierCollision(Ball ball, Barrier barrier) { + // TODO Auto-generated method stub + + } + +} diff --git a/src/de/steffenvogel/balls/controller/mode/InkBall.java b/src/de/steffenvogel/balls/controller/mode/InkBall.java new file mode 100644 index 0000000..b77fbb5 --- /dev/null +++ b/src/de/steffenvogel/balls/controller/mode/InkBall.java @@ -0,0 +1,170 @@ +package de.steffenvogel.balls.controller.mode; + +import java.awt.Color; +import java.awt.event.KeyEvent; +import java.awt.event.MouseEvent; +import java.awt.event.MouseWheelEvent; + +import de.steffenvogel.balls.controller.Game; +import de.steffenvogel.balls.model.Ball; +import de.steffenvogel.balls.model.Barrier; +import de.steffenvogel.balls.model.Hole; +import de.steffenvogel.balls.model.Level; +import de.steffenvogel.balls.model.State; +import de.steffenvogel.balls.view.Field; +import de.steffenvogel.util.Vector2d; + +public class InkBall extends Game { + + private Ball pressed, moved; + private Barrier barrier; + + public InkBall(Level level, State state) { + super(level, state); + + collisionWithBalls = true; + collisionWithBarriers = true; + gravity = 70000; + borderBehaviour = BorderBehaviour.BEAM; + + level.holes.add(new Hole(new Vector2d(Math.round(level.size.width / 2), Math.round(level.size.height / 2)), 3000, 6000)); + + while (!level.balls.add(Ball.random(level))); + } + + @Override + public void mouseClicked(MouseEvent arg0) { + // TODO Auto-generated method stub + + } + + @Override + public void mouseEntered(MouseEvent arg0) { + // TODO Auto-generated method stub + + } + + @Override + public void mouseExited(MouseEvent arg0) { + // TODO Auto-generated method stub + + } + + @Override + public void mousePressed(MouseEvent e) { + // Snapping + Vector2d mouse = Field.point2Vector(e.getPoint()); + for (Ball b : level.balls) { + if (b.position.distance(mouse) < 2000) { + pressed = b; + break; + } + } + + if (pressed == null) { + pressed = new Ball(Field.point2Vector(e.getPoint()), new Vector2d(0, 0), 1 * Field.VIRTUAL_RESOLUTION, 0, Color.white); + } + moved = new Ball(pressed); + + // TODO check collision between start and endpoint of barrier + if (level.balls.checkCollision(pressed) == false) { + barrier = new Barrier(pressed, moved); + level.barriers.add(barrier); + } else { + pressed = null; + moved = null; + } + } + + @Override + public void mouseReleased(MouseEvent arg0) { + // TODO Auto-generated method stub + + } + + @Override + public void mouseDragged(MouseEvent e) { + if (pressed != null) { + moved.position = Field.point2Vector(e.getPoint()); + + // Snapping + if (barrier != null) { + Ball snap = null; + Vector2d mouse = Field.point2Vector(e.getPoint()); + + for (Ball b : level.balls) { + if (b.position.distance(mouse) < 2000 && b != moved && b != barrier.start) { + snap = b; + break; + } + } + + if (snap != null) { + if (level.balls.contains(moved)) { + level.balls.remove(moved); + } + barrier.end = snap; + } else { + if (level.balls.contains(moved) == false) { + level.balls.add(moved); + } + barrier.end = moved; + } + + if (pressed.position.distance(moved.position) > 100 && e.getModifiersEx() == MouseEvent.BUTTON2_DOWN_MASK) { + level.barriers.add(new Barrier(pressed, moved)); + pressed = moved; + moved = new Ball(moved); + } + } + } + } + + @Override + public void mouseMoved(MouseEvent arg0) { + // TODO Auto-generated method stub + + } + + @Override + public void mouseWheelMoved(MouseWheelEvent arg0) { + // TODO Auto-generated method stub + + } + + @Override + public void keyPressed(KeyEvent arg0) { + + } + + @Override + public void keyReleased(KeyEvent arg0) { + // TODO Auto-generated method stub + + } + + @Override + public void keyTyped(KeyEvent arg0) { + // TODO Auto-generated method stub + + } + + @Override + protected void ballCollision(Ball b1, Ball b2) { + // TODO Auto-generated method stub + + } + + @Override + protected void ballInHole(Ball ball, Hole hole) { + while (!level.balls.add(Ball.random(level))); + state.addPoints(100); + } + + @Override + protected void barrierCollision(Ball ball, Barrier barrier) { + // TODO Auto-generated method stub + + } + +} diff --git a/src/de/steffenvogel/balls/controller/mode/Pong.java b/src/de/steffenvogel/balls/controller/mode/Pong.java new file mode 100644 index 0000000..8f9f943 --- /dev/null +++ b/src/de/steffenvogel/balls/controller/mode/Pong.java @@ -0,0 +1,110 @@ +package de.steffenvogel.balls.controller.mode; + +import java.awt.event.KeyEvent; +import java.awt.event.MouseEvent; +import java.awt.event.MouseWheelEvent; + +import de.steffenvogel.balls.controller.Game; +import de.steffenvogel.balls.model.Ball; +import de.steffenvogel.balls.model.Barrier; +import de.steffenvogel.balls.model.Hole; +import de.steffenvogel.balls.model.Level; +import de.steffenvogel.balls.model.State; + +public class Pong extends Game { + + public Pong(Level level, State state) { + super(level, state); + + collisionWithBalls = true; + collisionWithBarriers = true; + gravity = 70000; + beamBalls = false; + friction = 0.99; + } + + @Override + public void mouseClicked(MouseEvent e) { + // TODO Auto-generated method stub + + } + + @Override + public void mouseEntered(MouseEvent e) { + // TODO Auto-generated method stub + + } + + @Override + public void mouseExited(MouseEvent e) { + // TODO Auto-generated method stub + + } + + @Override + public void mousePressed(MouseEvent e) { + // TODO Auto-generated method stub + + } + + @Override + public void mouseReleased(MouseEvent e) { + // TODO Auto-generated method stub + + } + + @Override + public void mouseDragged(MouseEvent e) { + // TODO Auto-generated method stub + + } + + @Override + public void mouseMoved(MouseEvent e) { + // TODO Auto-generated method stub + + } + + @Override + public void mouseWheelMoved(MouseWheelEvent e) { + // TODO Auto-generated method stub + + } + + @Override + public void keyPressed(KeyEvent e) { + // TODO Auto-generated method stub + + } + + @Override + public void keyReleased(KeyEvent e) { + // TODO Auto-generated method stub + + } + + @Override + public void keyTyped(KeyEvent e) { + // TODO Auto-generated method stub + + } + + @Override + protected void ballCollision(Ball b1, Ball b2) { + // TODO Auto-generated method stub + + } + + @Override + protected void ballInHole(Ball ball, Hole hole) { + // TODO Auto-generated method stub + + } + + @Override + protected void barrierCollision(Ball ball, Barrier barrier) { + // TODO Auto-generated method stub + + } + +} diff --git a/src/de/steffenvogel/balls/model/Ball.java b/src/de/steffenvogel/balls/model/Ball.java new file mode 100644 index 0000000..64e23bc --- /dev/null +++ b/src/de/steffenvogel/balls/model/Ball.java @@ -0,0 +1,152 @@ +package de.steffenvogel.balls.model; + +import java.awt.Color; +import java.util.Random; + +import org.w3c.dom.Document; +import org.w3c.dom.Element; + +import de.steffenvogel.balls.view.Field; +import de.steffenvogel.util.Vector2d; + + +public class Ball implements Renderable { + public long size; // radius + + public static int maxSize = 40 * Field.VIRTUAL_RESOLUTION; + public static int minSize = 15 * Field.VIRTUAL_RESOLUTION; + private static long minSpeed = 6 * Field.VIRTUAL_RESOLUTION; + + public double mass; + public Vector2d orientation; // bearing & speed + public Vector2d position; // position + public Color color; + + public static long getMaxSpeed() { + return (2 * Ball.minSize) - 1; + } + + public Ball(Vector2d position, Vector2d orientation, long size, double mass, Color color) { + this.position = position; + this.orientation = orientation; + this.size = size; + this.color = color; + this.mass = mass == 0 ? 1e10 : mass; + } + + public Ball(Ball ball) { + this.position = new Vector2d(ball.position); + this.orientation = new Vector2d(ball.orientation); + this.size = ball.size; + this.color = ball.color; + this.mass = ball.mass; + } + + public Ball(Element xml) { + this.size = new Integer(xml.getAttribute("size")); + this.mass = new Double(xml.getAttribute("mass")); + this.color = new Color(new Integer(xml.getAttribute("color"))); + this.position = new Vector2d((Element) xml.getElementsByTagName("position").item(0)); + this.orientation = new Vector2d((Element) xml.getElementsByTagName("orientation").item(0)); + } + + public void move(float steps) { + position.x += Math.round(orientation.x * steps); + position.y += Math.round(orientation.y * steps); + } + + static public Ball random(Level level) { + Random rnd = new Random(); + + // speed + long speed = rnd.nextLong(); + if (speed < 0) + speed *= -1; + if (speed >= (getMaxSpeed() - minSpeed)) + speed %= (getMaxSpeed() - minSpeed); + + speed += minSpeed; + speed /= 3; + + // orientation + Vector2d orientation = new Vector2d(rnd.nextInt(), rnd.nextInt()); + orientation = orientation.scMultp(speed / (double) orientation.length()); + + // position + Vector2d position = new Vector2d(Ball.maxSize + Math.round(rnd.nextDouble() * (level.size.width - 2 * Ball.maxSize)), Ball.maxSize + Math.round(rnd.nextDouble() * (level.size.height - 2 * Ball.maxSize))); + long size = Ball.minSize + rnd.nextInt(Ball.maxSize - Ball.minSize); + + double mass = Math.PI * Math.pow(size, 2); + Color color = Ball.getColorFromSize(size); + + return new Ball(position, orientation, size, mass, color); + } + + public Element toXml(Document doc) { + Element xml = doc.createElement("ball"); + xml.setAttribute("size", String.valueOf(size)); + xml.setAttribute("mass", String.valueOf(mass)); + xml.setAttribute("color", String.valueOf(color.getRGB())); + xml.appendChild(position.toXml("position", doc)); + xml.appendChild(orientation.toXml("orientation", doc)); + + return xml; + } + + public static Color getColorFromSize(long size) { + return Color.getHSBColor((size - Ball.minSize) / (float) Ball.maxSize, 1f, 1f); + } + + public boolean checkCollision(Ball b) { + if (position.distance(b.position) <= size + b.size && b != this) { + return true; + } + else { + return false; + } + } + + public boolean checkCollision(Barrier barrier) { + Vector2d z = barrier.start.position.sub(position); + Vector2d r = barrier.end.position.sub(barrier.start.position); + + double d = Math.sqrt(2*z.x*r.x*z.y*r.y + Math.pow(r.x, 2)*Math.pow(size, 2) - Math.pow(r.x, 2)*Math.pow(z.y, 2) - Math.pow(r.y, 2)*Math.pow(z.x, 2) + Math.pow(r.y, 2)*Math.pow(size, 2)); + + double t1 = (-(z.Multp(r)) + d) / (float) r.sqLength(); + double t2 = -(z.Multp(r) + d) / (float) r.sqLength(); + + if (((t1 > 0 && t1 < 1) || (t2 > 0 && t2 < 1)) && this != barrier.start && this != barrier.end) { + return true; + } + else { + return false; + } + } + + public void collide(Ball b) { + Vector2d q = position.sub(b.position); + Vector2d n = new Vector2d(-q.y, q.x); + Vector2d p = orientation.sub(b.orientation).scMultp(mass); + + Vector2d pr = q.scMultp(q.Multp(p) / (double) q.sqLength()); + Vector2d pt = n. scMultp(n.Multp(p) / (double) n.sqLength()); + + orientation = pt.add(pr.scMultp((mass - b.mass) / (mass + b.mass))).scMultp(1 / mass).add(b.orientation); + b.orientation = pr.scMultp((2 * b.mass) / (mass + b.mass)).scMultp(1 / b.mass).add(b.orientation); + } + + public void collide(Barrier barrier) { + Vector2d q = barrier.end.position.sub(barrier.start.position); + Vector2d n = new Vector2d(-q.y, q.x); + Vector2d p = orientation; + + Vector2d pt = q.scMultp(q.Multp(p) / (double) q.sqLength()); + Vector2d pr = n.scMultp(n.Multp(p) / (double) n.sqLength()); + orientation = pt.sub(pr); + } + + public void stop() { + orientation.x = 0; + orientation.y = 0; + } +} diff --git a/src/de/steffenvogel/balls/model/BallList.java b/src/de/steffenvogel/balls/model/BallList.java new file mode 100644 index 0000000..9356eff --- /dev/null +++ b/src/de/steffenvogel/balls/model/BallList.java @@ -0,0 +1,48 @@ +package de.steffenvogel.balls.model; + +import java.util.concurrent.CopyOnWriteArrayList; + +import org.w3c.dom.Document; +import org.w3c.dom.Element; + +public class BallList extends CopyOnWriteArrayList { + + private static final long serialVersionUID = -8941543143009333597L; + + @Override + public boolean add(Ball b) { + if (checkCollision(b) == false) { + super.add(b); + return true; + } else { + return false; + } + } + + public boolean checkCollision(Ball b) { + boolean collision = false; + for (Ball ball : this) { + if (b.checkCollision(ball)) { + collision = true; + } + } + + return collision; + } + + public void clear() { + for (Ball ball : this) { + remove(ball); + } + } + + public Element toXml(Document doc) { + Element xmlBalls = doc.createElement("balls"); + + for (Ball ball : this) { + xmlBalls.appendChild(ball.toXml(doc)); + } + + return xmlBalls; + } +} diff --git a/src/de/steffenvogel/balls/model/Barrier.java b/src/de/steffenvogel/balls/model/Barrier.java new file mode 100644 index 0000000..3031eee --- /dev/null +++ b/src/de/steffenvogel/balls/model/Barrier.java @@ -0,0 +1,26 @@ +package de.steffenvogel.balls.model; + +import org.w3c.dom.Document; +import org.w3c.dom.Element; + + + +public class Barrier implements Renderable { + public Ball start, end; + + public Barrier(Ball start, Ball end) { + this.start = start; + this.end = end; + } + + + // TODO unused ? + public Element toXml(Document doc) { + Element xml = doc.createElement("barrier"); + + xml.appendChild(start.toXml(doc)); + xml.appendChild(end.toXml(doc)); + + return xml; + } +} diff --git a/src/de/steffenvogel/balls/model/BarrierList.java b/src/de/steffenvogel/balls/model/BarrierList.java new file mode 100644 index 0000000..91fe85d --- /dev/null +++ b/src/de/steffenvogel/balls/model/BarrierList.java @@ -0,0 +1,66 @@ +package de.steffenvogel.balls.model; + + +import java.util.concurrent.CopyOnWriteArrayList; + +import org.w3c.dom.Document; +import org.w3c.dom.Element; + +public class BarrierList extends CopyOnWriteArrayList { + + private static final long serialVersionUID = 8921059530813919037L; + + BallList balls; + + public BarrierList(BallList balls) { + this.balls = balls; + } + + public boolean add(Barrier barrier) { + balls.add(barrier.start); + balls.add(barrier.end); + return super.add(barrier); + } + + public void remove(Barrier barrier) { + super.remove(barrier); + balls.remove(barrier.start); + balls.remove(barrier.end); + } + + public void clear() { + for (Barrier barrier : this) { + remove(barrier); + } + } + + public Element toXml(Document doc) { + Element xmlBarriers = doc.createElement("barriers"); + BallList barrierBalls = new BallList(); + + /*for (Barrier barrier : this) { + xmlBarriers.appendChild(barrier.toXml(doc)); + }*/ + + // TODO complete xml generation + for (Barrier barrier : this) { + for (Barrier subBarrier : this) { + if (barrier.start == subBarrier.start) { + barrierBalls.add(barrier.start); + } + if (barrier.start == subBarrier.end) { + barrierBalls.add(subBarrier.start); + barrierBalls.add(barrier.start); + barrierBalls.add(barrier.end); + } + if (barrier.end == subBarrier.start) { + } + if (barrier.end == subBarrier.end) { + } + } + } + + return xmlBarriers; + } + +} diff --git a/src/de/steffenvogel/balls/model/HighScore.java b/src/de/steffenvogel/balls/model/HighScore.java new file mode 100644 index 0000000..70eba3e --- /dev/null +++ b/src/de/steffenvogel/balls/model/HighScore.java @@ -0,0 +1,6 @@ +package de.steffenvogel.balls.model; + +public class HighScore { + + public State list[]; +} diff --git a/src/de/steffenvogel/balls/model/Hole.java b/src/de/steffenvogel/balls/model/Hole.java new file mode 100644 index 0000000..473bf8d --- /dev/null +++ b/src/de/steffenvogel/balls/model/Hole.java @@ -0,0 +1,42 @@ +package de.steffenvogel.balls.model; + +import org.w3c.dom.Document; +import org.w3c.dom.Element; + +import de.steffenvogel.util.Vector2d; + +public class Hole implements Renderable { + + public Vector2d position; + public int size; + public double mass; + + public Hole(Vector2d position, int size, double mass) { + this.position = position; + this.size = size; + this.mass = mass; + } + + public Hole(Element xml) { + this.size = new Integer(xml.getAttribute("size")); + this.position = new Vector2d((Element) xml.getElementsByTagName("position").item(0)); + } + + public Element toXml(Document doc) { + Element xml = doc.createElement("hole"); + xml.setAttribute("size", new Integer(size).toString()); + xml.appendChild(position.toXml("position", doc)); + + return xml; + } + + + // TODO geschwindigkeit bei iteration beachten! + public void gravitate(Ball b, int gravity) { + double r2 = position.sqDistance(b.position); + if (mass / (double) r2 > 1 / (double) gravity) { + Vector2d r = position.sub(b.position); + b.orientation = b.orientation.add(r.scMultp(gravity * (1 / r.length())).scMultp(mass / r2)); + } + } +} diff --git a/src/de/steffenvogel/balls/model/HoleList.java b/src/de/steffenvogel/balls/model/HoleList.java new file mode 100644 index 0000000..8199338 --- /dev/null +++ b/src/de/steffenvogel/balls/model/HoleList.java @@ -0,0 +1,25 @@ +package de.steffenvogel.balls.model; + +import java.util.concurrent.CopyOnWriteArrayList; + +import org.w3c.dom.Document; +import org.w3c.dom.Element; + +public class HoleList extends CopyOnWriteArrayList { + + private static final long serialVersionUID = 379892301442116885L; + + public HoleList() { + // TODO Auto-generated constructor stub + } + + public Element toXml(Document doc) { + Element xmlHoles = doc.createElement("holes"); + + for (Hole hole : this) { + xmlHoles.appendChild(hole.toXml(doc)); + } + + return xmlHoles; + } +} diff --git a/src/de/steffenvogel/balls/model/Level.java b/src/de/steffenvogel/balls/model/Level.java new file mode 100644 index 0000000..11e57d5 --- /dev/null +++ b/src/de/steffenvogel/balls/model/Level.java @@ -0,0 +1,126 @@ +package de.steffenvogel.balls.model; + +import java.awt.Dimension; + + +import java.io.File; +import java.util.Observable; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; + +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.NodeList; + +import com.sun.org.apache.xml.internal.serialize.XMLSerializer; + +import de.steffenvogel.balls.view.Field; + +@SuppressWarnings("restriction") +public class Level extends Observable { + public BallList balls = new BallList(); + public BarrierList barriers = new BarrierList(balls); + public HoleList holes = new HoleList(); + + public String name; + public boolean resizable; + + public VirtualDimension size; + + public Level() { + load(); + } + + public class VirtualDimension { + public long width, height; + + public VirtualDimension(long width, long height) { + this.width = width; + this.height = height; + } + + public VirtualDimension() { + width = height = 0; + } + + public void set(Dimension dim) { + width = dim.width * Field.VIRTUAL_RESOLUTION; + height = dim.height * Field.VIRTUAL_RESOLUTION; + } + + public Dimension toDimension() { + return new Dimension(Math.round(width / Field.VIRTUAL_RESOLUTION), Math.round(height / Field.VIRTUAL_RESOLUTION)); + } + } + + public void load() { + this.size = new VirtualDimension(80000, 60000); + + this.balls.clear(); + this.barriers.clear(); + this.holes.clear(); + + this.setChanged(); + this.notifyObservers(); + } + + public void load(File file) { + DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); + DocumentBuilder builder; + try { + builder = factory.newDocumentBuilder(); + Document document = builder.parse(file); + + balls.clear(); + holes.clear(); + barriers.clear(); + + NodeList xmlBalls = document.getElementsByTagName("ball"); + for (int i = 0; i < xmlBalls.getLength(); i++) { + Element xml = (Element) xmlBalls.item(i); + balls.add(new Ball(xml)); + } + + NodeList xmlBarriers = document.getElementsByTagName("barrier"); + for (int i = 0; i < xmlBarriers.getLength(); i++) { + Element xml = (Element) xmlBarriers.item(i); + barriers.add(new Barrier(balls.get(Integer.valueOf(xml.getAttribute("start"))), balls.get(Integer.valueOf(xml.getAttribute("end"))))); + } + + NodeList xmlHoles = document.getElementsByTagName("hole"); + for (int i = 0; i < xmlHoles.getLength(); i++) { + Element xml = (Element) xmlHoles.item(i); + holes.add(new Hole(xml)); + } + + } catch (Exception e) { + e.printStackTrace(); + } + + this.setChanged(); + this.notifyObservers(); + } + + public void save(File file) { + DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); + DocumentBuilder builder; + try { + builder = factory.newDocumentBuilder(); + Document doc = builder.newDocument(); + + Element xmlLevel = doc.createElement("level"); + doc.appendChild(xmlLevel); + + xmlLevel.appendChild(balls.toXml(doc)); + xmlLevel.appendChild(holes.toXml(doc)); + xmlLevel.appendChild(barriers.toXml(doc)); + + XMLSerializer serializer = new XMLSerializer(); + serializer.setOutputCharStream(new java.io.FileWriter(file)); + serializer.serialize(doc); + } catch (Exception e) { + e.printStackTrace(); + } + } +} diff --git a/src/de/steffenvogel/balls/model/Renderable.java b/src/de/steffenvogel/balls/model/Renderable.java new file mode 100644 index 0000000..c8dafce --- /dev/null +++ b/src/de/steffenvogel/balls/model/Renderable.java @@ -0,0 +1,5 @@ +package de.steffenvogel.balls.model; + +public interface Renderable { + +} diff --git a/src/de/steffenvogel/balls/model/ServerHighScore.java b/src/de/steffenvogel/balls/model/ServerHighScore.java new file mode 100644 index 0000000..dc86755 --- /dev/null +++ b/src/de/steffenvogel/balls/model/ServerHighScore.java @@ -0,0 +1,5 @@ +package de.steffenvogel.balls.model; + +public class ServerHighScore extends HighScore { + +} diff --git a/src/de/steffenvogel/balls/model/State.java b/src/de/steffenvogel/balls/model/State.java new file mode 100644 index 0000000..d74c150 --- /dev/null +++ b/src/de/steffenvogel/balls/model/State.java @@ -0,0 +1,83 @@ +package de.steffenvogel.balls.model; + +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.util.Date; +import java.util.Observable; + +import javax.swing.JOptionPane; +import javax.swing.Timer; + +import de.steffenvogel.balls.controller.mode.Demo; + +public class State extends Observable implements ActionListener { + + public enum Status { + RUNNING, PAUSED, STOPPED + } + + private static final int TIME_RESOLUTION = 10; + + public Class game; + public int score; + public String nick; + + public long time; // playtime in ms; + public Status status; + + public int level; + + private Timer timer; + + public State() { + timer = new Timer(TIME_RESOLUTION, this); + + reset(); + } + + public void reset() { + this.stop(); + this.score = 0; + this.time = 0; + this.game = Demo.class; + + this.setChanged(); + this.notifyObservers(); + } + + public void gameOver() { + JOptionPane.showMessageDialog(null, "Sorry! Du hast verloren!", + "GameOver", JOptionPane.WARNING_MESSAGE); + this.stop(); + } + + public void pause() { + this.status = Status.PAUSED; + timer.stop(); + } + + public void stop() { + this.status = Status.STOPPED; + timer.stop(); + } + + public void start() { + this.status = Status.RUNNING; + timer.start(); + } + + public void addPoints(int points) { + score += points; + + this.setChanged(); + this.notifyObservers(); + } + + @Override + public void actionPerformed(ActionEvent e) { + this.time += TIME_RESOLUTION; + + this.setChanged(); + this.notifyObservers(); + } +} diff --git a/src/de/steffenvogel/balls/view/Field.java b/src/de/steffenvogel/balls/view/Field.java new file mode 100644 index 0000000..e9c01c8 --- /dev/null +++ b/src/de/steffenvogel/balls/view/Field.java @@ -0,0 +1,146 @@ +package de.steffenvogel.balls.view; + +import java.awt.Color; +import java.awt.Component; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.Point; +import java.awt.RenderingHints; +import java.awt.image.VolatileImage; +import java.util.Observable; +import java.util.Observer; + +import de.steffenvogel.balls.model.Ball; +import de.steffenvogel.balls.model.Barrier; +import de.steffenvogel.balls.model.Hole; +import de.steffenvogel.balls.model.Level; +import de.steffenvogel.util.Vector2d; + +public class Field extends Component implements Runnable, Observer { + + private static final long serialVersionUID = 1L; + public static final int VIRTUAL_RESOLUTION = 100; + + private Level level; + + VolatileImage backBuffer = null; + + /** + * This is the default constructor + */ + public Field(Level level) { + super(); + + this.level = level; + this.setSize(level.size.toDimension()); + } + + void createBackBuffer() { + if (backBuffer != null) { + backBuffer.flush(); + backBuffer = null; + } + backBuffer = createVolatileImage(getWidth(), getHeight()); + } + + + public void run() { + System.out.println("render thread started"); + + while (true) { + repaint(); + try { + Thread.sleep(20); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + } + + private void drawBall(Graphics g, Ball ball, boolean drawVec) { + g.setColor(ball.color); + g.fillOval(vPixel2Pixel(ball.position.x - ball.size), + vPixel2Pixel(ball.position.y - ball.size), + vPixel2Pixel(2 * ball.size), vPixel2Pixel(2 * ball.size)); + + if (drawVec) { + drawVector(g, ball.position, ball.orientation, true); + } + } + + private static int vPixel2Pixel(long vPixel) { + return Math.round(vPixel / VIRTUAL_RESOLUTION); + } + + private static long pixel2vPixel(int vPixel) { + return vPixel * VIRTUAL_RESOLUTION; + } + + public static Point vector2Point(Vector2d vec) { + return new Point(vPixel2Pixel(vec.x), vPixel2Pixel(vec.y)); + } + + public static Vector2d point2Vector(Point point) { + return new Vector2d(pixel2vPixel(point.x), pixel2vPixel(point.y)); + } + + public void paint(Graphics g) { + if (backBuffer == null) { + createBackBuffer(); + } + do { + int valCode = backBuffer.validate(getGraphicsConfiguration()); + if (valCode == VolatileImage.IMAGE_RESTORED) { } + else if (valCode == VolatileImage.IMAGE_INCOMPATIBLE || backBuffer.getWidth() != this.getWidth() || backBuffer.getHeight() != this.getHeight()) { + createBackBuffer(); + } + + Graphics2D gOff = (Graphics2D) backBuffer.getGraphics(); + gOff.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); + + gOff.setColor(Color.black); + gOff.fillRect(0, 0, getWidth(), getHeight()); + + for (Hole hole : level.holes) { + gOff.setColor(Color.white); + gOff.fillOval(vPixel2Pixel(hole.position.x - hole.size), + vPixel2Pixel(hole.position.y - hole.size), + vPixel2Pixel(2 * hole.size), vPixel2Pixel(2 * hole.size)); + } + + for (Barrier barrier : level.barriers) { + drawVector(gOff, barrier.start.position, barrier.end.position + .sub(barrier.start.position), false); + } + + for (Ball ball : level.balls) { + gOff.setColor(Color.white); + drawBall(gOff, ball, false); + } + + g.drawImage(backBuffer, 0, 0, this); + } while (backBuffer.contentsLost()); + } + + private void drawVector(Graphics g, Vector2d pos, Vector2d vec, + boolean arrow) { + g.setColor(Color.white); + g.drawLine(vPixel2Pixel(pos.x), vPixel2Pixel(pos.y), vPixel2Pixel(pos.x + + vec.x), vPixel2Pixel(pos.y + vec.y)); + + // TODO draw Vectorarrows + /* + * if (arrow) { int al = 1000; int ax = + * + * g.drawLine(vPixel2Pixel(pos.x + vec.x), vPixel2Pixel(pos.y + vec.y), + * 0, 0); g.drawLine(vPixel2Pixel(pos.x + vec.x), vPixel2Pixel(pos.y + + * vec.y), 0, 0); } + */ + } + + @Override + public void update(Observable o, Object arg) { + Level level = (Level) o; + this.setPreferredSize(level.size.toDimension()); + } +} // @jve:decl-index=0:visual-constraint="10,10" diff --git a/src/de/steffenvogel/balls/view/Gui.java b/src/de/steffenvogel/balls/view/Gui.java new file mode 100644 index 0000000..cc41bbe --- /dev/null +++ b/src/de/steffenvogel/balls/view/Gui.java @@ -0,0 +1,56 @@ +package de.steffenvogel.balls.view; + +import java.awt.BorderLayout; +import java.util.Observable; +import java.util.Observer; + +import javax.swing.ImageIcon; +import javax.swing.JFrame; + +import de.steffenvogel.balls.model.Level; +import de.steffenvogel.balls.model.State; + +public class Gui extends JFrame implements Observer { + private static final long serialVersionUID = -7936315723587248620L; + + public Field field; + public MenuBar menuBar; + public StatusBar statusBar; + + public Gui(Level level, State state) { + super(); + + // window + this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + this.setLayout(new BorderLayout()); + this.setIconImage(new ImageIcon(Gui.class.getResource("images/balls.png")).getImage()); + this.setTitle("2DBalls"); + + // menu + menuBar = new MenuBar(); + this.setJMenuBar(menuBar); + + // field + field = new Field(level); + this.add(field, BorderLayout.CENTER); + + // statusbar + statusBar = new StatusBar(); + this.add(statusBar, BorderLayout.SOUTH); + + // render thread + Thread thread = new Thread(field); + thread.start(); + this.setVisible(true); + + // observer + state.addObserver(statusBar); + level.addObserver(this); + level.addObserver(field); + } + + @Override + public void update(Observable o, Object arg) { + this.pack(); + } +} diff --git a/src/de/steffenvogel/balls/view/MenuBar.java b/src/de/steffenvogel/balls/view/MenuBar.java new file mode 100644 index 0000000..00d2d07 --- /dev/null +++ b/src/de/steffenvogel/balls/view/MenuBar.java @@ -0,0 +1,29 @@ +package de.steffenvogel.balls.view; + +import javax.swing.JMenu; +import javax.swing.JMenuBar; +import javax.swing.JMenuItem; + +public class MenuBar extends JMenuBar { + private static final long serialVersionUID = 3710344818603193892L; + + public JMenu smLoad, mnGame, mnHelp; + + public MenuBar() { + mnGame = new JMenu("Spiel"); + mnHelp = new JMenu("?"); + + smLoad = new JMenu("starten"); + JMenuItem miQuit = new JMenuItem("Beenden"); + JMenuItem miHelp = new JMenuItem("Hilfe"); + JMenuItem miAbout = new JMenuItem("Über"); + + this.add(mnGame); + this.add(mnHelp); + + mnGame.add(smLoad); + mnGame.add(miQuit); + mnHelp.add(miHelp); + mnHelp.add(miAbout); + } +} diff --git a/src/de/steffenvogel/balls/view/Sound.java b/src/de/steffenvogel/balls/view/Sound.java new file mode 100644 index 0000000..e4a4ebc --- /dev/null +++ b/src/de/steffenvogel/balls/view/Sound.java @@ -0,0 +1,61 @@ +package de.steffenvogel.balls.view; + +import java.io.File; +import java.util.concurrent.ArrayBlockingQueue; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.TimeUnit; + +import javax.sound.sampled.AudioFormat; +import javax.sound.sampled.AudioInputStream; +import javax.sound.sampled.AudioSystem; +import javax.sound.sampled.Clip; +import javax.sound.sampled.DataLine; + +public class Sound implements Runnable { + AudioInputStream stream; + DataLine.Info info; + Clip clip; + private ThreadPoolExecutor executor; + + public Sound(File file) { + BlockingQueue queue = new ArrayBlockingQueue(200); + executor = new ThreadPoolExecutor(30, 200, 1, TimeUnit.SECONDS, queue); + + + try{ + stream = AudioSystem.getAudioInputStream(file); + AudioFormat af = stream.getFormat(); + int size = (int) (af.getFrameSize() * stream.getFrameLength()); + byte[] audio = new byte[size]; + info = new DataLine.Info(Clip.class, af, size); + stream.read(audio, 0, size); + + clip = (Clip) AudioSystem.getLine(info); + clip.open(af, audio, 0, size); + } catch (Exception e) { + e.printStackTrace(); + } + } + + public void play() { + if (executor.getPoolSize() < 200) { + executor.execute(this); + } + + System.out.println("triggered" + executor.getTaskCount() ); + } + + @Override + public void run() { + try { + clip.setFramePosition(0); + clip.start(); + clip.stop(); + } catch (Exception e) { + // TODO: handle exception + e.printStackTrace(); + } + } + +} diff --git a/src/de/steffenvogel/balls/view/StatusBar.java b/src/de/steffenvogel/balls/view/StatusBar.java new file mode 100644 index 0000000..f22c697 --- /dev/null +++ b/src/de/steffenvogel/balls/view/StatusBar.java @@ -0,0 +1,57 @@ +package de.steffenvogel.balls.view; + +import java.awt.Dimension; +import java.awt.GridLayout; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.text.SimpleDateFormat; +import java.util.Observable; +import java.util.Observer; + +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.Timer; +import javax.swing.border.LineBorder; + +import de.steffenvogel.balls.model.State; + +public class StatusBar extends JPanel implements Observer { + + public JLabel score, nick, time, level, game; + + private static final long serialVersionUID = 1L; + + public StatusBar() { + this.setPreferredSize(new Dimension(-1, 22)); + this.setBorder(LineBorder.createGrayLineBorder()); + this.setLayout(new GridLayout(1, 4)); + + score = new JLabel(); + nick = new JLabel(); + time = new JLabel(); + level = new JLabel(); + game = new JLabel(); + + this.add(score); + this.add(nick); + this.add(time); + this.add(level); + this.add(game); + } + + public void update(State state) { + score.setText("Punkte: " + state.score); + nick.setText("Nick: " + state.nick); + level.setText("Level: " + state.level); + + SimpleDateFormat tf = new SimpleDateFormat("mm:ss.SSS"); + + time.setText("Zeit: " + tf.format(state.time)); + game.setText("Spiel: " + state.game.getSimpleName()); + } + + @Override + public void update(Observable o, Object arg) { + this.update((State) o); + } +} diff --git a/src/de/steffenvogel/balls/view/images/airhockey.png b/src/de/steffenvogel/balls/view/images/airhockey.png new file mode 100644 index 0000000000000000000000000000000000000000..a4e000c6882b681dee1de2352b7978436b137126 GIT binary patch literal 2252 zcmai0XE+-S7tJ6Psa=&?O&hBm$v5Hu=SFNJ9n0?K(h*nY5UPURj-&n5|wW~%{ ztq7s2u|it}ZS?c~et&%TdCoo0x##}5&vSpAWK)zLlm*5D005u{`bhJ0_B+QzX2^N( zyCeMSoEXq|4em3aR}`~5_FP{G)VD>S@6Y`Yz`NoF5$8kx5FMKki-3nA;V!`*fbj5e zX>WfYw3|zyhjc)&X8~0m1^_S{7$CLpM-=WB1^DvX@+Xy`iGDJM7Spqp37|5{+K~QL zAmY)!aPoEEHOX6?B!o|G!u+W=X@Fhvxp!cuM{m2?HKY>sG7tF5!hj7_+U|~}qV0!# zQ`jGue*fw^zb0cDTpR7M-~0P=hg=()xSXdFK9Skw{cxfKy)qFn@z-RY3fc()Kh~Cb z1tvDtE>*M4+}r3-I{LKAY*Pm1o_E`|Xspw45I|qB2oc z{DOket!+h+b(XoKPV96wyb+o!icb$(A9;zl&$_}VATJyY-Q?shLpi#sXC9{Yr55I-!76y6wz zxyOmoaX8<;9$w(^7k|0Z@|ET?VDcdQ(_Ng*yOcO~1TH6vUMca$iJ=(rUI3yA*#QYL zQGsB5C|NyFO@4B=P`(j`oGwg-bA%DK*)UJW|BG?H_TybW9Yj*)_rEK-KF zM*Ez|T#bF6bZ4+h`5&MDNJpe5#WEMrbE#CWCz40`No*gWSZn376xfcH*QzX56t1VV z??2qb69{f+tp&G&_kw0lr1xR_b6mfyU2C$;)3765_Aa3Lbt?|h7QD5CZUARyBe3ta6I63zg?z##*Cb?cgYoMa_@ts%)CZ#>+ipP0IK5@)Rqddo7! z>8xyWI#3q5%9gOFHyqtxeJB~&JtnLumAd;!+G54F7B0yBY|5D!)jU$ak^(Hlb(v(W6xBd9q4Fw6w49NKw;ZD@+mU1pS_-UKW=JC#*IAI9cEf?AR2KXC98V{ewQdtAUoEzCrk5Y+KrG?m9FMzY& zq}tE^9anlV`wNaB!WlT~B0Z$lbbFIY6BC2vW`ds-Y^-~bZ#Ob&>@O$x)U_O_?;3}A zrLgK^A^&`)`xDks75(Ldf;aNxZ3t`w&mM|c$%C89__4g>TD4vfR~>tGBNLNOHB(yyw{n^Rt${g|%lN9vua5P9x@;hlX@f#p;`pOZD~Ay1Kd!V;2Qg2jam@4r7UliOQi{S>J*> zJ3FguLrUgCHa_y#J9ci^T^dpecI_|!_r*N2Y`#D>lsz2&1=sLw#H2e_!RVMZ!gj1p zv4L^iH$tAn%_-E*XKQPVva{n(qmty6l;o6^ZDt&k8YPEyL|uNt(%A>P&0WNd6~Owq-4aq|g!VrVpasoQ5(wYG_G9Qm(jAVdZ` zK6iT1d$9-=rtA=2X4GDWn3BjX1}+==Ta^ZpX?Qfg7fic3{gh9rt$Z#pRwyFHp-)Tf z`3dN;<>n;Qw%yEysyBYf1`<^a>Y}mF9daDik%h|pkFwM*Q#-3D9y9FuPkbHX=ZH8a zz}p#AxCfj7#A=0WPE%$N&B%_np|ju>J((F{^to-K+G>HHjPEVa{K))RgJw<0!!(~T zFq-!bCXsc}8{?;P%bQYX`u^DrIt%Nm4$!`5t$DwBFbP9$>?4ymHhDA>=hfg4u3E3~ zkx57Aw|X`&s9Ek7RBz_!bif9PK6E8@m;JTee8=~oA2RQbu^V~4it(s3K7j_+);XXv za^qc|R4nTx_eSuFlX)>h^xrI`=cEJOqTF9 zRc$%#%fKoy?UIGK{nRrqFxG=*c#w{*x0n62!5)zZ-Kdr)$T7wwB4 z%tj1OHB`m-XIDMSv;#Fb}w?313gI)an zQHlY}0`B@d8E^(}PTD2}9?U*ppS1-nhDa`L)gkQL{0|+FH@)oa?Ap=aP}RK~()(H1 zE~^8v91C9h{12ALzd3X%;z|Vo)#rYW3)!DIC7zn!du>m;bzn3IJK&c2mNLj|VP>YS zqr-Um4&&+K5}%O3I7w@=)`DrUKIGEy-e=_OXjy!6#@-i0bOoDd)tx5~fPoGQS%3Ed F=D&#?L1_R0 literal 0 HcmV?d00001 diff --git a/src/de/steffenvogel/balls/view/images/balls.png b/src/de/steffenvogel/balls/view/images/balls.png new file mode 100644 index 0000000000000000000000000000000000000000..4201de31ed49c1a995797f976f0274f1f7cf3797 GIT binary patch literal 2716 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 literal 0 HcmV?d00001 diff --git a/src/de/steffenvogel/balls/view/images/dodge.png b/src/de/steffenvogel/balls/view/images/dodge.png new file mode 100644 index 0000000000000000000000000000000000000000..c7673c2f5ffb93fbcae3bbe8f36aeaeca0c2649a GIT binary patch literal 4934 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 RWZ?h+002ovPDHLkV1k%URl5KH literal 0 HcmV?d00001 diff --git a/src/de/steffenvogel/balls/view/images/pong.png b/src/de/steffenvogel/balls/view/images/pong.png new file mode 100644 index 0000000000000000000000000000000000000000..14fd5376c6a87823628c6df4ecbef1d4832a7dbe GIT binary patch literal 1242 zcmeAS@N?(olHy`uVBq!ia0vp^nLwPz!3HExT-pB~NU;<F{9-}6r9xd;mh9dcE^P!SLi9h1E0Mbxe6Srrw5&Wz$~*XHzGJQmi) zEiNp~ow?$L!u5+8@3=TN-Dy3oc5ml_cWHC(CrRFU@XlzlO#Z*Q|GodEq?M)rNZ+?- zX8m*9dBTF19?hA}IITg;fUk#1c_n{<4NC?y?*qdE`5$2}^U|%mPP8)KVVgJaUtsrt zal;QBJ7zw+)qNtt^T2HfU3PV|H6Ix&zS?^;?X%b__sgZtHtN9IGm{$Rizn1fRARI9 z)aCr4#_lO@nDpQ-w<@Fj6NQ^f?%WlB_oz&t^5EP~!3UNB2RTkU3+}wQ_h7kheLv?Z z=6s9i_uk)o;KK6!&gld42eukiNJru3HqKMRlb7e0GiWfrKYQlPoqIQL zCYF^=+qu(n&v)C!aqBm4+a_l4-KkLghXjLQr@ERN%Y?UYb0v>lyB7B1)pC!I)j@ZE zx-Axzmy)Y(>@x?;wYh_nP8uySux6{QbZGt;x*n)abIXu=pWlk(Qd8 zDn21=t5v~h8=~VlYGjV9X+BR`_3nU5 ztHS5E=epWgAD`#RWdK6~;dga)be7CIp`W{E-8weg`6fRs`hv?t9V$FsRf3nx&sZXm z^6CroWDzEy?@pL3;r0pQ@H&3{xH`kxw8?w-+CH+7lL!=PJ-4%9%Czaz>zVG|xp5;Q zD@&`y&W-=gy`>D3m*7DSK`&S~3AqZc4SRj5?|R;L{kIYNlXgEz5U8H0^ts`0h*a-_ z87i#ApcSwErP!`rzkc)X-M7ChKb@cM?(S|Mt~FKdfNar)<4G5d-CSAt|J({*E;uW~ zrEkG!pIdx$dM?i1Y{(Sn^6Ef5<7C6CV1KbmuikBU=#=>TQ#H~<j*IixPhwS9 zvUu*+n0{bufu&@ujo`%BC%f1!)+*I;Oq*0V&-$*m-pu0%EyJ1qv1l<)GWz#$VaJ^p z_X@s6dAKM&IIQh|^2IXVJ)hUFeV)FSX`k93{kKYPJR#L*Rjw6R89u1vo1_7tHb>8!`XIC5oG