董事会成员
package Final;
import java.awt.Color;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.RenderingHints;
import java.awt.Toolkit;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.util.Timer;
import java.util.TimerTask;
import javax.swing.JPanel;
public class Board extends JPanel implements Commons {
private Timer timer;
private String message = "Your Fired";
private Ball ball;
private Paddle paddle;
private Brick bricks[];
private boolean ingame = true;
public Board() {
initBoard();
}
private void initBoard() {
addKeyListener(new TAdapter());
setFocusable(true);
bricks = new Brick[N_OF_BRICKS];
setDoubleBuffered(true);
timer = new Timer();
timer.scheduleAtFixedRate(new ScheduleTask(), DELAY, PERIOD);
}
@Override
public void addNotify() {
super.addNotify();
gameInit();
}
private void gameInit() {
ball = new Ball();
paddle = new Paddle();
int k = 0;
for (int i = 0; i < 5; i++) {
for (int j = 0; j < 6; j++) {
bricks[k] = new Brick(j * 40 + 30, i * 10 + 50);
k++;
}
}
}
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setRenderingHint(RenderingHints.KEY_RENDERING,
RenderingHints.VALUE_RENDER_QUALITY);
if (ingame) {
drawObjects(g2d);
} else {
gameFinished(g2d);
}
Toolkit.getDefaultToolkit().sync();
}
private void drawObjects(Graphics2D g2d) {
g2d.drawImage(ball.getImage(), ball.getX(), ball.getY(),
ball.getWidth(), ball.getHeight(), this);
g2d.drawImage(paddle.getImage(), paddle.getX(), paddle.getY(),
paddle.getWidth(), paddle.getHeight(), this);
for (int i = 0; i < N_OF_BRICKS; i++) {
if (!bricks[i].isDestroyed()) {
g2d.drawImage(bricks[i].getImage(), bricks[i].getX(),
bricks[i].getY(), bricks[i].getWidth(),
bricks[i].getHeight(), this);
}
}
}
private void gameFinished(Graphics2D g2d) {
Font font = new Font("Verdana", Font.BOLD, 18);
FontMetrics metr = this.getFontMetrics(font);
g2d.setColor(Color.BLACK);
g2d.setFont(font);
g2d.drawString(message,
(Commons.WIDTH - metr.stringWidth(message)) / 2,
Commons.WIDTH / 2);
}
private class TAdapter extends KeyAdapter {
@Override
public void keyReleased(KeyEvent e) {
paddle.keyReleased(e);
}
@Override
public void keyPressed(KeyEvent e) {
paddle.keyPressed(e);
}
}
private class ScheduleTask extends TimerTask {
@Override
public void run() {
ball.move();
paddle.move();
checkCollision();
repaint();
}
}
private void stopGame() {
ingame = false;
timer.cancel();
}
private void checkCollision() {
if (ball.getRect().getMaxY() > Commons.BOTTOM_EDGE) {
stopGame();
}
for (int i = 0, j = 0; i < N_OF_BRICKS; i++) {
if (bricks[i].isDestroyed()) {
j++;
}
if (j == N_OF_BRICKS) {
message = "Pay Day";
stopGame();
}
}
if ((ball.getRect()).intersects(paddle.getRect())) {
int paddleLPos = (int) paddle.getRect().getMinX();
int ballLPos = (int) ball.getRect().getMinX();
int first = paddleLPos + 8;
int second = paddleLPos + 16;
int third = paddleLPos + 24;
int fourth = paddleLPos + 32;
if (ballLPos < first) {
ball.setXDir(-1);
ball.setYDir(-1);
}
if (ballLPos >= first && ballLPos < second) {
ball.setXDir(-1);
ball.setYDir(-1 * ball.getYDir());
}
if (ballLPos >= second && ballLPos < third) {
ball.setXDir(0);
ball.setYDir(-1);
}
if (ballLPos >= third && ballLPos < fourth) {
ball.setXDir(1);
ball.setYDir(-1 * ball.getYDir());
}
if (ballLPos > fourth) {
ball.setXDir(1);
ball.setYDir(-1);
}
}
for (int i = 0; i < N_OF_BRICKS; i++) {
if ((ball.getRect()).intersects(bricks[i].getRect())) {
int ballLeft = (int) ball.getRect().getMinX();
int ballHeight = (int) ball.getRect().getHeight();
int ballWidth = (int) ball.getRect().getWidth();
int ballTop = (int) ball.getRect().getMinY();
Point pointRight = new Point(ballLeft + ballWidth + 1, ballTop);
Point pointLeft = new Point(ballLeft - 1, ballTop);
Point pointTop = new Point(ballLeft, ballTop - 1);
Point pointBottom = new Point(ballLeft, ballTop + ballHeight + 1);
if (!bricks[i].isDestroyed()) {
if (bricks[i].getRect().contains(pointRight)) {
ball.setXDir(-1);
} else if (bricks[i].getRect().contains(pointLeft)) {
ball.setXDir(1);
}
if (bricks[i].getRect().contains(pointTop)) {
ball.setYDir(1);
} else if (bricks[i].getRect().contains(pointBottom)) {
ball.setYDir(-1);
}
bricks[i].setDestroyed(true);
}
}
}
}
}
砖类
package Final;
import javax.swing.ImageIcon;
public class Brick extends Sprite {
private boolean destroyed;
public Brick(int x, int y) {
ImageIcon ii = new ImageIcon("images/bricks.png");
image = ii.getImage();
i_width = image.getWidth(null);
i_heigth = image.getHeight(null);
destroyed = false;
}
public boolean isDestroyed() {
return destroyed;
}
public void setDestroyed(boolean val) {
destroyed = val;
}
}
Commons Class
package Final;
public interface Commons {
public static final int WIDTH = 300;
public static final int HEIGTH = 400;
public static final int BOTTOM_EDGE = 390;
public static final int N_OF_BRICKS = 30;
public static final int INIT_PADDLE_X = 200;
public static final int INIT_PADDLE_Y = 360;
public static final int INIT_BALL_X = 230;
public static final int INIT_BALL_Y = 355;
public static final int DELAY = 1000;
public static final int PERIOD = 10;
}
精灵等级
package Final;
import java.awt.Image;
import java.awt.Rectangle;
public class Sprite {
protected int x;
protected int y;
protected int i_width;
protected int i_heigth;
protected Image image;
public void setX(int x) {
this.x = x;
}
public int getX() {
return x;
}
public void setY(int y) {
this.y = y;
}
public int getY() {
return y;
}
public int getWidth() {
return i_width;
}
public int getHeight() {
return i_heigth;
}
Image getImage() {
return image;
}
Rectangle getRect() {
return new Rectangle(x, y,
image.getWidth(null), image.getHeight(null));
}
}
突破等级
package Final;
import java.awt.EventQueue;
import javax.swing.JFrame;
public class Breakout extends JFrame {
public Breakout() {
initUI();
}
private void initUI() {
add(new Board());
setTitle("Lord Carl's Demolition Job");
setDefaultCloseOperation(EXIT_ON_CLOSE);
setSize(Commons.WIDTH, Commons.HEIGTH);
setLocationRelativeTo(null);
setResizable(false);
setVisible(true);
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
Breakout game = new Breakout();
game.setVisible(true);
}
});
}
}
答案 0 :(得分:0)
问题出在checkCollision()
。在循环内部,由于循环条件,j
永远不会等于N_OF_BRICKS
。你可以改为:
private void checkCollision() {
if (ball.getRect().getMaxY() > Commons.BOTTOM_EDGE) {
stopGame();
}
int j = 0;
for (int i = 0; i < N_OF_BRICKS; i++) {
if (bricks[i].isDestroyed()) {
j++;
}
}
if (j == N_OF_BRICKS) {
message = "Pay Day";
stopGame();
}
}
此外,在Brick
课程中,您忽略了存储x,y坐标:
public class Brick extends Sprite {
....
public Brick(int x, int y) {
ImageIcon ii = new ImageIcon("images/bricks.png");
image = ii.getImage();
i_width = image.getWidth(null);
i_heigth = image.getHeight(null);
destroyed = false;
// Save these
this.x = x;
this.y = y
}
....
}
或者,向Sprite
类添加一个构造函数,并从Brick
构造函数中调用它:
public class Sprite {
....
public Sprite(int x, int y) {
this.x = x;
this.y = y;
}
....
}
public class Brick extends Sprite {
....
public Brick(int x, int y) {
// Call the sprite constructor
super(x, y);
ImageIcon ii = new ImageIcon("images/bricks.png");
image = ii.getImage();
i_width = image.getWidth(null);
i_heigth = image.getHeight(null);
destroyed = false;
}
....
}