package gameplay.match; import engine.Engine; import engine.gui.UIElement; import engine.gui.UIElementText; import engine.input.Button; 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.Throw; 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 org.lwjgl.system.CallbackI; 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, roundsWonP2; 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; // Debug private static boolean showP1Hitbox = true; // TODO modifier pour le rendre activable private static boolean showP2Hitbox = false; private static List listHitboxObj = new ArrayList<>(); private static Sprite objP1,objP2; private static Engine engine; private static Frame f; private static int acCode = 0; private static int height, width; /** * 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); //TODO : change to better values if needed p2.setPos((int) (750 - objP2.getWidth() * objP2.getScalingFactor()), groundLevel); //TODO : change to better values if needed objP1.translate(new Vector3f(p1.getPosX(),p1.getPosY(),0)); objP2.translate(new Vector3f(p2.getPosX(),p2.getPosY(),0)); // TODO meilleur implémentation possible objP1.getShadow().translate(new Vector3f(0f,p1.getPosY(),0)); objP2.getShadow().translate(new Vector3f(0f,p2.getPosY(),0)); } /** * Ends the round. * Used for playing animations and such. * TODO : Implement this once we know what to do. */ private static void endRound() { } /** * Ends the match. * Used for playing animations and such. * TODO : Implement this once we know what to do. */ private static void endMatch() { } 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")); } catch (ParseException | IOException e) { e.printStackTrace(); } } public static void main(String[] args) throws Exception { parse(); engine = new Engine(width, height, new Vector3f(4.0f, 3.0f)); engine.init(); boolean Joystick1Present = glfwJoystickPresent(GLFW_JOYSTICK_1); boolean Joystick2Present = glfwJoystickPresent(GLFW_JOYSTICK_2); String path = "textures/Sprite_sans_grille_9comp.png"; String 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); p1 = CharacterBlue.generateCharBlue(); p2 = CharacterBlue.generateCharBlue(); objP1 = new Sprite(14f, 4f, path, null); objP2 = new Sprite(15f, 5f, path, 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 */ 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); // 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.setColorVerticalGradient(new Vector3f(39f/255f, 201f/255f, 30f/255f), new Vector3f(19f/255f, 89f/255f, 15f/255f)); 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); //SetTracking engine.setCameraTrackingSF3ThirdStrike(objP1, objP2); while(frameCount < 5940 && engine.getRunning()) { ac(acCode); if(engine.shouldClose()) engine.setRunning(false); } engine.setRunning(false); } private static void ac(int i) { // 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: endRound(); if(roundsWonP1 >= 2 || roundsWonP2 >= 2) { endMatch();} //TODO : will probably need to specify more else{acCode = 0;} break; //if p1 is at 0 health case 12: roundsWonP2++; acCode = 11; break; //if p2 is at 0 health case 13: roundsWonP1++; 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); 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); 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(); } // 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 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 + ""); // Tracking update engine.cameraTracking(); timer = 99 - frameCount/60; timeStamp2 = System.currentTimeMillis(); while(timeStamp2-timeStamp1<(1000/60)) { timeStamp2 = 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) { 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() - atH.getSize_y() < ptH.getPosY()) && (atH.getPosY() > ptH.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() - aH.getSize_y() < pH.getPosY()) && (aH.getPosY() > pH.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) { try { //if(!c.getFrames().getNextframe().equals(null)){ c.goToNextFrames(); } catch (NullPointerException e) { switch(c.getStatus()) { case FALLING:case HITINAIR: if(c.getPosY() > groundLevel){ c.setStatus(Status.FALLING); c.setCurrentFrame(c.getFallingframe()); } else { c.setPos(c.getPosX(),groundLevel); c.setStatus(Status.KNOCKEDDOWN); c.addNextFrames(c.getKnockedDownFrames()); } 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()));} } // TODO giga memory leak ? 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); for (Passive_HitBox passive_hitBox : f.getPassHitBox()){ Hitbox hb = new Hitbox(100f, 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); } for (Passive_throw_HitBox passive_throw_hitBox : f.getPassThrowHitBox()){ Hitbox hb = new Hitbox(101f, 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); } for (Active_HitBox active_hitBox : f.getActHitBox()){ Hitbox hb = new Hitbox(102f, 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); } for (Active_throw_Hitbox active_throw_hitbox : f.getActThrowHitBox()){ Hitbox hb = new Hitbox(103f, 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); } } }