基于java的打砖块小游戏

游戏规则

在这里插入图片描述

  1. 游戏目标:
    使用一个球击打屏幕上方的砖块,使所有砖块都被破坏。在游戏中,玩家的目标是通过弹球来消除屏幕上的所有砖块。
  2. 控制方式:
    玩家控制一个位于屏幕底部的挡板(paddle),通过左右移动挡板来接住从挡板弹起的球。
  3. 游戏玩法:
    挡板: 挡板可以通过键盘上的左右箭头键进行移动,以便在球反弹回来时能够接住它。
    : 球在屏幕上移动并与砖块、挡板碰撞。球会反弹回来,并且会根据撞击角度改变方向。
    砖块: 砖块分布在屏幕的上方,每次球与砖块碰撞时,砖块会被破坏并从屏幕上消失。
  4. 胜利条件:
    当屏幕上的所有砖块被破坏时,游戏胜利。此时会弹出一个对话框显示游戏用时,并提供“再次游戏”或“退出游戏”的选项。
  5. 失败条件:
    如果球落到屏幕底部,未被挡板接住,游戏失败。此时会弹出一个对话框显示游戏用时,并提供“再次游戏”或“退出游戏”的选项。
  6. 游戏控制:
    使用键盘上的左右箭头键来移动挡板。挡板移动的速度固定,确保可以及时接住球。
    通过这些规则,玩家可以体验到经典的打砖块游戏的乐趣。

代码

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);
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值