package de.tutorials;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Rectangle;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.geom.Ellipse2D;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.WindowConstants;
public class BreakOutExample extends JFrame {
private static final int FIELD_WIDTH = 400;
private static final int FIELD_HEIGHT = 200;
private static final int BRICK_HEIGHT = 10;
private static final int BRICK_WIDTH = 30;
private static final int PLAYER_HEIGHT = 10;
private static final int PLAYER_WIDTH = 40;
private static final int BALL_SIZE = 10;
private static final int PLAYER_MARGIN = 20;
private int ballIncrementY = BALL_SIZE / -2;
private int ballIncrementX = 0;
private Rectangle field;
private List<Rectangle> bricks = new ArrayList<Rectangle>();
private Rectangle player;
private Ellipse2D.Double ball;
protected boolean windowClosed = false;
public BreakOutExample() {
super("Break Out");
this.setSize(FIELD_WIDTH + 50, FIELD_HEIGHT + 50);
this.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
init();
}
private void init() {
createField();
createWallBricks();
createPlayer();
createBall();
this.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent evt) {
BreakOutExample.this.windowClosed = true;
}
});
startGame();
}
private void startGame() {
Thread t = new Thread() {
@Override
public void run() {
while (windowIsOpen()) {
controller();
try {
TimeUnit.MILLISECONDS.sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
};
t.start();
}
protected boolean windowIsOpen() {
return !windowClosed;
}
private void createBall() {
ball = new Ellipse2D.Double(player.getCenterX() - BALL_SIZE, player
.getY()
- BALL_SIZE, BALL_SIZE, BALL_SIZE);
}
private void createPlayer() {
player = new Rectangle((int) field.getCenterX(), field.height
- PLAYER_MARGIN - PLAYER_HEIGHT, PLAYER_WIDTH, PLAYER_HEIGHT);
}
private void createField() {
field = new Rectangle(1, 1, FIELD_WIDTH, FIELD_HEIGHT);
JPanel main = new JPanel() {
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
paintField(g);
}
};
main.setBounds(field);
this.add(main);
}
private boolean isInField(Rectangle rect) {
return field.contains(rect);
}
public enum TouchLocation {
RIGHT, LEFT, TOP, BOTTOM, NONE;
}
private TouchLocation ballTouchesBrick(Rectangle rect) {
Rectangle biggerBall = new Rectangle((int) ball.x - 1,
(int) ball.y - 1, (int) ball.width + 2, (int) ball.height + 2);
if (biggerBall.intersects(rect)) {
return TouchLocation.TOP;
}
// return biggerBall.intersects(rect);
return TouchLocation.NONE;
}
private TouchLocation ballTouchesBricks() {
for (Rectangle brick : bricks) {
final TouchLocation location = ballTouchesBrick(brick);
if (location != TouchLocation.NONE) {
return location;
}
}
return TouchLocation.NONE;
}
private boolean ballBelowPlayer() {
return ball.getY() < player.getY();
}
private boolean ballTouchesPlayer() {
final boolean touchesY = player.getY() <= ((int) ball.getMaxY() + 1);
final boolean isInXRange = ball.getCenterX() >= player.getX()
&& ball.getCenterX() <= player.getMaxX();
return touchesY && isInXRange;
}
private void createWallBricks() {
final int maxCols = (field.width / BRICK_WIDTH) - 2;
final int maxRows = ((field.height / 2) / BRICK_HEIGHT) - 2;
for (int y = 0; y < maxRows; y++) {
for (int x = 0; x < maxCols; x++) {
bricks.add(new Rectangle(10 + BRICK_WIDTH * x, 10
+ BRICK_HEIGHT * y, BRICK_WIDTH, BRICK_HEIGHT));
}
}
}
protected void paintField(Graphics g) {
g.setColor(Color.RED);
g.drawRect(field.x, field.y, field.width, field.height);
for (Rectangle brick : bricks) {
g.fillRect(brick.x, brick.y, brick.width, brick.height);
}
g.setColor(Color.BLACK);
for (Rectangle brick : bricks) {
g.drawRect(brick.x, brick.y, brick.width, brick.height);
}
g.setColor(Color.BLUE);
g.fillRect(player.x, player.y, player.width, player.height);
g.setColor(Color.MAGENTA);
g.fillOval((int) ball.x, (int) ball.y, (int) ball.width,
(int) ball.height);
}
protected void controller() {
ball.y += ballIncrementY;
ball.x += ballIncrementX;
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
BreakOutExample.this.repaint();
}
});
final TouchLocation touchLocation = ballTouchesBricks();
if (touchLocation != TouchLocation.NONE) {
switch (touchLocation) {
case TOP:
ballIncrementY *= -1;
}
} else if (ballTouchesPlayer()) {
ballIncrementY *= -1;
}
}
public static void main(String[] args) {
BreakOutExample breakOut = new BreakOutExample();
breakOut.setVisible(true);
}
}