1
0
Fork 0
uni_informatik_projekt/src/break_out/model/Level.java

283 lines
6.7 KiB
Java

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<Stone> 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();
}
// Call here the balls method for reacting on stones of the playground
if(getBall().hitsStone(getStones())) {
updateStonesAndScore();
System.out.println("count: "+stones.size());
}
// if all stones are broken, go to next level
if(allStonesBroken()) {
// next level
System.out.println("next level");
}
// 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[][] stoneArray = 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 < stoneArray.length; y++) {
// foreach element in column x
for(int x = 0; x < stoneArray[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(stoneArray[y][x], tempPos);
// add stone to list
if(tempStone.getType() != 0)
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<Stone> getStones() {
// hacky workaround for ConcurrentModificationExceptions
ArrayList<Stone> copy = new ArrayList<>();
copy.addAll(stones);
return copy;
}
/**
* The updater for the levels stones and the player score
*/
private void updateStonesAndScore() {
Stone stone = getBall().getHitStone();
score += stone.getValue();
stone.setType(stone.getType()-1);
if(stone.getType() == 0) {
stones.remove(stone);
}
}
/**
* checks whether all stones are broken
* @return true when all stones are broken
*/
private boolean allStonesBroken() {
if(stones.isEmpty()) return true;
else return false;
}
}