├── .gitattributes ├── .gitignore ├── Ex0011_Game.iml ├── README.md ├── bricks.iml ├── build.xml ├── manifest.mf ├── pom.xml └── src └── main ├── java └── main │ └── game │ ├── components │ ├── Ball.java │ ├── Brick.java │ ├── GameComponents.java │ ├── Level.java │ └── Paddle.java │ ├── dialogs │ └── HighscoreDialog.java │ ├── main │ ├── AudioPlayer.java │ ├── Canvas.java │ ├── Game.java │ ├── GameLauncher.java │ └── Main.java │ ├── savedata │ ├── HighscoreLoader.java │ ├── LevelLoader.java │ └── ProgressLoader.java │ └── utils │ ├── Dimensions.java │ └── Files.java └── resources └── META-INF └── MANIFEST.MF /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.level 2 | *.levels 3 | *.highscores 4 | *.sav 5 | *.save 6 | 7 | /build 8 | /dist 9 | /nbproject 10 | /target 11 | 12 | *.wav 13 | *.jar 14 | 15 | .idea 16 | /.idea 17 | 18 | target 19 | /target 20 | 21 | # Compiled class file 22 | *.class 23 | 24 | # Log file 25 | *.log 26 | 27 | # BlueJ files 28 | *.ctxt 29 | 30 | # Mobile Tools for Java (J2ME) 31 | .mtj.tmp/ 32 | 33 | # Package Files # 34 | *.jar 35 | *.war 36 | *.nar 37 | *.ear 38 | *.zip 39 | *.tar.gz 40 | *.rar 41 | 42 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml 43 | hs_err_pid* 44 | -------------------------------------------------------------------------------- /Ex0011_Game.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Java Bricks 2 | A bricks game written in Java for school. 3 | 4 | ## How to run 5 | - Download the source code and run the `Main` file in your prefered IDE 6 | - Add a file called `music.wav` into the `resources` package to add music to your game 7 | -------------------------------------------------------------------------------- /bricks.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /build.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | Builds, tests, and runs the project Ex0011_Game. 12 | 13 | 73 | 74 | -------------------------------------------------------------------------------- /manifest.mf: -------------------------------------------------------------------------------- 1 | Manifest-Version: 1.0 2 | X-COMMENT: Main-Class will be added automatically by build 3 | 4 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | at.guelly 7 | bricks 8 | 1.0-SNAPSHOT 9 | jar 10 | 11 | 12 | 13 | 14 | 15 | org.apache.maven.plugins 16 | maven-compiler-plugin 17 | 18 | 11 19 | 11 20 | 21 | 22 | 23 | org.apache.maven.plugins 24 | maven-jar-plugin 25 | 26 | 27 | 28 | true 29 | libs/ 30 | 31 | main.game.main.Main 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | central 42 | Central Repository 43 | http://central.maven.org/maven2 44 | 45 | 46 | 47 | 1.11 48 | 1.11 49 | 50 | -------------------------------------------------------------------------------- /src/main/java/main/game/components/Ball.java: -------------------------------------------------------------------------------- 1 | package main.game.components; 2 | 3 | public class Ball { 4 | 5 | private double x, y, radius, deltax, deltay; 6 | 7 | public Ball(double radius, double x, double y, double deltax, double deltay) { 8 | this.radius = radius; 9 | this.x = x; 10 | this.y = y; 11 | this.deltax = deltax; 12 | this.deltay = deltay; 13 | } 14 | 15 | public double getX() { 16 | return x; 17 | } 18 | 19 | public void setX(double x) { 20 | this.x = x; 21 | } 22 | 23 | public double getY() { 24 | return y; 25 | } 26 | 27 | public void setY(double y) { 28 | this.y = y; 29 | } 30 | 31 | public double getRadius() { 32 | return radius; 33 | } 34 | 35 | public void setRadius(double radius) { 36 | this.radius = radius; 37 | } 38 | 39 | public double getDeltax() { 40 | return deltax; 41 | } 42 | 43 | public void setDeltax(double deltax) { 44 | this.deltax = deltax; 45 | } 46 | 47 | public double getDeltay() { 48 | return deltay; 49 | } 50 | 51 | public void setDeltay(double deltay) { 52 | this.deltay = deltay; 53 | } 54 | } -------------------------------------------------------------------------------- /src/main/java/main/game/components/Brick.java: -------------------------------------------------------------------------------- 1 | package main.game.components; 2 | 3 | import java.io.Serializable; 4 | 5 | public class Brick implements Serializable { 6 | 7 | private int width, height, x, y, health; 8 | 9 | public Brick(int width, int height, int x, int y, int health) { 10 | this.width = width; 11 | this.height = height; 12 | this.x = x; 13 | this.y = y; 14 | this.health = health; 15 | } 16 | 17 | public int getWidth() { 18 | return width; 19 | } 20 | 21 | public void setWidth(int width) { 22 | this.width = width; 23 | } 24 | 25 | public int getHeight() { 26 | return height; 27 | } 28 | 29 | public void setHeight(int height) { 30 | this.height = height; 31 | } 32 | 33 | public int getX() { 34 | return x; 35 | } 36 | 37 | public void setX(int x) { 38 | this.x = x; 39 | } 40 | 41 | public int getY() { 42 | return y; 43 | } 44 | 45 | public void setY(int y) { 46 | this.y = y; 47 | } 48 | 49 | public int getHealth() { 50 | return health; 51 | } 52 | 53 | public void setHealth(int health) { 54 | this.health = health; 55 | } 56 | } -------------------------------------------------------------------------------- /src/main/java/main/game/components/GameComponents.java: -------------------------------------------------------------------------------- 1 | package main.game.components; 2 | 3 | import main.game.utils.Dimensions; 4 | 5 | public interface GameComponents { 6 | Ball ball = new Ball((int) Dimensions.BALL_RADIUS, (int) Dimensions.BALL_X, (int) Dimensions.BALL_Y, (int) Dimensions.BALL_DELTAX, (int) Dimensions.BALL_DELTAY); 7 | Paddle paddle = new Paddle((int) Dimensions.PADDLE_WIDTH, (int) Dimensions.PADDLE_HEIGHT, (int) Dimensions.PADDLE_X, (int) Dimensions.PADDLE_Y, (int) Dimensions.PADDLE_DELTA); 8 | 9 | void reset(); 10 | } -------------------------------------------------------------------------------- /src/main/java/main/game/components/Level.java: -------------------------------------------------------------------------------- 1 | package main.game.components; 2 | 3 | import java.io.Serializable; 4 | import java.util.ArrayList; 5 | 6 | public class Level implements Serializable { 7 | 8 | private int level, speed; 9 | private ArrayList bricks; 10 | 11 | public Level(int level, int speed, ArrayList bricks) { 12 | this.level = level; 13 | this.speed = speed; 14 | this.bricks = bricks; 15 | } 16 | 17 | public int getLevel() { 18 | return level; 19 | } 20 | 21 | public int getSpeed() { 22 | return speed; 23 | } 24 | 25 | public ArrayList getBricks() { 26 | return bricks; 27 | } 28 | } -------------------------------------------------------------------------------- /src/main/java/main/game/components/Paddle.java: -------------------------------------------------------------------------------- 1 | package main.game.components; 2 | 3 | public class Paddle { 4 | 5 | private int width, height, x, y, delta; 6 | 7 | public Paddle(int width, int height, int x, int y, int delta) { 8 | this.width = width; 9 | this.height = height; 10 | this.x = x; 11 | this.y = y; 12 | this.delta = delta; 13 | } 14 | 15 | public int getWidth() { 16 | return width; 17 | } 18 | 19 | public void setWidth(int width) { 20 | this.width = width; 21 | } 22 | 23 | public int getHeight() { 24 | return height; 25 | } 26 | 27 | public void setHeight(int height) { 28 | this.height = height; 29 | } 30 | 31 | public int getX() { 32 | return x; 33 | } 34 | 35 | public void setX(int x) { 36 | this.x = x; 37 | } 38 | 39 | public int getY() { 40 | return y; 41 | } 42 | 43 | public void setY(int y) { 44 | this.y = y; 45 | } 46 | 47 | public int getDelta() { 48 | return delta; 49 | } 50 | 51 | public void setDelta(int delta) { 52 | this.delta = delta; 53 | } 54 | } -------------------------------------------------------------------------------- /src/main/java/main/game/dialogs/HighscoreDialog.java: -------------------------------------------------------------------------------- 1 | package main.game.dialogs; 2 | 3 | import main.game.savedata.HighscoreLoader; 4 | 5 | import javax.swing.*; 6 | import java.awt.event.ActionEvent; 7 | import java.awt.event.ActionListener; 8 | import java.util.Comparator; 9 | import java.util.HashMap; 10 | import java.util.LinkedHashMap; 11 | import java.util.Map; 12 | import java.util.stream.Collectors; 13 | 14 | public class HighscoreDialog extends JDialog implements ActionListener { 15 | 16 | public JFrame parent; 17 | 18 | public HighscoreDialog(JFrame parent) { 19 | this.parent = parent; 20 | } 21 | 22 | public LinkedHashMap sortHighscores(HashMap higscores) { 23 | LinkedHashMap sortedMap = new LinkedHashMap<>(); 24 | higscores.entrySet() 25 | .stream() 26 | .sorted(Map.Entry.comparingByValue(Comparator.reverseOrder())) 27 | .forEachOrdered(x -> sortedMap.put(x.getKey(), x.getValue())); 28 | return sortedMap; 29 | } 30 | 31 | @Override 32 | public void actionPerformed(ActionEvent e) { 33 | StringBuilder sb = new StringBuilder(); 34 | try { 35 | LinkedHashMap highscores = sortHighscores(HighscoreLoader.getScores()); 36 | if(highscores.size() < 1) throw new Exception("No Scores Existing"); 37 | sb.append(""); 38 | sb.append(""); 39 | int count = 0; 40 | for(Map.Entry entry : highscores.entrySet()) { 41 | count++; 42 | sb.append(""); 43 | sb.append(""); 44 | sb.append(""); 45 | sb.append(""); 46 | if(count == 10) break; 47 | } 48 | sb.append("
NameScore
" + entry.getKey() + "" + entry.getValue() + "
"); 49 | JOptionPane.showMessageDialog(this, sb.toString(), "Deine Top Scores", JOptionPane.INFORMATION_MESSAGE); 50 | } catch (Exception ex) { 51 | JOptionPane.showMessageDialog(this, "Ganz schön leer hier...", "Deine Top Scores", JOptionPane.INFORMATION_MESSAGE); 52 | } 53 | } 54 | } -------------------------------------------------------------------------------- /src/main/java/main/game/main/AudioPlayer.java: -------------------------------------------------------------------------------- 1 | package main.game.main; 2 | 3 | import javax.sound.sampled.AudioInputStream; 4 | import javax.sound.sampled.AudioSystem; 5 | import javax.sound.sampled.Clip; 6 | import javax.swing.*; 7 | import java.awt.event.ActionEvent; 8 | import java.awt.event.ActionListener; 9 | import java.io.File; 10 | 11 | public class AudioPlayer implements ActionListener { 12 | 13 | private Clip clip; 14 | private AudioInputStream input; 15 | 16 | private static boolean SOUND; 17 | 18 | public AudioPlayer(boolean sound) { 19 | AudioPlayer.SOUND = sound; 20 | } 21 | 22 | public AudioPlayer() { 23 | try { 24 | if(AudioPlayer.SOUND) { 25 | //Loading file from resources package 26 | File file = new File(getClass().getClassLoader().getResource("music.wav").getPath()); 27 | input = AudioSystem.getAudioInputStream(file); 28 | clip = AudioSystem.getClip(); 29 | clip.open(input); 30 | clip.loop(Clip.LOOP_CONTINUOUSLY); 31 | } 32 | } catch (Exception e) { 33 | e.printStackTrace(); 34 | } 35 | } 36 | 37 | public void play() { 38 | try { 39 | if(AudioPlayer.SOUND) clip.start(); 40 | } catch (Exception e) { 41 | e.printStackTrace(); 42 | } 43 | } 44 | 45 | public void stop() { 46 | try { 47 | if(AudioPlayer.SOUND) { 48 | clip.stop(); 49 | clip.close(); 50 | } 51 | } catch (Exception e) { 52 | e.printStackTrace(); 53 | } 54 | } 55 | 56 | @Override 57 | public void actionPerformed(ActionEvent e) { 58 | JButton button = (JButton) e.getSource(); 59 | String text = button.getText(); 60 | if(text.equals("Sound ON")) { 61 | AudioPlayer.SOUND = false; 62 | button.setText("Sound OFF"); 63 | } else { 64 | AudioPlayer.SOUND = true; 65 | button.setText("Sound ON"); 66 | } 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /src/main/java/main/game/main/Canvas.java: -------------------------------------------------------------------------------- 1 | package main.game.main; 2 | 3 | import main.game.components.*; 4 | 5 | import javax.swing.*; 6 | import java.awt.*; 7 | import java.awt.geom.Ellipse2D; 8 | import java.awt.geom.Rectangle2D; 9 | import java.util.ArrayList; 10 | 11 | class Canvas extends JPanel { 12 | 13 | private Ball ball; 14 | private Paddle paddle; 15 | private int score, remaining; 16 | private ArrayList bricks; 17 | 18 | public void reload(Ball ball, Paddle paddle, ArrayList bricks) { 19 | this.ball = ball; 20 | this.paddle = paddle; 21 | this.bricks = bricks; 22 | this.repaint(); 23 | } 24 | 25 | public void setScore(int score) { 26 | this.score = score; 27 | } 28 | 29 | public void setRemaining(int remaining) { 30 | this.remaining = remaining; 31 | } 32 | 33 | @Override 34 | public void paintComponent(Graphics g) { 35 | if(this.ball != null && this.paddle != null) { 36 | super.paintComponent(g); 37 | Graphics2D g2d = (Graphics2D) g; 38 | 39 | //Background color 40 | g2d.setColor(Color.DARK_GRAY); 41 | g2d.fillRect(0, 0, getWidth(), getHeight()); 42 | 43 | //Ball 44 | g2d.setColor(Color.RED); 45 | Ellipse2D.Double ball = new Ellipse2D.Double(this.ball.getX(), this.ball.getY(), 2 * this.ball.getRadius(), 2 * this.ball.getRadius()); 46 | g2d.fill(ball); 47 | 48 | paddle.setY(getHeight() - paddle.getHeight() * 2); 49 | 50 | //Paddle 51 | g2d.setColor(Color.CYAN); 52 | Rectangle2D.Double paddle = new Rectangle2D.Double(this.paddle.getX(), this.paddle.getY(), this.paddle.getWidth(), this.paddle.getHeight()); 53 | g2d.fill(paddle); 54 | 55 | //All bricks 56 | for(Brick b : this.bricks) { 57 | int health = b.getHealth(); 58 | if(health == 1) g2d.setColor(Color.GREEN); 59 | else if(health == 2) g2d.setColor(Color.YELLOW); 60 | else g2d.setColor(Color.ORANGE); 61 | Rectangle2D.Double brick = new Rectangle2D.Double(b.getX(), b.getY(), b.getWidth(), b.getHeight()); 62 | g2d.fill(brick); 63 | } 64 | 65 | Font font = new Font("Arial", Font.PLAIN, 20); 66 | g2d.setFont(font); 67 | g2d.setColor(Color.WHITE); 68 | 69 | if(this.score >= 0) { 70 | g2d.drawString("Score: " + this.score, 4, 22); 71 | } 72 | if(this.remaining >= 0) { 73 | g2d.drawString("Remaining: " + this.remaining, getWidth() - 130, 22); 74 | } 75 | } 76 | } 77 | } -------------------------------------------------------------------------------- /src/main/java/main/game/main/Game.java: -------------------------------------------------------------------------------- 1 | package main.game.main; 2 | 3 | import main.game.components.*; 4 | import main.game.savedata.HighscoreLoader; 5 | import main.game.savedata.LevelLoader; 6 | import main.game.savedata.ProgressLoader; 7 | import main.game.utils.Dimensions; 8 | 9 | import javax.swing.*; 10 | import java.awt.event.KeyEvent; 11 | import java.awt.event.KeyListener; 12 | import java.time.LocalDateTime; 13 | import java.time.format.DateTimeFormatter; 14 | import java.util.ArrayList; 15 | 16 | public class Game implements GameComponents, KeyListener { 17 | 18 | private ArrayList levels; 19 | private ArrayList bricks; 20 | 21 | private AudioPlayer audioPlayer; 22 | 23 | private int level, speed, score; 24 | private boolean gameover; 25 | 26 | private Canvas canvas; 27 | 28 | public Game(int level) { 29 | this.levels = LevelLoader.generateDefaultLevels(); 30 | this.level = level; 31 | this.gameover = false; 32 | this.audioPlayer = new AudioPlayer(); 33 | this.speed = levels.get(level - 1).getSpeed(); 34 | this.bricks = levels.get(level - 1).getBricks(); 35 | this.score = 0; 36 | GameLauncher.setStatusMessage("Du spielst gerade Level " + level + "!"); 37 | } 38 | 39 | public int getSpeed() { 40 | return speed; 41 | } 42 | 43 | public boolean isGameover() { 44 | return gameover; 45 | } 46 | 47 | public void run() { 48 | JFrame frame = new JFrame(); 49 | frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); 50 | frame.setSize(550, 600); 51 | frame.setTitle("Bricks Level " + level); 52 | frame.addKeyListener(this); 53 | frame.setResizable(false); 54 | 55 | audioPlayer.play(); 56 | 57 | paddle.setX(frame.getWidth() / 2 - paddle.getWidth() / 2); 58 | ball.setX(frame.getWidth() / 2 + ball.getRadius() / 2); 59 | ball.setY(frame.getHeight() - paddle.getY() + 75 + 2*ball.getRadius()); 60 | 61 | frame.addWindowListener(new java.awt.event.WindowAdapter() { 62 | @Override 63 | public void windowClosing(java.awt.event.WindowEvent windowEvent) { 64 | close(frame, "Das Spiel wurde geschlossen!"); 65 | } 66 | }); 67 | 68 | canvas = new Canvas(); 69 | frame.getContentPane().add(canvas); 70 | 71 | frame.setVisible(true); 72 | 73 | while(true) { 74 | if(!frame.isVisible()) { 75 | //close(frame, "Das Spiel wurde geschlossen!"); 76 | break; 77 | } 78 | ball.setX(ball.getX() + ball.getDeltax()); 79 | ball.setY(ball.getY() + ball.getDeltay()); 80 | 81 | canvas.reload(ball, paddle, this.bricks); 82 | canvas.setScore(this.score); 83 | canvas.setRemaining(bricks.size()); 84 | 85 | //Player has failed, ball is behind paddle 86 | if((ball.getY() + 2 * ball.getRadius()) > canvas.getHeight()) { 87 | gameover = true; 88 | close(frame, "Du hast Level " + level + " verloren! Punke: " + score); 89 | break; 90 | } 91 | 92 | //Ball collides with walls, reversing directions 93 | if(ball.getY() < 0) ball.setDeltay(-ball.getDeltay()); 94 | if((ball.getX() + 2 * ball.getRadius()) > canvas.getWidth()) ball.setDeltax(-ball.getDeltax()); 95 | if(ball.getX() < 0) ball.setDeltax(-ball.getDeltax()); 96 | 97 | //Ball collides with paddle 98 | if((((ball.getY() + 2 * ball.getRadius()) >= paddle.getY()) && ((ball.getY() + 2 * ball.getRadius() <= paddle.getY() + ball.getDeltay()))) && ((ball.getX() + 2 * ball.getRadius() > paddle.getX()) && (ball.getX() < paddle.getX() + paddle.getWidth()))) { 99 | ball.setDeltay(-ball.getDeltay()); 100 | this.score = this.score + 100; 101 | } 102 | ArrayList toRemove = new ArrayList<>(); 103 | boolean hasHit = false; 104 | for(Brick b : this.bricks) { 105 | //Ball hits paddle 106 | if((ball.getX() + 2 * ball.getRadius() >= b.getX() && ball.getX() <= b.getX() + b.getWidth()) && (ball.getY() <= b.getY() + b.getHeight() && ball.getY() + 2 * ball.getRadius() >= b.getY())) { 107 | hasHit = true; 108 | this.score = this.score + 1000; 109 | toRemove.add(b); 110 | } 111 | } 112 | //To avoid changing the directory twice (not) if hit two 113 | if(hasHit) { 114 | ball.setDeltay(-ball.getDeltay()); 115 | } 116 | for(Brick b : toRemove) { 117 | b.setHealth(b.getHealth() - 1); 118 | if(b.getHealth() <= 0) this.bricks.remove(b); 119 | if(this.bricks.size() == 0) { 120 | int playerLevel = 0; 121 | try { 122 | playerLevel = ProgressLoader.loadLevel(); 123 | } catch (Exception ignored) { 124 | } 125 | if(level > playerLevel) { 126 | try { 127 | ProgressLoader.saveLevel(playerLevel + 1); 128 | } catch (Exception ignored) { 129 | } 130 | } 131 | gameover = true; 132 | close(frame, "Du hast Level " + level + " bestanden! Punke: " + score + ((level > playerLevel) ? "
Erfolg: Du hast Level " + (level + 1) + " freigeschalten!": "") + ""); 133 | break; 134 | } 135 | } 136 | try { 137 | Thread.sleep(this.speed); 138 | } catch (InterruptedException e) { 139 | e.printStackTrace(); 140 | } 141 | } 142 | } 143 | 144 | @Override 145 | public void keyTyped(KeyEvent e) { 146 | } 147 | 148 | @Override 149 | public void keyPressed(KeyEvent e) { 150 | if(e.getKeyCode()==KeyEvent.VK_RIGHT){ 151 | if(paddle.getX() + paddle.getWidth() + 10 >= canvas.getWidth()) return; 152 | paddle.setX(paddle.getX() + paddle.getDelta()); 153 | } 154 | if(e.getKeyCode()==KeyEvent.VK_LEFT){ 155 | if(paddle.getX() <= 10) return; 156 | paddle.setX(paddle.getX() - paddle.getDelta()); 157 | } 158 | } 159 | 160 | public void close(JFrame frame, String message) { 161 | audioPlayer.stop(); 162 | GameLauncher.setActive(false); 163 | GameLauncher.setStatusMessage(message); 164 | GameLauncher.reloadLevels(); 165 | try { 166 | if(gameover) { 167 | String name = JOptionPane.showInputDialog(frame, "Speichere deinen Highscore!", "Dein Name"); 168 | if(name != null && name.length() > 1 && name.length() < 30) { 169 | HighscoreLoader.saveHighscore(name, this.score); 170 | } 171 | } 172 | } catch (Exception ignored) { 173 | } 174 | reset(); 175 | frame.dispose(); 176 | } 177 | 178 | @Override 179 | public void keyReleased(KeyEvent e) { 180 | } 181 | 182 | @Override 183 | public void reset() { 184 | ball.setX(Dimensions.BALL_X); 185 | ball.setY(Dimensions.BALL_Y); 186 | ball.setDeltax(Dimensions.BALL_DELTAX); 187 | ball.setDeltay(Dimensions.BALL_DELTAY); 188 | paddle.setX(Dimensions.PADDLE_X); 189 | paddle.setY(Dimensions.PADDLE_Y); 190 | } 191 | } -------------------------------------------------------------------------------- /src/main/java/main/game/main/GameLauncher.java: -------------------------------------------------------------------------------- 1 | package main.game.main; 2 | 3 | import main.game.dialogs.HighscoreDialog; 4 | import main.game.savedata.LevelLoader; 5 | import main.game.savedata.ProgressLoader; 6 | 7 | import javax.swing.*; 8 | import java.awt.*; 9 | import java.awt.event.ActionEvent; 10 | import java.awt.event.ActionListener; 11 | 12 | public class GameLauncher implements ActionListener { 13 | 14 | private volatile JFrame frame; 15 | private volatile JLabel status; 16 | private JPanel buttons; 17 | private JPanel options; 18 | private JButton sound; 19 | private JButton highscores; 20 | private boolean active = false; 21 | public static GameLauncher LAUNCHER; 22 | 23 | public GameLauncher() { 24 | frame = new JFrame("Bricks Launcher"); 25 | frame.setSize(300, 250); 26 | frame.setLocation(500, 500); 27 | frame.setResizable(false); 28 | frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 29 | frame.setVisible(true); 30 | GridLayout layout = new GridLayout(); 31 | layout.setColumns(1); 32 | layout.setRows(3); 33 | frame.setLayout(layout); 34 | status = new JLabel("Willkommen bei Bricks!
Bitte wähle einen Level aus!"); 35 | frame.add(status); 36 | buttons = new JPanel(); 37 | buttons.setLayout(new FlowLayout()); 38 | frame.add(buttons); 39 | options = new JPanel(); 40 | options.setLayout(new FlowLayout()); 41 | frame.add(options); 42 | status.setHorizontalAlignment(JTextField.CENTER); 43 | sound = new JButton("Sound ON"); 44 | sound.addActionListener(new AudioPlayer(true)); 45 | options.add(sound); 46 | highscores = new JButton("Show Highscores"); 47 | highscores.addActionListener(new HighscoreDialog(frame)); 48 | options.add(highscores); 49 | LAUNCHER = this; 50 | } 51 | 52 | public void run() { 53 | buttons.removeAll(); 54 | int playerLevel = 0; 55 | try { 56 | playerLevel = ProgressLoader.loadLevel(); 57 | } catch (Exception ignored) { 58 | } 59 | for(int i = 1; i <= Math.min(LevelLoader.generateDefaultLevels().size(), playerLevel + 1); i++) { 60 | JButton button = new JButton("Level " + i); 61 | buttons.add(button); 62 | button.addActionListener(this); 63 | button.addActionListener(e -> { 64 | //frame.dispose(); 65 | if(!this.active) { 66 | new Thread(() -> { 67 | String buttonText = ((JButton) e.getSource()).getText(); 68 | int level = Integer.parseInt(buttonText.substring(buttonText.length() - 1)); 69 | this.status.setText("Spiel lädt..."); 70 | Game game = new Game(level); 71 | game.run(); 72 | }).start(); 73 | } 74 | }); 75 | } 76 | buttons.revalidate(); 77 | buttons.repaint(); 78 | frame.revalidate(); 79 | frame.repaint(); 80 | } 81 | 82 | public static void setStatusMessage(String message) { 83 | LAUNCHER.status.setText(message); 84 | } 85 | 86 | public static void setActive(boolean active) { 87 | LAUNCHER.active = active; 88 | } 89 | 90 | public static void reloadLevels() { 91 | LAUNCHER.run(); 92 | } 93 | 94 | @Override 95 | public void actionPerformed(ActionEvent e) { 96 | if (this.active) { 97 | this.status.setText("Es läuft bereits ein Spiel!"); 98 | } else { 99 | String button = ((JButton) e.getSource()).getText(); 100 | try { 101 | int level = Integer.parseInt(button.substring(button.length() - 1)); 102 | this.status.setText("Du spielst gerade Level " + level + "!"); 103 | this.active = true; 104 | } catch(Exception ignored) { 105 | } 106 | } 107 | } 108 | } -------------------------------------------------------------------------------- /src/main/java/main/game/main/Main.java: -------------------------------------------------------------------------------- 1 | package main.game.main; 2 | 3 | public class Main { 4 | 5 | public static void main(String[] args) { 6 | GameLauncher launcher = new GameLauncher(); 7 | launcher.run(); 8 | } 9 | } -------------------------------------------------------------------------------- /src/main/java/main/game/savedata/HighscoreLoader.java: -------------------------------------------------------------------------------- 1 | package main.game.savedata; 2 | 3 | import main.game.utils.Files; 4 | 5 | import java.io.*; 6 | import java.util.HashMap; 7 | 8 | public class HighscoreLoader { 9 | 10 | public static HashMap scores; 11 | 12 | static { 13 | try { 14 | scores = loadHighscores(); 15 | } catch (Exception e) { 16 | scores = new HashMap<>(); 17 | } 18 | } 19 | 20 | public static void saveHighscore(String name, int score) throws Exception { 21 | ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(Files.HIGHSCORE_FILE)); 22 | if(scores.size() < 1) scores = new HashMap<>(); 23 | if(scores.containsKey(name)) { 24 | if(scores.get(name) < score) { 25 | scores.put(name, score); 26 | oos.writeObject(scores); 27 | } 28 | } 29 | oos.flush(); 30 | oos.close(); 31 | } 32 | 33 | public static HashMap loadHighscores() throws Exception { 34 | ObjectInputStream ois = new ObjectInputStream(new FileInputStream(Files.HIGHSCORE_FILE)); 35 | Object scores = ois.readObject(); 36 | ois.close(); 37 | return (HashMap) scores; 38 | } 39 | 40 | public static HashMap getScores() { 41 | return HighscoreLoader.scores; 42 | } 43 | } -------------------------------------------------------------------------------- /src/main/java/main/game/savedata/LevelLoader.java: -------------------------------------------------------------------------------- 1 | package main.game.savedata; 2 | 3 | import main.game.components.Brick; 4 | import main.game.components.Level; 5 | import main.game.utils.Files; 6 | 7 | import java.io.*; 8 | import java.util.ArrayList; 9 | import java.util.Random; 10 | 11 | public class LevelLoader { 12 | 13 | public static ArrayList generateDefaultLevels() { 14 | ArrayList levels = new ArrayList<>(); 15 | Random random = new Random(); 16 | int dx = 110, dy = 30; 17 | for(int level = 0; level < 6; level++) { 18 | ArrayList bricks = new ArrayList<>(); 19 | for(int row = 1; row < level + 8; row++) { 20 | for(int col = 0; col < 5; col++) { 21 | if(random.nextInt(10) > row || row < level + 1) { 22 | if(!((col == 0 || col == 4) && row < 2)) { 23 | int maxHealth = 3; 24 | if(level < 3) maxHealth = 2; 25 | if(level == 0) maxHealth = 1; 26 | bricks.add(new Brick(100, 20, dx * col, dy * row, 1 + (int) (Math.random() * maxHealth))); 27 | } 28 | } 29 | } 30 | } 31 | levels.add(new Level(level + 1, 9 - (level + 1), bricks)); 32 | } 33 | return levels; 34 | } 35 | } -------------------------------------------------------------------------------- /src/main/java/main/game/savedata/ProgressLoader.java: -------------------------------------------------------------------------------- 1 | package main.game.savedata; 2 | 3 | import main.game.utils.Files; 4 | 5 | import java.io.FileInputStream; 6 | import java.io.FileOutputStream; 7 | import java.io.ObjectInputStream; 8 | import java.io.ObjectOutputStream; 9 | 10 | public class ProgressLoader { 11 | 12 | public static void saveLevel(int level) throws Exception { 13 | ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(Files.PROGRESS_FILE)); 14 | oos.writeObject(level); 15 | oos.flush(); 16 | oos.close(); 17 | } 18 | 19 | public static int loadLevel() throws Exception { 20 | ObjectInputStream ois = new ObjectInputStream(new FileInputStream(Files.PROGRESS_FILE)); 21 | int level = (int) ois.readObject(); 22 | ois.close(); 23 | return level; 24 | } 25 | } -------------------------------------------------------------------------------- /src/main/java/main/game/utils/Dimensions.java: -------------------------------------------------------------------------------- 1 | package main.game.utils; 2 | 3 | public class Dimensions { 4 | 5 | public static double BALL_X = 80, BALL_Y = 80; 6 | public static double BALL_RADIUS = 15; 7 | public static double BALL_DELTAX = 2, BALL_DELTAY = 2; 8 | 9 | public static int PADDLE_X = 110, PADDLE_Y = 240; 10 | public static int PADDLE_WIDTH = 130; 11 | public static int PADDLE_HEIGHT = 20; 12 | public static int PADDLE_DELTA = 50; 13 | } -------------------------------------------------------------------------------- /src/main/java/main/game/utils/Files.java: -------------------------------------------------------------------------------- 1 | package main.game.utils; 2 | 3 | public class Files { 4 | 5 | public final static String HIGHSCORE_FILE = "highscores.sav"; 6 | 7 | public final static String PROGRESS_FILE = "level.sav"; 8 | 9 | } 10 | -------------------------------------------------------------------------------- /src/main/resources/META-INF/MANIFEST.MF: -------------------------------------------------------------------------------- 1 | Manifest-Version: 1.0 2 | Main-Class: main.game.main.Main 3 | 4 | --------------------------------------------------------------------------------