游戏规则
- 游戏目标:
使用一个球击打屏幕上方的砖块,使所有砖块都被破坏。在游戏中,玩家的目标是通过弹球来消除屏幕上的所有砖块。 - 控制方式:
玩家控制一个位于屏幕底部的挡板(paddle),通过左右移动挡板来接住从挡板弹起的球。 - 游戏玩法:
挡板: 挡板可以通过键盘上的左右箭头键进行移动,以便在球反弹回来时能够接住它。
球: 球在屏幕上移动并与砖块、挡板碰撞。球会反弹回来,并且会根据撞击角度改变方向。
砖块: 砖块分布在屏幕的上方,每次球与砖块碰撞时,砖块会被破坏并从屏幕上消失。 - 胜利条件:
当屏幕上的所有砖块被破坏时,游戏胜利。此时会弹出一个对话框显示游戏用时,并提供“再次游戏”或“退出游戏”的选项。 - 失败条件:
如果球落到屏幕底部,未被挡板接住,游戏失败。此时会弹出一个对话框显示游戏用时,并提供“再次游戏”或“退出游戏”的选项。 - 游戏控制:
使用键盘上的左右箭头键来移动挡板。挡板移动的速度固定,确保可以及时接住球。
通过这些规则,玩家可以体验到经典的打砖块游戏的乐趣。
代码
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.ArrayList;
import java.util.List;
public class BreakoutGame extends JPanel implements ActionListener, KeyListener {
private static final int WIDTH = 400;
private static final int HEIGHT = 300;
private static final int BRICK_WIDTH = 50;
private static final int BRICK_HEIGHT = 20;
private static final int PADDLE_WIDTH = 60;
private static final int PADDLE_HEIGHT = 10;
private static final int BALL_SIZE = 10;
private Timer timer;
private int paddleX;
private int ballX, ballY, ballXDir, ballYDir;
private List<Rectangle> bricks;
private boolean leftPressed, rightPressed;
private long startTime;
private boolean gameEnded;
public BreakoutGame() {
setPreferredSize(new Dimension(WIDTH, HEIGHT));
setBackground(Color.BLACK);
setFocusable(true);
addKeyListener(this);
startNewGame();
JFrame frame = (JFrame) SwingUtilities.getWindowAncestor(this);
if (frame != null) {
frame.setResizable(false);
}
}
private void startNewGame() {
paddleX = WIDTH / 2 - PADDLE_WIDTH / 2;
ballX = WIDTH / 2;
ballY = HEIGHT - PADDLE_HEIGHT - BALL_SIZE;
ballXDir = 1;
ballYDir = -1;
bricks = new ArrayList<>();
initializeBricks();
startTime = System.currentTimeMillis();
gameEnded = false;
timer = new Timer(5, this);
timer.start();
}
private void initializeBricks() {
for (int row = 0; row < 4; row++) {
for (int col = 0; col < WIDTH / BRICK_WIDTH; col++) {
bricks.add(new Rectangle(col * BRICK_WIDTH, row * BRICK_HEIGHT, BRICK_WIDTH, BRICK_HEIGHT));
}
}
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(Color.WHITE);
g.fillRect(paddleX, HEIGHT - PADDLE_HEIGHT, PADDLE_WIDTH, PADDLE_HEIGHT);
g.setColor(Color.RED);
g.fillOval(ballX, ballY, BALL_SIZE, BALL_SIZE);
g.setColor(Color.GREEN);
for (Rectangle brick : bricks) {
g.fillRect(brick.x, brick.y, brick.width, brick.height);
}
}
@Override
public void actionPerformed(ActionEvent e) {
if (!gameEnded) {
moveBall();
movePaddle();
checkCollisions();
if (bricks.isEmpty()) {
endGame(true);
} else if (ballY >= HEIGHT - BALL_SIZE) {
endGame(false);
}
repaint();
}
}
private void moveBall() {
ballX += ballXDir;
ballY += ballYDir;
if (ballX <= 0 || ballX >= WIDTH - BALL_SIZE) {
ballXDir = -ballXDir;
}
if (ballY <= 0) {
ballYDir = -ballYDir;
}
}
private void movePaddle() {
if (leftPressed && paddleX > 0) {
paddleX -= 2;
}
if (rightPressed && paddleX < WIDTH - PADDLE_WIDTH) {
paddleX += 2;
}
}
private void checkCollisions() {
Rectangle ballRect = new Rectangle(ballX, ballY, BALL_SIZE, BALL_SIZE);
Rectangle paddleRect = new Rectangle(paddleX, HEIGHT - PADDLE_HEIGHT, PADDLE_WIDTH, PADDLE_HEIGHT);
if (ballRect.intersects(paddleRect)) {
ballYDir = -ballYDir;
}
for (int i = 0; i < bricks.size(); i++) {
Rectangle brick = bricks.get(i);
if (ballRect.intersects(brick)) {
bricks.remove(i);
ballYDir = -ballYDir;
break;
}
}
}
private void endGame(boolean win) {
timer.stop();
gameEnded = true;
long elapsedTime = System.currentTimeMillis() - startTime;
int seconds = (int) (elapsedTime / 1000);
int minutes = seconds / 60;
seconds = seconds % 60;
String message = win ?
String.format("恭喜!您用时 %d 分钟 %d 秒完成了游戏。\n是否再次游戏?", minutes, seconds) :
String.format("游戏失败!您用时 %d 分钟 %d 秒。\n是否再次游戏?", minutes, seconds);
int option = JOptionPane.showOptionDialog(this, message, "游戏结束",
JOptionPane.YES_NO_OPTION, JOptionPane.INFORMATION_MESSAGE, null,
new Object[]{"再次游戏", "退出游戏"}, "再次游戏");
if (option == JOptionPane.YES_OPTION) {
startNewGame();
} else {
System.exit(0);
}
}
@Override
public void keyPressed(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_LEFT) {
leftPressed = true;
}
if (e.getKeyCode() == KeyEvent.VK_RIGHT) {
rightPressed = true;
}
}
@Override
public void keyReleased(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_LEFT) {
leftPressed = false;
}
if (e.getKeyCode() == KeyEvent.VK_RIGHT) {
rightPressed = false;
}
}
@Override
public void keyTyped(KeyEvent e) {}
public static void main(String[] args) {
JFrame frame = new JFrame("打砖块游戏");
BreakoutGame game = new BreakoutGame();
frame.add(game);
frame.pack();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
}