diff --git a/.gitignore b/.gitignore index 98b99a5..4bbc660 100644 --- a/.gitignore +++ b/.gitignore @@ -14,3 +14,6 @@ # Maven log/ target/ + +# no output +out/ \ No newline at end of file diff --git a/bin/break_out/Constants.class b/bin/break_out/Constants.class new file mode 100644 index 0000000..e0d6bff Binary files /dev/null and b/bin/break_out/Constants.class differ diff --git a/bin/break_out/Main.class b/bin/break_out/Main.class new file mode 100644 index 0000000..bc6bfb8 Binary files /dev/null and b/bin/break_out/Main.class differ diff --git a/bin/break_out/controller/Controller.class b/bin/break_out/controller/Controller.class new file mode 100644 index 0000000..6cd5319 Binary files /dev/null and b/bin/break_out/controller/Controller.class differ diff --git a/bin/break_out/model/Ball.class b/bin/break_out/model/Ball.class new file mode 100644 index 0000000..b437264 Binary files /dev/null and b/bin/break_out/model/Ball.class differ diff --git a/bin/break_out/model/Game.class b/bin/break_out/model/Game.class new file mode 100644 index 0000000..2dd9b4c Binary files /dev/null and b/bin/break_out/model/Game.class differ diff --git a/bin/break_out/model/IBall.class b/bin/break_out/model/IBall.class new file mode 100644 index 0000000..aba657f Binary files /dev/null and b/bin/break_out/model/IBall.class differ diff --git a/bin/break_out/model/Level.class b/bin/break_out/model/Level.class new file mode 100644 index 0000000..5792848 Binary files /dev/null and b/bin/break_out/model/Level.class differ diff --git a/bin/break_out/model/Position.class b/bin/break_out/model/Position.class new file mode 100644 index 0000000..d1c11d6 Binary files /dev/null and b/bin/break_out/model/Position.class differ diff --git a/bin/break_out/model/Vector2D.class b/bin/break_out/model/Vector2D.class new file mode 100644 index 0000000..7106eb1 Binary files /dev/null and b/bin/break_out/model/Vector2D.class differ diff --git a/bin/break_out/view/Field.class b/bin/break_out/view/Field.class new file mode 100644 index 0000000..4529106 Binary files /dev/null and b/bin/break_out/view/Field.class differ diff --git a/bin/break_out/view/SectionPanel.class b/bin/break_out/view/SectionPanel.class new file mode 100644 index 0000000..7b4e85e Binary files /dev/null and b/bin/break_out/view/SectionPanel.class differ diff --git a/bin/break_out/view/StartScreen.class b/bin/break_out/view/StartScreen.class new file mode 100644 index 0000000..39cb0f1 Binary files /dev/null and b/bin/break_out/view/StartScreen.class differ diff --git a/bin/break_out/view/View.class b/bin/break_out/view/View.class new file mode 100644 index 0000000..c78d68a Binary files /dev/null and b/bin/break_out/view/View.class differ diff --git a/libs/json-simple-1.1.1.jar b/libs/json-simple-1.1.1.jar new file mode 100644 index 0000000..66347a6 Binary files /dev/null and b/libs/json-simple-1.1.1.jar differ diff --git a/libs/miglayout-4.0-swing.jar b/libs/miglayout-4.0-swing.jar new file mode 100644 index 0000000..7b6a22c Binary files /dev/null and b/libs/miglayout-4.0-swing.jar differ diff --git a/res/Level1.json b/res/Level1.json new file mode 100644 index 0000000..c1f08b1 --- /dev/null +++ b/res/Level1.json @@ -0,0 +1,33 @@ +{ + "field" : [[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [0, 0, 2, 0, 2, 2, 2, 0, 2, 2, 0, 2, 2, 0, 0, 0, 0, 2, 2, 2, 0, 0], + [0, 0, 1, 0, 0, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0], + [0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0], + [0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0], + [0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0], + [0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0], + [0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0], + [0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0], + [0, 0, 3, 0, 0, 3, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 3, 3, 0, 0, 0], + [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]], + "maxLives" : 5 +} diff --git a/src/break_out/Constants.java b/src/break_out/Constants.java new file mode 100644 index 0000000..f1a3747 --- /dev/null +++ b/src/break_out/Constants.java @@ -0,0 +1,78 @@ +package break_out; + +import java.awt.Color; + +/** + * A class that contains all constant values to configure the game + * + * @author dmlux, modified by I. Schumacher + * + */ +public class Constants { + + /** + * The screen width in pixels + */ + public static final Integer SCREEN_WIDTH = 880; + + /** + * The screen height in pixels + */ + public static final Integer SCREEN_HEIGHT = 750; + + /** + * the application name + */ + public static final String APP_TITLE = "BreakOut"; + + /** + * Debugging flag for special rendering hints + */ + public static final boolean DEBUG_MODE = false; + + /** + * The background color for the game menu + */ + public static final Color BACKGROUND = new Color(52, 152, 219); + + /** + * Amount of columns for blocks + */ + public static final Integer SQUARES_X = 22; + + /** + * Amount of the rows + */ + public static final Integer SQUARES_Y = 30; + + /** + * The paddle width in pixels + */ + public static final Integer PADDLE_WIDTH = 70; + + /** + * The paddle height in pixels + */ + public static final Integer PADDLE_HEIGHT = 15; + + /** + * The distance between paddle and the lower reflection offset. + */ + public static final Double REFLECTION_OFFSET = 25.0; + + /** + * The ball diameter in pixels + */ + public static final Integer BALL_DIAMETER = 15; + + /** + * The paddle speed + */ + public static final Double DX_MOVEMENT = 4.5; + + /** + * The ball speed + */ + public static final Double BALL_SPEED = 1.20; + +} \ No newline at end of file diff --git a/src/break_out/Main.java b/src/break_out/Main.java new file mode 100644 index 0000000..acba5bc --- /dev/null +++ b/src/break_out/Main.java @@ -0,0 +1,31 @@ +package break_out; + +import break_out.controller.Controller; +import break_out.view.View; + +/** + * The entry point of the program. The game get started here and all components + * are initialized here. + * + * @author dmlux, modified by I. Schumacher + * + */ +public class Main { + + /** + * The main method + * + * @param args The arguments that were passed by the command line. + */ + public static void main(String[] args) { + + // Enable OpenGL for 2D graphics objects. (Linux Performance, but sometimes buggy) + // -Dsun.java2d.opengl=true as JVM argument seems to be a little bit more stable + System.setProperty("sun.java2d.opengl", "True"); + + // Create the view + View view = new View(); + // Create the controller and pass the view object to it + new Controller(view); + } +} diff --git a/src/break_out/controller/Controller.java b/src/break_out/controller/Controller.java new file mode 100644 index 0000000..9a6d622 --- /dev/null +++ b/src/break_out/controller/Controller.java @@ -0,0 +1,146 @@ +package break_out.controller; + +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.KeyEvent; +import java.awt.event.KeyListener; + +import break_out.model.Game; +import break_out.view.Field; +import break_out.view.StartScreen; +import break_out.view.View; + +/** + * The controller takes care of the input events and reacts on those events by + * manipulating the view and updates the model. + * + * @author dmlux, modified by I. Schumacher and I. Traupe + * + */ +public class Controller implements ActionListener, KeyListener { + + /** + * The game as model that is connected to this controller + */ + private Game game; + + /** + * The view that is connected to this controller + */ + private View view; + + /** + * The constructor expects a view to construct itself. + * + * @param view + * The view that is connected to this controller + */ + public Controller(View view) { + this.view = view; + + // Assigning the listeners + assignActionListener(); + assignKeyListener(); + } + + /** + * The controller gets all buttons out of the view with this method and adds + * this controller as an action listener. Every time the user pushed a button + * the action listener (this controller) gets an action event. + */ + private void assignActionListener() { + // Get the start screen to add this controller as action + // listener to the buttons. + view.getStartScreen().addActionListenerToStartButton(this); + view.getStartScreen().addActionListenerToQuitButton(this); + } + + /** + * With this method the controller adds himself as a KeyListener. Every time the + * user pushed a key the KeyListener (this controller) gets an KeyEvent. + */ + private void assignKeyListener() { + // Get the field to add this controller as KeyListener + view.getField().addKeyListener(this); + } + + /** + * If the user clicks any button this ActionListener will get called. The method + * will get an ActionEvent e which held the source of this event. + */ + @Override + public void actionPerformed(ActionEvent e) { + // We will get the startScreen view from the view + StartScreen startScreen = view.getStartScreen(); + + // The startScreen view has some buttons. We will compare the source of the + // event e with the startButton to get sure that this button was the event + // source ... or simple: The user clicked this particular button. + if (startScreen.getStartButton().equals(e.getSource())) { + // The players name of the input field in the start window + String playersName = startScreen.getPlayersName(); + playersName = playersName.trim(); + if (playersName.length() < 1) { + // If the players name is too short, we won't accept this and display an error + // message + startScreen.showError("Der Name ist ungültig"); + } else { + // If everything is fine we can go on and create a new game. + game = new Game(this); + // ... and tell the view to set this new game object. + view.setGame(game); + } + } + + // If the eventSource was the quit button we will exit the whole application. + else if (startScreen.getQuitButton().equals(e.getSource())) { + System.exit(0); + } + } + + /** + * This method will be called, after a key was typed. This means, that the key + * was pressed and released, before this method get called. + * @param e The key event + */ + @Override + public void keyTyped(KeyEvent e) { + + } + + /** + * This method will be called, after a key was pressed down. + * @param e The key event + */ + @Override + public void keyPressed(KeyEvent e) { + + } + + /** + * This method will be called, after a key was released. + * @param e The key event + */ + @Override + public void keyReleased(KeyEvent e) { + + } + + /** + * This method switches the view to the StartScreen view. + */ + public void toStartScreen() { + view.showScreen(StartScreen.class.getName()); + view.getStartScreen().requestFocusInWindow(); + } + + /** + * This method switches the view to the FieldView which will display the + * playground. + */ + public void toPlayground() { + view.showScreen(Field.class.getName()); + view.getField().requestFocusInWindow(); + } + +} diff --git a/src/break_out/model/Ball.java b/src/break_out/model/Ball.java new file mode 100644 index 0000000..0d97474 --- /dev/null +++ b/src/break_out/model/Ball.java @@ -0,0 +1,62 @@ +package break_out.model; + +import break_out.Constants; + +/** + * This class contains the information about the balls characteristics and behavior + * + * @author iSchumacher + * + */ +public class Ball implements IBall{ + + /** + * The balls position on the playground + */ + private Position position; + + /** + * The balls direction + */ + private Vector2D direction; + + /** + * The constructor of a ball + * The balls position and direction are initialized here. + */ + public Ball() { + this.position = new Position(0, 0); + this.direction = new Vector2D(0,0); + } + + /** + * The getter for the balls position + * @return position The balls current position + */ + public Position getPosition() { + return this.position; + } + + /** + * The getter for the balls direction + * @return direction The balls current direction + */ + public Vector2D getDirection() { + return this.direction; + } + + /** + * + */ + public void updatePosition() { + + } + + /** + * + */ + public void reactOnBorder() { + + } + +} diff --git a/src/break_out/model/Game.java b/src/break_out/model/Game.java new file mode 100644 index 0000000..73d22de --- /dev/null +++ b/src/break_out/model/Game.java @@ -0,0 +1,127 @@ +package break_out.model; + +import java.util.List; +import java.util.ArrayList; + +import break_out.controller.Controller; +import break_out.view.View; + +/** + * This class contains information about the game (the model in MVC) + * + * @author dmlux, modified by I. Schumacher + * + */ +public class Game { + + /** + * A list of observer objects + */ + private List observers = new ArrayList(); + + /** + * The controller of the game + */ + private Controller controller; + + /** + * The current level + */ + private Level level; + + /** + * The first levelnumber + */ + private int firstLevel = 1; + + /** + * The last levelnumber + */ + private int maxLevel = 1; + + /** + * The total score of the game + */ + private int score = 0; + + /** + * The constructor creates a new game instance with the given Controller + * + * @param controller + * The controller to manage this instance (MVC-patter) + */ + public Game(Controller controller) { + this.controller = controller; + createLevel(firstLevel, 0); + } + + // The three methods of the mvc pattern ---------------- + public void addObserver(View observer) { + observers.add(observer); + } + + public void removeObserver(View observer) { + observers.remove(observer); + } + + public void notifyObservers() { + for (View observer : observers) + observer.modelChanged(this); + } + // ------------------------------------------------------- + + /** + * Getter for the Controller + * + * @return controller The controller of this game + */ + public Controller getController() { + return controller; + } + + /** + * Getter for the current Level + * + * @return level The current level of the game + */ + public Level getLevel() { + return level; + } + + /** + * Getter for the total score + * + * @return score The current score of the game + */ + public int getScore() { + return score; + } + + /** + * Creates the first or the next level, if the level number is less or equal + * maxLevel. If the current level is higher than maxLevel the view will be + * switched to the startScreen. + * + * @param levelnr + * The number for the next level + * @param score + * The current players score after finishing the previous level. + */ + public void createLevel(int levelnr, int score) { + this.score = score; + if (levelnr <= maxLevel) { + // Creates a new level instance + level = new Level(this, levelnr, score); + // calls the run method to start the new level + level.start(); + // tells the controller to switch to the field view which displays the playground + controller.toPlayground(); + } else { + // tells the controller to switch to the startScreen of the game + controller.toStartScreen(); + + } + + } + +} diff --git a/src/break_out/model/IBall.java b/src/break_out/model/IBall.java new file mode 100644 index 0000000..fd5c227 --- /dev/null +++ b/src/break_out/model/IBall.java @@ -0,0 +1,10 @@ +package break_out.model; + +public interface IBall { + + // Exercise 1 + public void updatePosition(); + public void reactOnBorder(); + public Position getPosition(); + public Vector2D getDirection(); +} diff --git a/src/break_out/model/Level.java b/src/break_out/model/Level.java new file mode 100644 index 0000000..6c2f177 --- /dev/null +++ b/src/break_out/model/Level.java @@ -0,0 +1,126 @@ +package break_out.model; + + +/** + * This class contains information about the running game + * + * @author dmlux + * @author I. Schumacher + */ +public class Level extends Thread { + + /** + * 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 = true; + + /** + * 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(); + + 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 (true) { + // if ballWasStarted is true, the ball is moving + if (ballWasStarted) { + + // Call here the balls method for updating his position on the playground + + + // Call here the balls method for reacting on the borders of the playground + + + + // 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) { + + } + +} + + + + diff --git a/src/break_out/model/Position.java b/src/break_out/model/Position.java new file mode 100644 index 0000000..dbdc170 --- /dev/null +++ b/src/break_out/model/Position.java @@ -0,0 +1,67 @@ +package break_out.model; + + +/** + * This class represents a position within the board in pixel coordinates + * + * @author dmlux + * + */ +public class Position { + + /** + * X coordinate + */ + private double x; + + /** + * Y coordinate + */ + private double y; + + /** + * The constructor needs a x and y coordinate to be called + * + * @param x The x position of the object on the board + * @param y The y position of the object on the board + */ + public Position(double x, double y) { + this.x = x; + this.y = y; + } + + /** + * Getter for the x-coordinate + * + * @return x The x value of this position + */ + public double getX() { + return x; + } + + /** + * Setter for the x-coordinate + * @param x The new x-coordinate + */ + public void setX(double x) { + this.x = x; + } + + /** + * Getter for y-coordinate + * + * @return y The y value of the position + */ + public double getY() { + return y; + } + + /** + * Setter for the y-coordinate + * @param y The new y-coordinate + */ + public void setY(double y) { + this.y = y; + } + +} diff --git a/src/break_out/model/Vector2D.java b/src/break_out/model/Vector2D.java new file mode 100644 index 0000000..3fb2dd6 --- /dev/null +++ b/src/break_out/model/Vector2D.java @@ -0,0 +1,70 @@ +package break_out.model; + +import break_out.Constants; +import break_out.model.Position; + +/** + * This class represent a two dimensional vector. + * + * @author I. Schumacher + */ +public class Vector2D { + + /** + * The x part of the vector + */ + private double dx; + + /** + * The y part of the vector + */ + private double dy; + + /** + * This constructor creates a new vector with the given x and y parts. + * + * @param dx the delta x part for the new vector + * @param dy the delty y part for the new vector + */ + public Vector2D(double dx, double dy) { + this.dx = dx; + this.dy = dy; + } + + /** + * Getter for the dx-part + * + * @return dx The dx part of this vector + */ + public double getDx() { + return dx; + } + + /** + * Setter for the dx-part + * + * @param dx The new dx part of this vector + */ + public void setDx(double dx) { + this.dx = dx; + } + + /** + * Getter for the dy-part + * + * @return dy The dy part of this vector + */ + public double getDy() { + return dy; + } + + /** + * Setter for the dy-part + * + * @param dy The new dy part of this vector + */ + public void setDy(double dy) { + this.dy = dy; + } + +} diff --git a/src/break_out/view/Field.java b/src/break_out/view/Field.java new file mode 100644 index 0000000..cb577a0 --- /dev/null +++ b/src/break_out/view/Field.java @@ -0,0 +1,114 @@ +package break_out.view; + +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.RenderingHints; + +import javax.swing.JPanel; + +import break_out.Constants; +import net.miginfocom.swing.MigLayout; + +/** + * The field represents the board of the game. All components are on the board + * + * @author dmlux, modified by iSchumacher + * + */ +public class Field extends JPanel { + + /** + * Automatic generated serial version UID + */ + private static final long serialVersionUID = 2434478741721823327L; + + /** + * The connected view object + */ + private View view; + + /** + * The background color + */ + private Color background; + + /** + * The constructor needs a view + * + * @param view The view of this board + */ + public Field(View view) { + super(); + + this.view = view; + this.background = new Color(177, 92, 107); + + setFocusable(true); + + // Load settings + initialize(); + } + + /** + * Initializes the settings for the board + */ + private void initialize() { + // creates a layout + setLayout(new MigLayout("", "0[grow, fill]0", "0[grow, fill]0")); + } + + /** + * Change the background color + * @param color The new color + */ + public void changeBackground(Color color) { + background = color; + repaint(); + } + + /** + * This method is called when painting/repainting the playground + * @param g the graphics object + */ + @Override + protected void paintComponent(Graphics g) { + super.paintComponent(g); + + double w = Constants.SCREEN_WIDTH; + double h = Constants.SCREEN_HEIGHT; + + // Setting the dimensions of the playground + setPreferredSize(new Dimension((int) w, (int) h)); + setMaximumSize(new Dimension((int) w, (int) h)); + setMinimumSize(new Dimension((int) w, (int) h)); + + Graphics2D g2 = (Graphics2D) g; + g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, + RenderingHints.VALUE_ANTIALIAS_ON); + + // Setting the background color + g2.setColor(background); + g2.fillRect(0, 0, getWidth(), getHeight()); + + // Setting the color for the following components + g2.setColor(new Color(200, 200, 200)); + + // Calls the method for drawing the ball + drawBall(g2); + + } + + /** + * Draws the ball + * @param g2 The graphics object + */ + private void drawBall(Graphics2D g2) { + g2.fillOval((int) view.getGame().getLevel().getBall().getPosition().getX(), + (int) view.getGame().getLevel().getBall().getPosition().getY(), + Constants.BALL_DIAMETER, + Constants.BALL_DIAMETER); + } + +} diff --git a/src/break_out/view/SectionPanel.java b/src/break_out/view/SectionPanel.java new file mode 100644 index 0000000..0ea1f0c --- /dev/null +++ b/src/break_out/view/SectionPanel.java @@ -0,0 +1,145 @@ +package break_out.view; + +import java.awt.BasicStroke; +import java.awt.Color; +import java.awt.Dimension; +import java.awt.GradientPaint; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.RenderingHints; + +import javax.swing.JPanel; + +/** + * This panel represents the background for special divisions in this application + * + * @author dmlux + * + */ +public class SectionPanel extends JPanel { + + /** + * Automatic generated serial version UID + */ + private static final long serialVersionUID = -7773487090869704154L; + + /** + * Color of the panel + */ + private Color color; + + /** + * Thickness of the border + */ + protected int strokeSize = 1; + + /** + * Color of the shadow + */ + protected Color shadowColor = new Color(50, 50, 50); + + /** + * Shadow flag + */ + protected boolean shady = true; + + /** + * Double value for the vertical curvature + */ + protected Dimension arcs = new Dimension(10, 10); + + /** + * Distance of shadow to the panel border + */ + protected int shadowGap = 3; + + /** + * Shadow offset + */ + protected int shadowOffset = 3; + + /** + * Shadow transparency + */ + protected int shadowAlpha = 200; + + + /** + * A constructor for the section panel + */ + public SectionPanel() { + super(); + setOpaque(false); + + // set background color + this.color = new Color(220, 220, 220); + } + + /** + * A constructor that expects a background color for this panel + * + * @param background The background color + */ + public SectionPanel(Color background) { + super(); + setOpaque(false); + + // set background + this.color = background; + } + + + @Override + public void setBackground(Color bg) { + color = bg; + repaint(); + } + + @Override + protected void paintComponent(Graphics g) { + super.paintComponent(g); + + int width = getWidth(); + int height = getHeight(); + int shadowGap = this.shadowGap; + + Color shadowColorA = new Color(shadowColor.getRed(), + shadowColor.getGreen(), shadowColor.getBlue(), shadowAlpha); + Graphics2D g2 = (Graphics2D) g; + + // Sets antialiasing + g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, + RenderingHints.VALUE_ANTIALIAS_ON); + + // Draws shadow borders if any. + if (shady) { + g2.setColor(shadowColorA); + g2.fillRoundRect(shadowOffset, // X position + shadowOffset, // Y position + width - strokeSize - shadowOffset, // width + height - strokeSize - shadowOffset, // height + arcs.width, arcs.height); // arc Dimension + } else + shadowGap = 1; + + // Draws the rounded opaque panel with borders. + Color c1 = color; + int nr = Math.min((color.getRed() + 40), 255); + int ng = Math.min((color.getGreen() + 40), 255); + int nb = Math.min((color.getBlue() + 40), 255); + Color c2 = new Color(nr, ng, nb); + GradientPaint gradient = new GradientPaint(0, 0, c1, getWidth(), + getHeight(), c2, true); + g2.setPaint(gradient); + g2.fillRoundRect(0, 0, width - shadowGap, height - shadowGap, + arcs.width, arcs.height); + + g2.setColor(new Color(120, 120, 120)); + g2.setStroke(new BasicStroke(strokeSize)); + g2.drawRoundRect(0, 0, width - shadowGap, height - shadowGap, + arcs.width, arcs.height); + + // Sets strokes to default, is better. + g2.setStroke(new BasicStroke()); + } +} diff --git a/src/break_out/view/StartScreen.java b/src/break_out/view/StartScreen.java new file mode 100644 index 0000000..d086204 --- /dev/null +++ b/src/break_out/view/StartScreen.java @@ -0,0 +1,198 @@ +package break_out.view; + +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Font; +import java.awt.event.ActionListener; + +import javax.swing.JButton; +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.JTextField; +import javax.swing.SwingConstants; + +import break_out.Constants; +import net.miginfocom.swing.MigLayout; + +/** + * This screen serves the configuration of the game. + * + * @author dmlux, modified by I. Schumacher + * + */ +public class StartScreen extends JPanel { + + /** + * Automatic generated serial version UID + */ + private static final long serialVersionUID = -131505828069382345L; + + /** + * Start game button + */ + private JButton startGame; + + /** + * The connected view object + */ + private View view; + + /** + * Quit game button + */ + private JButton quitGame; + + /** + * Input field for the players name + */ + private JTextField playersName; + + /** + * The error label + */ + private JLabel error; + + + /** + * The constructor needs a view + * + * @param view The view of this board + */ + public StartScreen(View view) { + super(); + this.view = view; + double w = Constants.SCREEN_WIDTH; + double h = Constants.SCREEN_HEIGHT; + + setPreferredSize(new Dimension((int) w, (int) h)); + setMaximumSize(new Dimension((int) w, (int) h)); + setMinimumSize(new Dimension((int) w, (int) h)); + + initialize(); + } + + + /** + * Initializes the settings for this screen + */ + private void initialize() { + // layout + setLayout(new MigLayout("", + "10[35%, center, grow, fill][65%, center, grow, fill]10", + "10[center, grow, fill]10")); + + // background color + setBackground(Constants.BACKGROUND); + + // initializes menu + initializeLeftMenu(); + initializeScoreMenu(); + } + + /** + * Initializes the left menu + */ + private void initializeLeftMenu() { + // the layout + SectionPanel leftMenu = new SectionPanel(); + leftMenu.shady = false; + leftMenu.setLayout(new MigLayout("", "10[center, grow, fill]10", + "10[center]30[center]5[center]20[center]5[center]0")); + + // adding components to the layout + startGame = new JButton("Spiel starten"); + quitGame = new JButton("Spiel beenden"); + playersName = new JTextField(); + + error = new JLabel(""); + error.setForeground(new Color(204, 0, 0)); + error.setHorizontalAlignment(SwingConstants.CENTER); + + JLabel menuLabel = new JLabel(Constants.APP_TITLE + " Spielmenü"); + menuLabel.setFont(new Font("Sans-serif", Font.PLAIN, 16)); + menuLabel.setHorizontalAlignment(SwingConstants.CENTER); + + leftMenu.add(menuLabel, "cell 0 0, growx"); + leftMenu.add(new JLabel("Spielername:"), "cell 0 1, growx, gapleft 5"); + leftMenu.add(playersName, "cell 0 2, growx"); + leftMenu.add(startGame, "cell 0 3, growx"); + leftMenu.add(quitGame, "cell 0 4, growx"); + leftMenu.add(error, "cell 0 5, growx"); + add(leftMenu, "cell 0 0"); + } + + /** + * Initializes the right menu + */ + private void initializeScoreMenu() { + // The layout + SectionPanel scoreMenu = new SectionPanel(Color.WHITE); + scoreMenu.shady = false; + scoreMenu.setLayout(new MigLayout("", "10[center, grow, fill]10", + "5[center]5")); + + // adding the compoenents to the layout + JLabel headline = new JLabel("Scores"); + headline.setFont(new Font("Sans-serif", Font.PLAIN, 16)); + headline.setHorizontalAlignment(SwingConstants.CENTER); + scoreMenu.add(headline, "cell 0 0, gaptop 5"); + + add(scoreMenu, "cell 1 0, gapleft 5"); + } + + /** + * Adds an action listener to the start button + * @param l The actionListener + */ + public void addActionListenerToStartButton(ActionListener l) { + startGame.addActionListener(l); + } + + /** + * Returns the start button + * @return startGame The button for starting the game + */ + public JButton getStartButton() { + return startGame; + } + + /** + * Adds an action listener to the quit button + * @param l The actionListener + */ + public void addActionListenerToQuitButton(ActionListener l) { + quitGame.addActionListener(l); + } + + /** + * Returns the quit button + * @return quitGame The button for ending the game + */ + public JButton getQuitButton() { + return quitGame; + } + + /** + * Returns the players name + * @return The name of the player in the JTextField playersName + */ + public String getPlayersName() { + return playersName.getText(); + } + + /** + * Shows an error in the menu + * @param message The String to be shown + */ + public void showError(String message) { + error.setText(message); + } + + /** + * Removes error message from the screen + */ + public void hideError() { + error.setText(""); + } + +} diff --git a/src/break_out/view/View.java b/src/break_out/view/View.java new file mode 100644 index 0000000..5def037 --- /dev/null +++ b/src/break_out/view/View.java @@ -0,0 +1,127 @@ +package break_out.view; + +import java.awt.CardLayout; + +import javax.swing.JFrame; + +import break_out.Constants; +import break_out.model.Game; + +/** + * The view class manages the depiction of the components inside the JFrames. It + * gets the components from the game which is connected to this class + * + * @author dmlux + * + */ +public class View extends JFrame { + + /** + * Automatic generated serial version UID + */ + private static final long serialVersionUID = -1850986636132660133L; + + /** + * THe layout + */ + private CardLayout cardLayout; + + /** + * The connected game + */ + private Game game; + + /** + * The start screen of this application + */ + private StartScreen startScreen; + + /** + * The playground + */ + private Field field; + + + /** + * The constructor of the view + */ + public View() { + super(Constants.APP_TITLE); + + // sets the default close operation + setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); //DISPOSE_ON_CLOSE); + + // adds a layout to the view + cardLayout = new CardLayout(); + getContentPane().setLayout(cardLayout); + + // adding screens to the view + startScreen = new StartScreen(this); + field = new Field(this); + + getContentPane().add(startScreen, StartScreen.class.getName()); + getContentPane().add(field, Field.class.getName()); + + // show start screen first + cardLayout.show(getContentPane(), StartScreen.class.getName()); + + // set the start position of the frame + setLocationRelativeTo(null); + setResizable(false); + setVisible(true); + pack(); + } + + /** + * Getter for the start screen + * @return startScreen + */ + public StartScreen getStartScreen() { + return startScreen; + } + + /** + * Getter for the playground + * @return field + */ + public Field getField() { + return field; + } + + /** + * Getter for the game + * @return game + */ + public Game getGame() { + return game; + } + + /** + * Setter for the game + * @param game The current game + */ + public void setGame(Game game) { + // set the game as model + this.game = game; + game.addObserver(this); + } + + /** + * Shows a given screen if the card layout contains this screen + * @param screenName The screen to be shown + */ + public void showScreen(String screenName) { + cardLayout.show(getContentPane(), screenName); + } + + /** + * Called by game.notifyObservers() in the run()-method of Level class + * to repaint the playground + * @param game The game to observe + */ + public void modelChanged(Game game) { + this.game = game; + // Calls the method paintComponents() in the Field class + field.repaint(); + } +}