From 0605e4d91b8f55a7c2a0671a53e7d6c22fae10ec Mon Sep 17 00:00:00 2001 From: Gnarwhal Date: Wed, 7 Aug 2024 05:04:16 +0000 Subject: [PATCH] Added parallax background, ship, and firing. Collision is WIP --- res/img/background/background-layer-0.png | Bin 0 -> 1480 bytes res/img/background/background-layer-1.png | Bin 0 -> 2396 bytes res/img/bullets/bullet-0/bullet-0.png | Bin 0 -> 177 bytes res/img/bullets/bullet-0/bullet-1.png | Bin 0 -> 166 bytes res/img/bullets/bullet-0/bullet-2.png | Bin 0 -> 176 bytes res/img/bullets/bullet-0/bullet-3.png | Bin 0 -> 161 bytes res/img/player-ship.png | Bin 553 -> 0 bytes res/img/player-ship/player-ship-0.png | Bin 0 -> 544 bytes res/img/player-ship/player-ship-1.png | Bin 0 -> 543 bytes res/img/player-ship/player-ship-2.png | Bin 0 -> 537 bytes res/img/player-ship/player-ship-3.png | Bin 0 -> 543 bytes res/shaders/s2b/frag.gls | 19 ++ res/shaders/s2b/vert.gls | 13 ++ res/shaders/s2t/frag.gls | 14 +- src/com/gnarly/engine/display/Window.java | 58 +----- src/com/gnarly/engine/model/Rect.java | 10 +- src/com/gnarly/engine/model/TexRect.java | 24 --- src/com/gnarly/engine/shaders/Shader.java | 10 +- src/com/gnarly/engine/shaders/Shader2b.java | 32 +++ src/com/gnarly/engine/shaders/Shader2t.java | 23 +-- src/com/gnarly/engine/texture/Texture.java | 50 ++--- src/com/gnarly/engine/texture/TextureSet.java | 20 ++ src/com/gnarly/game/Background.java | 47 +++++ src/com/gnarly/game/BulletList.java | 188 ++++++++++++++++++ src/com/gnarly/game/Collision.java | 103 ++++++++++ src/com/gnarly/game/GamePanel.java | 32 ++- src/com/gnarly/game/Main.java | 32 ++- src/com/gnarly/game/Player.java | 63 ++++++ 28 files changed, 588 insertions(+), 150 deletions(-) create mode 100644 res/img/background/background-layer-0.png create mode 100644 res/img/background/background-layer-1.png create mode 100644 res/img/bullets/bullet-0/bullet-0.png create mode 100644 res/img/bullets/bullet-0/bullet-1.png create mode 100644 res/img/bullets/bullet-0/bullet-2.png create mode 100644 res/img/bullets/bullet-0/bullet-3.png delete mode 100644 res/img/player-ship.png create mode 100644 res/img/player-ship/player-ship-0.png create mode 100644 res/img/player-ship/player-ship-1.png create mode 100644 res/img/player-ship/player-ship-2.png create mode 100644 res/img/player-ship/player-ship-3.png create mode 100644 res/shaders/s2b/frag.gls create mode 100644 res/shaders/s2b/vert.gls create mode 100644 src/com/gnarly/engine/shaders/Shader2b.java create mode 100644 src/com/gnarly/engine/texture/TextureSet.java create mode 100644 src/com/gnarly/game/Background.java create mode 100644 src/com/gnarly/game/BulletList.java create mode 100644 src/com/gnarly/game/Collision.java create mode 100644 src/com/gnarly/game/Player.java diff --git a/res/img/background/background-layer-0.png b/res/img/background/background-layer-0.png new file mode 100644 index 0000000000000000000000000000000000000000..5a46c0202dc1bb838ce45241305b2dbb90aa1c54 GIT binary patch literal 1480 zcmeAS@N?(olHy`uVBq!ia0y~yU~*t!V07VN1B#q~+_)D=F%}28J29*~C-V}>VM%xN zb!1@J*w6hZkrl}2EbxddW?iF9Bx^hJzbUCKVeb*sjR>Jw`Ca^`eE%*69|DlKkNc02q zP?sXh=l!@K4mR@l2SpdYll%-|&Jsxm zps_}OnUR&^WN+ACIBWXXTXKr7|EI)m{GYh{|H%hHM*>YSVQv725{JPBpbJue*8o|0J>k`J4qFk;M!Qe1}1p@p%4<6b1&4kDe}$Ar*0N?^^e*HehhLs9rYl?|PL| zv8n1R;v$P@x*TTsXzT7I_P4a_$6ijUyR>B52?N_d4;#AnEy=_P@Jtx&T$$zhXb{A7`|yoDf~eXX zbj_Iqmeqr;KmSln0U~Rrb2|_$c$4SvZ6+2}Eoi*pPm)DY*V|V|9OFQfhH(va<$o;z zhmFx+`NQo8cBt4hz&v-!hXG~+OgZuNfop$1?pb@jqE!SGPN&k|)Js0@_o;&!n5o79 zjWc;BpAx8O{pr)u4aim``12V-eQf>LngtTp1zO&-p-%k&_a-zLWKILpOAn{+_rkZdOgr@2)@AK1yYa)GSR5WeWS%7l`kEr1by$ T+Z(Dt6B#^R{an^LB{Ts5SYA46 literal 0 HcmV?d00001 diff --git a/res/img/bullets/bullet-0/bullet-1.png b/res/img/bullets/bullet-0/bullet-1.png new file mode 100644 index 0000000000000000000000000000000000000000..df8cd00431ff5bbf5f9902b0068995e2587711b4 GIT binary patch literal 166 zcmeAS@N?(olHy`uVBq!ia0vp^EI`b`!3HGn8ON~#DaPU;cPEB*=VV@jWYZme9T^xl z_H+M91W9rhctjR6Fz_7&Va6R3v)=**tvy{FLnOkJ8Jac!|8F)FFldtCoRyH+#(G^+ zVupeb2Rq9FEd?Ki6NxD;s~HLx=qNZCi7aH&p7H6wJ;Pr|v8c(_D;ENdVeoYIb6Mw< G&;$Ty-7N?J literal 0 HcmV?d00001 diff --git a/res/img/bullets/bullet-0/bullet-2.png b/res/img/bullets/bullet-0/bullet-2.png new file mode 100644 index 0000000000000000000000000000000000000000..cd73e5fa1fbba617a4c6d7f31f64269233dd0466 GIT binary patch literal 176 zcmeAS@N?(olHy`uVBq!ia0vp^EI`b`!3HGn8ON~#DaPU;cPEB*=VV@jWYZme9T^xl z_H+M91W9rhctjR6Fz_7&Va6R3v)=**T|HeKLnOjOdpGhnIPe^qlXE!i%Nl0eXv4mT zUmmeeTQsNJ+iNM`lY_llWwFyW=7@jka6YtN=$H0RL+y!g>JF=z8~t2X#N6{!iTUg$ R$5fz!44$rjF6*2UngI6sIMDzA literal 0 HcmV?d00001 diff --git a/res/img/bullets/bullet-0/bullet-3.png b/res/img/bullets/bullet-0/bullet-3.png new file mode 100644 index 0000000000000000000000000000000000000000..4f298baec9e8e266ba8f4adada6a3005b0c7e740 GIT binary patch literal 161 zcmeAS@N?(olHy`uVBq!ia0vp^EI`b`!3HGn8ON~#DaPU;cPEB*=VV@jWYZme9T^xl z_H+M91W9rhctjR6Fz_7&Va6R3v)=**%{*NkLnOkJ8Jac!|8F)FFldtCoRyH+#(G^+ zVnzawL;}m?fTs!!f((o*jv~$n(-ts^Eal;0C{mZ;->#=+05pNY)78&qol`;+05UQs A3IG5A literal 0 HcmV?d00001 diff --git a/res/img/player-ship.png b/res/img/player-ship.png deleted file mode 100644 index 78358716b2379052a90ac12d44b5043303f69f9e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 553 zcmV+^0@nSBP)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D0lrB@K~z{r?Upfb z!Y~kp9Y!R?uVCnil$jZcfxl2#+n>{}(2-E~yp}dyhIRjw*4~K*PR8V&x zyp|w1fYg4b&N4i_1CdrQ&S&52^+;#487Y&0?>(;f4_)R=-4I?&aLpVH1_NCc`0j_w z05ArwO?M51xE4fg6HK9!u{3*-Bnjzau^^R@mZj7Inr;q^t7bhM4t4cMtJTt#8>u5E z0F0qN?Viu)x~hjAf&zq?-;3pPNuH(y|7mX1z>8&wId8UmfG$+th9QIoYc`vtwF2Cu z3u&5?1_#(~x1@FmpEJOQ%|WBn=|rc~N#P0w#v$E+v2EV(_oLFuwApM*hr~JUc3W3U zb-P_%71*=4O(bBfOZh0COeQACcsw@0;eZ^3L$Em;+XmC=)QmM6jV}De0O~8t-rtn^ z+2!?Txk~^+IK=UIB!#(c%tYVHjFo*{`pE%69)eT|05}8(a6SJK04kY->bt;U4&peb r%?qktK3v9(GXVam9}zd>4x!X9JYhC#v|(eD00000NkvXXu0mjfIok4$ diff --git a/res/img/player-ship/player-ship-0.png b/res/img/player-ship/player-ship-0.png new file mode 100644 index 0000000000000000000000000000000000000000..aee124cff1f7eb3024f9d94bdb060884cf67346e GIT binary patch literal 544 zcmV+*0^j|KP)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGizyJUazyWI3i3tDz0kug)K~z{r?Uuc6 z!Y~v@Zy2-i6bv0BF*74E#4&`>cEi0(+Hjrc8jQb5xm9Lat+U<6#@5^Hf?lS=9|9Cvgy_&x3 z;4uZ>0Zip*`b@*kD-g)miJx~rnM_2xTCGIORL7mibw068&h!o8GzDF9Fq_R}uf}yf zSOY)|+7?|G2+mZp zh|}pLTF7-V6TFiet9-fi83W+OhzrGzApqbI9H8y{&*PZn!1@%lT?EGCu~@vo_VZyI i0~iAY=9~Tlh`s>Mm^Fm=X|Rj{0000Px#1ZP1_K>z@;j|==^1poj532;bRa{vGizyJUazyWI3i3tDz0kla(K~z{r?Uyl+ zf-n@vAB--13Wgg=n3+i&{0ax_-N(6GjBrp=VRTC#|_Yzuj5_V?RKJX%X11IGXTzi(=_~Sz;zuw zr@%UZs{Dk@G~B%c9&e5K{q#wau(m8q))M`7<8h5|)X53g5JpolB}eA-Iqwaau7}Y8 zC`NRPZVC)B6+{_;dzsi(E;AP7VxCZn?U)qHzgR3_wOa8jKb%e{Sg+UoOpm-iLXF)HgcTjTY*&=-G(;U2Aj=hthElX-|w|DlN~^u z&u7*;S3nM7`}8D7{4fl?Rt9u|HJ=LBM+eQ55msfLwlA zq5{RdtNu1zE|(%mp6B8o3P?dH1j$J(3yPu;V`W)(WLkFI-t0r)!f{rAf%AsB>0 zv~9~;l*?km`vfso_jc_YU4*I+AaNYCbt9vaBf2q0VQ=QX3j7VN1uJ3l@0i9?9m)!L hebt?kYtWAc@C|@Px#1ZP1_K>z@;j|==^1poj532;bRa{vGizyJUazyWI3i3tDz0j^0zK~z{r?Uuc6 zgD@0EFN`ca1w%((fEkG)uh6ijkJGNuk(D7*Rx(G**dff>Q506nHNLKC46)s)QKTFR z*&y)wxHdoV7Y>I*S5;Nl1GbyX$GRJj8=x;=$GfoIZbjde=M+3<0G$82uKC`8?K*f) zfpGv;`3ak8xO)X0-fHpt?xQGTZBZ1gCHmvq<7%HcB`0h{XidR2Ig%s^?+xg#huHuq zMy3|sH88}rAj$yT%fz;FnYkdNc|s|+b5bn-VzGd-EcuZiPNx&B*K58vjl4cY1$5+u zN^XK&4Hm#eek(Sc4ReYL{HI*T#UD!(InMK~z$(l>h9;N>^E{8W#sT*G{iICi2_V|G zWvz7uV4#U^qT%knsmozaVEx7&&5Q-$yQyay15A@2>y<(DNY zP|UmPuVI#DB1oF1;v5P{K_~>tNh}NUJQrgvm&*&EG61}H-Rld$=U3l<8&?UzAQa+w zJhB$$vY2o_K#bL`E`7=X_+rEh*^VLrLLn%?)c2ppQOS|X0EDCVGcd&YeAfQ?P;s*t bksScvffP7=4EIph00000NkvXXu0mjfWnAZf literal 0 HcmV?d00001 diff --git a/res/img/player-ship/player-ship-3.png b/res/img/player-ship/player-ship-3.png new file mode 100644 index 0000000000000000000000000000000000000000..8cafa0caab7881741874c8c59bb2ea950d97f96d GIT binary patch literal 543 zcmV+)0^t3LP)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGizyJUazyWI3i3tDz0kla(K~z{r?Upf* zf-n@vAB--33Wgg=n4L`+_zI`%-N(6G@kUn$5>}W^9B+`BotUt4ywcYz*ka3>Gba8L z@+!gp{=T*<{Dsr$)aH5KcEH@r<#XMQ#|_Z6ujNB1ib9NSc`m_Y2Eg?%%aXt9nY$03 zOJE&9)qY~mGTglb4zEUxKmBU8Vs*dYvr2ULjpsFfP$wtmhA>)!YjPwELq6&;-4Bxi zP>kp{-8C@8wIIp>+{?ssjv#_z)}AsB>0 zR8_?)%4IR(e1e#(eY^B&17N{7bg)}vC>w)=0!~YeCX!X h9z&B5rs(Ga_yG>5H&>zC?mz$l002ovPDHLkV1luk?f3uy literal 0 HcmV?d00001 diff --git a/res/shaders/s2b/frag.gls b/res/shaders/s2b/frag.gls new file mode 100644 index 0000000..3358cdb --- /dev/null +++ b/res/shaders/s2b/frag.gls @@ -0,0 +1,19 @@ +#version 330 core + +uniform sampler2D layer0; +uniform sampler2D layer1; + +uniform float offset0 = 1; +uniform float offset1 = 1; + +in vec2 texCoords; + +out vec4 color; + +void main() { + vec4 color0 = texture(layer0, texCoords + vec2(0, offset0)); + vec4 color1 = texture(layer1, texCoords + vec2(0, offset1)); + color = mix(color0, color1, 1 - color0.a); + if (color.a == 0) + discard; +} \ No newline at end of file diff --git a/res/shaders/s2b/vert.gls b/res/shaders/s2b/vert.gls new file mode 100644 index 0000000..6c3699d --- /dev/null +++ b/res/shaders/s2b/vert.gls @@ -0,0 +1,13 @@ +#version 330 core + +uniform mat4 mvp; + +layout (location = 0) in vec3 vertices; +layout (location = 1) in vec2 itexCoords; + +out vec2 texCoords; + +void main() { + texCoords = itexCoords; + gl_Position = mvp * vec4(vertices, 1); +} \ No newline at end of file diff --git a/res/shaders/s2t/frag.gls b/res/shaders/s2t/frag.gls index 6d0ed1d..ad07ab5 100644 --- a/res/shaders/s2t/frag.gls +++ b/res/shaders/s2t/frag.gls @@ -2,20 +2,12 @@ uniform sampler2D sampler; -uniform vec4 iColor = vec4(1, 1, 1, 1); -uniform float alpha = 1; -uniform float amount = 1; - in vec2 texCoords; out vec4 color; void main() { - vec4 texColor = texture(sampler, texCoords); - if(texColor.a == 0) - discard; - else { - color = mix(iColor, texColor, amount); - color.a = color.a * alpha; - } + color = texture(sampler, texCoords); + if (color.a == 0) + discard; } \ No newline at end of file diff --git a/src/com/gnarly/engine/display/Window.java b/src/com/gnarly/engine/display/Window.java index 73aba3f..aed8a15 100644 --- a/src/com/gnarly/engine/display/Window.java +++ b/src/com/gnarly/engine/display/Window.java @@ -1,39 +1,6 @@ package com.gnarly.engine.display; -import static org.lwjgl.glfw.GLFW.GLFW_CONTEXT_VERSION_MAJOR; -import static org.lwjgl.glfw.GLFW.GLFW_CONTEXT_VERSION_MINOR; -import static org.lwjgl.glfw.GLFW.GLFW_DECORATED; -import static org.lwjgl.glfw.GLFW.GLFW_FALSE; -import static org.lwjgl.glfw.GLFW.GLFW_KEY_LAST; -import static org.lwjgl.glfw.GLFW.GLFW_MAXIMIZED; -import static org.lwjgl.glfw.GLFW.GLFW_MOUSE_BUTTON_LAST; -import static org.lwjgl.glfw.GLFW.GLFW_OPENGL_CORE_PROFILE; -import static org.lwjgl.glfw.GLFW.GLFW_OPENGL_FORWARD_COMPAT; -import static org.lwjgl.glfw.GLFW.GLFW_OPENGL_PROFILE; -import static org.lwjgl.glfw.GLFW.GLFW_PRESS; -import static org.lwjgl.glfw.GLFW.GLFW_RELEASE; -import static org.lwjgl.glfw.GLFW.GLFW_REPEAT; -import static org.lwjgl.glfw.GLFW.GLFW_RESIZABLE; -import static org.lwjgl.glfw.GLFW.GLFW_SAMPLES; -import static org.lwjgl.glfw.GLFW.GLFW_TRUE; -import static org.lwjgl.glfw.GLFW.glfwCreateWindow; -import static org.lwjgl.glfw.GLFW.glfwGetCursorPos; -import static org.lwjgl.glfw.GLFW.glfwGetPrimaryMonitor; -import static org.lwjgl.glfw.GLFW.glfwGetVideoMode; -import static org.lwjgl.glfw.GLFW.glfwGetWindowSize; -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.glfwSetErrorCallback; -import static org.lwjgl.glfw.GLFW.glfwSetKeyCallback; -import static org.lwjgl.glfw.GLFW.glfwSetMouseButtonCallback; -import static org.lwjgl.glfw.GLFW.glfwSetWindowShouldClose; -import static org.lwjgl.glfw.GLFW.glfwSetWindowSizeCallback; -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.glfw.GLFW.*; import static org.lwjgl.opengl.GL.createCapabilities; import static org.lwjgl.opengl.GL11.GL_BLEND; import static org.lwjgl.opengl.GL11.GL_COLOR_BUFFER_BIT; @@ -55,12 +22,11 @@ import org.lwjgl.glfw.GLFWErrorCallback; import org.lwjgl.glfw.GLFWVidMode; public class Window { - - public static String resolution; public static int SCREEN_WIDTH, - SCREEN_HEIGHT; + SCREEN_HEIGHT, + REFRESH_RATE; public static final int BUTTON_RELEASED = 0, @@ -115,6 +81,7 @@ public class Window { SCREEN_WIDTH = vidMode.width(); SCREEN_HEIGHT = vidMode.height(); SCALE = SCREEN_HEIGHT / 1080f; + REFRESH_RATE = vidMode.refreshRate(); if(lwidth == 0 || lheight == 0) { width = vidMode.width(); height = vidMode.height(); @@ -168,22 +135,13 @@ public class Window { glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glEnable(GL_MULTISAMPLE); + + glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_HIDDEN); int[] awidth = new int[1], aheight = new int[1]; glfwGetWindowSize(window, awidth, aheight); width = awidth[0]; height = aheight[0]; - - if(SCREEN_HEIGHT > 2160) - resolution = "8k"; - else if(SCREEN_HEIGHT > 1440) - resolution = "4k"; - else if(SCREEN_HEIGHT > 1080) - resolution = "1440p"; - else if(SCREEN_HEIGHT > 720) - resolution = "1080p"; - else - resolution = "720p"; } public void update() { @@ -198,9 +156,9 @@ public class Window { } public void activateClearColor() { - glClearColor(0, 0, 0, 1); + glClearColor(0, 0, 0.02f, 1); } - + public int getWidth() { return width; } diff --git a/src/com/gnarly/engine/model/Rect.java b/src/com/gnarly/engine/model/Rect.java index 9a6c950..fc0a162 100644 --- a/src/com/gnarly/engine/model/Rect.java +++ b/src/com/gnarly/engine/model/Rect.java @@ -53,7 +53,11 @@ public class Rect { public float getY() { return position.y; } - + + public Vector2f getPosition() { + return new Vector2f(position.x, position.y); + } + public float getWidth() { return width; } @@ -61,6 +65,10 @@ public class Rect { public float getHeight() { return height; } + + public Vector2f getDimensions() { + return new Vector2f(width, height); + } public void setX(float x) { position.x = x; diff --git a/src/com/gnarly/engine/model/TexRect.java b/src/com/gnarly/engine/model/TexRect.java index c01d76e..ecace33 100644 --- a/src/com/gnarly/engine/model/TexRect.java +++ b/src/com/gnarly/engine/model/TexRect.java @@ -13,12 +13,6 @@ public class TexRect extends Rect { private Texture texture; private Shader2t shader = Shader.SHADER2T; protected float direction = 1; - private float alpha = 1; - private float r; - private float g; - private float b; - private float a; - private float amount = 1; public TexRect(Camera camera, String path, float x, float y, float z, float width, float height, float rotation, boolean gui) { super(camera, x, y, z, width, height, rotation, gui); @@ -35,8 +29,6 @@ public class TexRect extends Rect { shader.enable(); Matrix4f cmat = gui ? camera.getProjection() : camera.getMatrix(); shader.setMVP(cmat.translate(position.add(width * scale / 2, height * scale / 2, 0, new Vector3f())).rotateZ(rotation).scale(width * scale * direction, height * scale, 1).translate(-0.5f, -0.5f, 0)); - shader.setAlpha(alpha); - shader.setMixColor(r, g, b, a, amount); vao.render(); shader.disable(); texture.unbind(); @@ -50,20 +42,4 @@ public class TexRect extends Rect { public void setTexture(Texture texture) { this.texture = texture; } - - public void setMix(float r, float g, float b, float a, float amount) { - this.r = r; - this.g = g; - this.b = b; - this.a = a; - this.amount = 1 - amount; - } - - public void setAlpha(float alpha) { - this.alpha = alpha; - } - - public float getAlpha() { - return alpha; - } } diff --git a/src/com/gnarly/engine/shaders/Shader.java b/src/com/gnarly/engine/shaders/Shader.java index fda1e06..6c02233 100644 --- a/src/com/gnarly/engine/shaders/Shader.java +++ b/src/com/gnarly/engine/shaders/Shader.java @@ -27,8 +27,9 @@ import org.joml.Matrix4f; public abstract class Shader { - public static Shader2c SHADER2C; - public static Shader2t SHADER2T; + public static Shader2c SHADER2C; + public static Shader2t SHADER2T; + public static Shader2b SHADER2B; protected int program; @@ -93,7 +94,8 @@ public abstract class Shader { } public static void init() { - SHADER2C = new Shader2c(); - SHADER2T = new Shader2t(); + SHADER2C = new Shader2c(); + SHADER2T = new Shader2t(); + SHADER2B = new Shader2b(); } } diff --git a/src/com/gnarly/engine/shaders/Shader2b.java b/src/com/gnarly/engine/shaders/Shader2b.java new file mode 100644 index 0000000..dfdd233 --- /dev/null +++ b/src/com/gnarly/engine/shaders/Shader2b.java @@ -0,0 +1,32 @@ +package com.gnarly.engine.shaders; + +import static org.lwjgl.opengl.GL20.*; + +public class Shader2b extends Shader { + + private int offset0Loc; + private int offset1Loc; + + protected Shader2b() { + super("res/shaders/s2b/vert.gls", "res/shaders/s2b/frag.gls"); + getUniforms(); + } + + public void setOffset(float offset0, float offset1) { + glUniform1f(offset0Loc, offset0); + glUniform1f(offset1Loc, offset1); + } + + @Override + protected void getUniforms() { + offset0Loc = glGetUniformLocation(program, "offset0"); + offset1Loc = glGetUniformLocation(program, "offset1"); + + int layer0 = glGetUniformLocation(program, "layer0"); + int layer1 = glGetUniformLocation(program, "layer1"); + + enable(); + glUniform1i(layer0, 0); + glUniform1i(layer1, 1); + } +} \ No newline at end of file diff --git a/src/com/gnarly/engine/shaders/Shader2t.java b/src/com/gnarly/engine/shaders/Shader2t.java index 8b473b2..8d9475e 100644 --- a/src/com/gnarly/engine/shaders/Shader2t.java +++ b/src/com/gnarly/engine/shaders/Shader2t.java @@ -1,33 +1,12 @@ package com.gnarly.engine.shaders; -import static org.lwjgl.opengl.GL20.glGetUniformLocation; -import static org.lwjgl.opengl.GL20.glUniform1f; -import static org.lwjgl.opengl.GL20.glUniform4f; - public class Shader2t extends Shader { - - private int alphaLoc; - private int colorLoc; - private int amountLoc; protected Shader2t() { super("res/shaders/s2t/vert.gls", "res/shaders/s2t/frag.gls"); getUniforms(); } - public void setMixColor(float r, float g, float b, float a, float amount) { - glUniform4f(colorLoc, r, g, b, a); - glUniform1f(amountLoc, amount); - } - - public void setAlpha(float a) { - glUniform1f(alphaLoc, a); - } - @Override - protected void getUniforms() { - alphaLoc = glGetUniformLocation(program, "alpha"); - colorLoc = glGetUniformLocation(program, "iColor"); - amountLoc = glGetUniformLocation(program, "amount"); - } + protected void getUniforms() {} } \ No newline at end of file diff --git a/src/com/gnarly/engine/texture/Texture.java b/src/com/gnarly/engine/texture/Texture.java index 5461aa3..8a04a0f 100644 --- a/src/com/gnarly/engine/texture/Texture.java +++ b/src/com/gnarly/engine/texture/Texture.java @@ -1,20 +1,5 @@ package com.gnarly.engine.texture; -import static org.lwjgl.opengl.GL11.GL_CLAMP; -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_TEXTURE_WRAP_S; -import static org.lwjgl.opengl.GL11.GL_TEXTURE_WRAP_T; -import static org.lwjgl.opengl.GL11.GL_UNSIGNED_BYTE; -import static org.lwjgl.opengl.GL11.glBindTexture; -import static org.lwjgl.opengl.GL11.glDeleteTextures; -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; @@ -26,20 +11,24 @@ import org.lwjgl.BufferUtils; import com.gnarly.engine.display.Window; +import static org.lwjgl.opengl.GL11.*; +import static org.lwjgl.opengl.GL13.GL_TEXTURE0; +import static org.lwjgl.opengl.GL13.glActiveTexture; + public class Texture { protected int id, width, height; - + public Texture(String name) { + this(name, GL_CLAMP); + } + + public Texture(String name, int wrap) { BufferedImage bi = null; try { - bi = ImageIO.read(new File("res/img/" + Window.resolution + "/" + name)); + bi = ImageIO.read(new File(name)); } catch (IOException e) { - try { - bi = ImageIO.read(new File("res/img/const/" + name)); - } catch (IOException ex) { - e.printStackTrace(); - } + e.printStackTrace(); } if (bi != null) { width = bi.getWidth(); @@ -57,13 +46,13 @@ public class Texture { } } buffer.flip(); - + id = glGenTextures(); bind(); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrap); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrap); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, buffer); unbind(); } @@ -82,8 +71,13 @@ public class Texture { public int getHeight() { return height; } - + public void bind() { + bind(0); + } + + public void bind(int activeTexture) { + glActiveTexture(GL_TEXTURE0 + activeTexture); glBindTexture(GL_TEXTURE_2D, id); } diff --git a/src/com/gnarly/engine/texture/TextureSet.java b/src/com/gnarly/engine/texture/TextureSet.java new file mode 100644 index 0000000..bed05f5 --- /dev/null +++ b/src/com/gnarly/engine/texture/TextureSet.java @@ -0,0 +1,20 @@ +package com.gnarly.engine.texture; + +public class TextureSet { + + private Texture[] textures; + + public TextureSet(String[] paths) { + textures = new Texture[paths.length]; + for (int i = 0; i < textures.length; ++i) + textures[i] = new Texture(paths[i]); + } + + public int length() { + return textures.length; + } + + public Texture get(int index) { + return textures[index]; + } +} diff --git a/src/com/gnarly/game/Background.java b/src/com/gnarly/game/Background.java new file mode 100644 index 0000000..659574f --- /dev/null +++ b/src/com/gnarly/game/Background.java @@ -0,0 +1,47 @@ +package com.gnarly.game; + +import com.gnarly.engine.model.Rect; +import com.gnarly.engine.shaders.Shader2b; +import org.joml.Matrix4f; +import org.joml.Vector3f; + +import com.gnarly.engine.display.Camera; +import com.gnarly.engine.shaders.Shader; +import com.gnarly.engine.shaders.Shader2t; +import com.gnarly.engine.texture.Texture; + +import static org.lwjgl.opengl.GL11.GL_REPEAT; + +public class Background extends Rect { + + private Texture layer0; + private Texture layer1; + private Shader2b shader = Shader.SHADER2B; + private float offset; + + private double speed = -0.25; + + public Background(Camera camera) { + super(camera, 0, 0, -0.5f, camera.getWidth(), camera.getHeight(), 0, false); + layer0 = new Texture("res/img/background/background-layer-0.png", GL_REPEAT); + layer1 = new Texture("res/img/background/background-layer-1.png", GL_REPEAT); + } + + public void update() { + offset = (float) (offset + speed * Main.dtime) % 2; + } + + public void render() { + layer0.bind(0); + layer1.bind(1); + shader.enable(); + shader.setOffset(offset, offset * 0.5f); + shader.setMVP(camera.getMatrix().translate(position).scale(width * scale, height * scale, 1)); + vao.render(); + } + + public void setCenter(float x, float y) { + position.x = x - width / 2; + position.y = y - height / 2; + } +} diff --git a/src/com/gnarly/game/BulletList.java b/src/com/gnarly/game/BulletList.java new file mode 100644 index 0000000..3a16f88 --- /dev/null +++ b/src/com/gnarly/game/BulletList.java @@ -0,0 +1,188 @@ +package com.gnarly.game; + +import com.gnarly.engine.display.Camera; +import com.gnarly.engine.model.ColRect; +import com.gnarly.engine.model.Rect; +import com.gnarly.engine.model.Vao; +import com.gnarly.engine.shaders.Shader; +import com.gnarly.engine.shaders.Shader2t; +import com.gnarly.engine.texture.TextureSet; +import org.joml.Vector2f; + +import java.util.ArrayList; + +public class BulletList { + + private static final double SPF = 1.0 / 20.0; + + private static TextureSet[] sprites = null; + private static Vao vao; + private Shader2t shader = Shader.SHADER2T; + + public static class Bullet { + public double lifetime; + public int sprite; + public Vector2f position; + public Vector2f side0; + public Vector2f side1; + public Vector2f velocity; + + public float width; + public float height; + public float rotation; + + public Vector2f boundingPosition; + public Vector2f bounds; + } + + public static final Vector2f[] DIMENSIONS = new Vector2f[] { + new Vector2f(4, -8) + }; + + public static final float[] SPEEDS = new float[] { + 20 + }; + + public static final int + TYPE_PLAYER = 0x00; + + private Camera camera; + + private ArrayList bullets; + + public BulletList(Camera camera) { + this.camera = camera; + bullets = new ArrayList<>(); + + if (sprites == null) { + sprites = new TextureSet[1]; + sprites[0] = new TextureSet(new String[] { + "res/img/bullets/bullet-0/bullet-0.png", + "res/img/bullets/bullet-0/bullet-1.png", + "res/img/bullets/bullet-0/bullet-2.png", + "res/img/bullets/bullet-0/bullet-3.png", + }); + float vertices[] = { + 1, 1, 0, // Top left + 1, 0, 0, // Bottom left + 0, 0, 0, // Bottom right + 0, 1, 0 // Top right + }; + int indices[] = { + 0, 1, 3, + 1, 2, 3 + }; + float[] texCoords = { + 1, 0, + 1, 1, + 0, 1, + 0, 0 + }; + vao = new Vao(vertices, indices); + vao.addAttrib(texCoords, 2); + } + } + + public void update(Rect rect, Vector2f velocity) { + for (int i = 0; i < bullets.size(); ++i) { + Bullet bullet = bullets.get(i); + Vector2f deltaV = bullet.velocity.mul((float) Main.dtime, new Vector2f()); + if (Collision.collide(rect.getPosition(), rect.getDimensions(), velocity, bullet)) + System.out.println("collision"); + bullet.position.add(deltaV); + bullet.boundingPosition.add(deltaV); + bullet.lifetime += Main.dtime; + + if (bullet.boundingPosition.x > camera.getWidth() || bullet.boundingPosition.y > camera.getHeight() + || bullet.boundingPosition.x + bullet.bounds.x < 0 || bullet.boundingPosition.y + bullet.bounds.y < 0) { + bullets.remove(i); + --i; + } + } + } + + public void render() { + for (int i = 0; i < bullets.size(); ++i) { + Bullet bullet = bullets.get(i); + sprites[bullet.sprite].get((int) (bullet.lifetime / SPF) % sprites[bullet.sprite].length()).bind(); + shader.enable(); + shader.setMVP(camera.getMatrix().translate(bullet.position.x, bullet.position.y, -0.25f).rotateZ(bullet.rotation).scale(bullet.width, bullet.height, 1)); + vao.render(); + } + } + + public void spawnBullet(Vector2f position, float rotation, int type) { + spawnBullet(position, DIMENSIONS[type], rotation, SPEEDS[type], type); + } + + private void spawnBullet(Vector2f position, Vector2f dimensions, float rotation, float velocity, int sprite) { + float sin = (float) -Math.sin(rotation); + float cos = (float) Math.cos(rotation); + + float initialPosition = -dimensions.x / 2; + + /************************************** + * * + * 2D Rotations * + * * + ************************************** + * * + * x + yi * cos + sini * + * (xcos - ysin) + (xsin + ycos)i * + * * + **************************************/ + Bullet bullet = new Bullet(); + bullet.position = new Vector2f(initialPosition * cos, initialPosition * sin); + bullet.position.add(position); + bullet.side0 = new Vector2f( dimensions.x * cos, dimensions.x * sin); + bullet.side1 = new Vector2f(-dimensions.y * sin, dimensions.y * cos); + bullet.velocity = new Vector2f(velocity * sin, -velocity * cos); + + bullet.width = dimensions.x; + bullet.height = dimensions.y; + bullet.rotation = -rotation; + + bullet.lifetime = 0; + bullet.sprite = sprite; + + Vector2f p0 = new Vector2f(bullet.position); + Vector2f p1 = new Vector2f(bullet.position).add(bullet.side0); + Vector2f p2 = new Vector2f(bullet.position).add(bullet.side1); + Vector2f p3 = new Vector2f(bullet.position).add(bullet.side0).add(bullet.side1); + + bullet.boundingPosition = new Vector2f( + min(new float[]{ p0.x, p1.x, p2.x, p3.x }), + min(new float[]{ p0.y, p1.y, p2.y, p3.y }) + ); + bullet.bounds = new Vector2f( + max(new float[]{ p0.x, p1.x, p2.x, p3.x }), + max(new float[]{ p0.y, p1.y, p2.y, p3.y }) + ).sub(bullet.boundingPosition); + + bullets.add(bullet); + } + + public float getWidth(int type) { + return DIMENSIONS[type].x; + } + + public float getHeight(int type) { + return DIMENSIONS[type].y; + } + + private float min(float[] nums) { + float min = nums[0]; + for (int i = 1; i < nums.length; ++i) + if (nums[i] < min) + min = nums[i]; + return min; + } + + private float max(float[] nums) { + float max = nums[0]; + for (int i = 1; i < nums.length; ++i) + if (nums[i] > max) + max = nums[i]; + return max; + } +} diff --git a/src/com/gnarly/game/Collision.java b/src/com/gnarly/game/Collision.java new file mode 100644 index 0000000..edb1e8e --- /dev/null +++ b/src/com/gnarly/game/Collision.java @@ -0,0 +1,103 @@ +package com.gnarly.game; + +import org.joml.Vector2f; + +public class Collision { + public static class Bounds { + public Vector2f position; + public Vector2f dimensions; + + public Bounds(Vector2f position, Vector2f dimensions) { + this.position = new Vector2f(position); + this.dimensions = new Vector2f(dimensions); + } + } + + public static boolean collide(Vector2f position, Vector2f dimensions, Vector2f boundVelocity, BulletList.Bullet bullet) { + Bounds bounds = getBounds(position, dimensions, boundVelocity); + Bounds bulletBounds = getBounds(bullet.boundingPosition, bullet.bounds, bullet.velocity); + if (overlap(bounds, bulletBounds)) { + Vector2f[] boundsSegments = new Vector2f[] { + position, + new Vector2f( dimensions.x, 0), + new Vector2f( 0, dimensions.y), + new Vector2f(-dimensions.x, 0), + new Vector2f( 0, -dimensions.y) + }; + Vector2f[] bulletSegments = new Vector2f[] { + bullet.position, + bullet.side0, + bullet.side1, + bullet.side0.negate(new Vector2f()), + bullet.side1.negate(new Vector2f()) + }; + Vector2f curBoundsSegment = new Vector2f(); + for (int i = 0; i < boundsSegments.length - 1; ++i) { + curBoundsSegment.add(boundsSegments[i]); + Vector2f curBulletSegment = new Vector2f(); + for (int j = 0; j < bulletSegments.length - 1; ++j) { + curBulletSegment.add(bulletSegments[i]); + if (segmentCollision(curBoundsSegment, boundsSegments[i + 1], boundVelocity, curBulletSegment, bulletSegments[j + 1], bullet.velocity)) + return true; + } + } + } + return false; + } + + public static boolean overlap(Bounds bounds0, Bounds bounds1) { + return bounds0.position.x < bounds1.position.x + bounds1.dimensions.x && bounds0.position.x + bounds0.dimensions.x > bounds1.position.x + && bounds0.position.y < bounds1.position.y + bounds1.dimensions.y && bounds1.position.y + bounds1.dimensions.y > bounds1.position.y; + } + + public static Bounds getBounds(Vector2f position, Vector2f dimensions, Vector2f velocity) { + Bounds bounds = new Bounds(position, dimensions); + if (velocity.x < 0) + bounds.position.x += velocity.x; + else + bounds.dimensions.x += velocity.x; + if (velocity.y < 0) + bounds.position.y += velocity.y; + else + bounds.dimensions.y += velocity.y; + return bounds; + } + + public static boolean segmentCollision(Vector2f P1, Vector2f D1, Vector2f V1, Vector2f P2, Vector2f D2, Vector2f V2) { + final float DELTA = 0.00001f; + + if ((V1.length() == 0 && V2.length() > 0) + || (V2.length() == 0 && V1.length() > 0) + || V1.angle(V2) > DELTA) { + float b = (P1.y - P2.y - (V2.y - V1.y) * (P1.x + D1.x - P2.x) / (V2.x - V1.x)) / (D2.y + (V2.y - V1.y) / (V2.x - V1.x)); + if (rangeCheck(b)) { + float t = (P1.x - P2.x - D2.x * b) / (V2.x - V1.x); + if (rangeCheck(t)) + return true; + } + float a = (P2.y - P1.y - (V1.y - V2.y) * (P2.x + D2.x - P1.x) / (V1.x - V2.x)) / (D1.y + (V1.y - V2.y) / (V1.x - V2.x)); + if (rangeCheck(a)) { + float t = (P1.x + D1.x * a - P2.x) / (V2.x - V1.x); + if (rangeCheck(t)) + return true; + } + b = (P1.y + D1.y - P2.y - (V2.y - V1.y) * (P1.x + D1.x - P2.x) / (V2.x - V1.x)) / (D2.y + (V2.y - V1.y) / (V2.x - V1.x)); + if (rangeCheck(b)) { + float t = (P1.x + D1.x - P2.x - D2.x * b) / (V2.x - V1.x); + if (rangeCheck(t)) + return true; + } + a = (P2.y + D2.y - P1.y - (V1.y - V2.y) * (P2.x + D2.x - P1.x) / (V1.x - V2.x)) / (D1.y + (V1.y - V2.y) / (V1.x - V2.x)); + if (rangeCheck(a)) { + float t = (P1.x + D1.x * a - P2.x - D2.x) / (V2.x - V1.x); + if (rangeCheck(t)) + return true; + } + } + return false; + } + + public static boolean rangeCheck(float num) { + return 0 <= num && num <= 1; + } +} diff --git a/src/com/gnarly/game/GamePanel.java b/src/com/gnarly/game/GamePanel.java index 2aa03ff..b866369 100644 --- a/src/com/gnarly/game/GamePanel.java +++ b/src/com/gnarly/game/GamePanel.java @@ -2,25 +2,53 @@ package com.gnarly.game; import com.gnarly.engine.display.Camera; import com.gnarly.engine.display.Window; +import com.gnarly.engine.model.ColRect; +import org.joml.Vector2f; + +import static org.lwjgl.glfw.GLFW.GLFW_KEY_SPACE; public class GamePanel extends Panel { private Window window; private Camera camera; + private BulletList bullets; + + private Background background; + private Player player; + + private float rotation = 0; + + private ColRect testRect; + public GamePanel(Window window, Camera camera) { this.window = window; this.camera = camera; - + + bullets = new BulletList(camera); + + background = new Background(camera); + player = new Player(window, camera); + + testRect = new ColRect(camera, 100, 100, 0, 25, 25, 1, 0, 0, 1, false); + state = Main.GAME_PANEL; } public void update() { + bullets.update(testRect, new Vector2f(0, 100)); + background.update(); + player.update(); + if (window.keyPressed(GLFW_KEY_SPACE) == Window.BUTTON_PRESSED) + bullets.spawnBullet(new Vector2f(player.getX() + (player.getWidth()) / 2, player.getY() + bullets.getHeight(BulletList.TYPE_PLAYER)), rotation += Math.PI / 16, BulletList.TYPE_PLAYER); } public void render() { - + testRect.render(); + bullets.render(); + background.render(); + player.render(); } public void reset() { diff --git a/src/com/gnarly/game/Main.java b/src/com/gnarly/game/Main.java index c068208..659af86 100644 --- a/src/com/gnarly/game/Main.java +++ b/src/com/gnarly/game/Main.java @@ -4,10 +4,13 @@ import com.gnarly.engine.audio.ALManagement; import com.gnarly.engine.display.Camera; import com.gnarly.engine.display.Window; import com.gnarly.engine.shaders.Shader; +import org.joml.Vector2f; + +import java.io.IOException; public class Main { - - public static long FPS = 999; + + public static int fps; public static double dtime; public static final int @@ -23,16 +26,29 @@ public class Main { private int panel; public void start() { - long curTime, pastTime, nspf = 1000000000 / FPS; init(); + int frames = 0; + long curTime, pastTime, pastSec, nspf = 1000000000 / Window.REFRESH_RATE; pastTime = System.nanoTime(); + pastSec = pastTime; while(!window.shouldClose()) { curTime = System.nanoTime(); if (curTime - pastTime > nspf) { - dtime = (curTime - pastTime) / 1000000000d; + dtime = nspf / 1000000000d; update(); render(); - pastTime = curTime; + pastTime += nspf; + ++frames; + if (curTime - pastSec > 1000000000) { + fps = frames; + frames = 0; + pastSec += 1000000000; + } + try { + Thread.sleep(nspf / 1000000); + } catch (Exception e) { + e.printStackTrace(); + } } } al.destroy(); @@ -41,9 +57,9 @@ public class Main { private void init() { al = new ALManagement(); - window = new Window("Gamer Time", true); - //window = new Window(100, 100, "Gamer Time", true, true, true); - camera = new Camera(1920, 1080); + //window = new Window("Gamer Time", true); + window = new Window(768, 432, "Gamer Time", true, true, true); + camera = new Camera(768, 432); Shader.init(); panels = new Panel[NUM_PANELS]; diff --git a/src/com/gnarly/game/Player.java b/src/com/gnarly/game/Player.java new file mode 100644 index 0000000..cc8ad32 --- /dev/null +++ b/src/com/gnarly/game/Player.java @@ -0,0 +1,63 @@ +package com.gnarly.game; + +import com.gnarly.engine.display.Camera; +import com.gnarly.engine.display.Window; +import com.gnarly.engine.model.TexRect; +import com.gnarly.engine.texture.Texture; + +import static org.lwjgl.glfw.GLFW.*; + +public class Player extends TexRect { + + private double spf = 1.0 / 14.0; + private double time = 0; + private int frame = 0; + + private static Texture[] frames = null; + + private Window window; + + public Player(Window window, Camera camera) { + super(camera, (Texture) null, 0, 0, -0.1f, 32, 32, 0, false); + this.window = window; + + if (frames == null) { + frames = new Texture[4]; + frames[0] = new Texture("res/img/player-ship/player-ship-0.png"); + frames[1] = new Texture("res/img/player-ship/player-ship-1.png"); + frames[2] = new Texture("res/img/player-ship/player-ship-2.png"); + frames[3] = new Texture("res/img/player-ship/player-ship-3.png"); + } + + setTexture(frames[0]); + } + + public void update() { + final int SPEED = 150; + if (window.keyPressed(GLFW_KEY_W) >= Window.BUTTON_PRESSED) + position.y -= SPEED * Main.dtime; + if (window.keyPressed(GLFW_KEY_A) >= Window.BUTTON_PRESSED) + position.x -= SPEED * Main.dtime; + if (window.keyPressed(GLFW_KEY_S) >= Window.BUTTON_PRESSED) + position.y += SPEED * Main.dtime; + if (window.keyPressed(GLFW_KEY_D) >= Window.BUTTON_PRESSED) + position.x += SPEED * Main.dtime; + + if (position.x < 0) + position.x = 0; + else if (position.x + width >= camera.getWidth()) + position.x = camera.getWidth() - width; + + if (position.y < 0) + position.y = 0; + else if (position.y + height >= camera.getHeight()) + position.y = camera.getHeight() - height; + + time += Main.dtime; + while (time >= spf) { + time -= spf; + frame = (frame + 1) % frames.length; + setTexture(frames[frame]); + } + } +}