package gameplay.match; import engine.Engine; import engine.gui.UIElement; import engine.gui.UIElementText; import engine.gui.UIInputList; import engine.input.GamepadInput; import engine.math.Vector3f; import engine.object.Hitbox; import engine.object.HorizontalProgressBar; import engine.object.ObjectGl; import engine.object.Sprite; import gameplay.Characters.Blue.CharacterBlue; import gameplay.actions.Attack; import gameplay.actions.attackPart; import gameplay.actions.ThrowPart; import gameplay.entities.Status; import gameplay.frames.Frame; import gameplay.hitboxes.*; import gameplay.input.InputBuffer; import gameplay.entities.Character; import gameplay.input.Inputs; import gameplay.input.ButtonIG; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.IOException; import java.util.ArrayList; import java.util.List; import org.json.simple.JSONArray; import org.json.simple.JSONObject; import org.json.simple.parser.JSONParser; import org.json.simple.parser.ParseException; import static org.lwjgl.glfw.GLFW.*; /** * Main class that describes the base structure of the match, with characters, timer and such * @author Victor Azra * */ public class match { /** * the number of inputs read for each character, a.k.a. for how many frames the inputs are saved in memory. */ private static final int inputBufferSize = 120; /** * the level of the "ground", used to determine if a character is in the air or not. */ private static final int groundLevel = 180; private static int timer; private static InputBuffer inputsP1, inputsP2; private static int roundsWonP1=0, roundsWonP2=0; private static Character p1, p2; //characters of player 1 and 2 private static long timeStamp1; private static long timeStamp2; private static int frameCount; private static int oldPosXp1; private static int oldPosXp2; private static int oldPosYp1; private static int oldPosYp2; private static GamepadInput gamepad1 = null; private static GamepadInput gamepad2 = null; // GUI / HUD ? private static UIElementText coordP1; private static UIElementText coordP2; private static UIElement healthBarP1; private static UIElement healthBarP2; private static HorizontalProgressBar healthBarP1Obj; private static HorizontalProgressBar healthBarP2Obj; private static UIElementText timerUI; private static UIElementText fpsCounter; private static boolean showInputListP1 = false; private static UIInputList inputListP1; private static UIElementText matchWon; // Stage attribute private static int leftBoundary; private static int rightBoundary; // Debug public static boolean debugMode = false; public static boolean showP1Hitbox; public static boolean showP2Hitbox; private static List listHitboxObj = new ArrayList<>(); private static float slowFactor = 1f; private static long timeStampFpsCounter; private static int frameCounter; private static int roundCounter=0; private static Sprite objP1,objP2; private static Engine engine; private static Frame f; private static int acCode = 0; private static boolean roundP1=false; // Settings private static int height, width, rounds; private static String character1, character2, stage; private static boolean fullscreen; /** * Starts a new round, by placing the timer back at base value, characters back at full hp and such. */ private static void startNewRound() { timer = 99; inputsP1 = new InputBuffer(inputBufferSize); inputsP2 = new InputBuffer(inputBufferSize); p1.setPos(-750, groundLevel); p2.setPos((int) (750 - objP2.getWidth() * objP2.getScalingFactor()), groundLevel); p1.setCurrentHP(p1.getMaxHP()); p2.setCurrentHP(p2.getMaxHP()); objP1.translate(new Vector3f(p1.getPosX(),p1.getPosY(),0)); objP2.translate(new Vector3f(p2.getPosX(),p2.getPosY(),0)); objP1.getShadow().translate(new Vector3f(0f,p1.getPosY(),0)); objP2.getShadow().translate(new Vector3f(0f,p2.getPosY(),0)); // Crée l'InputList if(showInputListP1){ inputListP1 = new UIInputList(inputsP1, 10f, 0f, 0.85f, 110f, engine); engine.add_uiElement(inputListP1); inputListP1.init(); } } /** * Ends the round. * Used for playing animations and such. */ private static void endRound() { roundCounter++; String victoryTxt = roundP1 ? "Player1 won the round "+roundCounter : "Player2 won the round "+roundCounter; System.out.println(victoryTxt); matchWon = new UIElementText(victoryTxt, 5f, 0.25f, 0.5f, 200f, engine); matchWon.setShader("/shaders/StylishShaders/WavyTextVert.glsl", "/shaders/StylishShaders/TextFrag.glsl", true, true); engine.add_uiElement(matchWon); timeStamp1 = System.currentTimeMillis(); while(System.currentTimeMillis() - timeStamp1 < 2500){ engine.update(); engine.render(); } engine.remove_uiElement(matchWon); if(showInputListP1){ engine.remove_uiElement(inputListP1); } //replacement des sprites objP1.translate(new Vector3f(-p1.getPosX(), -p1.getPosY())); objP2.translate(new Vector3f(-p2.getPosX(), -p2.getPosY())); objP1.getShadow().translate(new Vector3f(0f,-p1.getPosY(),0)); objP2.getShadow().translate(new Vector3f(0f,-p2.getPosY(),0)); acCode = 0; } /** * Ends the match. * Used for playing animations and such. */ private static void endMatch() { String victoryTxt = roundsWonP1 > roundsWonP2 ? "P1 won the match" : "P2 won the match"; matchWon = new UIElementText(victoryTxt, 5f, 0.3f, 0.5f, 200f, engine); matchWon.setShader("/shaders/StylishShaders/WavyTextVert.glsl", "/shaders/StylishShaders/TextFrag.glsl", true, true); engine.add_uiElement(matchWon); timeStamp1 = System.currentTimeMillis(); while(System.currentTimeMillis() - timeStamp1 < 2500){ engine.update(); engine.render(); } engine.setRunning(false); } public static void parse() throws FileNotFoundException { JSONParser jsonP = new JSONParser(); try { JSONObject jsonO = (JSONObject) jsonP.parse(new FileReader("game.set")); JSONArray game = (JSONArray) jsonO.get("game"); JSONObject settings = (JSONObject) game.get(0); height = Integer.parseInt((String) settings.get("height")); width = Integer.parseInt((String) settings.get("width")); fullscreen = Boolean.parseBoolean((String) settings.get("fullscreen")); rounds = Integer.parseInt((String) settings.get("rounds")); character1 = (String) settings.get("character1"); character2 = (String) settings.get("character2"); stage = (String) settings.get("stage"); showP1Hitbox = Boolean.parseBoolean((String) settings.get("hitboxes")); showP2Hitbox = showP1Hitbox; } catch (ParseException | IOException e) { e.printStackTrace(); } } public static void main(String[] args) throws Exception { parse(); engine = new Engine(width, height, fullscreen, new Vector3f(4.0f, 3.0f)); engine.init(); boolean Joystick1Present = glfwJoystickPresent(GLFW_JOYSTICK_1); boolean Joystick2Present = glfwJoystickPresent(GLFW_JOYSTICK_2); String pathToBG = ""; switch (stage) { case "arena1": pathToBG = "/textures/arena1.png"; break; default: pathToBG = "/textures/arena1.png"; } ObjectGl background = new ObjectGl(0f,1f,1f,2.5f, pathToBG, null); background.setTextureWrap(0, 0, 1914f, 701f); background.translate(new Vector3f(-1350f, 1000f, 0f)); engine.add_objectGl(background); String pathp1 = ""; String pathp2 = ""; switch (character1) { case "blue": p1 = CharacterBlue.generateCharBlue(); pathp1 = "/textures/Sprite_sans_grille_9comp.png"; break; default: p1 = CharacterBlue.generateCharBlue(); pathp1 = "/textures/Sprite_sans_grille_9comp.png"; break; } switch (character2) { case "blue": p2 = CharacterBlue.generateCharBlue(); pathp2 = "/textures/Sprite_sans_grille_9comp.png"; break; default: p2 = CharacterBlue.generateCharBlue(); pathp2 = "/textures/Sprite_sans_grille_9comp.png"; break; } objP1 = new Sprite(14f, 5f, pathp1, null); objP2 = new Sprite(15f, 5f, pathp2, new Vector3f(1.0f,0.0f,1.0f)); engine.add_objectGl(objP1); engine.add_objectGl(objP2); f = p1.getCurrentframe(); objP1.setTextureWrap(f.getSprite()[0], f.getSprite()[1], f.getSprite()[2], f.getSprite()[3]); f = p2.getCurrentframe(); objP2.setTextureWrap(f.getSprite()[0], f.getSprite()[1], f.getSprite()[2], f.getSprite()[3]); objP2.flipTextureWrapH(); //Création des ombres objP1.setShadow(); engine.add_objectGl(objP1.getShadow()); objP2.setShadow(); engine.add_objectGl(objP2.getShadow()); if(Joystick1Present) { gamepad1 = new GamepadInput(GLFW_JOYSTICK_1); gamepad1.inputRefresh(); System.out.println("P1 Controller: " + gamepad1.getGamepadName()); } if(Joystick2Present) { gamepad2 = new GamepadInput(GLFW_JOYSTICK_2); gamepad2.inputRefresh(); System.out.println("P2 Controller: " + gamepad2.getGamepadName()); } /* GUI Setup */ // Barre de vie healthBarP1Obj = new HorizontalProgressBar(80f, 8.5f, 0.4f, 100f, p1.getCurrentHP(), p1.getMaxHP(), false); healthBarP1Obj.setShader("/shaders/StylishShaders/BasicNoTexVert.glsl", "/shaders/StylishShaders/HorizontalProgressBarGradientSquareFrag.glsl"); healthBarP1Obj.setUseHeight(true); healthBarP1Obj.useTime = true; healthBarP1 = new UIElement(healthBarP1Obj, 0.0138f, 0.980f, engine); healthBarP2Obj = new HorizontalProgressBar(80f, 8.5f, 0.4f, 100f, p2.getCurrentHP(), p2.getMaxHP(), true); healthBarP2Obj.setShader("/shaders/StylishShaders/BasicNoTexVert.glsl", "/shaders/StylishShaders/HorizontalProgressBarGradientSquareFrag.glsl"); healthBarP2Obj.setUseHeight(true); healthBarP2Obj.useTime = true; healthBarP2 = new UIElement(healthBarP2Obj, 0.563f, 0.980f, engine); engine.add_uiElement(healthBarP1); engine.add_uiElement(healthBarP2); // Habillage barre de vie ObjectGl healthBarP1Hab = new ObjectGl(81f, 1f, 1f, 1f, "/textures/health_bar.png", null); healthBarP1Hab.setTextureWrap(0,0, 883, 158); UIElement healthBarP1HabUI = new UIElement(healthBarP1Hab, 0.005f, 0.995f, engine); engine.add_uiElement(healthBarP1HabUI); ObjectGl healthBarP2Hab = new ObjectGl(81f, 1f, 1f, 1f, "/textures/health_bar.png", null); healthBarP2Hab.setTextureWrap(0,0, 883, 158); healthBarP2Hab.flipTextureWrapH(); UIElement healthBarP2HabUI = new UIElement(healthBarP2Hab, 0.555f, 0.995f, engine); engine.add_uiElement(healthBarP2HabUI); // Timer timerUI = new UIElementText(timer + "", 10f, 0.453f, 0.995f, 85f, engine); engine.add_uiElement(timerUI); debugToggle(); timeStampFpsCounter = System.currentTimeMillis(); //SetTracking engine.setCameraTrackingSF3ThirdStrike(objP1, objP2); //Stage leftBoundary = (int) background.getXPos(); rightBoundary = (int) (background.getXPos() + background.getWidth() * background.getScalingFactor()); while(frameCount < 5940 && engine.getRunning()) { ac(acCode); if(engine.shouldClose()) engine.setRunning(false); } engine.setRunning(false); } private static void ac(int i) throws InterruptedException { // System.out.println(i); switch (i) { //initiate a round case 0 : startNewRound(); timeStamp1 = System.currentTimeMillis(); frameCount = 0; acCode = 10; break; //checks if one or both of the chars are out of health case 10: oldPosXp1 = p1.getPosX(); oldPosXp2 = p2.getPosX(); oldPosYp1 = p1.getPosY(); oldPosYp2 = p2.getPosY(); if(p1.getCurrentHP() <= 0 && p2.getCurrentHP() <= 0) { acCode = 11;} else if(p1.getCurrentHP() <= 0) { acCode = 12;} else if(p2.getCurrentHP() <= 0) { acCode = 13;} else { acCode = 20;} break; //end round case 11: if(roundsWonP1 >= (rounds/2 +1) || roundsWonP2 >= (rounds/2 +1)) { endMatch(); break;} endRound(); acCode = 0; break; //if p1 is at 0 health case 12: roundsWonP2++; roundP1 =false; acCode = 11; break; //if p2 is at 0 health case 13: roundsWonP1++; roundP1=true; acCode = 11; break; //read both players inputs case 20: if (glfwJoystickPresent(GLFW_JOYSTICK_1)) { gamepad1.inputRefresh(); inputsP1.recordInputsFromGamepad(gamepad1, p1.getPosX() < p2.getPosX()); handleInputs(p1, inputsP1); } if (glfwJoystickPresent(GLFW_JOYSTICK_2)) { gamepad2.inputRefresh(); inputsP2.recordInputsFromGamepad(gamepad2, p2.getPosX() <= p1.getPosX()); handleInputs(p2, inputsP2); } // acCode = 21; break; //start of the handling of hitboxes case 21: try { handleThrows(p1, p2); } catch (IndexOutOfBoundsException e) {} try { handleHits(p1, p2, inputsP2); } catch (IndexOutOfBoundsException e) {}; try { handleThrows(p2,p1); } catch (IndexOutOfBoundsException e) {} try { handleHits(p2, p1, inputsP1); } catch (IndexOutOfBoundsException e) {}; acCode = 22; break; //Update of the current frame of each character case 22: if(p1.getCurrentframe().islastFrameOfHit()) { p1.removeFirstAttackPart(); } if(p2.getCurrentframe().islastFrameOfHit()) { p2.removeFirstAttackPart(); } nextFrame(p1,inputsP1); nextFrame(p2,inputsP2); boolean p1LooksRight = p1.getPosX() < p2.getPosX(); updatePos(p1,p1LooksRight); updatePos(p2,!p1LooksRight); stageBoundary(); pushBox(); cameraPushBack(); if(p1LooksRight) { f = p1.getCurrentframe(); objP1.setTextureWrap(f.getSprite()[0], f.getSprite()[1], f.getSprite()[2], f.getSprite()[3]); objP1.translate(new Vector3f(p1.getPosX()-oldPosXp1,p1.getPosY()-oldPosYp1,0)); f = p2.getCurrentframe(); objP2.setTextureWrap(f.getSprite()[0], f.getSprite()[1], f.getSprite()[2], f.getSprite()[3]); objP2.translate(new Vector3f(p2.getPosX() - oldPosXp2,p2.getPosY()-oldPosYp2,0)); Frame nf = new Frame(); nf.clone(p2.getCurrentframe()); nf.invertHitBoxes(); p2.setCurrentFrame(nf); objP2.flipTextureWrapH(); } else { Frame p1f = p1.getCurrentframe(); objP1.setTextureWrap(p1f.getSprite()[0], p1f.getSprite()[1], p1f.getSprite()[2], p1f.getSprite()[3]); objP1.translate(new Vector3f(p1.getPosX()-oldPosXp1,p1.getPosY()-oldPosYp1,0)); Frame p2f = p2.getCurrentframe(); objP2.setTextureWrap(p2f.getSprite()[0], p2f.getSprite()[1], p2f.getSprite()[2], p2f.getSprite()[3]); objP2.translate(new Vector3f(p2.getPosX()-oldPosXp2,p2.getPosY()-oldPosYp2,0)); Frame nf = new Frame(); nf.clone(p1.getCurrentframe()); nf.invertHitBoxes(); p1.setCurrentFrame(nf); objP1.flipTextureWrapH(); } engine.cameraTracking(); // Debug Hitbox Management removeHitboxEngine(); if (showP1Hitbox){ addHitbox(p1); } if (showP2Hitbox) { addHitbox(p2); } addHitboxEngine(); engine.update(); engine.render(); acCode = 23; break; //Waits the end of 1/60th of a second since start of frame then loops back to start case 23: // GUI update here if (debugMode){ coordP1.setText("objP1: " + objP1.getXPos() + ":" + objP1.getYPos() + " P1: " + p1.getPosX() +":" + p1.getPosY()); coordP2.setText("objP2: " + objP2.getXPos() + ":" + objP2.getYPos() + " P2: " + p2.getPosX() +":" + p2.getPosY()); } healthBarP1Obj.setCurrent(p1.getCurrentHP()); healthBarP1Obj.setMax(p1.getMaxHP()); healthBarP2Obj.setCurrent(p2.getCurrentHP()); healthBarP2Obj.setMax(p2.getMaxHP()); timerUI.setText(timer + ""); timer = 99 - frameCount/60; timeStamp2 = System.currentTimeMillis(); while(timeStamp2-timeStamp1<(1000/(60 * slowFactor))) { timeStamp2 = System.currentTimeMillis(); } frameCounter++; if (System.currentTimeMillis() - timeStampFpsCounter >= 1000){ if(debugMode){ fpsCounter.setText("FPS: " + frameCounter); } frameCounter = 0; timeStampFpsCounter = System.currentTimeMillis(); } frameCount++; timeStamp1 = System.currentTimeMillis(); acCode=10; break; } } /** * Will handle the inputs recorder and have the character do a corresponding action if possible * Order of priority is Throw > Special > Normal > Jump > Dash > Crouch > Move > do nothing * @param c * @param input */ private static void handleInputs(Character c, InputBuffer input) { Inputs latestIn = input.getLatestInputs(); boolean actionSet = false; if(latestIn.containsButtonTab(c.getNormalthrow().getCommand()[0]) && c.getCurrentframe().isNormalCancellable()) { c.clearNextFrames(); c.addNextFramesList(c.getNormalthrow().getFrame()); actionSet = true; } else { int atkCount = 0; //do an attack if possible while(atkCount < c.getAttacks().length && !actionSet) { Attack atk = c.getAttacks()[atkCount]; boolean attackIsPossible = input.commandRecognized(atk.getCommand()) && atk.getRequiredStatus().equals(c.getStatus()) && ((atk.isSpecial() && c.getCurrentframe().isSpecialCancellable()) || (!atk.isSpecial() && c.getCurrentframe().isNormalCancellable())); if(attackIsPossible) { if(c.getStatus() == Status.JUMPING) { ArrayList af = new ArrayList<>(c.getFrames()); c.clearNextFrames(); for(int i = 0; (i < af.size() - 1) && (i < atk.getFrame().size()); i++) { Frame jumpf = af.get(i+1); jumpf.cloneWithoutMovement(atk.getFrame().get(i)); c.addSingleFrame(jumpf); } c.setAttackPartsArray(atk.getParts()); } else { c.clearNextFrames(); c.addNextFramesList(atk.getFrame()); c.setAttackPartsArray(atk.getParts()); } actionSet = true; } atkCount++; } if(c.getCurrentframe().isJumpCancellable() && !actionSet) { if (input.commandRecognized(c.getForwardJump().getCommand())) { c.clearNextFrames(); c.addNextFramesList(c.getForwardJump().getFrame()); actionSet = true; c.setStatus(Status.JUMPING); } else if (input.commandRecognized(c.getBackJump().getCommand())) { c.clearNextFrames(); c.addNextFramesList(c.getBackJump().getFrame()); actionSet = true; c.setStatus(Status.JUMPING); } else if (input.commandRecognized(c.getNeutralJump().getCommand())) { c.clearNextFrames(); c.addNextFramesList(c.getNeutralJump().getFrame()); actionSet = true; c.setStatus(Status.JUMPING); } } if(c.getCurrentframe().isDashCancellable() && !actionSet) { if (input.commandRecognized(c.getForwardDash().getCommand())) { c.clearNextFrames(); c.addNextFramesList(c.getForwardDash().getFrame()); actionSet = true; } else if (input.commandRecognized(c.getBackDash().getCommand())) { c.clearNextFrames(); c.addNextFramesList(c.getBackDash().getFrame()); actionSet = true; } } if(c.getCurrentframe().isMoveCancellable() && !actionSet) { if(input.getLatestInputs().containsInput(ButtonIG.DOWN)) { c.clearNextFrames(); c.addNextFrames(c.getDefaultCrouchingFrames()); } else if(input.getLatestInputs().containsInput(ButtonIG.BACK)) { c.clearNextFrames(); c.addNextFrames(c.getBackWalkFrames()); } if(input.getLatestInputs().containsInput(ButtonIG.FORWARD)) { c.clearNextFrames(); c.addNextFrames(c.getForwardWalkFrames()); } } } } private static void handleThrows(Character p1, Character p2) { ArrayList activeP1 = new ArrayList<>(p1.getCurrentframe().getActThrowHitBox()); ArrayList passiveP2 = new ArrayList<>(p2.getCurrentframe().getPassThrowHitBox()); ArrayList tP = new ArrayList<>(p1.getNextThrowParts()); ThrowPart hit = new ThrowPart(tP.get(0).getFrames()); hit.clone(tP.get(0)); for(Active_throw_Hitbox atH : activeP1) { for(Passive_throw_HitBox ptH : passiveP2) { if(!hit.hasHit()){ boolean p1LooksRight = p1.getPosX() < p2.getPosX(); boolean touchH = (p1LooksRight && (atH.getPosX()+p1.getPosX()+ atH.getSize_x() > ptH.getPosX()+p2.getPosX()+ptH.getSize_x()) && (atH.getPosX() < ptH.getPosX())) || (!p1LooksRight && (atH.getPosX()+p1.getPosX()+ atH.getSize_x() < ptH.getPosX()+p2.getPosX()+ptH.getSize_x()) && (atH.getPosX() > ptH.getPosX())); boolean touchV = (atH.getPosY()+p1.getPosY() - atH.getSize_y() < ptH.getPosY()+p2.getPosY()) && (atH.getPosY()+p1.getPosY() > ptH.getPosY()+p2.getPosY() - ptH.getSize_y()); if(touchH && touchV) { hit.setHasHit(true); tP.set(0,hit); } } } } } /** * handles the if the first character hits the second one * @param p1 the character whose hits to handle * @param p2 the character who is or isn't hit * @param inputsP2 the inputs of the player 2, used to see if they're guarding */ private static void handleHits(Character p1, Character p2, InputBuffer inputsP2) { ArrayList activeP1 = new ArrayList<>(p1.getCurrentframe().getActHitBox()); ArrayList passiveP2 = new ArrayList<>(p2.getCurrentframe().getPassHitBox()); ArrayList aP = new ArrayList<>(p1.getNextAttackParts()); attackPart hit = new attackPart(aP.get(0).getFrames()); hit.clone(aP.get(0)); for(Active_HitBox aH : activeP1) { for(Passive_HitBox pH : passiveP2) { if(!hit.hasHit()){ boolean p1LooksRight = p1.getPosX() < p2.getPosX(); boolean touchH = (p1LooksRight && (aH.getPosX()+p1.getPosX()+ aH.getSize_x() > pH.getPosX()+p2.getPosX()+pH.getSize_x()) && (aH.getPosX() < pH.getPosX())) || (!p1LooksRight && (aH.getPosX()+p1.getPosX()+ aH.getSize_x() < pH.getPosX()+p2.getPosX()+pH.getSize_x()) && (aH.getPosX() > pH.getPosX())); boolean touchV = (aH.getPosY()+p1.getPosY() - aH.getSize_y() < pH.getPosY()+p2.getPosY()) && (aH.getPosY()+p1.getPosY() > pH.getPosY()+p2.getPosY() - pH.getSize_y()); if(touchH && touchV) { getHit(p2,hit,inputsP2.getLatestInputs()); hit.setHasHit(true); aP.set(0,hit); } } } } } /** * Handles a character getting hit by an attack part. * @param c the character that's getting hit * @param aP the attackPart hitting the character * @param inputs the current inputs of c */ private static void getHit(Character c, attackPart aP, Inputs inputs) { boolean getsHit = (c.getStatus() == Status.JUMPING) || (c.getStatus() == Status.HITINAIR) || (c.getStatus() == Status.FALLING) || !inputs.containsInput(ButtonIG.BACK) || (aP.isLow() && !inputs.containsInput(ButtonIG.DOWN)) || (aP.isOverHead() && inputs.containsInput(ButtonIG.DOWN)); Frame[] nextFrames; c.clearNextFrames(); if(getsHit) { switch (c.getStatus()) { case JUMPING: case HITINAIR: case FALLING : nextFrames = new Frame[20]; for(int i = 0; i < nextFrames.length; i++) { nextFrames[i] = c.getHitInAirFrame(); } c.addNextFrames(nextFrames); c.reduceHP(aP.getDamage()); c.setStatus(Status.HITINAIR); break; default : c.clearNextFrames(); if(!aP.knocksDown()) { nextFrames = new Frame[aP.getHitstun()]; if (inputs.containsInput(ButtonIG.DOWN)) { for (int i = 0; i < nextFrames.length; i++) { nextFrames[i] = c.getCrouchHitFrame(); } } else { for (int i = 0; i < nextFrames.length; i++) { nextFrames[i] = c.getStandHitFrame(); } } } else { nextFrames = new Frame[c.getKnockedDownFrames().length]; for (int i = 0; i < nextFrames.length; i++) { nextFrames[i] = c.getKnockedDownFrames()[i]; } } c.addNextFrames(nextFrames); c.reduceHP(aP.getDamage()); break; } } else { nextFrames = new Frame[aP.getBlockstun()]; if(inputs.containsInput(ButtonIG.DOWN)) { for(int i = 0; i < nextFrames.length; i++) { nextFrames[i] = c.getCrouchGuardFrame(); } } else { for(int i = 0; i < nextFrames.length; i++) { nextFrames[i] = c.getStandGuardFrame(); } } c.reduceHP(aP.getChipDamage()); c.addNextFrames(nextFrames); } } /** * Sets the character to its next logical frame * @param c the character * @param in the input buffer corresponding to the character */ private static void nextFrame(Character c, InputBuffer in) { c.goToNextFrames(); if (c.getFrames().size() == 0) { switch(c.getStatus()) { case FALLING:case HITINAIR: if(c.getPosY() > groundLevel){ c.setStatus(Status.FALLING); c.addSingleFrame(c.getFallingframe()); } else { c.setPos(c.getPosX(),groundLevel); c.setStatus(Status.KNOCKEDDOWN); c.addNextFrames(c.getKnockedDownFrames()); } break; case JUMPING: if(c.getPosY() > groundLevel) { c.addSingleFrame(c.getNeutralJump().getFrame().get(c.getNeutralJump().getFrame().size() - 1)); } else { c.setPos(c.getPosX(),groundLevel); c.setStatus(Status.NORMAL); c.addNextFrames(c.getDefaultStandingFrames()); } break; default: c.setStatus(Status.NORMAL); if(in.getLatestInputs().containsInput(ButtonIG.DOWN)) { c.addNextFrames(c.getDefaultCrouchingFrames()); } else { c.addNextFrames(c.getDefaultStandingFrames()); } break; } } } private static void updatePos(Character c, boolean looksRight) { if(looksRight) {c.setPos((int)(c.getPosX()+c.getCurrentframe().getMove_x()),(int)(c.getPosY()+c.getCurrentframe().getMove_y()));} else {c.setPos((int)(c.getPosX()-c.getCurrentframe().getMove_x()),(int)(c.getPosY()+c.getCurrentframe().getMove_y()));} } private static void pushBox(){ int push = 100; Push_HitBox phb1 = p1.getCurrentframe().getPushHitBox(); Push_HitBox phb2 = p2.getCurrentframe().getPushHitBox(); // Check if there is an intersection only on the x axis, if we push on the y axis character could get stuck in the air boolean lookRight = p1.getPosX() < p2.getPosX(); float sizeIntersection = lookRight ? p1.getPosX() + phb1.getPosX() + phb1.getSize_x() - p2.getPosX() - phb2.getPosX() : p2.getPosX() + phb2.getPosX() + phb2.getSize_x() - p1.getPosX() - phb1.getPosX(); boolean col = 0 < sizeIntersection; boolean colV = (phb1.getPosY() + p1.getPosY() - phb1.getSize_y() < phb2.getPosY() + p2.getPosY()) && (phb1.getPosY() + p1.getPosY() > phb2.getPosY() + p2.getPosY() - phb2.getSize_y()); if (col && colV){ if(lookRight){ p1.setPos((int) (p1.getPosX() - sizeIntersection/2), p1.getPosY()); p2.setPos((int) (p2.getPosX() + sizeIntersection/2), p2.getPosY()); } else { p1.setPos((int) (p1.getPosX() + sizeIntersection/2), p1.getPosY()); p2.setPos((int) (p2.getPosX() - sizeIntersection/2), p2.getPosY()); } } } /** * */ private static void cameraPushBack(){ boolean lookRight = p1.getPosX() < p2.getPosX(); Character left; Character right; ObjectGl rightObj; if (lookRight) { left = p1; right = p2; rightObj = objP2; } else { left = p2; right = p1; rightObj = objP1; } float leftOutOfView = left.getPosX() - (-engine.getViewXPos() - engine.getCamera().getDimension()); float rightOutOfView = (right.getPosX() + rightObj.getWidth() * rightObj.getScalingFactor()) - (-engine.getViewXPos() + engine.getCamera().getDimension()); boolean leftOOB = left.getPosX() < -engine.getViewXPos() - engine.getCamera().getDimension(); boolean rightOOB = right.getPosX() + rightObj.getWidth() * rightObj.getScalingFactor() > -engine.getViewXPos() + engine.getCamera().getDimension(); if(leftOOB && rightOutOfView - leftOutOfView > 0){ left.setPos((int) (left.getPosX() - leftOutOfView), left.getPosY()); } if(rightOOB && leftOutOfView - rightOutOfView < 0){ right.setPos((int) (right.getPosX() - rightOutOfView), right.getPosY()); } } private static void stageBoundary(){ // TODO arrêter de dupliquer du code boolean lookRight = p1.getPosX() < p2.getPosX(); Character left; Character right; ObjectGl rightObj; if (lookRight) { left = p1; right = p2; rightObj = objP2; } else { left = p2; right = p1; rightObj = objP1; } int leftBoundaryDist = leftBoundary - left.getPosX(); if (leftBoundaryDist > 0){ left.setPos(left.getPosX() + leftBoundaryDist, left.getPosY()); } int rightBoundaryDist = rightBoundary - (int) (right.getPosX() + rightObj.getWidth() * rightObj.getScalingFactor()); if (rightBoundaryDist < 0){ right.setPos(right.getPosX() + rightBoundaryDist, right.getPosY()); } } /* HITBOX DEBUG METHOD */ private static void addHitboxEngine(){ for (ObjectGl obj : listHitboxObj){ engine.add_objectGl(obj); } } private static void removeHitboxEngine(){ for (ObjectGl obj : listHitboxObj){ // Il faut le cast en ObjectGl engine.remove_objectGl(obj); } listHitboxObj = new ArrayList<>(); } private static void addHitbox(Character c){ Frame f = c.getCurrentframe(); Vector3f posC = new Vector3f(c.getPosX(), c.getPosY(), 100f); Vector3f darkBlue = new Vector3f(8f/255f, 29f/255f, 153f/255f); Vector3f green = new Vector3f(33f/255f, 135f/255f, 12f/255f); Vector3f red = new Vector3f(120f/255f, 19f/255f, 12f/255f); Vector3f lightBlue = new Vector3f(32f/255f, 103f/255f, 201f/255f); Vector3f purple = new Vector3f(116f/255f, 52f/255f, 235f/255f); float offset = 0; Push_HitBox pushHitBox = f.getPushHitBox(); if (pushHitBox != null){ Hitbox hb = new Hitbox(100f + offset, pushHitBox.getSize_x(), pushHitBox.getSize_y(), 1f, purple); hb.translate(new Vector3f(pushHitBox.getPosX() + posC.x, pushHitBox.getPosY() + posC.y)); listHitboxObj.add(hb); offset+=0.1f; } for (Passive_HitBox passive_hitBox : f.getPassHitBox()){ Hitbox hb = new Hitbox(100f + offset, passive_hitBox.getSize_x(), passive_hitBox.getSize_y(), 1f, darkBlue); hb.translate(new Vector3f(passive_hitBox.getPosX() + posC.x, passive_hitBox.getPosY() + posC.y)); listHitboxObj.add(hb); offset+=0.1f; } for (Passive_throw_HitBox passive_throw_hitBox : f.getPassThrowHitBox()){ Hitbox hb = new Hitbox(100f + offset, passive_throw_hitBox.getSize_x(), passive_throw_hitBox.getSize_y(), 1f, green); hb.translate(new Vector3f(passive_throw_hitBox.getPosX() + posC.x, passive_throw_hitBox.getPosY() + posC.y)); listHitboxObj.add(hb); offset+=0.1f; } for (Active_HitBox active_hitBox : f.getActHitBox()){ Hitbox hb = new Hitbox(100f + offset, active_hitBox.getSize_x(), active_hitBox.getSize_y(), 1f, red); hb.translate(new Vector3f(active_hitBox.getPosX() + posC.x, active_hitBox.getPosY() + posC.y)); listHitboxObj.add(hb); offset+=0.1f; } for (Active_throw_Hitbox active_throw_hitbox : f.getActThrowHitBox()){ Hitbox hb = new Hitbox(100f + offset, active_throw_hitbox.getSize_x(), active_throw_hitbox.getSize_y(), 1f, lightBlue); hb.translate(new Vector3f(active_throw_hitbox.getPosX() + posC.x, active_throw_hitbox.getPosY() + posC.y)); listHitboxObj.add(hb); offset+=1; } } public static void debugToggle(){ if (debugMode){ if(coordP1 != null){ engine.remove_uiElement(coordP1); } if(coordP2 != null){ engine.remove_uiElement(coordP2); } if(fpsCounter != null){ engine.remove_uiElement(fpsCounter); } debugMode = false; } else { coordP1 = new UIElementText("objP1: " + objP1.getXPos() + ":" + objP1.getYPos() + " P1: " + p1.getPosX() +":" + p1.getPosY(), 5f, 0f, 0.15f, 70f, engine); coordP1.setBackground(new Vector3f(0f,0f,0f)); engine.add_uiElement(coordP1); coordP2 = new UIElementText("objP2: " + objP2.getXPos() + ":" + objP2.getYPos() + " P1: " + p2.getPosX() +":" + p2.getPosY(), 5f, 0f, 0.1f, 70f, engine); coordP2.setBackground(new Vector3f(0f,0f,0f)); engine.add_uiElement(coordP2); // FPS counter fpsCounter = new UIElementText("Boulevard Combattant", 5f, 0f, 0.04f, 100f, engine); fpsCounter.setBackground(new Vector3f(0f,0f,0f)); engine.add_uiElement(fpsCounter); debugMode = true; } } }