该程序通过一个发射按钮可以发射一个弹球,该球遇到边界时会自动弹回,在移动固定次数后,该球停止运动。要求每次点击发射按钮都会发射一个弹球,如果点击多次,则多个弹球同时运动。该程序通过另一个结束可以结束程序的运行。
package priv.lhw.pinball;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Rectangle2D;
import java.util.Random;
public class Ball {
private static final int DIAMETER = 15;
private double x;
private double y;
private double dx;
private double dy;
private final int multiplierX;
private final int multiplierY;
public Ball(Rectangle2D rectangle2D){
Random random = new Random();
x = random.nextDouble() * rectangle2D.getWidth();
y = random.nextDouble() * rectangle2D.getHeight();
dx = random.nextDouble();
dy = random.nextDouble();
multiplierX = random.nextBoolean() ? 1 : -1;
multiplierY = random.nextBoolean() ? 1 : -1;
}
/**
* 移动球
* @param rectangle2D 球所在的矩形
*/
public void move(Rectangle2D rectangle2D){
x += multiplierX * dx;
y += multiplierY * dy;
if(x < rectangle2D.getMinX()){
x = rectangle2D.getMinX();
dx = -dx;
}
if(x + DIAMETER >= rectangle2D.getMaxX()) {
x = rectangle2D.getMaxX() - DIAMETER;
dx = - dx;
}
if(y < rectangle2D.getMinY()) {
y = rectangle2D.getMinY();
dy = - dy;
}
if(y + DIAMETER >= rectangle2D.getMaxY()) {
y = rectangle2D.getMaxY() - DIAMETER;
dy = -dy;
}
}
/**
* 生成一个球
* @return 新球
*/
public Ellipse2D getBall() {
return new Ellipse2D.Double(x,y, DIAMETER, DIAMETER);
}
}
package priv.lhw.pinball;
import javax.swing.*;
import java.awt.*;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class MyFrame extends JFrame {
private final MyPanel myPanel;
public MyFrame(){
setTitle("Pinball");
Toolkit toolkit = Toolkit.getDefaultToolkit();
Dimension dimension = toolkit.getScreenSize();
setSize(dimension.width / 2, dimension.height / 2);
setLocation((dimension.width - getWidth()) / 2, (dimension.height - getHeight()) / 2);
myPanel = new MyPanel();
add(myPanel, BorderLayout.CENTER);
JPanel buttonPanel = new JPanel();
JButton beginButton = new JButton("开始");
beginButton.addActionListener(event -> addBall());
buttonPanel.add(beginButton);
JButton endButton = new JButton("结束");
endButton.addActionListener(event -> System.exit(0));
buttonPanel.add(endButton);
add(buttonPanel,BorderLayout.SOUTH);
}
/**
* 添加一个球
*/
public void addBall(){
Ball b = new Ball(myPanel.getBounds());
myPanel.add(b);
class BallRunnable implements Runnable {
@Override
public void run() {
try {
int count = 1000;
for (int i = 1; i <= count; i++) {
b.move(myPanel.getBounds());
myPanel.repaint();
Thread.sleep(10);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
ExecutorService service = Executors.newCachedThreadPool();
service.execute(new BallRunnable());
}
}
package priv.lhw.pinball;
import javax.swing.*;
import java.awt.*;
import java.util.ArrayList;
public class MyPanel extends JPanel {
private final ArrayList<Ball> ballArrayList = new ArrayList<>();
/**
* 将球加入到列表中
* @param ball
*/
public void add(Ball ball) {
ballArrayList.add(ball);
}
@Override
public void paintComponent(Graphics g)
{
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
for(Ball b : ballArrayList) {
g2.fill(b.getBall());
}
}
}
package priv.lhw.pinball;
import javax.swing.*;
import java.awt.*;
public class Main {
public static void main(String[] args) {
EventQueue.invokeLater(() -> {
JFrame frame = new MyFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
});
}
}