编写程序,该程序通过一个发射按钮可以发射一个弹球,该球遇到边界时会自动弹回,在移动固定次数后,该球停止运动。要求每次点击发射按钮都会发射一个弹球,如果点击多次,则多个弹球同时运动。该程序通过另一个结束可以结束程序的运行。参考界面如图所示。
前言:博主这学期上的Java课,在PTA上老师布置了这个题,当时被折磨了很久所以打算写个博客记录下,同时复习一下,明天JAVA直接期末考试了!!!!!
本题主要是JAVA GUI的加上多线程的应用,所以个人认为难度挺大,本文也是参考了其他代码的基础上自己写得。
直接上代码分析:
package PTA;
// 记得自己把package包改了!
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Rectangle2D;
import java.util.ArrayList;
// 定义球的类,包括球的坐标,球沿着x与y的运动方向以及运动速度(速度可以自己设定),以及球的大小(自己设定)。
class Ball
{
private final int speedx = 30;
private final int speedy = 30;
// 球的移动速度 以象素为单位
private final int diameter = 16;
// 球的半径
private int x;
private int y;
// 球的坐标,初始是(400,100)
private int dx = -1;
private int dy = 1;
// 球移动的方向
Ball(int x,int y)
{
this.x = x;
this.y = y;
}
// 球的移动函数,rect指代当前的窗口,如果到达边界则方向改变
// 这个函数在本文中很重要
void move(Rectangle2D rect)
{
//rect 为窗体的size
x += dx * speedx;
y += dy * speedy;
if(x<rect.getMinX())
{
x = (int)rect.getMinX()+diameter;
dx = -dx;
}
if(x+diameter>rect.getMaxX())
{
x = (int)rect.getMaxX()-diameter;
dx = -dx;
}
if(y<rect.getMinY())
{
y = (int)rect.getMinY();
dy = -dy;
}
if(y+diameter>rect.getMaxY())
{
y = (int)rect.getMaxY() - diameter;
dy = -dy;
}
}
Ellipse2D DrawBall()
{
return new Ellipse2D.Float(x,y,diameter,diameter);
}
//根据当前坐标返回一个球的对象
}
// 弹球的窗口
class BallPanel extends JPanel
{
private ArrayList<Ball> Balls = new ArrayList<>();
void add(Ball ball)
{
Balls.add(ball);
}
@Override
public void setPreferredSize(Dimension preferredSize) {
super.setPreferredSize(preferredSize);
preferredSize.width = 400;
preferredSize.height = 450;
}
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
g.drawLine(0,412,386,412);
for(Ball balls: Balls)
g2.fill(balls.DrawBall());
}
}
// 主窗口
class BallWindow extends JFrame
{
private final BallPanel ballPanel = new BallPanel();
BallWindow()
{
this.add(ballPanel,BorderLayout.CENTER);
JPanel panel = new JPanel();
panel.setPreferredSize(new Dimension(500,50));
JButton btn1 = new JButton("开始");
JButton btn2 = new JButton("结束");
btn1.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
AddBall();
}
});
panel.add(btn1);
btn2.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
System.exit(0);
}
});
panel.add(btn2);
this.setTitle("弹球程序");
this.add(panel,BorderLayout.SOUTH);
this.setSize(400,500);
this.setVisible(true);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setCenter();
}
void setCenter()
{
Dimension screensize = Toolkit.getDefaultToolkit().getScreenSize();
int x = (screensize.width-400)/2;
int y = (screensize.height-500)/2;
this.setLocation(x,y);
}
// 每点击一次按钮,记得添加一个球,即创建一个新的进程
// 通过将球插入到Arraylist中 保存多个球的位置
void AddBall()
{
Ball ball = new Ball(400,100);
ballPanel.add(ball);
//System.out.println("i am added");
class BallRun implements Runnable
{
@Override
public void run() {
try {
while(true)
{
ball.move(ballPanel.getBounds());
ballPanel.repaint();
Thread.sleep(100);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
BallRun ballRun = new BallRun();
Thread t = new Thread(ballRun);
t.start();
}
}
public class JumpBall {
public static void main(String[] args) {
BallWindow ballWindow = new BallWindow();
}
}