diff --git a/.classpath b/.classpath index 914add1..9fea69d 100644 --- a/.classpath +++ b/.classpath @@ -6,6 +6,12 @@ + + + + + + diff --git a/pom.xml b/pom.xml index 3ba0902..d41c1e9 100644 --- a/pom.xml +++ b/pom.xml @@ -1,28 +1,32 @@ - - + + 4.0.0 - + jeu-de-combat jeu-de-combat 0.0.1-SNAPSHOT Boulevard Combattant - Jeu de combat inspiré de Street Fighter 3: Third Strike. Projet de fin d'année de L3. + Jeu de combat inspiré de Street Fighter 3: Third Strike. + Projet de fin d'année de L3. + https://gitlab.istic.univ-rennes1.fr/fautin/jeu-de-combat - + - + src - + - + /src/launcher/ui - + - + - + maven-compiler-plugin 3.8.1 @@ -30,21 +34,21 @@ 11 - + - + - + - + 3.2.3 natives-windows 11 - + - + org.lwjgl @@ -54,92 +58,99 @@ pom - + - + org.lwjgl lwjgl - + org.lwjgl lwjgl-assimp - + org.lwjgl lwjgl-glfw - + org.lwjgl lwjgl-openal - + org.lwjgl lwjgl-opengl - + org.lwjgl lwjgl-stb - + org.lwjgl lwjgl ${lwjgl.natives} - + org.lwjgl lwjgl-assimp ${lwjgl.natives} - + org.lwjgl lwjgl-glfw ${lwjgl.natives} - + org.lwjgl lwjgl-openal ${lwjgl.natives} - + org.lwjgl lwjgl-opengl ${lwjgl.natives} - + org.lwjgl lwjgl-stb ${lwjgl.natives} - - + + org.openjfx javafx-controls ${javafx.version} - + org.openjfx javafx-fxml ${javafx.version} - + + + + com.googlecode.json-simple + json-simple + 1.1.1 + + - \ No newline at end of file + diff --git a/sound/jump.ogg b/sound/jump.ogg new file mode 100644 index 0000000..9a15e59 Binary files /dev/null and b/sound/jump.ogg differ diff --git a/sound/jump.wav b/sound/jump.wav new file mode 100644 index 0000000..bb6ee48 Binary files /dev/null and b/sound/jump.wav differ diff --git a/src/configuration/JsonToJava.java b/src/configuration/JsonToJava.java new file mode 100644 index 0000000..f0d0d8f --- /dev/null +++ b/src/configuration/JsonToJava.java @@ -0,0 +1,54 @@ +package configuration; + +import java.io.*; +import org.json.simple.*; +import org.json.simple.parser.*; + +public class JsonToJava { + + public static void main(String args[]) { + + // initialize the parser + JSONParser jsonP = new JSONParser(); + try { + // read the json document + JSONObject jsonO = (JSONObject) jsonP.parse(new FileReader("src/configuration/config.json")); + + //to print all values + //System.out.println(jsonO.values()); + + // isolate the "test" part and print it + // String test = (String) jsonO.get("test"); + // System.out.println("ceci est un test :" + test); + + + //select an element on the list + JSONArray arene = (JSONArray) jsonO.get("arena"); + //print a case of this element + System.out.println(arene.get(1)); + + JSONArray nb_players = (JSONArray) jsonO.get("nb_players"); + System.out.println(nb_players.get(1)); + + JSONArray character1 = (JSONArray) jsonO.get("character1"); + System.out.println(character1.get(1)); + + JSONArray character2 = (JSONArray) jsonO.get("character2"); + System.out.println(character2.get(1)); + + JSONArray resolution = (JSONArray) jsonO.get("resolution"); + System.out.println(resolution.get(1)); + + JSONArray button = (JSONArray) jsonO.get("button"); + System.out.println(button); + + } catch (FileNotFoundException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } catch (ParseException e) { + e.printStackTrace(); + + } + } +} diff --git a/src/configuration/config.json b/src/configuration/config.json index 028c17f..fbd5c52 100644 --- a/src/configuration/config.json +++ b/src/configuration/config.json @@ -1,29 +1,55 @@ { "arena": [ + "random", "arena1.png", - "arena2.png", - "random" + "arena2.png" ], "nb_players": [ "1", "2" ], "character1": [ + "random", "character1.png", - "character2.png", - "random" + "character2.png" ], "character2": [ + "random", "character1.png", "character1_swapcolor.png", "character2.png", - "character2_swapcolor.png", - "random" + "character2_swapcolor.png" ], "resolution": [ - "1280 x 1024", - "1680 x 1050", - "1920 x 1080", - "800 x 600" + { + "width": "800", + "height": "600" + }, + { + "width": "1280", + "height": "1024" + }, + { + "width": "1680", + "height": "1050" + }, + { + "width": "1920", + "height": "1080" + }, + { + "persoWidth": "800", + "persoHeight": "600" + } + ], + "button": [ + "UP", + "DOWN", + "RIGTH", + "LEFT", + "A", + "B", + "X", + "Y" ] } diff --git a/src/engine/Engine.java b/src/engine/Engine.java index 342552d..657804e 100644 --- a/src/engine/Engine.java +++ b/src/engine/Engine.java @@ -1,7 +1,9 @@ package engine; +import engine.input.*; import engine.math.*; import engine.object.*; +import engine.sound.*; import org.lwjgl.glfw.GLFWFramebufferSizeCallback; import org.lwjgl.glfw.GLFWVidMode; @@ -20,13 +22,13 @@ public class Engine { private final List objectsGl; - private static boolean present = glfwJoystickPresent(GLFW_JOYSTICK_1); - private boolean running; private final int width; private final int height; + private float viewXPos; + /** * Create the engine and initial attributes use .init() to start the engine */ @@ -37,6 +39,7 @@ public class Engine { this.height = height; ObjectGl.projection = Matrix4f.orthographic(-1000, 1000, -1000 * aspectRatio, 1000 * aspectRatio, 0.1f, 100.0f); ObjectGl.view = Matrix4f.translate(new Vector3f(0.0f, 0.0f, 1.0f)); + this.viewXPos = 0.0f; } /** @@ -60,8 +63,8 @@ public class Engine { this.setWindow(glfwCreateWindow(width, height, "Boulevard Combattant", NULL, NULL)); assert getWindow() != NULL; - - System.out.println(present); + boolean present = glfwJoystickPresent(GLFW_JOYSTICK_1); + System.out.println("Manette détectée : " + present); // On récupère les informations du moniteur principal GLFWVidMode vidmode = glfwGetVideoMode(glfwGetPrimaryMonitor()); @@ -70,7 +73,7 @@ public class Engine { // On met la fenêtre au centre de l'écran principale glfwSetWindowPos(getWindow(), (vidmode.width() - width) / 2, (vidmode.height() - height) / 2); - glfwSetKeyCallback(getWindow(), new Input()); + glfwSetKeyCallback(getWindow(), new KeyboardInput()); glfwSetInputMode(getWindow(), GLFW_STICKY_KEYS, GLFW_TRUE); // Contexte = zone cible des rendus @@ -78,6 +81,8 @@ public class Engine { glfwShowWindow(getWindow()); GL.createCapabilities(); + correctViewport(this.width, this.height); + glfwSetFramebufferSizeCallback(getWindow(), resizeWindow); glEnable(GL_DEPTH_TEST); // Z-Buffer plus z est grand plus l'objet est proche de la camera limite à 100.0f au dela l'objet disparait @@ -101,6 +106,7 @@ public class Engine { */ public void render() { + glEnable(GL_SCISSOR_TEST); glClearColor(0.2f, 0.3f, 0.3f, 1.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); @@ -116,7 +122,6 @@ public class Engine { /** * Add obj to the render queue - * * @param obj ObjectGl to render */ public void add_objectGl(ObjectGl obj) { @@ -127,6 +132,28 @@ public class Engine { objectsGl.remove(obj); } + public void translateView(Vector3f vec){ + ObjectGl.view = ObjectGl.view.multiply(Matrix4f.translate(vec)); + viewXPos += vec.x; + } + + public static void correctViewport(int width, int height){ + int heightViewport, widthViewport, x, y; + if (width >= height * 4.0f/3.0f){ + heightViewport = height; + widthViewport = (int) (height * 4.0f/3.0f); + y = 0; + x = (width - widthViewport)/2; + } else { + widthViewport = width; + heightViewport = (int) (width * 3.0f/4.0f); + y = (height - heightViewport)/2; + x = 0; + } + glScissor(x, y, widthViewport, heightViewport); + glViewport(x, y, widthViewport, heightViewport); + } + public boolean isRunning() { return running; } @@ -148,53 +175,101 @@ public class Engine { } /** - * Est appelé àa chaque modification de la taille de la fenêtre, et modifie la taille de la zone de rendu + * Est appelé à chaque modification de la taille de la fenêtre, et modifie la taille de la zone de rendu * pour quelle corresponde à la taille de la fenêtre */ private static final GLFWFramebufferSizeCallback resizeWindow = new GLFWFramebufferSizeCallback() { @Override public void invoke(long window, int width, int height) { - glViewport(0, 0, width, height); + correctViewport(width, height); } }; - public static void main(String[] args) { - Engine engine = new Engine(1280, 720, 9.0f / 16.0f); - int speed = 10; //vitesse déplacement Object + public static void main(String[] args) throws Exception { + /* + OpenAl TEST + */ + SoundManager soundManager = new SoundManager(); + soundManager.init(); + + SoundListener soundListener = new SoundListener(); + + soundManager.setListener(soundListener); + + SoundBuffer jumpSoundBuffer = new SoundBuffer("sound/jump.ogg"); + SoundSource soundSource = new SoundSource(false, false); + soundSource.setBuffer(jumpSoundBuffer.getBufferId()); + + soundManager.addSoundSource("jump", soundSource); + soundManager.playSoundSource("jump"); + + /* + Engine Init + */ + Engine engine = new Engine(1280, 720, 3.0f / 4.0f); + int speed = 10; //vitesse d�placement Object engine.init(); // Add objects to render String path = "textures/zangief_sprite.png"; - String path2 = "textures/awesomeface.png"; + String pathToBG = "textures/background_beach.png"; - ObjectGl zangief = new ObjectGl(0f, 60f, 80f, 10f, path, null); - zangief.setTextureWrap(58, 0, 62, 84, ObjectGl.STICK_TOP); + ObjectGl zangief = new ObjectGl(10.0f, 1f, 1f, 10f, path, null); + zangief.setTextureWrap(58, 0, 62, 84, ObjectGl.DEFAULT); engine.add_objectGl(zangief); - zangief.translate(new Vector3f(-5000.0f, 500.0f, 10.0f)); - zangief.setColor(new Vector3f(1.0f, 1.0f, 1.0f)); - zangief.useTime = true; - zangief.setShader("shaders/StylishShaders/BasicVert.glsl", "shaders/StylishShaders/FlashFrag.glsl"); + zangief.translate(new Vector3f(-1000.0f, 200.0f, 0.0f)); ObjectGl smiley2 = new ObjectGl(0.0f, 500.0f, 500.0f, 1f, path2, null); engine.add_objectGl(smiley2); - smiley2.translate(new Vector3f(0.0f, 0.0f, 5.0f)); + smiley2.translate(new Vector3f(0.0f, 0.0f, 15.0f)); + + //Create background + ObjectGl background = new ObjectGl(0f,1f,1f,10f, pathToBG, null); + background.setTextureWrap(0,0,621, 224, ObjectGl.DEFAULT); + background.translate(new Vector3f(-3011.0f, 1400.0f, 1.0f)); + engine.add_objectGl(background); long timer = System.currentTimeMillis(); long lastFrame; int frame = 0; boolean nextFrame = false; + boolean Joystick1Present = glfwJoystickPresent(GLFW_JOYSTICK_1); + + /* + * Cr�ation des manettes / action + */ + + GamepadInput gamepad1 = null; + Button jump = null; + + if (Joystick1Present){ + gamepad1 = new GamepadInput(GLFW_JOYSTICK_1); + gamepad1.inputRefresh(); + List listJump = new ArrayList<>(); + listJump.add(InputConst.buttonA); + jump = new Button("jump", listJump, gamepad1); + } + + while (engine.isRunning()) { lastFrame = System.currentTimeMillis(); // Game logic should fit here - if (present) { - Input.gamepadInput(zangief, speed); - } + if (Joystick1Present) { + gamepad1.inputRefresh(); + // Check si le personnage a sauté + if (jump.isButtonPressed()){ + // Le personnage saute + System.out.println(" JE SAUTE "); + } + } - Input.keyboardInput(zangief, speed); -// input(smiley2, speed); + KeyboardInput.keyboardInput(zangief, speed); + + Vector3f vecTransView = new Vector3f((-zangief.getXPos() - engine.viewXPos) - 250.0f,0.0f,0.0f); + engine.translateView(vecTransView); /* ******************** @@ -219,5 +294,8 @@ public class Engine { nextFrame = false; if (engine.shouldClose()) engine.setRunning(false); } + + soundManager.cleanup(); + } } diff --git a/src/engine/graphics/Texture.java b/src/engine/graphics/Texture.java index 4f06db9..15e5a19 100644 --- a/src/engine/graphics/Texture.java +++ b/src/engine/graphics/Texture.java @@ -1,6 +1,6 @@ package engine.graphics; -import engine.utils.BufferUtils; +import engine.utils.BufferUtilsEngine; import org.lwjgl.opengl.GL11; import java.awt.image.BufferedImage; @@ -49,7 +49,7 @@ public class Texture { glBindTexture(GL_TEXTURE_2D, result); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - GL11.glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, BufferUtils.createIntBuffer(data)); + GL11.glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, BufferUtilsEngine.createIntBuffer(data)); glGenerateMipmap(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, 0); return result; diff --git a/src/engine/graphics/VertexArray.java b/src/engine/graphics/VertexArray.java index a8dc154..a3626be 100644 --- a/src/engine/graphics/VertexArray.java +++ b/src/engine/graphics/VertexArray.java @@ -1,6 +1,6 @@ package engine.graphics; -import engine.utils.BufferUtils; +import engine.utils.BufferUtilsEngine; import static org.lwjgl.opengl.GL11.*; import static org.lwjgl.opengl.GL15.*; @@ -28,7 +28,7 @@ public class VertexArray { EBO = glGenBuffers(); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO); - glBufferData(GL_ELEMENT_ARRAY_BUFFER, BufferUtils.createByteBuffer(indices), GL_STATIC_DRAW); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, BufferUtilsEngine.createByteBuffer(indices), GL_STATIC_DRAW); glBindBuffer(GL_ARRAY_BUFFER, 0); glBindVertexArray(0); @@ -37,7 +37,7 @@ public class VertexArray { private void createVertexBufferObject(float[] vertices){ VBO = glGenBuffers(); glBindBuffer(GL_ARRAY_BUFFER, VBO); - glBufferData(GL_ARRAY_BUFFER, BufferUtils.createFloatBuffer(vertices), GL_STATIC_DRAW); + glBufferData(GL_ARRAY_BUFFER, BufferUtilsEngine.createFloatBuffer(vertices), GL_STATIC_DRAW); glVertexAttribPointer(0, 3, GL_FLOAT, false, 0, 0); glEnableVertexAttribArray(0); } @@ -45,7 +45,7 @@ public class VertexArray { private void createColorBufferObject(float[] color){ CBO = glGenBuffers(); glBindBuffer(GL_ARRAY_BUFFER, CBO); - glBufferData(GL_ARRAY_BUFFER, BufferUtils.createFloatBuffer(color), GL_STATIC_DRAW); + glBufferData(GL_ARRAY_BUFFER, BufferUtilsEngine.createFloatBuffer(color), GL_STATIC_DRAW); glVertexAttribPointer(1, 3, GL_FLOAT, false, 0, 0); glEnableVertexAttribArray(1); } @@ -53,19 +53,19 @@ public class VertexArray { private void createTextureBufferObject(float[] texture){ TBO = glGenBuffers(); glBindBuffer(GL_ARRAY_BUFFER, TBO); - glBufferData(GL_ARRAY_BUFFER, BufferUtils.createFloatBuffer(texture), GL_STATIC_DRAW); + glBufferData(GL_ARRAY_BUFFER, BufferUtilsEngine.createFloatBuffer(texture), GL_STATIC_DRAW); glVertexAttribPointer(2, 2, GL_FLOAT, false, 0, 0); glEnableVertexAttribArray(2); } public void swapVertexBufferObject(float[] vertices){ glBindBuffer(GL_ARRAY_BUFFER, VBO); - glBufferData(GL_ARRAY_BUFFER, BufferUtils.createFloatBuffer(vertices), GL_STATIC_DRAW); + glBufferData(GL_ARRAY_BUFFER, BufferUtilsEngine.createFloatBuffer(vertices), GL_STATIC_DRAW); } public void swapTextureBufferObject(float [] texture){ glBindBuffer(GL_ARRAY_BUFFER, TBO); - glBufferData(GL_ARRAY_BUFFER, BufferUtils.createFloatBuffer(texture), GL_STATIC_DRAW); + glBufferData(GL_ARRAY_BUFFER, BufferUtilsEngine.createFloatBuffer(texture), GL_STATIC_DRAW); } public void bind(){ diff --git a/src/engine/input/Button.java b/src/engine/input/Button.java new file mode 100644 index 0000000..942b13f --- /dev/null +++ b/src/engine/input/Button.java @@ -0,0 +1,25 @@ +package engine.input; + +import java.util.List; + +public class Button { + + public String name; + private final List buttons; + private final GamepadInput controller; + + public Button(String name, List buttons, GamepadInput controller){ + this.name = name; + this.buttons = buttons; + this.controller = controller; + } + + public boolean isButtonPressed(){ + for (int i : buttons){ + if (controller.checkPressed(i)) return true; + } + return false; + } + + +} diff --git a/src/engine/input/GamepadInput.java b/src/engine/input/GamepadInput.java new file mode 100644 index 0000000..1cfd164 --- /dev/null +++ b/src/engine/input/GamepadInput.java @@ -0,0 +1,212 @@ +package engine.input; + +import engine.math.Vector3f; + +import java.nio.ByteBuffer; +import java.nio.FloatBuffer; + +import static engine.input.InputConst.*; +import static org.lwjgl.glfw.GLFW.*; +/* Buttons +0 : Croix / A +1: rond /B +2: carré / X +3: triangle / Y +4: L1 / LB +5: R1 / RB +6:select +7:start +8:L3 +9:R3 +10: haut +11: droite +12: bas +13: gauche +*/ + +/* Axes +0 : left X axe ( right : 1 left -1) +1: left Y axe ( down : 1 , Up -1) +2: right X axe ( right : 1 left -1) +3: right Y axe ( down : 1 , Up -1) +4:L2 / LT : 1 active, -1 unactive +5: R2 /RT : 1 active, -1 unactive +*/ + +public class GamepadInput { + + private final int gamepadNum; + private ByteBuffer gamepadButton; + private FloatBuffer gamepadAxes; + + public boolean buttonA_pressed ; + public boolean buttonB_pressed ; + public boolean buttonY_pressed ; + public boolean buttonX_pressed; + + public boolean LB_pressed ; + public boolean RB_pressed ; + + public boolean select_pressed; + public boolean start_pressed; + + public boolean R_JoyClick_pressed; + public boolean L_JoyClick_pressed; + + public boolean up_pressed ; + public boolean down_pressed; + public boolean left_pressed ; + public boolean right_pressed; + + public boolean leftJoyRight; + public boolean leftJoyLeft; + public boolean leftJoyDown; + public boolean leftJoyUp; + + public boolean rightJoyLeft; + public boolean rightJoyRight; + public boolean rightJoyDown ; + public boolean rightJoyUp; + + public boolean LT_pressed ; + public boolean RT_pressed; + + public GamepadInput (int gamepadNum){ + this.gamepadNum = gamepadNum; + this.gamepadAxes = null; + this.gamepadButton = null; + this.buttonA_pressed = false; + this.buttonB_pressed = false; + this.buttonY_pressed = false; + this.buttonX_pressed = false; + this.LB_pressed = false; + this.RB_pressed = false; + this.select_pressed = false; + this.start_pressed = false; + this.R_JoyClick_pressed = false; + this.L_JoyClick_pressed = false; + this.up_pressed = false; + this.down_pressed = false; + this.left_pressed = false; + this.right_pressed = false; + this.leftJoyRight = false; + this.leftJoyLeft = false; + this.leftJoyDown = false; + this.leftJoyUp = false; + this.rightJoyLeft = false; + this.rightJoyRight = false; + this.rightJoyDown = false; + this.rightJoyUp = false; + this.LT_pressed = false; + this.RT_pressed = false; + } + + public void inputRefresh() { + + this.gamepadButton = glfwGetJoystickButtons(this.gamepadNum); + this.gamepadAxes = glfwGetJoystickAxes(this.gamepadNum); + + assert gamepadAxes != null; + assert gamepadButton != null; + + + // A B X Y + buttonA_pressed = gamepadButton.get(buttonA) == 1; + buttonB_pressed = gamepadButton.get(buttonB) == 1; + buttonY_pressed = gamepadButton.get(buttonY) == 1; + buttonX_pressed = gamepadButton.get(buttonX) == 1; + + + // LB RB + LB_pressed = gamepadButton.get(LB) == 1; + RB_pressed = gamepadButton.get(RB) == 1; + + + //start select + start_pressed = gamepadButton.get(start) == 1; + select_pressed = gamepadButton.get(select) == 1; + + + //R & L JoystickClick + R_JoyClick_pressed = gamepadButton.get(R_JoystickClick) == 1; + L_JoyClick_pressed = gamepadButton.get(L_JoystickClick) == 1; + + + //up, down, left, right + up_pressed = gamepadButton.get(up) == 1; + down_pressed = gamepadButton.get(down) == 1; + left_pressed = gamepadButton.get(left) == 1; + right_pressed = gamepadButton.get(right) == 1; + + + //Left Joystick + leftJoyRight = gamepadAxes.get(leftJoyX_Axe) > 0.1; + leftJoyLeft = gamepadAxes.get(leftJoyX_Axe) < -0.1; + leftJoyDown = gamepadAxes.get(leftJoyY_Axe) > 0.1; + leftJoyUp = gamepadAxes.get(leftJoyY_Axe) < -0.1; + + + //Right Joystick + rightJoyRight = gamepadAxes.get(rightJoyX_Axe) > 0.1; + rightJoyLeft = gamepadAxes.get(rightJoyX_Axe) < -0.1; + rightJoyDown = gamepadAxes.get(rightJoyY_Axe) > 0.1; + rightJoyUp = gamepadAxes.get(rightJoyY_Axe) < -0.1; + + //LT RT + LT_pressed = gamepadButton.get(LT) == 1; + RT_pressed = gamepadButton.get(RT) == 1; + } + + public boolean checkPressed(int keyCode){ + this.gamepadButton = glfwGetJoystickButtons(GLFW_JOYSTICK_1); + + assert gamepadButton != null; + + return gamepadButton.get(keyCode) == 1; + } + + /** + * Envoie la position du stick pointé par axisId sous forme de direction général (9 directions) + * @param axisId l'identifiant du joystick (AXE X) + * @return la direction du stick valeur possible : RIGHT, UPPER_RIGHT, UP, UPPER_LEFT, LEFT, LOWER_LEFT, DOWN, LOWER_RIGHT, CENTER; + */ + public int getAxisDiscreet(int axisId){ + + float x = gamepadAxes.get(axisId); + float y = gamepadAxes.get(axisId + 1); + + float magnitude = (float) Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2)); + float angle = (float) Math.toDegrees(2 * Math.atan(y /(x + magnitude))); + + if (magnitude < 0.3) return CENTER; + if (angle < 22.5 && angle > -22.5) return RIGHT; + else if (angle > -67.5 && angle < -22.5) return UPPER_RIGHT; + else if (angle > -112.5 && angle < -67.5) return UP; + else if (angle > -157.5 && angle < -112.5) return UPPER_LEFT; + else if (angle < -157.5 || angle > 157.5) return LEFT; + else if (angle < 157.5 && angle > 112.5) return LOWER_LEFT; + else if (angle < 112.5 && angle > 67.5) return DOWN; + else if (angle < 67.5 && angle > 22.5) return LOWER_RIGHT; + + return -1; // TEST + } + + /** + * Envoie la position du stick pointé par axisID (AXE X) sous forme de Vecteur + * @param axisId l'identifiant du joystick (AXE X) + * @return un Vecteur représentant la position actuel du joystick + */ + public Vector3f getAxisContinuous(int axisId){ + + float x = gamepadAxes.get(axisId); + float y = gamepadAxes.get(axisId + 1); + + if (x < 0.1 && x > -0.1) x = 0; + if (y < 0.1 && y > -0.1) y = 0; + + System.out.println("x: " + x + " y: " + y); + + return new Vector3f(x,y); + } + +} diff --git a/src/engine/input/InputConst.java b/src/engine/input/InputConst.java new file mode 100644 index 0000000..e45db72 --- /dev/null +++ b/src/engine/input/InputConst.java @@ -0,0 +1,17 @@ +package engine.input; + +public class InputConst { + /* + Button ID + */ + public final static int buttonA=0, buttonB=1, buttonX=2, buttonY=3, LB = 4, RB = 5, select = 6, start = 7, + L_JoystickClick = 8, R_JoystickClick =9, up = 10, right = 11, down = 12, left = 13; + + /* + Axis ID + */ + public final static int leftJoyX_Axe = 0, leftJoyY_Axe = 1, rightJoyX_Axe = 2, rightJoyY_Axe = 3, LT = 4, RT = 5; + + public final static int RIGHT = 0, UPPER_RIGHT = 1, UP = 2, UPPER_LEFT = 3, LEFT = 4, LOWER_LEFT = 5, + DOWN = 6, LOWER_RIGHT = 7, CENTER = 8; +} diff --git a/src/engine/Input.java b/src/engine/input/KeyboardInput.java similarity index 85% rename from src/engine/Input.java rename to src/engine/input/KeyboardInput.java index 8d88645..0bc484c 100644 --- a/src/engine/Input.java +++ b/src/engine/input/KeyboardInput.java @@ -1,5 +1,6 @@ -package engine; +package engine.input; +import engine.Engine; import engine.math.Vector3f; import engine.object.ObjectGl; import org.lwjgl.glfw.GLFW; @@ -11,7 +12,7 @@ import java.nio.FloatBuffer; import static org.lwjgl.glfw.GLFW.*; import static org.lwjgl.opengl.GL11.*; -public class Input extends GLFWKeyCallback { +public class KeyboardInput extends GLFWKeyCallback { public static boolean[] keys = new boolean[65536]; @@ -38,9 +39,7 @@ public class Input extends GLFWKeyCallback { String name = GLFW.glfwGetJoystickName(GLFW_JOYSTICK_1); System.out.println("GamePad Name :" + name); -// for (int i =0 ; i < gamepadAxes.capacity(); i++) { -// System.out.println(i + " :" + gamepadAxes.get(i)); -// } + if (gamepadButton.get(0) ==1 ) { // appuie sur croix(PlayStation) A (Xbox) @@ -90,22 +89,25 @@ public class Input extends GLFWKeyCallback { public static void keyboardInput(ObjectGl token, int speed) { boolean keyPressed = false; - if (Input.isKeyDown(GLFW.GLFW_KEY_S)) { + if (KeyboardInput.isKeyDown(GLFW.GLFW_KEY_S)) { token.setTextureWrap(161,260,56,59, ObjectGl.STICK_BOTTOM); keyPressed = true; - } else if (Input.isKeyDown(GLFW.GLFW_KEY_W)) { + } else if (KeyboardInput.isKeyDown(GLFW.GLFW_KEY_W)) { keyPressed = true; + token.scale(new Vector3f(1.001f,1.001f,1.0f)); } - if (Input.isKeyDown(GLFW.GLFW_KEY_A)) { - token.translate(new Vector3f (speed * -5.0f, 0.0f, 0.0f)); + if (KeyboardInput.isKeyDown(GLFW.GLFW_KEY_A)) { + token.translate(new Vector3f (speed * -1.0f, 0.0f, 0.0f)); token.setTextureWrap(121,0,57,82, ObjectGl.STICK_TOP); keyPressed = true; } - else if (Input.isKeyDown(GLFW.GLFW_KEY_D)) { - token.translate(new Vector3f (speed * 5.0f, 0.0f, 0.0f)); + else if (KeyboardInput.isKeyDown(GLFW.GLFW_KEY_D)) { + token.translate(new Vector3f (speed * 1.0f, 0.0f, 0.0f)); token.setTextureWrap(178,0,62,82, ObjectGl.STICK_TOP); keyPressed = true; } if (!keyPressed) token.setTextureWrap(58,0,62,82, ObjectGl.STICK_TOP); + + token.flipTextureWrapH(); } } diff --git a/src/engine/math/Matrix4f.java b/src/engine/math/Matrix4f.java index 6291eb9..d3d2388 100644 --- a/src/engine/math/Matrix4f.java +++ b/src/engine/math/Matrix4f.java @@ -1,6 +1,6 @@ package engine.math; -import engine.utils.BufferUtils; +import engine.utils.BufferUtilsEngine; import java.nio.FloatBuffer; @@ -117,7 +117,7 @@ public class Matrix4f { } public FloatBuffer toFloatBuffer() { - return BufferUtils.createFloatBuffer(elements); + return BufferUtilsEngine.createFloatBuffer(elements); } } diff --git a/src/engine/math/Vector3f.java b/src/engine/math/Vector3f.java index 4f7c98b..37cf4de 100644 --- a/src/engine/math/Vector3f.java +++ b/src/engine/math/Vector3f.java @@ -10,6 +10,12 @@ public class Vector3f { z = 0.0f; } + public Vector3f(float x, float y){ + this.x = x; + this.y = y; + this.z = 0.0f; + } + public Vector3f(float x, float y, float z){ this.x = x; this.y = y; diff --git a/src/engine/object/ObjectGl.java b/src/engine/object/ObjectGl.java index 723cc2d..1abcef6 100644 --- a/src/engine/object/ObjectGl.java +++ b/src/engine/object/ObjectGl.java @@ -27,7 +27,15 @@ public class ObjectGl { public static Matrix4f projection; public static Matrix4f view; + /** + * xPos and yPos will stop to be relevant if you use rotate function + */ + private float xPos; + private float yPos; private float zPos; + private float xAngle; + private float yAngle; + private float zAngle; private float width; // To be used in setTextureWrap private float height; private float scalingFactor; @@ -35,6 +43,7 @@ public class ObjectGl { public boolean useTime; private Texture texture; + private float[] textureWrap; /** * Create a rectangle shape, use setTextureWrap to correctly align the texture with the model @@ -61,15 +70,18 @@ public class ObjectGl { this.texture = new Texture(tex, 0); } + this.xPos = 0.0f; + this.yPos = 0.0f; this.zPos = z; this.height = h; this.width = w; + this.textureWrap = Primitive.stdTexWrap; this.vertexArray = new VertexArray(Primitive.createRectangle(this.zPos, this.width, this.height), Primitive.rectangle_indices, colorBuffer, Primitive.stdTexWrap); - this.scalingFactor = size; + this.scalingFactor = 1; this.transform = Matrix4f.identity(); - this.scale(new Vector3f(size, size,1f)); + this.scale(new Vector3f(size, size,1.0f)); this.stick_state = DEFAULT; this.useTime = false; @@ -92,6 +104,9 @@ public class ObjectGl { public void resetTransform(){ this.transform = Matrix4f.identity(); this.scalingFactor = 1; + this.xPos = 0.0f; + this.yPos = 0.0f; + this.zPos = 0.0f; } /** @@ -99,9 +114,11 @@ public class ObjectGl { * @param vec Vector3f */ public void translate(Vector3f vec){ + this.xPos += vec.x; + this.yPos += vec.y; + this.zPos += vec.z; vec.divXY(this.scalingFactor); this.transform = this.transform.multiply(Matrix4f.translate(vec)); - this.zPos += vec.z; } /** @@ -183,6 +200,19 @@ public class ObjectGl { this.setTextureWrap(result); } + /** + * Reverse the textureWrap left to right + */ + public void flipTextureWrapH(){ + float[] textureWrapTemp = new float[] { + this.textureWrap[2], this.textureWrap[3], + this.textureWrap[0], this.textureWrap[1], + this.textureWrap[6], this.textureWrap[7], + this.textureWrap[4], this.textureWrap[5] + }; + setTextureWrap(textureWrapTemp); + } + /** * Set a new shader to be used by this object * @param vert path to glsl Vertex Shader @@ -207,9 +237,18 @@ public class ObjectGl { } private void setTextureWrap(float[] texture){ + this.textureWrap = texture; this.vertexArray.swapTextureBufferObject(texture); } + public float getXPos(){ + return xPos; + } + + public float getYPos(){ + return yPos; + } + public float getZPos(){ return zPos; } diff --git a/src/engine/sound/SoundBuffer.java b/src/engine/sound/SoundBuffer.java index 01cfa03..cfe1640 100644 --- a/src/engine/sound/SoundBuffer.java +++ b/src/engine/sound/SoundBuffer.java @@ -5,6 +5,7 @@ package engine.sound; +import engine.utils.FileUtils; import org.lwjgl.stb.STBVorbisInfo; import org.lwjgl.system.MemoryStack; import org.lwjgl.system.MemoryUtil; @@ -13,7 +14,6 @@ import java.nio.ByteBuffer; import java.nio.IntBuffer; import java.nio.ShortBuffer; -import static engine.utils.BufferUtils.StringToByteBuffer; import static org.lwjgl.openal.AL10.*; import static org.lwjgl.stb.STBVorbis.*; import static org.lwjgl.system.MemoryUtil.NULL; @@ -56,19 +56,19 @@ public class SoundBuffer { /** * Source : https://github.com/lwjglgamedev/lwjglbook/blob/master/chapter28/src/main/java/org/lwjglb/engine/sound/SoundBuffer.java * lis un fichier .ogg et le convertis en .pcm seul format lisible par openAl - * @param resource le fichier .ogg + * @param path chemin vers un fichier .ogg * @param info STBVorbisInfo * @return pcm * @throws Exception MemoryStack.stackPush() */ - private ShortBuffer readVorbis(String resource, STBVorbisInfo info) throws Exception { + private ShortBuffer readVorbis(String path, STBVorbisInfo info) throws Exception { try (MemoryStack stack = MemoryStack.stackPush()) { - vorbis = StringToByteBuffer(resource); + this.vorbis = FileUtils.loadAsByteBuffer(path); IntBuffer error = stack.mallocInt(1); long decoder = stb_vorbis_open_memory(vorbis, error, null); if (decoder == NULL) { throw new RuntimeException("Failed to open Ogg Vorbis file. Error: " + error.get(0)); - } + } //Failed to open Ogg Vorbis file. Error: 30 / 34 stb_vorbis_get_info(decoder, info); diff --git a/src/engine/sound/SoundManager.java b/src/engine/sound/SoundManager.java index a087be8..45cb69c 100644 --- a/src/engine/sound/SoundManager.java +++ b/src/engine/sound/SoundManager.java @@ -1,6 +1,9 @@ +// Source : https://github.com/lwjglgamedev/lwjglbook/blob/master/chapter28/src/main/java/org/lwjglb/engine/sound/SoundManager.java + package engine.sound; import engine.math.Matrix4f; +import engine.math.Vector3f; import org.lwjgl.openal.*; import java.nio.ByteBuffer; import java.nio.IntBuffer; @@ -9,6 +12,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import static org.lwjgl.openal.AL10.*; import static org.lwjgl.openal.ALC10.*; import static org.lwjgl.system.MemoryUtil.NULL; @@ -46,4 +50,69 @@ public class SoundManager { alcMakeContextCurrent(context); AL.createCapabilities(deviceCaps); } + + public void addSoundSource(String name, SoundSource soundSource) { + this.soundSourceMap.put(name, soundSource); + } + + public SoundSource getSoundSource(String name) { + return this.soundSourceMap.get(name); + } + + public void playSoundSource(String name) { + SoundSource soundSource = this.soundSourceMap.get(name); + if (soundSource != null && !soundSource.isPlaying()) { + soundSource.play(); + } + } + + public void removeSoundSource(String name) { + this.soundSourceMap.remove(name); + } + + public void addSoundBuffer(SoundBuffer soundBuffer) { + this.soundBufferList.add(soundBuffer); + } + + public SoundListener getListener() { + return this.listener; + } + + public void setListener(SoundListener listener) { + this.listener = listener; + } + +// Camera Statique de notre côté pas besoin de "corriger" cette fonction +// public void updateListenerPosition(Camera camera) { +// // Update camera matrix with camera data +// Transformation.updateGenericViewMatrix(camera.getPosition(), camera.getRotation(), cameraMatrix); +// +// listener.setPosition(camera.getPosition()); +// Vector3f at = new Vector3f(); +// cameraMatrix.positiveZ(at).negate(); +// Vector3f up = new Vector3f(); +// cameraMatrix.positiveY(up); +// listener.setOrientation(at, up); +// } + + public void setAttenuationModel(int model) { + alDistanceModel(model); + } + + public void cleanup() { + for (SoundSource soundSource : soundSourceMap.values()) { + soundSource.cleanup(); + } + soundSourceMap.clear(); + for (SoundBuffer soundBuffer : soundBufferList) { + soundBuffer.cleanup(); + } + soundBufferList.clear(); + if (context != NULL) { + alcDestroyContext(context); + } + if (device != NULL) { + alcCloseDevice(device); + } + } } diff --git a/src/engine/utils/BufferUtils.java b/src/engine/utils/BufferUtilsEngine.java similarity index 83% rename from src/engine/utils/BufferUtils.java rename to src/engine/utils/BufferUtilsEngine.java index 50a2ddb..14ccc53 100644 --- a/src/engine/utils/BufferUtils.java +++ b/src/engine/utils/BufferUtilsEngine.java @@ -1,13 +1,16 @@ package engine.utils; +import java.io.IOException; +import java.io.RandomAccessFile; import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.nio.FloatBuffer; import java.nio.IntBuffer; +import java.nio.channels.FileChannel; -public class BufferUtils { +public class BufferUtilsEngine { - private BufferUtils() { + private BufferUtilsEngine() { } @@ -29,8 +32,4 @@ public class BufferUtils { return result; } - public static ByteBuffer StringToByteBuffer(String msg){ - return ByteBuffer.wrap(msg.getBytes()); - } - } diff --git a/src/engine/utils/FileUtils.java b/src/engine/utils/FileUtils.java index 4f82877..13d8017 100644 --- a/src/engine/utils/FileUtils.java +++ b/src/engine/utils/FileUtils.java @@ -1,9 +1,13 @@ package engine.utils; -import java.io.BufferedReader; -import java.io.FileNotFoundException; -import java.io.FileReader; -import java.io.IOException; +import org.lwjgl.BufferUtils; + +import java.io.*; +import java.nio.ByteBuffer; +import java.nio.channels.SeekableByteChannel; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; public class FileUtils { @@ -17,13 +21,27 @@ public class FileUtils { BufferedReader reader = new BufferedReader(new FileReader(file)); String buffer = ""; while ((buffer = reader.readLine()) != null) { - result.append(buffer +"\n"); + result.append(buffer).append("\n"); } reader.close(); } catch (IOException e){ e.printStackTrace(); + System.exit(1); } return result.toString(); } + public static ByteBuffer loadAsByteBuffer(String file) throws IOException{ + ByteBuffer buffer; + + Path path = Paths.get(file); + + try (SeekableByteChannel fc = Files.newByteChannel(path)) { + buffer = BufferUtils.createByteBuffer((int) fc.size() + 1); + while (fc.read(buffer) != -1) ; + } + + buffer.flip(); + return buffer; + } } diff --git a/src/gameplay/match/match.java b/src/gameplay/match/match.java index 6f54f84..f5c069a 100644 --- a/src/gameplay/match/match.java +++ b/src/gameplay/match/match.java @@ -1,9 +1,19 @@ package gameplay.match; +import engine.Engine; +import engine.input.Button; +import engine.input.GamepadInput; +import engine.input.InputConst; +import engine.object.ObjectGl; import gameplay.input.InputBuffer; import gameplay.entities.*; import gameplay.entities.Character; +import java.util.ArrayList; +import java.util.List; + +import static org.lwjgl.glfw.GLFW.*; + /** * Main class that describes the base structure of the match, with characters, timer and such * @author Victor Azra @@ -37,6 +47,68 @@ public class match { this.roundsWonP1 = 0; this.roundsWonP2 = 0; } - - + + public static void main(String[] args) throws Exception { + + Engine engine = new Engine(800, 600, 3.0f / 4.0f); + engine.init(); + + String path = "textures/zangief_sprite.png"; + + ObjectGl zangief = new ObjectGl(0f, 60f, 80f, 10f, path, null); + zangief.setTextureWrap(58, 0, 62, 84, ObjectGl.STICK_TOP); + engine.add_objectGl(zangief); + + long timer = System.currentTimeMillis(); + long lastFrame; + int frame = 0; + boolean nextFrame = false; + boolean Joystick1Present = glfwJoystickPresent(GLFW_JOYSTICK_1); + + GamepadInput gamepad1 = null; + Button jump = null; + + if (Joystick1Present) { + gamepad1 = new GamepadInput(GLFW_JOYSTICK_1); + gamepad1.inputRefresh(); + List listJump = new ArrayList<>(); + listJump.add(InputConst.buttonA); + jump = new Button("jump", listJump, gamepad1); + } + + while (engine.isRunning()) { + lastFrame = System.currentTimeMillis(); + // Game logic should fit here + + if (Joystick1Present) { + gamepad1.inputRefresh(); + + System.out.println(gamepad1.getAxisDiscreet(GLFW_GAMEPAD_AXIS_LEFT_X)); + + // Check si le personnage a sauté + if (jump.isButtonPressed()) { + // Le personnage saute + System.out.println(" JE SAUTE "); + } + } + + engine.update(); + engine.render(); + + frame++; + + if (System.currentTimeMillis() - timer > 1000) { + timer += 1000; + System.out.println("FPS: " + frame); + frame = 0; + } + + while (!nextFrame) { + nextFrame = System.currentTimeMillis() - lastFrame >= 16.66f; + } + + nextFrame = false; + if (engine.shouldClose()) engine.setRunning(false); + } + } } diff --git a/textures/background_beach.png b/textures/background_beach.png new file mode 100644 index 0000000..92598e8 Binary files /dev/null and b/textures/background_beach.png differ