package break_out.model; import break_out.Constants; import break_out.controller.JSONReader; import java.util.ArrayList; /** * This class contains information about the running game * * @author dmlux * @author I. Schumacher; modified by Gruppe 175 (Moritz Henseleit, Ruben Meyer) */ public class Level extends Thread implements ILevel { /** * The game to which the level belongs */ private Game game; /** * The number of the level */ private int levelnr; /** * The score of the level */ private int score; /** * The ball of the level */ private Ball ball; /** * Flag that shows if the ball was started */ private boolean ballWasStarted = false; /** * Flag that shows if the level was finished */ private boolean levelFinished = false; /** * The paddles of the level */ private Paddle paddleTop, paddleBottom; /** * The stones of the level */ private ArrayList stones = new ArrayList<>(); /** * The life counter of the level */ private int lifeCounter; /** * The constructor creates a new level object and needs the current game object, * the number of the level to be created and the current score * * @param game The game object * @param levelnr The number of the new level object * @param score The score */ public Level(Game game, int levelnr, int score) { this.game = game; this.levelnr = levelnr; this.score = score; this.ball = new Ball(); // calc paddle positions Position posPaddleTop = new Position((Constants.SCREEN_WIDTH - Constants.PADDLE_WIDTH) / 2.0, 0); Position posPaddleBottom = new Position((Constants.SCREEN_WIDTH - Constants.PADDLE_WIDTH) / 2.0, Constants.SCREEN_HEIGHT - Constants.PADDLE_HEIGHT); // set paddles this.paddleTop = new Paddle(posPaddleTop); this.paddleBottom = new Paddle(posPaddleBottom); // set paddles color this.paddleTop.setColor(Constants.COLOR_PADDLE_TOP); this.paddleBottom.setColor(Constants.COLOR_PADDLE_BOTTOM); loadLevelData(levelnr); } /** * The getter for the ball object * * @return ball The ball of the level */ public Ball getBall() { return this.ball; } /** * Sets ballWasStarted to true, the ball is moving */ public void startBall() { ballWasStarted = true; } /** * Sets ballWasStarted to false, the ball is stopped */ public void stopBall() { ballWasStarted = false; } /** * Returns if the ball is moving or stopped * * @return ballWasStarted True: the ball is moving; false: the ball is stopped */ public boolean ballWasStarted() { return ballWasStarted; } /** * The method of the level thread */ public void run() { game.notifyObservers(); // endless loop while (!levelFinished) { // if ballWasStarted is true, the ball is moving if (ballWasStarted()) { // Call here the balls method for updating his position on the playground getBall().updatePosition(); // Call here the balls method for reacting on the borders of the playground getBall().reactOnBorder(); // if ball hits paddle (top|bottom), reflect ball if(getBall().hitsPaddle(paddleTop)) getBall().reflectOnPaddle(paddleTop); if(getBall().hitsPaddle(paddleBottom)) getBall().reflectOnPaddle(paddleBottom); if(getBall().hitsPaddle(paddleTop) || getBall().hitsPaddle(paddleBottom)) { getBall().setHitState(true); // DEBUG OUTPUT //System.out.println(String.format("hitstate: %s, color: %s", this.ball.getHitState(), this.ball.getColor().getRGB())); } // if ball has hit a paddle set a new random color to it else if(getBall().getHitState()) { getBall().setHitState(false); getBall().newRandomColor(); } // update paddles position getPaddleTop().updatePosition(getBall()); getPaddleBottom().updatePosition(getBall()); // Tells the observer to repaint the components on the playground game.notifyObservers(); } // The thread pauses for a short time try { Thread.sleep(4); } catch (InterruptedException e) { e.printStackTrace(); } } } /** * Loads the information for the level from a json-file located in the folder /res of the project * * @param levelnr The number X for the LevelX.json file */ private void loadLevelData(int levelnr) { JSONReader reader = new JSONReader(String.format("res/Level%s.json", levelnr)); int[][] stoneTypes = reader.getStones2DArray(); lifeCounter = reader.getLifeCounter(); // clear stones list, not needed but could cause problems when not done stones.clear(); // foreach column for(int y = 0; y < stoneTypes.length; y++) { // foreach element in column x for(int x = 0; x < stoneTypes[y].length; x++) { Position tempPos = new Position(-1, -1); // position calculation, equivalent to grid calculation in "view.Field" // size of grid blocks int blockWidth = Constants.SCREEN_WIDTH / Constants.SQUARES_X; int blockHeight = Constants.SCREEN_HEIGHT / Constants.SQUARES_Y; tempPos.setX(blockWidth * x); tempPos.setY(blockHeight * y); Stone tempStone = new Stone(stoneTypes[y][x], tempPos); // add stone to list stones.add(tempStone); } } } /** * The getter for the top paddle object * * @return paddleTop The top paddle of the level */ public Paddle getPaddleTop() { return paddleTop; } /** * The getter for the bottom paddle object * * @return paddleBottom The bottom paddle of the level */ public Paddle getPaddleBottom() { return paddleBottom; } /** * The setter for the levels game state * @param finished game state */ public void setFinished(boolean finished) { this.levelFinished = finished; } /** * The getter for the levels stones * @return stones The stones of the level */ public ArrayList getStones() { return stones; } }