动态弹球(Java多线程实现+Swing)

这是老师布置的作业,同时自己也增加了一些要求

1,有增加小球数量的按钮,每一个小球都有自己的颜色和序号,从0开始,每个小球不会碰撞反弹

2,暂停按钮,第一次按暂停按钮,所有小球,都停止运动,再次按时,所有小球继续运动,

3,退出按钮,没啥好说的

再说一下整体的思路

1. **创建主窗口**:程序首先创建一个名为"弹球"的主窗口。这是通过Java Swing库实现的。
2. **小球面板**:在主窗口中,创建一个名为`BallPanel`的小球面板。这个面板用于显示和控制小球的运动。它包括一个`List`用于存储小球对象,
以及一个布尔值`paused`来表示是否暂停小球运动。
3. **控制按钮面板**:在主窗口底部创建一个控制按钮面板,包括"添加小球"、"暂停"和"退出"按钮。用户可以点击这些按钮来添加小球、暂停/继续
小球运动以及退出程序。
4. **定时器**:创建一个定时器(Timer),用于定期触发小球的移动和重绘,以实现小球的动画效果。如果没有暂停,定时器会定期更新小球的位置。
5. **小球类**:定义了一个名为`Ball`的小球类,它实现了`Runnable`接口,以便可以在单独的线程中运行每个小球。
每个小球对象包括位置、速度、颜色和序号等属性。
6. **绘制小球**:小球类中的`draw`方法用于绘制小球,包括填充小球的颜色和在小球中心绘制序号。
7. **移动小球**:小球类的`move`方法控制小球的运动,包括检测碰撞边界并进行反弹处理。如果程序没有暂停,小球将按照其速度在面板上移动。
8. **添加小球**:点击"添加小球"按钮时,程序在小球面板中创建一个新的小球对象,并将其添加到小球列表中。然后,程序启动一个新线程来执行小球的运动。
9. **暂停/继续**:点击"暂停"按钮时,程序会切换小球面板的暂停状态。当暂停时,小球不再移动;再次点击"暂停"按钮时,程序将继续小球的运动。
10. **退出程序**:点击"退出"按钮时,程序会退出应用程序。
总的来说,这个程序演示了如何使用Java Swing库创建一个图形用户界面,动态生成和控制多个小球,以及实现小球的弹跳动画效果。
用户可以通过按钮与小球交互,包括添加小球、暂停/继续小球运动和退出应用程序。

话不多说,直接附上代码,代码里面也有详细的注解,方便大家理解

 
package 弹球;

import java.awt.*;

public class Ball implements Runnable {
    private static int ballCount = 0;
    private BallPanel panel;
    private int x, y, diameter;
    private int xSpeed, ySpeed;
    private Color color;
    private int number;

    public Ball(BallPanel panel, int number) {
        this.panel = panel;
        diameter = 30;
        x = (int) (Math.random() * (panel.getWidth() - diameter)); // 随机初始x坐标
        y = (int) (Math.random() * (panel.getHeight() - diameter)); // 随机初始y坐标
        xSpeed = (int) (Math.random() * 5) + 1; // 随机x轴速度
        ySpeed = (int) (Math.random() * 5) + 1; // 随机y轴速度
        color = new Color((int) (Math.random() * 256), (int) (Math.random() * 256), (int) (Math.random() * 256)); // 随机颜色
        this.number = number;
        ballCount++;
    }

    public void draw(Graphics g) {
        g.setColor(color);
        g.fillOval(x, y, diameter, diameter); // 绘制小球
        g.setColor(Color.BLACK);
        g.drawString(String.valueOf(number), x + diameter / 2 - 5, y + diameter / 2 + 5); // 绘制小球序号
    }

    public void move() {
        if (!panel.isPaused()) {
            if (x + xSpeed < 0 || x + diameter + xSpeed > panel.getWidth()) {
                xSpeed = -xSpeed; // 反弹处理
            }
            if (y + ySpeed < 0 || y + diameter + ySpeed > panel.getHeight()) {
                ySpeed = -ySpeed; // 反弹处理
            }
            x += xSpeed;
            y += ySpeed;
        }
    }

    @Override
    public void run() {
        while (x > 0 && x < panel.getWidth() - diameter && y > 0 && y < panel.getHeight() - diameter) {
            try {
                Thread.sleep(16); // 调整休眠时间以控制小球的速度
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            move();
            panel.repaint(); // 重绘小球
        }
        ballCount--;
        if (ballCount == 0) {
            panel.togglePause(); // 当所有小球停止时切换暂停状态
        }
    }
}
package 弹球;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;

public class BallPanel extends JPanel {
    private java.util.List<Ball> balls;
    private boolean paused;

    public BallPanel() {
        balls = new ArrayList<>();
        paused = false;

        Timer timer = new Timer(16, new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                if (!paused) {
                    for (Ball ball : balls) {
                        ball.move();
                    }
                    repaint();
                }
            }
        });
        timer.start(); // 启动定时器来触发小球动画
    }

    public void addBall() {
        Ball ball = new Ball(this, balls.size() + 1); // 创建新的小球
        balls.add(ball);
        Thread thread = new Thread(ball); // 创建小球线程
        thread.start(); // 启动小球线程
    }

    public void togglePause() {
        paused = !paused; // 切换暂停状态
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        for (Ball ball : balls) {
            ball.draw(g); // 绘制每个小球
        }
    }

    public boolean isPaused() {
        return paused; // 返回暂停状态
    }
}
package 弹球;

import javax.swing.*;
import java.awt.*;

public class DynamicBouncingBalls {
    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> createAndShowGUI()); // 启动Swing应用程序
    }

    private static void createAndShowGUI() {
        JFrame frame = new JFrame("弹球"); // 创建主窗口
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // 设置窗口关闭操作

        BallPanel ballPanel = new BallPanel(); // 创建包含小球的面板
        frame.add(ballPanel, BorderLayout.CENTER); // 将小球面板添加到主窗口中

        JPanel controlPanel = new JPanel(); // 创建控制按钮面板
        JButton addButton = new JButton("添加小球"); // 创建“添加小球”按钮
        JButton pauseButton = new JButton("暂停"); // 创建“暂停”按钮
        JButton exitButton = new JButton("退出"); // 创建“退出”按钮

        addButton.addActionListener(e -> ballPanel.addBall()); // 添加小球按钮的点击事件
        pauseButton.addActionListener(e -> ballPanel.togglePause()); // 暂停按钮的点击事件
        exitButton.addActionListener(e -> System.exit(0)); // 退出按钮的点击事件

        controlPanel.add(addButton);
        controlPanel.add(pauseButton);
        controlPanel.add(exitButton);

        frame.add(controlPanel, BorderLayout.SOUTH); // 将控制按钮面板添加到主窗口中

        frame.setSize(600, 400); // 设置窗口大小
        frame.setVisible(true); // 显示窗口
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值