├── .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("Name | Score |
");
39 | int count = 0;
40 | for(Map.Entry entry : highscores.entrySet()) {
41 | count++;
42 | sb.append("");
43 | sb.append("" + entry.getKey() + " | ");
44 | sb.append("" + entry.getValue() + " | ");
45 | sb.append("
");
46 | if(count == 10) break;
47 | }
48 | sb.append("
");
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 |
--------------------------------------------------------------------------------