From 80c9e2d168462f8440346c94adef0c5032f7e4b9 Mon Sep 17 00:00:00 2001 From: Gnarwhal Date: Wed, 7 Aug 2024 04:28:53 +0000 Subject: [PATCH] Project as is --- res/hitboxes/stages/mountain.shb | Bin 0 -> 66 bytes .../blue stick/fall/blue stick fall 1.png | Bin 0 -> 319 bytes .../blue stick/fall/blue stick fall 2.png | Bin 0 -> 342 bytes .../blue stick/fall/blue stick fall 3.png | Bin 0 -> 339 bytes .../blue stick/fall/blue stick fall 4.png | Bin 0 -> 342 bytes .../blue stick/fall/blue stick fall 5.png | Bin 0 -> 328 bytes .../blue stick/fall/blue stick fall 6.png | Bin 0 -> 320 bytes .../blue stick/idle/blue stick idle 1.png | Bin 0 -> 208 bytes .../blue stick/idle/blue stick idle 2.png | Bin 0 -> 202 bytes .../blue stick/idle/blue stick idle 3.png | Bin 0 -> 203 bytes .../blue stick/idle/blue stick idle 4.png | Bin 0 -> 198 bytes .../blue stick/idle/blue stick idle 5.png | Bin 0 -> 203 bytes .../blue stick/idle/blue stick idle 6.png | Bin 0 -> 202 bytes .../blue stick/idle/blue stick idle 7.png | Bin 0 -> 208 bytes .../blue stick/idle/blue stick idle 8.png | Bin 0 -> 199 bytes .../blue stick/jump/blue stick jump 1.png | Bin 0 -> 334 bytes .../blue stick/jump/blue stick jump 2.png | Bin 0 -> 350 bytes .../blue stick/jump/blue stick jump 3.png | Bin 0 -> 353 bytes .../blue stick/jump/blue stick jump 4.png | Bin 0 -> 350 bytes .../blue stick/jump/blue stick jump 5.png | Bin 0 -> 336 bytes .../blue stick/jump/blue stick jump 6.png | Bin 0 -> 328 bytes .../blue stick/run/blue stick run 1.png | Bin 0 -> 288 bytes .../blue stick/run/blue stick run 2.png | Bin 0 -> 300 bytes .../blue stick/run/blue stick run 3.png | Bin 0 -> 303 bytes .../blue stick/run/blue stick run 4.png | Bin 0 -> 308 bytes .../blue stick/run/blue stick run 5.png | Bin 0 -> 292 bytes .../blue stick/walk/blue stick walk 1.png | Bin 0 -> 237 bytes .../blue stick/walk/blue stick walk 2.png | Bin 0 -> 245 bytes .../blue stick/walk/blue stick walk 3.png | Bin 0 -> 249 bytes .../blue stick/walk/blue stick walk 4.png | Bin 0 -> 251 bytes .../blue stick/walk/blue stick walk 5.png | Bin 0 -> 254 bytes .../blue stick/walk/blue stick walk 6.png | Bin 0 -> 252 bytes .../blue stick/walk/blue stick walk 7.png | Bin 0 -> 254 bytes .../blue stick/walk/blue stick walk 8.png | Bin 0 -> 244 bytes .../blue stick/walk/blue stick walk 9.png | Bin 0 -> 236 bytes res/img/stages/mountain/mountain 1.png | Bin 0 -> 4627 bytes res/shaders/default/default.fs | 9 + res/shaders/default/default.vs | 13 + res/shaders/shapes/shapes.fs | 5 + res/shaders/shapes/shapes.vs | 9 + .../gnarly/engine/components/Animation.java | 74 +++++ src/com/gnarly/engine/components/Shader.java | 153 +++++++++ src/com/gnarly/engine/components/Texture.java | 89 +++++ src/com/gnarly/engine/components/VAO.java | 87 +++++ src/com/gnarly/engine/display/Camera.java | 82 +++++ src/com/gnarly/engine/display/Window.java | 178 ++++++++++ src/com/gnarly/engine/utils/CHitbox.java | 55 +++ src/com/gnarly/engine/utils/Library.java | 86 +++++ src/com/gnarly/engine/utils/MemoryUtils.java | 58 ++++ src/com/gnarly/engine/utils/RHitbox.java | 99 ++++++ src/com/gnarly/game/Main.java | 83 +++++ src/com/gnarly/game/objects/Character.java | 314 ++++++++++++++++++ src/com/gnarly/game/objects/Rectangle.java | 48 +++ src/com/gnarly/game/objects/Stage.java | 99 ++++++ src/com/gnarly/game/panels/PlayPanel.java | 32 ++ 55 files changed, 1573 insertions(+) create mode 100755 res/hitboxes/stages/mountain.shb create mode 100755 res/img/characters/blue stick/fall/blue stick fall 1.png create mode 100755 res/img/characters/blue stick/fall/blue stick fall 2.png create mode 100755 res/img/characters/blue stick/fall/blue stick fall 3.png create mode 100755 res/img/characters/blue stick/fall/blue stick fall 4.png create mode 100755 res/img/characters/blue stick/fall/blue stick fall 5.png create mode 100755 res/img/characters/blue stick/fall/blue stick fall 6.png create mode 100755 res/img/characters/blue stick/idle/blue stick idle 1.png create mode 100755 res/img/characters/blue stick/idle/blue stick idle 2.png create mode 100755 res/img/characters/blue stick/idle/blue stick idle 3.png create mode 100755 res/img/characters/blue stick/idle/blue stick idle 4.png create mode 100755 res/img/characters/blue stick/idle/blue stick idle 5.png create mode 100755 res/img/characters/blue stick/idle/blue stick idle 6.png create mode 100755 res/img/characters/blue stick/idle/blue stick idle 7.png create mode 100755 res/img/characters/blue stick/idle/blue stick idle 8.png create mode 100755 res/img/characters/blue stick/jump/blue stick jump 1.png create mode 100755 res/img/characters/blue stick/jump/blue stick jump 2.png create mode 100755 res/img/characters/blue stick/jump/blue stick jump 3.png create mode 100755 res/img/characters/blue stick/jump/blue stick jump 4.png create mode 100755 res/img/characters/blue stick/jump/blue stick jump 5.png create mode 100755 res/img/characters/blue stick/jump/blue stick jump 6.png create mode 100755 res/img/characters/blue stick/run/blue stick run 1.png create mode 100755 res/img/characters/blue stick/run/blue stick run 2.png create mode 100755 res/img/characters/blue stick/run/blue stick run 3.png create mode 100755 res/img/characters/blue stick/run/blue stick run 4.png create mode 100755 res/img/characters/blue stick/run/blue stick run 5.png create mode 100755 res/img/characters/blue stick/walk/blue stick walk 1.png create mode 100755 res/img/characters/blue stick/walk/blue stick walk 2.png create mode 100755 res/img/characters/blue stick/walk/blue stick walk 3.png create mode 100755 res/img/characters/blue stick/walk/blue stick walk 4.png create mode 100755 res/img/characters/blue stick/walk/blue stick walk 5.png create mode 100755 res/img/characters/blue stick/walk/blue stick walk 6.png create mode 100755 res/img/characters/blue stick/walk/blue stick walk 7.png create mode 100755 res/img/characters/blue stick/walk/blue stick walk 8.png create mode 100755 res/img/characters/blue stick/walk/blue stick walk 9.png create mode 100755 res/img/stages/mountain/mountain 1.png create mode 100755 res/shaders/default/default.fs create mode 100755 res/shaders/default/default.vs create mode 100755 res/shaders/shapes/shapes.fs create mode 100755 res/shaders/shapes/shapes.vs create mode 100755 src/com/gnarly/engine/components/Animation.java create mode 100755 src/com/gnarly/engine/components/Shader.java create mode 100755 src/com/gnarly/engine/components/Texture.java create mode 100755 src/com/gnarly/engine/components/VAO.java create mode 100755 src/com/gnarly/engine/display/Camera.java create mode 100755 src/com/gnarly/engine/display/Window.java create mode 100755 src/com/gnarly/engine/utils/CHitbox.java create mode 100755 src/com/gnarly/engine/utils/Library.java create mode 100755 src/com/gnarly/engine/utils/MemoryUtils.java create mode 100755 src/com/gnarly/engine/utils/RHitbox.java create mode 100755 src/com/gnarly/game/Main.java create mode 100755 src/com/gnarly/game/objects/Character.java create mode 100755 src/com/gnarly/game/objects/Rectangle.java create mode 100755 src/com/gnarly/game/objects/Stage.java create mode 100755 src/com/gnarly/game/panels/PlayPanel.java diff --git a/res/hitboxes/stages/mountain.shb b/res/hitboxes/stages/mountain.shb new file mode 100755 index 0000000000000000000000000000000000000000..be3fc284c2161d6e1c827a52059c51f3ee299add GIT binary patch literal 66 zcmZ4UmVve0#(5e8gVQ|*5MXvzV_-%RJ6y_ z#WBRfzjx9_!NUd|&U>BgcgKgn_@l=@O`9X(`MaZn9-sV=Rn)3aNWXJHQuO`#5Q84Z zhP|I}pLPjldE0Cesgo3V#VhQ>J&EtJjmBZcKQ~QwF$sIZDq-S!!@7Q_z^w7p3c5KIct~ncL zot{2dWzj|@{R0a$58eBDy7dCv^*CPjWU)JvV$~IbEd7j^S$i$(s*+ONqBCOt1O36^ M>FVdQ&MBb@0Nl2ChyVZp literal 0 HcmV?d00001 diff --git a/res/img/characters/blue stick/fall/blue stick fall 2.png b/res/img/characters/blue stick/fall/blue stick fall 2.png new file mode 100755 index 0000000000000000000000000000000000000000..9de87d1ab14edc6aaac19b83a690d5032344444e GIT binary patch literal 342 zcmeAS@N?(olHy`uVBq!ia0vp^0zfRm!3HEhFR0}KQY`6?zK#qG8~eHcB(eheoCO|{ z#S9F5hd`K7RKu$QC@5Lt8c`CQpH@-%RCL+X z#WBRfzjuIDbO-1s1n4mR z3I2CY;PRsn)d`|&x-J$99%gsl!80dPu&+LvMfUw0r^i=A&HFB?xzwjm;5F1Qdi5|q zb_R=;j khs{bcZ0FYO_?%tev?w6zbmLQVp!XO&UHx3vIVCg!0H=h4%K!iX literal 0 HcmV?d00001 diff --git a/res/img/characters/blue stick/fall/blue stick fall 3.png b/res/img/characters/blue stick/fall/blue stick fall 3.png new file mode 100755 index 0000000000000000000000000000000000000000..4646885fb5c3e1c07bdc6686ca483c539abefe10 GIT binary patch literal 339 zcmeAS@N?(olHy`uVBq!ia0vp^0zfRm!3HEhFR0}KQY`6?zK#qG8~eHcB(eheoCO|{ z#S9F5hd`K7RKu$QC@5Lt8c`CQpH@-%RCK}9 z#WBRfzjuz|#9rV1NAc1sH8Rc0vl z=sht{@JOo$yWvfTm^qaxW>3HEzPm)d&34AY7a@g#to^peajTXed34J7GH=rp*BktQ zpE^xxD$Q?=Eo3um^X2Aucp<#ONZ{4-+%BE8J05#}hlI9Y>3AdQ7}HTCFq!wr(V6aP z!Fj(nzwq(rsWxbi{9F0qhVkR2RbD#lY>e+Jc*M2*y%4YGq8af$?1pH1Lh_9*9~fHf f7`2&W^M5i+G6Y09KK&U0^c#bxtDnm{r-UW|m{fhB literal 0 HcmV?d00001 diff --git a/res/img/characters/blue stick/fall/blue stick fall 4.png b/res/img/characters/blue stick/fall/blue stick fall 4.png new file mode 100755 index 0000000000000000000000000000000000000000..056bbf1919b57176aa6170d687e17e0d12b03a75 GIT binary patch literal 342 zcmeAS@N?(olHy`uVBq!ia0vp^0zfRm!3HEhFR0}KQY`6?zK#qG8~eHcB(eheoCO|{ z#S9F5hd`K7RKu$QC@5Lt8c`CQpH@-%RCL+X z#WBRfzjuQd^W)eF=EZuORx$9tGl^THbV~TM%>DTH{^Bgl9<=(W3+=O#3Y(!X{bcpC-Yq+x z*lv)ONWIvhw>(7pZP(((Ni+DnHb{7dwtU_)d%>c)dS~|SUR69TM&e`dM0U5>lu$;g zJDGbTT&Ji%v)s4;MOLGJoL30glso2)U2H#-r2RyworWOahI!Kp=pv3@JfZi%|P lA2pB{Ni>|Y>W1Yl{`LL=Q4_CE*9Ur!!PC{xWt~$(69ACigU|o~ literal 0 HcmV?d00001 diff --git a/res/img/characters/blue stick/fall/blue stick fall 5.png b/res/img/characters/blue stick/fall/blue stick fall 5.png new file mode 100755 index 0000000000000000000000000000000000000000..7a30e4159c08b0a14a9ae3daea4607f84c5e0a8a GIT binary patch literal 328 zcmeAS@N?(olHy`uVBq!ia0vp^0zfRm!3HEhFR0}KQY`6?zK#qG8~eHcB(eheoCO|{ z#S9F5hd`K7RKu$QC@5Lt8c`CQpH@-%RCLtS z#WBRfzjsog5VInO^Ij+W>iv72&gTpEN(Wpxx94Dsi~Y8xHFcsV*55fWSMNwz+e_{T zx~7URB-`RSDg`IAK6v1F__C)`?Zx*GH#;0)QI7Yko%G>g$J3_w!J?* zbff+L4HuUkPMRg|xhS;S8_U@H~8apqI-r81ADpDJU^kA z-F5u)S((%%eipr&+`{jsBYx*kqSTGqH9G_@J-RVJ{zk^-M8mV)N)bG2+GSZknU~6^ VxY^q3zXW=S!PC{xWt~$(69C#0c;5g3 literal 0 HcmV?d00001 diff --git a/res/img/characters/blue stick/fall/blue stick fall 6.png b/res/img/characters/blue stick/fall/blue stick fall 6.png new file mode 100755 index 0000000000000000000000000000000000000000..a7184a63fb19c984e11fd1cc75b54fa3de611eba GIT binary patch literal 320 zcmeAS@N?(olHy`uVBq!ia0vp^0zfRm!3HEhFR0}KQY`6?zK#qG8~eHcB(eheoCO|{ z#S9F5hd`K7RKu$QC@5Lt8c`CQpH@-%RJ7OA z#WBRfzqgN3=!gOb^WQ_Z-|pR4lIRt=aPCcl)1utB-|HJ{-m<-$ArLLOOur%YmD2@d zp8W!^l+?Hn9P~JR*>h3N#rF?4J0x(Y?VFP`>BGUEA50QQU2o+7EK!_tbmR2{ni8Vv z?MF@YyB;JPgbJ>?&ga->t#-ujZ&v!$T>@Wt4(qq<>Nv?%U~uU}$s~>VFV#PE1a36V z)K{OaQe&XJkHM`_@LRN9EJteL8`A-%ROIXF z;uvD#pPV3|^VeUHO>mOt|A#Xg8SUKyxs4fgIE^Pp@LX;_!^ou2Z6IfwaD_ntLN1%j tsFIk%9Khu@fkm!okyskT&mCXv8S;9|`1B9mKL9kC!PC{xWt~$(69C)aH|PKW literal 0 HcmV?d00001 diff --git a/res/img/characters/blue stick/idle/blue stick idle 2.png b/res/img/characters/blue stick/idle/blue stick idle 2.png new file mode 100755 index 0000000000000000000000000000000000000000..ef9e6bc325c3a9c9561a067663cd19a50d9c718f GIT binary patch literal 202 zcmeAS@N?(olHy`uVBq!ia0vp^0zfRm!3HEhFR0}KQY`6?zK#qG8~eHcB(eheoCO|{ z#S9F5hd`K7RKu$QC@5Lt8c`CQpH@-%ROIgI z;uvD#pPV3|^VeUnP2m5*2qV_U#H5O+0Xz*eJ#>zx0d0?L`M82{F-%ROI35 z;uvD#pPV3|^VeUnP2hjvh7_){o^^az8D?}INy=ekV4UD8(Jy6?#lQg}FP~$WWYEUw oAralkb?C(_0k#Rf-v5~y@_NhoI)&f#0L^6ZboFyt=akR{08Mr{00000 literal 0 HcmV?d00001 diff --git a/res/img/characters/blue stick/idle/blue stick idle 4.png b/res/img/characters/blue stick/idle/blue stick idle 4.png new file mode 100755 index 0000000000000000000000000000000000000000..c4e44702b15d6c427222a31544c073f0da3d127d GIT binary patch literal 198 zcmeAS@N?(olHy`uVBq!ia0vp^0zfRm!3HEhFR0}KQY`6?zK#qG8~eHcB(eheoCO|{ z#S9F5hd`K7RKu$QC@5Lt8c`CQpH@-%ROIaG z;uvD#pPV3|^VeUnP2m5=q>~~X$JE%5X|NseQ4vcvX5eVhIaG0_A&}VtLe3~-o6us& jbD*hHKjh@GrT-aQY>U*sJ?mHkG>*a3)z4*}Q$iB}dn-8} literal 0 HcmV?d00001 diff --git a/res/img/characters/blue stick/idle/blue stick idle 5.png b/res/img/characters/blue stick/idle/blue stick idle 5.png new file mode 100755 index 0000000000000000000000000000000000000000..e5aab66689a7538966924d7ced9690abbb2fcc36 GIT binary patch literal 203 zcmeAS@N?(olHy`uVBq!ia0vp^0zfRm!3HEhFR0}KQY`6?zK#qG8~eHcB(eheoCO|{ z#S9F5hd`K7RKu$QC@5Lt8c`CQpH@-%ROI35 z;uvD#pPV3|^VeUnP2hjvh7_){o^^az8D?}INy=ekV4UD8(Jy6?#lQg}FP~$WWYEUw oAralkb?C(_0k#Rf-v5~y@_NhoI)&f#0L^6ZboFyt=akR{08Mr{00000 literal 0 HcmV?d00001 diff --git a/res/img/characters/blue stick/idle/blue stick idle 6.png b/res/img/characters/blue stick/idle/blue stick idle 6.png new file mode 100755 index 0000000000000000000000000000000000000000..ef9e6bc325c3a9c9561a067663cd19a50d9c718f GIT binary patch literal 202 zcmeAS@N?(olHy`uVBq!ia0vp^0zfRm!3HEhFR0}KQY`6?zK#qG8~eHcB(eheoCO|{ z#S9F5hd`K7RKu$QC@5Lt8c`CQpH@-%ROIgI z;uvD#pPV3|^VeUnP2m5*2qV_U#H5O+0Xz*eJ#>zx0d0?L`M82{F-%ROIXF z;uvD#pPV3|^VeUHO>mOt|A#Xg8SUKyxs4fgIE^Pp@LX;_!^ou2Z6IfwaD_ntLN1%j tsFIk%9Khu@fkm!okyskT&mCXv8S;9|`1B9mKL9kC!PC{xWt~$(69C)aH|PKW literal 0 HcmV?d00001 diff --git a/res/img/characters/blue stick/idle/blue stick idle 8.png b/res/img/characters/blue stick/idle/blue stick idle 8.png new file mode 100755 index 0000000000000000000000000000000000000000..82c6e9dcf13bbfbf724a7e8831adaaddf3761fcd GIT binary patch literal 199 zcmeAS@N?(olHy`uVBq!ia0vp^0zfRm!3HEhFR0}KQY`6?zK#qG8~eHcB(eheoCO|{ z#S9F52SJ!|$HeTnKtah8*NBqf{Irtt#G+J&g2c?c61}|C5(N`I13g1y6XxhDpduGf z7sn6_|KtP#oxlEqY=V~c&j7yTC55EyRM}y9xiYpC)%nlH8Mj6|L kmWjLz_5`R(Pyffx&|+JpcIRp8VxV~pp00i_>zopr077#)DF6Tf literal 0 HcmV?d00001 diff --git a/res/img/characters/blue stick/jump/blue stick jump 1.png b/res/img/characters/blue stick/jump/blue stick jump 1.png new file mode 100755 index 0000000000000000000000000000000000000000..0dd4998a58ccf108d7158f456a90a58aae73bce7 GIT binary patch literal 334 zcmeAS@N?(olHy`uVBq!ia0vp^0zfRm!3HEhFR0}KQjEnx?oJHr&dIz4a#+$GeH|GX zHuiJ>Nn{1`ISV`@iy0XB4ude`@%$AjKtah8*NBqf{Irtt#G+J&g2c?c61}|C5(N`I z13g1y6XxhDprU=AE{-7<{=JjD`3@U!xD>bQRqu~ee7;LRf zr*J^woLhLqu}^MSiW#|;7G7VpHzuKBqVZbAAIo>dyY2RS9_<+@>rtTf>G45}mwJ;F zgsMKyKPuo-l%`|Q`}XU}_a-9Ehw2Pw?`~pfwvdixlsYXPc%D@UXk+)cqDIDJ`o*Wk YJ3>?3)Vt*kfIeaHboFyt=akR{0P2K!r2qf` literal 0 HcmV?d00001 diff --git a/res/img/characters/blue stick/jump/blue stick jump 2.png b/res/img/characters/blue stick/jump/blue stick jump 2.png new file mode 100755 index 0000000000000000000000000000000000000000..558c6776f1a22b04ae0e95c7e2598654ec21d248 GIT binary patch literal 350 zcmeAS@N?(olHy`uVBq!ia0vp^0zfRm!3HEhFR0}KQjEnx?oJHr&dIz4a#+$GeH|GX zHuiJ>Nn{1`ISV`@iy0XB4ude`@%$AjKtah8*NBqf{Irtt#G+J&g2c?c61}|C5(N`I z13g1y6XxhDprUi0E{-7<{=JhNg_<2WSpGI0|8rjdN8O=Kl1$2PsxowEWS$CnDll={ z<2|VdetYcw)2VDK*8b^2$7<)#8#UK`k~C9lw)t8c*fHNbMWDR-#T0ghsAV4(zPQm~ z)E(wDvFQC$#tA=WOf5O!thLPl*`50`8Um6}ehN(E;+DOr$^GE$!>Z2LR&VQ~Nn{1`ISV`@iy0XB4ude`@%$AjKtah8*NBqf{Irtt#G+J&g2c?c61}|C5(N`I z13g1y6XxhDprVVOE{-7<{=GrB1rHl=oaXxbrY=_TbMS$Q-5U=64Y05+-g#P8Np;-(7!-gerBDZK#x-`Q-$$Q-q;bp%})Lb`8 rOZ7W%_}m^T^6_~inMT&ljo$a+Z$Q+)$Rj2|&oOwq`njxgN@xNAeRG78 literal 0 HcmV?d00001 diff --git a/res/img/characters/blue stick/jump/blue stick jump 4.png b/res/img/characters/blue stick/jump/blue stick jump 4.png new file mode 100755 index 0000000000000000000000000000000000000000..6825c50d05514084c484aa740b68007d511b8d03 GIT binary patch literal 350 zcmeAS@N?(olHy`uVBq!ia0vp^0zfRm!3HEhFR0}KQjEnx?oJHr&dIz4a#+$GeH|GX zHuiJ>Nn{1`ISV`@iy0XB4ude`@%$AjKtah8*NBqf{Irtt#G+J&g2c?c61}|C5(N`I z13g1y6XxhDprUi0E{-7<{=Jhf3LZA#aNg`>zdJtc#Gfk@PPiKF_#0rMGH=qouLhgL zj=wgV{ws3p&xUzzX0Cfo9;|y&XVU)uvQw;Fjwr(y=Ih%y99UNs395-|2(b71v;LS< zWAIl!y6DFi2PQr1Ju|j^P~02%+0s;kX@%1{SA%wu7gJ__V)(UuhuKBDZSnTK)7kEb z-tB*8@c;8Fn;TjTFWA@R3N~Nn{1`ISV`@iy0XB4ude`@%$AjKtah8*NBqf{Irtt#G+J&g2c?c61}|C5(N`I z13g1y6XxhDprQkwE{-7<{=JhN#hM*BocB6S-y6UF!B0(AW7Wb3J3D5y^h@&_XP55r z`|bI8Rc%G%`~KEt&N)&ARwhl^nJ*T3Zy)haa2Mj&?j@91+$8H|=P)#OWH*#a)x zx6hS(ndWL4%XO?f{Z}{La7%+s_bp|0X3mPwCz2*Tbp5sHTXxn%rWH=-+XZ%sy!evt b_nRqpMvB{w*GfNteqr!*^>bP0l+XkK&~Sa6 literal 0 HcmV?d00001 diff --git a/res/img/characters/blue stick/jump/blue stick jump 6.png b/res/img/characters/blue stick/jump/blue stick jump 6.png new file mode 100755 index 0000000000000000000000000000000000000000..1464c2ecde5ab8d0b665cd407f3baf20485a5bdd GIT binary patch literal 328 zcmeAS@N?(olHy`uVBq!ia0vp^0zfRm!3HEhFR0}KQjEnx?oJHr&dIz4a#+$GeH|GX zHuiJ>Nn{1`ISV`@iy0XB4ude`@%$AjKtah8*NBqf{Irtt#G+J&g2c?c61}|C5(N`I z13g1y6XxhDprRd~E{-7<{=NR*Vl4(7pSg-7&i6<7v>$PbbvbkWd19Js-~CMUkn<7U z{vXTOXDO<=Zj|miu6E;RqL?dd%_;wdnp#E6WhLU4{*J!mqQM~R_;sN$pW4arp*L zw0?WwgVx>qkJOwPUvRAApUa_eRJ`3xPmu4D_|^I0yzE_EKWtboE^Ouce=bw}Z%EiI U`AbY*KtC{ey85}Sb4q9e0K-amJOBUy literal 0 HcmV?d00001 diff --git a/res/img/characters/blue stick/run/blue stick run 1.png b/res/img/characters/blue stick/run/blue stick run 1.png new file mode 100755 index 0000000000000000000000000000000000000000..0f87c04b7c08a79471f8628f31ad05cdadc2e65a GIT binary patch literal 288 zcmeAS@N?(olHy`uVBq!ia0vp^0zfRm!3HEhFR0}KQY`6?zK#qG8~eHcB(eheoCO|{ z#S9F5hd`K7RKu$QC@5Lt8c`CQpH@-%R5aJq z#WBRff9a%)yayCGTw)i_zq?+$q)scugfZlR+W8lA%Wo}P8lzva(tl#W!M_jAGzNa+ zkGbSGD``rPr|FIs)6UREW-i`mcqa;_F3F$3Ir$h{`}7Wj)W8J>v#ecqh*wNZbm0v2 zF+B8BdqLqB!ORDf$}Wj4PVrea@!!N>N`Xmv9aA)vYny#$n3!4YacR-)W@^27NAb|! f1Km8#4nG-=S=ZgsnteYL=uievS3j3^P6-%RJ795 z#WBRff9a%)yoU`qT=qKI?~V_D@n_vZhYL3&9=KHrTJAX9dFj^c+nakyY)+9dW sm~k_kw{e?robiD_EGmx0@Av*?SQlCH%r7g>59nwHPgg&ebxsLQ0OFi(WdHyG literal 0 HcmV?d00001 diff --git a/res/img/characters/blue stick/run/blue stick run 3.png b/res/img/characters/blue stick/run/blue stick run 3.png new file mode 100755 index 0000000000000000000000000000000000000000..9c267aae600f1530cd0f8aec1870da61545ab666 GIT binary patch literal 303 zcmeAS@N?(olHy`uVBq!ia0vp^0zfRm!3HEhFR0}KQY`6?zK#qG8~eHcB(eheoCO|{ z#S9F5hd`K7RKu$QC@5Lt8c`CQpH@-%RJ6v^ z#WBRff9a%)yhjvxoFf;`zq?+$q|S@Svz0S+f%;ypt;vVy>MebIF7TAP;noE`XDUOj z?rN^&*UeP-&9ruAWJ`Cxk7rDiocW=@qkYT`Y&C_n3lBcpdJ9Acu?K|iv uAtgOOKqAtZ!!q_o3D-%RJ764 z#WBRff9a%)f`=7&oFf(I-(9a=QrE?zc;g16`rc~3W0O2~E-Cr*N$=@&6VnAcws!Zq zs+E^aGhQav;c5Go+3bo=M|u-F1YFL( z30!mV#3#OE2X#;Rz{vDJoc^0rh=>^d744$rjF6*2UngBX# BbF=^e literal 0 HcmV?d00001 diff --git a/res/img/characters/blue stick/run/blue stick run 5.png b/res/img/characters/blue stick/run/blue stick run 5.png new file mode 100755 index 0000000000000000000000000000000000000000..406be65dc267c4db7e89e1991bf84f90968237b0 GIT binary patch literal 292 zcmeAS@N?(olHy`uVBq!ia0vp^0zfRm!3HEhFR0}KQY`6?zK#qG8~eHcB(eheoCO|{ z#S9F5hd`K7RKu$QC@5Lt8c`CQpH@-%RJ733 z#WBRff9b?%z6JvhmTFe}z4OCA{NaemVY(-N}J@4GF%=UccXZs-kkC;)2YS?E5Pl*#=4;=Gi^d8F>n^4hncaA5Fs^>bP0l+XkKSUG3H literal 0 HcmV?d00001 diff --git a/res/img/characters/blue stick/walk/blue stick walk 1.png b/res/img/characters/blue stick/walk/blue stick walk 1.png new file mode 100755 index 0000000000000000000000000000000000000000..30fec4f157b6aef268561b3a949a296e92d5d12b GIT binary patch literal 237 zcmeAS@N?(olHy`uVBq!ia0vp^0zfRm!3HEhFR0}KQY`6?zK#qG8~eHcB(eheoCO|{ z#S9F52SAuH>slu#P*AeOHKHUqKdq!Zu_%?HATcwqL@zJ3M8QPQK+n+FggLqjs3^=9VGrOsrAkJ6ojj%~_W<+Uw_8`{5^?^K)c z^_^P-&v{cu7wsbUc!rBjAqT}Bt|+bFV31IGCSCFm!|UXI&L5cn**vS}=hSxq+FJx*{Ln><8M);OXk;vd$@?2>{`(PX7P^ literal 0 HcmV?d00001 diff --git a/res/img/characters/blue stick/walk/blue stick walk 2.png b/res/img/characters/blue stick/walk/blue stick walk 2.png new file mode 100755 index 0000000000000000000000000000000000000000..293b2fd5189c87dd887aaecb67bda0764336a4e5 GIT binary patch literal 245 zcmeAS@N?(olHy`uVBq!ia0vp^0zfRm!3HEhFR0}KQY`6?zK#qG8~eHcB(eheoCO|{ z#S9F52SAuH>slu#P*AeOHKHUqKdq!Zu_%?HATcwqL@zJ3M8QPQK+n+FggLqjsHn)( z#WBRf|7u?#*8v3%hrNgF%J;`E{Jh;H>Cu%;L49sM9}gcmV=&irqn&}ZPkGQ9{u;?;)q1-s m82?x~_1j!=n4mu4AzQ$ohB;Z!9M=PFXYh3Ob6Mw<&;$Ttt5kvj literal 0 HcmV?d00001 diff --git a/res/img/characters/blue stick/walk/blue stick walk 3.png b/res/img/characters/blue stick/walk/blue stick walk 3.png new file mode 100755 index 0000000000000000000000000000000000000000..58c9311d700b3f67aaabe1993fdd1a51a6693bf4 GIT binary patch literal 249 zcmeAS@N?(olHy`uVBq!ia0vp^0zfRm!3HEhFR0}KQY`6?zK#qG8~eHcB(eheoCO|{ z#S9F52SAuH>slu#P*AeOHKHUqKdq!Zu_%?HATcwqL@zJ3M8QPQK+n+FggLqjsHn`- z#WBRf|7u?}SAzi$OEIhc-udAl{%oBsHD%LFZ;l9wTW2Q)PJHXL`H8Zd;1l&5{Y|M| z+B@F*Rx$B>VBe7)!>FCEvZX_OLs7^hv5!n)eI9q1ex^4~O+6bYs2ve|O;S6FHGW#@ qKfPThtdcdd5z7J&s`M+IWX;{vFvm0S+&`cT7(8A5T-G@yGywpsuu~5J literal 0 HcmV?d00001 diff --git a/res/img/characters/blue stick/walk/blue stick walk 4.png b/res/img/characters/blue stick/walk/blue stick walk 4.png new file mode 100755 index 0000000000000000000000000000000000000000..ee1ac6384380ebe5f85349c3a7254be58a77ab91 GIT binary patch literal 251 zcmeAS@N?(olHy`uVBq!ia0vp^0zfRm!3HEhFR0}KQY`6?zK#qG8~eHcB(eheoCO|{ z#S9F52SAuH>slu#P*AeOHKHUqKdq!Zu_%?HATcwqL@zJ3M8QPQK+n+FggLqjsHnoz z#WBRf|7zbw&I1ZOE}Na~cgKgn_;bz0S-HYZmqp8_qx^~H#lq#GpA?sJd|ELl{9qby zK)_pPo5r?3%yUIG9GFVdQ&MBb@0Ar9slu#P*AeOHKHUqKdq!Zu_%?HATcwqL@zJ3M8QPQK+n+FggLqjsHoc0 z#WBRf|7u?%SAznNTX}0;nf>|;KhK^GbN-Vi#lt1{P68nM vb#m71)Y&cSe5avt|G6!@FYx+&VlkS#+@@iUsd$7T&>0M#u6{1-oD!Mslu#P*AeOHKHUqKdq!Zu_%?HATcwqL@zJ3M8QPQK+n+FggLqjsHoD@ z#WBRf|7zb|-UbC8w%twr@1Ap=>laxwZT@-|9w|>f$G&+2y1QQ=)fY-SkY9XFH^@T5 z;slu#P*AeOHKHUqKdq!Zu_%?HATcwqL@zJ3M8QPQK+n+FggLqjsHoc0 z#WBRf|7u?@UxNZi+fFC@-SOcs{-{l0$VKLHpz+X_x8W_=`VxucwvGB-b8}V!0Yc?F4w1V4SyvO9Sq`LNsnc5P$%Vvpt wJmcDD5**9s>(t1&uW!XJ%@slu#P*AeOHKHUqKdq!Zu_%?HATcwqL@zJ3M8QPQK+n+FggLqjsHo7> z#WBRf|7xEj-vI>QR9^qj!lVEUhKH6^)tYcW#?84eaG}= z54Q5pvw l>tyXUHm^&V=s)2F-%RFvuI z;uvD#f3@c#Z-W5`Yve)y@5QXo*SCDr%*x=d6PO)ytLS0Jw7nG%ofokEuspo$V=i0N z-s1)fjtUzyNcPTAGG~zNyyKF`a7ntdQ=VPv^r!1e`U0`jBwgYjoZfV%G{ME*pi#D< ch?Prr@$5-m>b##e0WD?lboFyt=akR{0K~&fc>n+a literal 0 HcmV?d00001 diff --git a/res/img/stages/mountain/mountain 1.png b/res/img/stages/mountain/mountain 1.png new file mode 100755 index 0000000000000000000000000000000000000000..e9c94998bab923033bf69106c6fb9b9af2f2f0e6 GIT binary patch literal 4627 zcmeHKX;hO*7LD2}7!^^$W)+4J1OkZAD!Yh)tg=W5gb+V8?5l)*8(9^E^c-6d(MF_M zBmurG0wRgii4Zli1qcubNNCou352j`aOThao8NP$-+6WF)U8{u&b#%h&Z&nk&bG&n z$RB|~Ajj-(Tz7*&_9GyWeK3gwd&v25v)}f*ebH{V*C2HriZgqI9|A0$EFlmg4!R8- zgg_2JTpVv%@8RldYC2k47A7WkSFSkP*mzvM3U_hw_4Gs{kzrwBkZ>_%OjQhl4A38R zbaeFfiTQl~#KeR^AQp+ld$t$hPy17W|4{{+v|AGP?g<3z=Is8xn*Wat;x0OTZtoZ+ zBX4*`Lm$ zqGO@zvdTU{_28fW-xO&5ospQ5(kIavvjpz0KL+oe;CLR3a?g$jts*D^54yNse+Nsnu&jr&{kEfOs z6jTYnH(s+!{wU4ZB(L9@axl6Jq>Ptyj-B8b!^9;)+|6pWY#~!}!ez&3{j=V<#q{5R z!IGW@6Sz2mC4QA7suf6cia{EUwv6o2R=NP&`8rf~tc^sn-J-tM``WLl2TO~X9jRO! zCCvuFpn2#|==-2^W`*tI=hSnZi;b!6-{@={6~$!}36I3-d83i2g-Bq-#J$BrxQIyX zsI^HgfvE0#o0uSz@CCNIo4iMwH9i`#rRTU_WStV zGF$R4bjEdSuI@5Sd`q0N&MLiVlvbc-6pKg`uOrL(?DMM`UCmljyJPrd!sVjUaZ%hf zxV!tUTwA~g`Krw|;-+aYX%7D@uoG>K@DSxmoc)nr6VGI?=YstEV62h}Y)8XK!Ma}t z_$gC{!Jh?J110c(A^a%Y_#hqBqUQpZh{o#(eVBxxP(nNVAiz5bw1O%Gq_HnTtht+* zw56@Qjn~=8ZScW?HH<8b^pmFq{4$uFUv>$V57uO4_i1=&8JPE0;-%p+10d|TO`6P| ztr{m!HNtEp&{z0@NxK_?p0MiA>GFtf0li%~>} zKH$3&d}o9hJ~;qvxHxUNl+;-x+Q;b2sW5eSjZG)e<~5}3e%;xjq0%)W`#aAN_FfIQEBq~d3a&_?G+8M$V7L7ey=@Oaf{$Ew@+4=z zIYS>GA16!Iy)rk!G703iT&;22XC0UAlUKtGw`$(bvA&ZMR96A zU@aFyeegD~9Ld%6_90ddN2-@nik)5N&w67p&ETYFNCS8`UhjPJB*o^hcQlA z`SF#7V$WH6&D1P&9wQKJ`rIiQD6@CCgTy#_-r0XD%cGuzT5X!szj!J7*%?N104WsJ zS- zHoynPa+T)aEMCgyA{2I^6?yviU(=UE=K4+RnzOUc&YhvWddPi9l-iC;dhi4WB)m7`jL_#0Am4MP0bOv4KhRzN)POTi)cv@Q!3>42BX^M#yd?TnbKu zlp2*b9BgkM=QUzxxiEhytG-@Ny;)yAf**8KM8s{jvy^)6T`b$u9^W;*%;D4P*(!6o?VAjz0E4;D-!NlcJ$RmgR5!9tJU;y=!W^21C0$ z6mf|%B_EekLTTD&6}o45{G+Ll!OaZTBw{H+dgaI7JHkMijCTs$aW-Hl_3lkT&6b`{wngeTx5_!n7NVocG^bc_q`diUsRDY585=nePN|7Z7gyMCx7%-2 z86;IxhR);J9^(D1yv-UNxzf0;LOULxnO`WFsnicb=+~>2PQRQS%A&)!%aj!w6?C)} zcVu|9G;}lg%agc1YI?pPub0gHvVIAv7|`bF1JfH)*LOwCcg*<$O1*?G|MurP8;mta znm?s3-e)_PO*1!Jzg9u@pVo2?V43&k^+xY4hH__vjYHYXq_E@e*%ceNqi5cDkzFp$ z04eIod&Cj339?~xd3kARX?689I&|&U#U%EmPysF-kXxp__P!K@cAaAAqG9k(YV@h> zia~qD-VYxpg$weW&8Ix0sl&62`|ZspP@kWXa@gJDCkyjpd^SBq zjkk6hUT$f7UoWI3T}C0~BSP!9i|2=|q81&E*jYj!^Bb*xqKUFFa(x!bJEvmIC{;cG zCMiNdU*Y8!)45_j>cEqJm+i@r7SdaXD8cir<<;J{Bw)rx+rdNbMJM`NIeE@e{#WVx z>Q9R5P=^e&A#HRx%_gLTnmWF{mY|P9SRdWg6aH+Dv3AF;Sx;$i_Y7}+E;ck~`MNTU z9A!9qT9?t~`9hTF)||s>@+po+=|<7T-ZBXmd2_kxh~R7L6gbPAgkIN_eI%6)63XQZ z(}W;@;3V8jmCzBP#A)?De<|LF3Z&#dGjA=j6}w4!BSxNxSr^x;4V0CEV(zCI(A*2L zhB=B46%zPp`YXagKt|^jH7?&mQs=d7VH)bVxkbua-Ryg9D}>D6)ME*OCD7^(6}V># zt3m$KRHrZ8l=u>+O7NSp2NKj$5QVn_j1+-ZJ4MVvdN8W*6C-2CpBjsCYE^(Uas8xV zJK_zm``|0>{6;{t;_qkcffSBG9-@kn4sz@fzvcv-LOsEGsExikC4G^_CSUjqq4u0S?jxP__Z%6ktcjAV7t*8R7BD5`v z{9q~(ADKzO2CXq+xAgHYP9kJ!Wop@ia;Ee(tnA`zyP%7|2(Nh|Gy4>pmw$!>t*%Ip zp6mPo6cZ*5ufk%0*Z3PZzFkKrN+U@jz0z7ua761SM literal 0 HcmV?d00001 diff --git a/res/shaders/default/default.fs b/res/shaders/default/default.fs new file mode 100755 index 0000000..1c1e008 --- /dev/null +++ b/res/shaders/default/default.fs @@ -0,0 +1,9 @@ +#version 450 + +uniform sampler2D sampler; + +in vec2 textureCoords; + +void main() { + gl_FragColor = texture2D(sampler, textureCoords); +} \ No newline at end of file diff --git a/res/shaders/default/default.vs b/res/shaders/default/default.vs new file mode 100755 index 0000000..213e572 --- /dev/null +++ b/res/shaders/default/default.vs @@ -0,0 +1,13 @@ +#version 450 + +uniform mat4 projection; + +in vec3 vertices; +in vec2 texCoords; + +out vec2 textureCoords; + +void main() { + textureCoords = texCoords; + gl_Position = projection * vec4(vertices, 1); +} \ No newline at end of file diff --git a/res/shaders/shapes/shapes.fs b/res/shaders/shapes/shapes.fs new file mode 100755 index 0000000..7cef706 --- /dev/null +++ b/res/shaders/shapes/shapes.fs @@ -0,0 +1,5 @@ +#version 450 + +void main() { + gl_FragColor = vec4(0, 1, 1, 0.5); +} \ No newline at end of file diff --git a/res/shaders/shapes/shapes.vs b/res/shaders/shapes/shapes.vs new file mode 100755 index 0000000..e9fde75 --- /dev/null +++ b/res/shaders/shapes/shapes.vs @@ -0,0 +1,9 @@ +#version 450 + +uniform mat4 projection; + +in vec3 vertices; + +void main() { + gl_Position = projection * vec4(vertices, 1); +} \ No newline at end of file diff --git a/src/com/gnarly/engine/components/Animation.java b/src/com/gnarly/engine/components/Animation.java new file mode 100755 index 0000000..fb295a9 --- /dev/null +++ b/src/com/gnarly/engine/components/Animation.java @@ -0,0 +1,74 @@ +package com.gnarly.engine.components; + +import com.gnarly.engine.utils.Library; + +public class Animation { + + int curFrame, numFrames; + float pastTime, curTime, mspf; + boolean play, loop; + Texture[] frames; + + public Animation(String name, String type, int numFrames, int fps, boolean loop) { + this.numFrames = numFrames; + this.loop = loop; + play = true; + mspf = 1000.0f / (float) fps; + pastTime = System.nanoTime() / 1000000.0f; + frames = new Texture[numFrames]; + for (int i = 0; i < frames.length; i++) + frames[i] = Library.getTexture(name + " " + (i + 1) + "." + type); + } + + public Animation(String name) { + frames = new Texture[1]; + frames[0] = Library.getTexture(name); + } + + public void update() { + if(frames.length > 1) { + curTime = System.nanoTime() / 1000000.0f; + while(play && curTime - pastTime > mspf) { + if(curFrame != frames.length - 1) + ++curFrame; + else if(loop) + curFrame = 0; + else + pause(); + pastTime += mspf; + } + } + } + + public int getWidth() { + return frames[curFrame].getWidth(); + } + + public int getHeight() { + return frames[curFrame].getHeight(); + } + + public void pause() { + play = false; + } + + public void play() { + if(!play) { + pastTime = System.nanoTime() / 1000000.0f; + play = true; + } + } + + public void reset() { + curFrame = 0; + pastTime = System.nanoTime() / 1000000.0f; + } + + public void bind() { + frames[curFrame].bind(); + } + + public void unbind() { + frames[curFrame].unbind(); + } +} diff --git a/src/com/gnarly/engine/components/Shader.java b/src/com/gnarly/engine/components/Shader.java new file mode 100755 index 0000000..e7a4bf5 --- /dev/null +++ b/src/com/gnarly/engine/components/Shader.java @@ -0,0 +1,153 @@ +package com.gnarly.engine.components; + +import static com.gnarly.engine.utils.MemoryUtils.GL_PROGRAM; +import static com.gnarly.engine.utils.MemoryUtils.GL_SHADER; +import static com.gnarly.engine.utils.MemoryUtils.add; +import static org.lwjgl.opengl.GL20.GL_COMPILE_STATUS; +import static org.lwjgl.opengl.GL20.GL_FRAGMENT_SHADER; +import static org.lwjgl.opengl.GL20.GL_VERTEX_SHADER; +import static org.lwjgl.opengl.GL20.glAttachShader; +import static org.lwjgl.opengl.GL20.glBindAttribLocation; +import static org.lwjgl.opengl.GL20.glCompileShader; +import static org.lwjgl.opengl.GL20.glCreateProgram; +import static org.lwjgl.opengl.GL20.glCreateShader; +import static org.lwjgl.opengl.GL20.glGetShaderInfoLog; +import static org.lwjgl.opengl.GL20.glGetShaderi; +import static org.lwjgl.opengl.GL20.glGetUniformLocation; +import static org.lwjgl.opengl.GL20.glLinkProgram; +import static org.lwjgl.opengl.GL20.glShaderSource; +import static org.lwjgl.opengl.GL20.glUniform1f; +import static org.lwjgl.opengl.GL20.glUniform1i; +import static org.lwjgl.opengl.GL20.glUniform2f; +import static org.lwjgl.opengl.GL20.glUniform3f; +import static org.lwjgl.opengl.GL20.glUniformMatrix4fv; +import static org.lwjgl.opengl.GL20.glUseProgram; +import static org.lwjgl.opengl.GL20.glValidateProgram; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileReader; +import java.io.IOException; +import java.nio.FloatBuffer; +import java.util.HashMap; +import java.util.Map; + +import org.joml.Matrix4f; +import org.joml.Vector3f; +import org.lwjgl.BufferUtils; + +public class Shader { + + private String name; + private int program, vs, fs; + public static int VERT_ATTRIB = 0, TEX_COORD_ATTRIB = 1; + boolean enabled; + Map uniforms; + + public Shader(String vertPath, String fragPath) { + name = new File(new File(vertPath).getParent()).getName(); + uniforms = new HashMap<>(); + String vert = load(vertPath); + String frag = load(fragPath); + create(vert, frag); + } + + private String load(String path) { + StringBuilder file = new StringBuilder(); + try { + BufferedReader reader = new BufferedReader(new FileReader(new File(path))); + String line; + while((line = reader.readLine()) != null) + file.append(line + '\n'); + reader.close(); + } catch (IOException e) { + e.printStackTrace(); + } + return file.toString(); + } + + public void create(String vert, String frag) { + program = glCreateProgram(); + add(GL_PROGRAM, program); + + vs = glCreateShader(GL_VERTEX_SHADER); + add(GL_SHADER, vs); + glShaderSource(vs, vert); + glCompileShader(vs); + if(glGetShaderi(vs, GL_COMPILE_STATUS) != 1) + throw new RuntimeException("Failed to compile shader! " + glGetShaderInfoLog(vs)); + + fs = glCreateShader(GL_FRAGMENT_SHADER); + add(GL_SHADER, fs); + glShaderSource(fs, frag); + glCompileShader(fs); + if(glGetShaderi(fs, GL_COMPILE_STATUS) != 1) + throw new RuntimeException("Failed to compile shader! " + glGetShaderInfoLog(fs)); + + glAttachShader(program, vs); + glAttachShader(program, fs); + + glBindAttribLocation(program, VERT_ATTRIB, "vertices"); + glBindAttribLocation(program, TEX_COORD_ATTRIB, "texCoords"); + + glLinkProgram(program); + glValidateProgram(program); + } + + public int getLocation(String name) { + if(uniforms.containsKey(name)) + return uniforms.get(name); + int location = glGetUniformLocation(program, name); + uniforms.put(name, location); + if(location != -1) + return location; + else + throw new RuntimeException("Could not find uniform: " + name); + } + + public void setUniform1i(String name, int value) { + enable(); + glUniform1i(getLocation(name), value); + disable(); + } + + public void setUniform1f(String name, float value) { + enable(); + glUniform1f(getLocation(name), value); + disable(); + } + + public void setUniform2f(String name, float x, float y) { + enable(); + glUniform2f(getLocation(name), x, y); + disable(); + } + + public void setUniform3f(String name, Vector3f vector) { + enable(); + glUniform3f(getLocation(name), vector.x, vector.y, vector.z); + disable(); + } + + public void setUniformMat4f(String name, Matrix4f matrix) { + enable(); + FloatBuffer buffer = BufferUtils.createFloatBuffer(16); + matrix.get(buffer); + glUniformMatrix4fv(getLocation(name), false, buffer); + disable(); + } + + public String getName() { + return name; + } + + public void enable() { + enabled = true; + glUseProgram(program); + } + + public void disable() { + enabled = false; + glUseProgram(0); + } +} diff --git a/src/com/gnarly/engine/components/Texture.java b/src/com/gnarly/engine/components/Texture.java new file mode 100755 index 0000000..88d6a3e --- /dev/null +++ b/src/com/gnarly/engine/components/Texture.java @@ -0,0 +1,89 @@ +package com.gnarly.engine.components; + +import static com.gnarly.engine.utils.MemoryUtils.GL_TEXTURE; +import static com.gnarly.engine.utils.MemoryUtils.add; +import static org.lwjgl.opengl.GL11.GL_NEAREST; +import static org.lwjgl.opengl.GL11.GL_RGBA; +import static org.lwjgl.opengl.GL11.GL_TEXTURE_2D; +import static org.lwjgl.opengl.GL11.GL_TEXTURE_MAG_FILTER; +import static org.lwjgl.opengl.GL11.GL_TEXTURE_MIN_FILTER; +import static org.lwjgl.opengl.GL11.GL_UNSIGNED_BYTE; +import static org.lwjgl.opengl.GL11.glBindTexture; +import static org.lwjgl.opengl.GL11.glGenTextures; +import static org.lwjgl.opengl.GL11.glTexImage2D; +import static org.lwjgl.opengl.GL11.glTexParameterf; + +import java.awt.image.BufferedImage; +import java.io.File; +import java.io.IOException; +import java.nio.ByteBuffer; + +import javax.imageio.ImageIO; + +import org.lwjgl.BufferUtils; + +public class Texture { + + private String name; + private int id, width, height; + + public Texture(String fileName) { + try { + File file = new File(fileName); + name = file.getName(); + BufferedImage bi = ImageIO.read(file); + width = bi.getWidth(); + height = bi.getHeight(); + + int[] pixelsRaw = new int[width * height]; + pixelsRaw = bi.getRGB(0, 0, width, height, null, 0, width); + + ByteBuffer pixels = BufferUtils.createByteBuffer(width * height * 4); + + for (int i = 0; i < height; i++) { + for (int j = 0; j < width; j++) { + int pixel = pixelsRaw[i * width + j]; + pixels.put((byte)((pixel >> 16) & 0xFF)); //RED + pixels.put((byte)((pixel >> 8) & 0xFF)); //GREEN + pixels.put((byte)((pixel ) & 0xFF)); //BLUE + pixels.put((byte)((pixel >> 24) & 0xFF)); //ALPHA + } + } + pixels.flip(); + + id = glGenTextures(); + add(GL_TEXTURE, id); + + bind(); + + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels); + + unbind(); + } catch(IOException e) { + e.printStackTrace(); + } + } + + public int getWidth() { + return width; + } + + public int getHeight() { + return height; + } + + public String getName() { + return name; + } + + public void bind() { + glBindTexture(GL_TEXTURE_2D, id); + } + + public void unbind() { + glBindTexture(GL_TEXTURE_2D, 0); + } +} diff --git a/src/com/gnarly/engine/components/VAO.java b/src/com/gnarly/engine/components/VAO.java new file mode 100755 index 0000000..64853d1 --- /dev/null +++ b/src/com/gnarly/engine/components/VAO.java @@ -0,0 +1,87 @@ +package com.gnarly.engine.components; + +import static com.gnarly.engine.utils.MemoryUtils.GL_BUFFER; +import static com.gnarly.engine.utils.MemoryUtils.add; +import static org.lwjgl.opengl.GL11.GL_FLOAT; +import static org.lwjgl.opengl.GL11.GL_TRIANGLES; +import static org.lwjgl.opengl.GL11.GL_UNSIGNED_INT; +import static org.lwjgl.opengl.GL11.glDrawElements; +import static org.lwjgl.opengl.GL15.GL_ARRAY_BUFFER; +import static org.lwjgl.opengl.GL15.GL_ELEMENT_ARRAY_BUFFER; +import static org.lwjgl.opengl.GL15.GL_STATIC_DRAW; +import static org.lwjgl.opengl.GL15.glBindBuffer; +import static org.lwjgl.opengl.GL15.glBufferData; +import static org.lwjgl.opengl.GL15.glGenBuffers; +import static org.lwjgl.opengl.GL20.glDisableVertexAttribArray; +import static org.lwjgl.opengl.GL20.glEnableVertexAttribArray; +import static org.lwjgl.opengl.GL20.glVertexAttribPointer; + +import java.nio.FloatBuffer; +import java.nio.IntBuffer; + +import org.lwjgl.BufferUtils; + + +public class VAO { + + private int count, vbo, ibo, tcbo; + + public VAO(float[] vertices, int[] indices, float[] texCoords) { + count = indices.length; + init(vertices, indices, texCoords); + } + + private void init(float[] vertices, int[] indices, float[] texCoords) { + vbo = glGenBuffers(); + glBindBuffer(GL_ARRAY_BUFFER, vbo); + glBufferData(GL_ARRAY_BUFFER, createFloatBuffer(vertices), GL_STATIC_DRAW); + add(GL_BUFFER, vbo); + + ibo = glGenBuffers(); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, createIntBuffer(indices), GL_STATIC_DRAW); + add(GL_BUFFER, ibo); + + tcbo = glGenBuffers(); + glBindBuffer(GL_ARRAY_BUFFER, tcbo); + glBufferData(GL_ARRAY_BUFFER, createFloatBuffer(texCoords), GL_STATIC_DRAW); + add(GL_BUFFER, tcbo); + + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); + glBindBuffer(GL_ARRAY_BUFFER, 0); + } + + public void render() { + glEnableVertexAttribArray(Shader.VERT_ATTRIB); + glEnableVertexAttribArray(Shader.TEX_COORD_ATTRIB); + + glBindBuffer(GL_ARRAY_BUFFER, vbo); + glVertexAttribPointer(Shader.VERT_ATTRIB, 3, GL_FLOAT, false, 0, 0); + + glBindBuffer(GL_ARRAY_BUFFER, tcbo); + glVertexAttribPointer(Shader.TEX_COORD_ATTRIB, 2, GL_FLOAT, false, 0, 0); + + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo); + glDrawElements(GL_TRIANGLES, count, GL_UNSIGNED_INT, 0); + + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); + glBindBuffer(GL_ARRAY_BUFFER, 0); + + glDisableVertexAttribArray(Shader.VERT_ATTRIB); + glDisableVertexAttribArray(Shader.TEX_COORD_ATTRIB); + } + + public FloatBuffer createFloatBuffer(float[] data) { + FloatBuffer buffer = BufferUtils.createFloatBuffer(data.length); + buffer.put(data); + buffer.flip(); + return buffer; + } + + public IntBuffer createIntBuffer(int[] data) { + IntBuffer buffer = BufferUtils.createIntBuffer(data.length); + buffer.put(data); + buffer.flip(); + return buffer; + } +} \ No newline at end of file diff --git a/src/com/gnarly/engine/display/Camera.java b/src/com/gnarly/engine/display/Camera.java new file mode 100755 index 0000000..03490dd --- /dev/null +++ b/src/com/gnarly/engine/display/Camera.java @@ -0,0 +1,82 @@ +package com.gnarly.engine.display; + +import org.joml.Matrix4f; +import org.joml.Vector3f; + +public class Camera { + + private int width, height; + private Vector3f position; + private Matrix4f projection; + + public Camera(int width, int height) { + this.width = width; + this.height = height; + position = new Vector3f(0,0,0); + setProjection(width, height); + } + + public void setProjection(int width, int height) { + projection = new Matrix4f().setOrtho2D(0, width, height, 0); + } + + public void setPosition(Vector3f position) { + this.position.x = -position.x; + this.position.y = -position.y; + this.position.z = -position.z; + } + + public void setPosition(float x, float y, float z) { + position.x = -x; + position.y = -y; + position.z = -z; + } + + public void setCenterPosition(Vector3f position) { + this.position.x = -position.x + width / 2; + this.position.y = -position.y + height / 2; + this.position.z = -position.z; + } + + public void setCenterPosition(float x, float y, float z) { + position.x = -x + width / 2; + position.y = -y + height / 2; + position.z = -z; + } + + public void translate(Vector3f position) { + this.position.x -= position.x; + this.position.y -= position.y; + this.position.z -= position.z; + } + + public void translate(float x, float y, float z) { + position.x -= x; + position.y -= y; + position.z -= z; + } + + public Matrix4f getUnatransformedProjection() { + return new Matrix4f(projection); + } + + public Matrix4f getProjection() { + return projection.translate(position, new Matrix4f()); + } + + public float getX() { + return -position.x; + } + + public float getY() { + return -position.y; + } + + public int getWidth() { + return width; + } + + public int getHeight() { + return height; + } +} diff --git a/src/com/gnarly/engine/display/Window.java b/src/com/gnarly/engine/display/Window.java new file mode 100755 index 0000000..09c1d7e --- /dev/null +++ b/src/com/gnarly/engine/display/Window.java @@ -0,0 +1,178 @@ +package com.gnarly.engine.display; + +import static org.lwjgl.glfw.GLFW.GLFW_FALSE; +import static org.lwjgl.glfw.GLFW.GLFW_PRESS; +import static org.lwjgl.glfw.GLFW.GLFW_RESIZABLE; +import static org.lwjgl.glfw.GLFW.GLFW_TRUE; +import static org.lwjgl.glfw.GLFW.GLFW_VISIBLE; +import static org.lwjgl.glfw.GLFW.glfwCreateWindow; +import static org.lwjgl.glfw.GLFW.glfwDestroyWindow; +import static org.lwjgl.glfw.GLFW.glfwGetKey; +import static org.lwjgl.glfw.GLFW.glfwGetMouseButton; +import static org.lwjgl.glfw.GLFW.glfwGetPrimaryMonitor; +import static org.lwjgl.glfw.GLFW.glfwGetVideoMode; +import static org.lwjgl.glfw.GLFW.glfwInit; +import static org.lwjgl.glfw.GLFW.glfwMakeContextCurrent; +import static org.lwjgl.glfw.GLFW.glfwPollEvents; +import static org.lwjgl.glfw.GLFW.glfwSetCursorPosCallback; +import static org.lwjgl.glfw.GLFW.glfwSetErrorCallback; +import static org.lwjgl.glfw.GLFW.glfwSetWindowPos; +import static org.lwjgl.glfw.GLFW.glfwSetWindowShouldClose; +import static org.lwjgl.glfw.GLFW.glfwShowWindow; +import static org.lwjgl.glfw.GLFW.glfwSwapBuffers; +import static org.lwjgl.glfw.GLFW.glfwSwapInterval; +import static org.lwjgl.glfw.GLFW.glfwTerminate; +import static org.lwjgl.glfw.GLFW.glfwWindowHint; +import static org.lwjgl.glfw.GLFW.glfwWindowShouldClose; +import static org.lwjgl.opengl.GL11.GL_BLEND; +import static org.lwjgl.opengl.GL11.GL_COLOR_BUFFER_BIT; +import static org.lwjgl.opengl.GL11.GL_DEPTH_BUFFER_BIT; +import static org.lwjgl.opengl.GL11.GL_ONE_MINUS_SRC_ALPHA; +import static org.lwjgl.opengl.GL11.GL_SRC_ALPHA; +import static org.lwjgl.opengl.GL11.GL_TEXTURE_2D; +import static org.lwjgl.opengl.GL11.GL_VERSION; +import static org.lwjgl.opengl.GL11.glBlendFunc; +import static org.lwjgl.opengl.GL11.glClear; +import static org.lwjgl.opengl.GL11.glClearColor; +import static org.lwjgl.opengl.GL11.glEnable; +import static org.lwjgl.opengl.GL11.glGetString; +import static org.lwjgl.system.MemoryUtil.NULL; + +import java.awt.Dimension; +import java.awt.Toolkit; + +import org.joml.Vector3f; +import org.lwjgl.glfw.GLFWErrorCallback; +import org.lwjgl.glfw.GLFWVidMode; +import org.lwjgl.opengl.GL; + +public class Window { + + private long window; + + private int width, height, mx, my; + private boolean vSync; + + public Window(Camera camera, String name, float scale, boolean vSync, boolean resizable) { + width = camera.getWidth(); + height = camera.getHeight(); + this.vSync = vSync; + init(name, scale, resizable, false); + } + + public Window(float percentWidth, float percentHeight, String name, boolean vSync, boolean resizable) { + this.vSync = vSync; + Dimension screen = Toolkit.getDefaultToolkit().getScreenSize(); + width = (int) (percentWidth / 100.0f * screen.getWidth()); + height = (int) (percentHeight / 100.0f * screen.getHeight()); + init(name, 1, resizable, false); + } + + public Window(boolean vSync) { + this.vSync = vSync; + init("null", 1, false, true); + } + + private void init(String name, float scale, boolean resizable, boolean fullscreen) { + glfwSetErrorCallback(GLFWErrorCallback.createPrint(System.err)); + + if(!glfwInit()) + throw new IllegalStateException("Could not initalize GLFW!"); + + if(!fullscreen) + glfwWindowHint(GLFW_RESIZABLE, resizable ? GLFW_TRUE : GLFW_FALSE); + glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE); + + GLFWVidMode vidMode = glfwGetVideoMode(glfwGetPrimaryMonitor()); + + if(fullscreen || vidMode.width() < width || vidMode.height() < height) { + width = vidMode.width(); + height = vidMode.height(); + window = glfwCreateWindow(width, height, name, glfwGetPrimaryMonitor(), NULL); + } + else { + window = glfwCreateWindow((int)(width * scale), (int)(height * scale), name, NULL, NULL); + + glfwSetWindowPos(window, (int)((vidMode.width() - (width * scale)) / 2), (int)((vidMode.height() - (height * scale)) / 2)); + } + + glfwSetCursorPosCallback(window, (long window, double xpos, double ypos) -> { + mx = (int)xpos; + my = (int)ypos; + }); + + glfwMakeContextCurrent(window); + GL.createCapabilities(); + + if(vSync) + glfwSwapInterval(1); + + glfwShowWindow(window); + + glClearColor(0.0f, 0.0f, 0.0f, 1.0f); + + glEnable(GL_TEXTURE_2D); + + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glEnable(GL_BLEND); + + System.out.println("OpenGL Version: " + glGetString(GL_VERSION)); + } + + public void update() { + glfwPollEvents(); + } + + public void clear() { + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + } + + public void swap() { + glfwSwapBuffers(window); + } + + public Vector3f getMouseCoords() { + return new Vector3f(mx, my, 0); + } + + public int isMousePressed() { + int button = -1; + for (int i = 0; i < 8 && button == -1; i++) + if(glfwGetMouseButton(window, i) == GLFW_PRESS) + button = i; + return button; + } + + public boolean isKeyPressed(int keyCode) { + return glfwGetKey(window, keyCode) == GLFW_PRESS; + } + + public void close() { + glfwSetWindowShouldClose(window, true); + } + + public boolean shouldClose() { + boolean close = glfwWindowShouldClose(window); + if(close) { + glfwDestroyWindow(window); + glfwTerminate(); + } + return close; + } + + public static void cleanup() { + + } + + public long getWindow() { + return window; + } + + public int getWidth() { + return width; + } + + public int getHeight() { + return height; + } +} diff --git a/src/com/gnarly/engine/utils/CHitbox.java b/src/com/gnarly/engine/utils/CHitbox.java new file mode 100755 index 0000000..8666227 --- /dev/null +++ b/src/com/gnarly/engine/utils/CHitbox.java @@ -0,0 +1,55 @@ +package com.gnarly.engine.utils; + +import org.joml.Vector3f; + +public class CHitbox { + + private Vector3f center; + private float radius; + + public CHitbox(float x, float y, float radius) { + center = new Vector3f(x, y, 0); + this.radius = radius; + } + + public Vector3f collisionAdjust(CHitbox hitbox) { + Vector3f distance = hitbox.center.sub(center, new Vector3f()); + distance.x = (float)Math.abs(distance.x); + distance.y = (float)Math.abs(distance.y); + + if (2 * radius * radius < distance.lengthSquared()) { + float angle = (float) Math.asin((center.x - hitbox.center.x)/(center.y - hitbox.center.y)); + distance.x = (float) Math.cos(angle) * 2 * radius * radius; + distance.y = (float) Math.sin(angle) * 2 * radius * radius; + } + return distance; + } + + public boolean checkCollision(CHitbox hitbox) { + Vector3f distance = hitbox.center.sub(center, new Vector3f()); + distance.x = (float)Math.abs(distance.x); + distance.y = (float)Math.abs(distance.y); + return 2 * radius * radius < distance.lengthSquared(); + } + + public void setPosition(float x, float y) { + center.x = x; + center.y = y; + } + + public float getX() { + return center.x; + } + + public float getY() { + return center.y; + } + + public Vector3f getCenter() { + return center; + } + + public float radius() { + return radius; + } +} diff --git a/src/com/gnarly/engine/utils/Library.java b/src/com/gnarly/engine/utils/Library.java new file mode 100755 index 0000000..2cc873a --- /dev/null +++ b/src/com/gnarly/engine/utils/Library.java @@ -0,0 +1,86 @@ +package com.gnarly.engine.utils; + +import java.io.File; +import java.util.ArrayList; + +import com.gnarly.engine.components.Shader; +import com.gnarly.engine.components.Texture; + +public class Library { + + private static Texture[] textures; + private static Shader[] shaders; + private static File[] hitboxes; + + private Library() {} + + public static void init(String texStart, String shaderStart, String hitboxStart) { + loadTextures(texStart); + loadShaders(shaderStart); + loadHitboxes(hitboxStart); + } + + private static void loadTextures(String texStart) { + String[] paths = loadStructure(texStart); + textures = new Texture[paths.length]; + for (int i = 0; i < paths.length; i++) + textures[i] = new Texture(paths[i]); + } + + private static void loadShaders(String shaderStart) { + String[] paths = loadStructure(shaderStart); + shaders = new Shader[paths.length / 2]; + for (int i = 0; i < paths.length; i += 2) + shaders[i / 2] = new Shader(paths[i + 1], paths[i]); + } + + private static void loadHitboxes(String hitboxStart) { + String[] paths = loadStructure(hitboxStart); + hitboxes = new File[paths.length]; + for (int i = 0; i < paths.length; i++) + hitboxes[i] = new File(paths[i]); + } + + private static String[] loadStructure(String structureStart) { + ArrayList check = new ArrayList<>(); + ArrayList files = new ArrayList<>(); + check.add(structureStart); + while(check.size() > 0) { + File file = new File(check.get(0)); + String path = file.getPath(); + String[] paths = file.list(); + if(paths != null) { + for (int i = 0; i < paths.length; i++) + check.add(path + "/" + paths[i]); + } + else + files.add(path); + check.remove(0); + } + String[] ret = new String[files.size()]; + for (int i = 0; i < ret.length; i++) + ret[i] = files.get(i); + return ret; + } + + public static Texture getTexture(String name) { + for (int i = 0; i < textures.length; i++) + if(textures[i].getName().equals(name)) + return textures[i]; + throw new RuntimeException("Could not find texture: " + name + "!"); + } + + public static Shader getShader(String name) { + for (int i = 0; i < shaders.length; i++) + if(shaders[i].getName().equals(name)) + return shaders[i]; + throw new RuntimeException("Could not find shader: " + name + "!"); + } + + public static File getHitboxes(String name) { + for (int i = 0; i < hitboxes.length; i++) + if(hitboxes[i].getName().equals(name)) + return hitboxes[i]; + throw new RuntimeException("Could not find hitboxes: " + name + "!"); + } +} diff --git a/src/com/gnarly/engine/utils/MemoryUtils.java b/src/com/gnarly/engine/utils/MemoryUtils.java new file mode 100755 index 0000000..21f56ce --- /dev/null +++ b/src/com/gnarly/engine/utils/MemoryUtils.java @@ -0,0 +1,58 @@ +package com.gnarly.engine.utils; + +import static org.lwjgl.openal.AL10.alDeleteBuffers; +import static org.lwjgl.openal.AL10.alDeleteSources; +import static org.lwjgl.opengl.GL11.glDeleteTextures; +import static org.lwjgl.opengl.GL15.glDeleteBuffers; +import static org.lwjgl.opengl.GL20.glDeleteProgram; +import static org.lwjgl.opengl.GL20.glDeleteShader; + +import java.util.ArrayList; + +public class MemoryUtils { + + private static final byte numTypes = 6; + private static boolean init = false; + + public static final byte + AL_BUFFER = 0, + AL_SOURCE = 1, + GL_BUFFER = 2, + GL_PROGRAM = 3, + GL_SHADER = 4, + GL_TEXTURE = 5; + + private static ArrayList[] data; + + private MemoryUtils() {} + + private static void init() { + data = new ArrayList[numTypes]; + for (int i = 0; i < numTypes; i++) + data[i] = new ArrayList(); + init = true; + } + + public static void add(byte type, int num) { + if(!init) + init(); + data[type].add(num); + } + + public static void destroy() { + if(init) { + for (int i : data[AL_BUFFER]) + alDeleteBuffers(i); + for (int i : data[AL_SOURCE]) + alDeleteSources(i); + for (int i : data[GL_BUFFER]) + glDeleteBuffers(i); + for (int i : data[GL_PROGRAM]) + glDeleteProgram(i); + for (int i : data[GL_SHADER]) + glDeleteShader(i); + for (int i : data[GL_TEXTURE]) + glDeleteTextures(i); + } + } +} diff --git a/src/com/gnarly/engine/utils/RHitbox.java b/src/com/gnarly/engine/utils/RHitbox.java new file mode 100755 index 0000000..c00662f --- /dev/null +++ b/src/com/gnarly/engine/utils/RHitbox.java @@ -0,0 +1,99 @@ +package com.gnarly.engine.utils; + +import org.joml.Vector3f; + +public class RHitbox { + + private Vector3f center, halfExtent; + + public RHitbox(float x, float y, float width, float height) { + center = new Vector3f(x + width / 2, y + height / 2, 0); + halfExtent = new Vector3f(width / 2, height / 2, 0); + } + + public Vector3f collisionAdjust(RHitbox hitbox) { + Vector3f ret = new Vector3f(); + Vector3f distance = hitbox.center.sub(center, new Vector3f()); + distance.x = (float)Math.abs(distance.x); + distance.y = (float)Math.abs(distance.y); + + distance.sub(halfExtent.add(hitbox.getHalfExtent(), new Vector3f())); + if (distance.x < 0 && distance.y < 0) { + Vector3f correction = hitbox.getCenter().sub(center, new Vector3f()); + if(distance.x > distance.y) { + if(correction.x > 0) + ret.x = distance.x; + else + ret.x = -distance.x; + } + else if(distance.x < distance.y) { + if(correction.y > 0) + ret.y = distance.y; + else + ret.y = -distance.y; + } + else { + if(correction.x > 0) + ret.x = distance.x; + else + ret.x = -distance.x; + if(correction.y > 0) + ret.y = distance.y; + else + ret.y = -distance.y; + + } + } + return ret; + } + + public boolean checkCollision(RHitbox hitbox) { + Vector3f distance = hitbox.center.sub(center, new Vector3f()); + distance.x = (float)Math.abs(distance.x); + distance.y = (float)Math.abs(distance.y); + + distance.sub(halfExtent.add(hitbox.getHalfExtent(), new Vector3f())); + return (distance.x < 0 && distance.y < 0); + } + + public void setPosition(float x, float y) { + center.x = x + halfExtent.x; + center.y = y + halfExtent.y; + } + + public void translate(Vector3f translate) { + center.x += translate.x; + center.y += translate.y; + } + + public void setBounds(float width, float height) { + halfExtent.x = width / 2; + halfExtent.y = height / 2; + center.x += (width - halfExtent.x) / 2; + center.y += (height - halfExtent.y) / 2; + } + + public float getX() { + return center.x - halfExtent.x; + } + + public float getY() { + return center.y - halfExtent.y; + } + + public float getWidth() { + return halfExtent.x * 2; + } + + public float getHeight() { + return halfExtent.y * 2; + } + + public Vector3f getCenter() { + return center; + } + + public Vector3f getHalfExtent() { + return halfExtent; + } +} diff --git a/src/com/gnarly/game/Main.java b/src/com/gnarly/game/Main.java new file mode 100755 index 0000000..b97f674 --- /dev/null +++ b/src/com/gnarly/game/Main.java @@ -0,0 +1,83 @@ +package com.gnarly.game; + +import com.gnarly.engine.display.Camera; +import com.gnarly.engine.display.Window; +import com.gnarly.engine.utils.Library; +import com.gnarly.engine.utils.MemoryUtils; +import com.gnarly.game.panels.PlayPanel; + +public class Main implements Runnable { + + private final int UPS = 120; + private final int FPS = 120; + + private final int PIXEL = 5; + + private Window window; + private Camera camera; + private Thread gameLoop; + private PlayPanel panel; + + public Main() { + gameLoop = new Thread(this); + gameLoop.start(); + } + + public void run() { + init(); + float pastUTime = (float) System.nanoTime() / 1000000.0f; + float curUTime = 0.0f; + float mspu = 1000.0f / (float)UPS; + float pastFTime = pastUTime; + float curFTime = 0.0f; + float mspf = 1000.0f / (float)FPS; + float pastSec = pastUTime / 1000f; + float curSec = 0.0f; + int frames = 0; + int updates = 0; + while(!window.shouldClose()) { + curUTime = (float) System.nanoTime() / 1000000.0f; + curFTime = curUTime; + if(curUTime - pastUTime > mspu) { + update(); + pastUTime += mspu; + ++updates; + } + if(curFTime - pastFTime > mspf) { + render(); + pastFTime += mspf; + ++frames; + } + curSec = (float) System.nanoTime() / 1000000000.0f; + if(curSec - pastSec > 1.0f) { + System.out.println(frames); + frames = 0; + updates = 0; + pastSec += 1; + } + } + MemoryUtils.destroy(); + } + + private void init() { + camera = new Camera(1920 / PIXEL, 1080 / PIXEL); + window = new Window(true); + Library.init("res/img", "res/shaders", "res/hitboxes"); + panel = new PlayPanel(window, camera); + } + + private void update() { + window.update(); + panel.update(); + } + + private void render() { + window.clear(); + panel.render(); + window.swap(); + } + + public static void main(String[] args) { + new Main(); + } +} diff --git a/src/com/gnarly/game/objects/Character.java b/src/com/gnarly/game/objects/Character.java new file mode 100755 index 0000000..7acc808 --- /dev/null +++ b/src/com/gnarly/game/objects/Character.java @@ -0,0 +1,314 @@ +package com.gnarly.game.objects; + +import static org.lwjgl.glfw.GLFW.GLFW_KEY_A; +import static org.lwjgl.glfw.GLFW.GLFW_KEY_D; +import static org.lwjgl.glfw.GLFW.GLFW_KEY_LEFT_SHIFT; +import static org.lwjgl.glfw.GLFW.GLFW_KEY_S; +import static org.lwjgl.glfw.GLFW.GLFW_KEY_SPACE; + +import com.gnarly.engine.components.Animation; +import com.gnarly.engine.components.Shader; +import com.gnarly.engine.components.VAO; +import com.gnarly.engine.display.Camera; +import com.gnarly.engine.display.Window; +import com.gnarly.engine.utils.Library; +import com.gnarly.engine.utils.RHitbox; + +public class Character { + + private final boolean + LEFT = true, + RIGHT = false; + + private final int + IDLE = 0, + WALK = 1, + RUN = 2, + JUMP = 3, + FALL = 4; + + private final float + WALK_ACCEL = 1, + SPRINT_ACCEL = 2, + STRAFE_ACCEL = 0.05f, + WALK_SPEED = 1, + SPRINT_SPEED = 2, + STRAFE_SPEED = 0.8f, + GROUND_DECAY = 0.15f, + AERIAL_DECAY = 0.01f, + FASTFALL = 2.0f, + BOUNCE_SPEED = 6.0f, + BOUNCE_SCALE = 0.8f; + + private final float + GRAVITY = 0.1f, + MAX_GRAV = 8.0f; + + private final float + SHORT_HOP = 0.65f, + LONG_JUMP = 0.35f, + AERIAL_JUMP = 3.0f; + + private final int + NUM_JUMPS = 50, + MIN_JUMP = 4, + MAX_JUMP = 7; + + private float fallSpeed; + + private int state = 0; + + private float x, y, width, height, dx, dy; + + private boolean airborne = false; + private boolean dir = false; + + private int jump = 0; + private int jumps = 0; + private int jumpFrames = 0; + + private Animation anims[]; + private Shader shader; + private VAO right; + private VAO left; + private Camera camera; + private Window window; + private RHitbox rHitbox; + + public Character(Window window, Camera camera, String name, float x, float y) { + this.camera = camera; + this.window = window; + anims = new Animation[5]; + anims[IDLE] = new Animation(name + " idle", "png", 8, 10, true); + anims[WALK] = new Animation(name + " walk", "png", 9, 10, true); + anims[RUN] = new Animation(name + " run", "png", 4, 10, true); + anims[JUMP] = new Animation(name + " jump", "png", 6, 20, true); + anims[FALL] = new Animation(name + " fall", "png", 6, 20, true); + this.x = x; + this.y = y - anims[0].getHeight(); + width = anims[0].getWidth(); + height = anims[0].getHeight(); + shader = Library.getShader("default"); + rHitbox = new RHitbox(this.x, this.y, width, height); + float[] vertices = new float[] { + 0.0f, 0.0f, 0.5f, //TOP LEFT + 0.0f, height, 0.5f, //BOTTOM LEFT + width, height, 0.5f, //BOTTOM RIGHT + width, 0.0f, 0.5f //TOP RIGHT + }; + int[] indices = new int[] { + 0, 1, 3, + 1, 2, 3 + }; + float[] texCoords = new float[] { + 0, 0, + 0, 1, + 1, 1, + 1, 0 + }; + right = new VAO(vertices, indices, texCoords); + texCoords = new float[] { + 1, 0, + 1, 1, + 0, 1, + 0, 0 + }; + left = new VAO(vertices, indices, texCoords); + } + + public void update() { + boolean move = false; + if(window.isKeyPressed(GLFW_KEY_D)) { + move = true; + if(window.isKeyPressed(GLFW_KEY_LEFT_SHIFT) && !airborne && dx < 2) { + if(dx > 0) + dx += SPRINT_ACCEL; + else + dx += SPRINT_ACCEL / 20; + if(dx > SPRINT_SPEED) + dx = SPRINT_SPEED; + } + else if(!airborne && dx < 1) { + if(dx > 0) + dx += WALK_ACCEL; + else + dx += WALK_ACCEL / 20; + if(dx > WALK_SPEED) + dx = WALK_SPEED; + } + else if(dx < STRAFE_SPEED) + dx += STRAFE_ACCEL; + } + if(window.isKeyPressed(GLFW_KEY_A)) { + move = true; + if(window.isKeyPressed(GLFW_KEY_LEFT_SHIFT) && !airborne && dx > -2) { + if(dx < 0) + dx -= SPRINT_ACCEL; + else + dx -= SPRINT_ACCEL / 20; + if(dx < -SPRINT_SPEED) + dx = -SPRINT_SPEED; + } + else if(!airborne && dx > -1) { + if(dx < 0) + dx -= WALK_ACCEL; + else + dx -= WALK_ACCEL / 20; + if(dx < -WALK_SPEED) + dx = -WALK_SPEED; + } + else if(dx > -STRAFE_SPEED) + dx -= STRAFE_ACCEL; + } + if(window.isKeyPressed(GLFW_KEY_S) && airborne) { + if(dy > 0) + fallSpeed = FASTFALL; + dy += fallSpeed; + } + jump(); + updateAnim(); + if(dy < MAX_GRAV) { + if(dy + GRAVITY > MAX_GRAV) + dy = MAX_GRAV; + else + dy += GRAVITY; + } + x += dx; + y += dy; + anims[state].update(); + rHitbox.setPosition(x, y); + if(!move) { + if(!airborne && dx > 0) { + dx -= GROUND_DECAY; + if(dx < 0) + dx = 0; + } + else if(!airborne && dx < 0) { + dx += GROUND_DECAY; + if(dx > 0) + dx = 0; + } + } + else if(dx > 0) { + dx -= AERIAL_DECAY; + if(dx < 0) + dx = 0; + } + else if(dx < 0) { + dx += AERIAL_DECAY; + if(dx > 0) + dx = 0; + } + if(window.isKeyPressed(GLFW_KEY_S) && airborne) { + dy -= fallSpeed; + } + } + + public void render() { + shader.setUniformMat4f("projection", camera.getProjection().translate(x, y, 0)); + anims[state].bind(); + shader.enable(); + if(dir == RIGHT) + right.render(); + else if(dir == LEFT) + left.render(); + shader.disable(); + anims[state].unbind(); + } + + private void jump() { + if(airborne && jumps < 2) + jumps = 2; + if((window.isKeyPressed(GLFW_KEY_SPACE) || (jump > 0 && jump < 3)) && jumpFrames < MIN_JUMP) { + if(jump == 0) { + jump = 1; + if(dx > 1) + dx = 1; + else if(dx < -1) + dx = -1; + } + dy -= SHORT_HOP; + airborne = true; + } + else if(window.isKeyPressed(GLFW_KEY_SPACE) && jumpFrames < MAX_JUMP) + dy -= LONG_JUMP; + if(jump % 2 == 1 && !window.isKeyPressed(GLFW_KEY_SPACE)) + ++jump; + else if(jump % 2 == 0 && jump > 1 && window.isKeyPressed(GLFW_KEY_SPACE) && jumps < NUM_JUMPS) { + ++jump; + ++jumps; + dy = -AERIAL_JUMP; + if(window.isKeyPressed(GLFW_KEY_A)) + dx = -1f; + if(window.isKeyPressed(GLFW_KEY_D)) + dx = 1f; + } + if(jumps == 1) + jumpFrames = MAX_JUMP; + else if(jumpFrames < MAX_JUMP && jump > 0) + ++jumpFrames; + } + + private void updateAnim() { + int tAnim = 0; + if(!airborne) { + if(dx > 1 || dx < -1) + tAnim = RUN; + else if(dx > 0 || dx < 0) + tAnim = WALK; + else + tAnim = IDLE; + if(dx > 0) + dir = RIGHT; + else if(dx < 0) + dir = LEFT; + } + else if(airborne && dy <= 0) + tAnim = JUMP; + else if(airborne && dy > 0) + tAnim = FALL; + if(tAnim != state) { + anims[state].pause(); + anims[state].reset(); + anims[tAnim].play(); + state = tAnim; + } + } + + public void hitStage(boolean hit) { + if(!hit) + airborne = true; + else { + if(rHitbox.getX() != x) { + if(Math.abs(dx) < BOUNCE_SPEED) + dx = 0; + else + dx = -dx * BOUNCE_SCALE; + } + else if(rHitbox.getY() < y) { + if(Math.abs(dy) < BOUNCE_SPEED) { + fallSpeed = 0.2f; + dy = 0; + jump = 0; + jumpFrames = 0; + jumps = 0; + airborne = false; + } + else + dy = -dy * BOUNCE_SCALE; + } + else if(rHitbox.getY() > y) { + if(Math.abs(dy) < BOUNCE_SPEED) + dy = 0; + else + dy = -dy * BOUNCE_SCALE; + } + x = rHitbox.getX(); + y = rHitbox.getY(); + } + } + + public RHitbox getRHitbox() { + return rHitbox; + } +} diff --git a/src/com/gnarly/game/objects/Rectangle.java b/src/com/gnarly/game/objects/Rectangle.java new file mode 100755 index 0000000..d8e488f --- /dev/null +++ b/src/com/gnarly/game/objects/Rectangle.java @@ -0,0 +1,48 @@ +package com.gnarly.game.objects; + +import com.gnarly.engine.components.Shader; +import com.gnarly.engine.components.VAO; +import com.gnarly.engine.display.Camera; +import com.gnarly.engine.utils.Library; + +public class Rectangle { + + private float x, y, width, height; + + private Camera camera; + private Shader shader; + private VAO vao; + + public Rectangle(Camera camera, float x, float y, float width, float height) { + this.camera = camera; + this.x = x; + this.y = y; + this.width = width; + this.height = height; + shader = Library.getShader("shapes"); + float[] vertices = { + 0.0f, 0.0f, 1.0f, //TOP LEFT + 0.0f, height, 1.0f, //BOTTOM LEFT + width, height, 1.0f, //BOTTOM RIGHT + width, 0.0f, 1.0f //TOP RIGHT + }; + int[] indices = { + 0, 1, 3, + 1, 2, 3 + }; + float[] texCoords = { + 0, 0, + 0, 1, + 1, 1, + 1, 0 + }; + vao = new VAO(vertices, indices, texCoords); + } + + public void render() { + shader.setUniformMat4f("projection", camera.getProjection().translate(x, y, 0)); + shader.enable(); + vao.render(); + shader.disable(); + } +} diff --git a/src/com/gnarly/game/objects/Stage.java b/src/com/gnarly/game/objects/Stage.java new file mode 100755 index 0000000..d42b1b9 --- /dev/null +++ b/src/com/gnarly/game/objects/Stage.java @@ -0,0 +1,99 @@ +package com.gnarly.game.objects; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.ObjectInputStream; + +import org.joml.Matrix4f; +import org.joml.Vector3f; + +import com.gnarly.engine.components.Animation; +import com.gnarly.engine.components.Shader; +import com.gnarly.engine.components.VAO; +import com.gnarly.engine.display.Camera; +import com.gnarly.engine.utils.Library; +import com.gnarly.engine.utils.RHitbox; + +public class Stage { + + private float width, height, floor; + private Vector3f center; + + private VAO vao; + private Shader shader; + private Animation stage; + private RHitbox[] hitboxes; + private Camera camera; + + public Stage(Camera camera, String stageName) { + this.camera = camera; + stage = new Animation("mountain", "png", 1, 10, true); + shader = Library.getShader("default"); + width = stage.getWidth(); + height = stage.getHeight(); + try { + File hitboxFile = Library.getHitboxes(stageName + ".shb"); + ObjectInputStream input = new ObjectInputStream(new FileInputStream(hitboxFile)); + center = new Vector3f(input.readFloat(), input.readFloat(), 0); + hitboxes = new RHitbox[input.readInt()]; + for (int i = 0; i < hitboxes.length; i++) + hitboxes[i] = new RHitbox(input.readFloat(), input.readFloat(), input.readFloat(), input.readFloat()); + input.close(); + } catch(IOException e) { + e.printStackTrace(); + } + floor = hitboxes[0].getY(); + float[] vertices = { + 0.0f, 0.0f, 0.0f, //TOP LEFT + 0.0f, height, 0.0f, //BOTTOM LEFT + width, height, 0.0f, //BOTTOM RIGHT + width, 0.0f, 0.0f //TOP RIGHT + }; + int[] indices = { + 0, 1, 3, + 1, 2, 3 + }; + float[] texCoords = { + 0, 0, + 0, 1, + 1, 1, + 1, 0 + }; + vao = new VAO(vertices, indices, texCoords); + } + + public void update() { + stage.update(); + } + + public void render() { + shader.setUniformMat4f("projection", camera.getProjection()); + stage.bind(); + shader.enable(); + vao.render(); + shader.disable(); + stage.unbind(); + } + + public boolean checkPlayer(RHitbox character) { + Vector3f translate = new Vector3f(); + for (int i = 0; i < hitboxes.length && translate.x == 0 && translate.y == 0; i++) + translate = character.collisionAdjust(hitboxes[i]); + if(translate.x != 0 || translate.y != 0) { + character.translate(translate); + checkPlayer(character); + return true; + } + else + return false; + } + + public float getFloor() { + return floor; + } + + public Vector3f getCenter() { + return center; + } +} diff --git a/src/com/gnarly/game/panels/PlayPanel.java b/src/com/gnarly/game/panels/PlayPanel.java new file mode 100755 index 0000000..c6ad528 --- /dev/null +++ b/src/com/gnarly/game/panels/PlayPanel.java @@ -0,0 +1,32 @@ +package com.gnarly.game.panels; + +import com.gnarly.engine.display.Camera; +import com.gnarly.engine.display.Window; +import com.gnarly.game.objects.Character; +import com.gnarly.game.objects.Stage; + +public class PlayPanel { + + private Stage stage; + private Camera camera; + private Character character; + + public PlayPanel(Window window, Camera camera) { + this.camera = camera; + stage = new Stage(camera, "mountain"); + character = new Character(window, camera, "blue stick", stage.getCenter().x, stage.getFloor()); + camera.setCenterPosition(stage.getCenter()); + } + + public void update() { + stage.update(); + character.update(); + boolean hit = stage.checkPlayer(character.getRHitbox()); + character.hitStage(hit); + } + + public void render() { + stage.render(); + character.render(); + } +}