这里是提纲
1.线程弹球游戏实现
1.实现界面需要使用哪些API类
JFrame
JPanel
JButton
FlowLayout
Graphics2D
Thread
Color
ActionListener
ActionEvent
MouseListener
MouseEvent
BorderLayout
2.实现界面步骤
3.给按钮添加监听器,传递centerPanel
4.定义小球类
5.点击添加按钮,创建小球,让小球运动起来
2.练习
1.绘制立体球
实现的代码是这样
for (int i = 0; i != 100; i++) {
g.setColor(new Color(i, i, i));
g.fillOval(x - r + i / 2, y - r + i / 2, r * 2 - i, r * 2 - i);
}
2.球体碰撞
在BallListener类中定义三个数组队列分别保存小球的坐标,x,y,半径R
,作为ball类构造函数的形参传过去,在ball的peng函数中计算是否碰撞,只要计算两个小球圆心的距离之和小于等于两个小球的半径之和就可以了。每个小球每次都要和其他的所有小球进行比较。
3.如何移除
这个还没想到,之后补上
4.如何暂停
在Ball类的构造函数中传一个布尔型的isrun参数,值为true,如果点暂停,isrun变成false.在run函数中进行判断,若isrun为true则线程继续,否则线程暂停。
下面为具体代码,仍有很多BUG,之后完善了再改
package MMM0528; import java.awt.Color; import java.awt.Graphics2D; import java.awt.RenderingHints; import java.util.ArrayList; import javax.swing.JPanel; public class ball extends Thread { private int x; private int y; private int r; private Color color; private int xspeed; private int yspeed; private JPanel centerpanel; private Graphics2D g; public static boolean isrun; public boolean isremove ; private ArrayList arrayx; private ArrayList arrayy; private ArrayList arrayr; private int i; public ball(int x, int y, int r, int xspeed, int yspeed, JPanel centerpanel, boolean isrun,int i,ArrayList arrayx,ArrayList arrayy,ArrayList arrayr) { this.x = x; this.y = y; this.r = r; this.xspeed = xspeed; this.yspeed = yspeed; this.centerpanel = centerpanel; this.g = (Graphics2D) centerpanel.getGraphics(); this.isrun = isrun; this.i=i; this.arrayx = arrayx; this.arrayy = arrayy; this.arrayr = arrayr; // 设置取表画笔的锯齿状 g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); } public void run() { while (true) { if (balllistener.getisrun() == true) { this.peng(); this.draw(g); this.move(); this.peng(); try { Thread.sleep(30); } catch (InterruptedException e1) { e1.printStackTrace(); } } } } public void draw(Graphics2D g) { // 擦除上一次绘制的小球 // g.setColor(Color.white); // g.fillOval(x - r - 10, y - r - yspeed + xspeed, r * 2 + 10, r * 2 + 10); // 绘制新的小球 for (int i = 0; i != 100; i++) { g.setColor(new Color(i, i, i)); g.fillOval(x - r + i / 2, y - r + i / 2, r * 2 - i, r * 2 - i); } } public void remove(Graphics2D g) { g.setColor(Color.white); g.fillOval(x - r - 1, y - r - yspeed - 1, r * 2 + 2, r * 2 + 3); g.fillOval(x - r, y - r, r * 2, r * 2); } public void move() { x += xspeed; y += yspeed; arrayx.set(i,x); arrayy.set(i,y); if (y >= (centerpanel.getHeight() - r)) { yspeed = -yspeed; } else if (y <= r) { yspeed = -yspeed; } else if (x <= r) { xspeed = -xspeed; } else if (x >= (centerpanel.getWidth() - r)) { xspeed = -xspeed; } } public void peng() { for (int j = 0; j < arrayx.size(); j++) { if(j==i){ j++; continue; } double dis; int xx, yy; xx = (int) arrayx.get(j); yy = (int) arrayy.get(j); dis = Math.sqrt(Math.abs((xx - x)) * Math.abs((xx - x)) + Math.abs((yy - y)) * Math.abs((yy - y))); int R = (int) arrayr.get(j); R += r; int dist = (int) dis; if (dist == R) { System.out.println(xx); // if (x >= xx && y >= yy) { // xspeed = -xspeed; // yspeed = -yspeed; // }else if (x >= xx && y < yy) { // xspeed = -xspeed; // }else if (x < xx && y >= yy) { // yspeed = -yspeed; // }else if (x < xx && y < yy) { xspeed = -xspeed; yspeed = -yspeed; // } } } } // public void collide(){ // // } public int getX() { return x; } public void setX(int x) { this.x = x; } public int getY() { return y; } public void setY(int y) { this.y = y; } public int getR() { return r; } public void setR(int r) { this.r = r; } public Color getColor() { return color; } public void setColor(Color color) { this.color = color; } public int getXspeed() { return xspeed; } public void setXspeed(int xspeed) { this.xspeed = xspeed; } public int getYspeed() { return yspeed; } public void setYspeed(int yspeed) { this.yspeed = yspeed; } public static void setisrun() { isrun = true; } }
package MMM0528; import java.awt.Color; import java.awt.Graphics2D; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.util.ArrayList; import java.util.Random; import javax.swing.JPanel; public class balllistener implements ActionListener { static boolean isrun=true; private static int i=0; private JPanel centerPanel; private Graphics2D g; private ArrayList arrayx =new ArrayList(); private ArrayList arrayy =new ArrayList(); private ArrayList arrayr =new ArrayList(); public balllistener(JPanel centerPanel) { this.centerPanel = centerPanel; g = (Graphics2D)centerPanel.getGraphics();//强制转型 // g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, // RenderingHints.VALUE_ANTIALIAS_ON); } public void actionPerformed(ActionEvent e) { //判断点击的是否添加按钮 if(e.getActionCommand().equals("添加")){ // System.out.println("添加"); Random rand = new Random(); int x = rand.nextInt(centerPanel.getWidth()); int y = 50; int r = 40-rand.nextInt(20); int xspeed = rand.nextInt(10)-5; int yspeed = rand.nextInt(10)-5; //创建小球对象 arrayx.add(x); arrayy.add(y); arrayr.add(r); ball balll = new ball(x,y,r,xspeed,yspeed,centerPanel,true,i, arrayx, arrayy, arrayr); i++; balll.start();//启动线程 }else if(e.getActionCommand().equals("移除")){ // System.out.println("移除"); }else if(e.getActionCommand().equals("暂停")){ isrun=false; } } public static boolean getisrun(){ return isrun; } public void setisrun(){ isrun=true; } public static int getI(){ return i; } }
package MMM0528; import java.awt.BorderLayout; import java.awt.Color; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JPanel; public class TanqiuUI extends JFrame { public static void main(String[] args) { TanqiuUI tq = new TanqiuUI(); tq.intUI(); } public void intUI() { this.setTitle("弹球游戏"); this.setSize(500, 500); this.setLocationRelativeTo(null); this.setDefaultCloseOperation(3); this.setResizable(false); BorderLayout bl = new BorderLayout(); this.setLayout(bl); /* * 北边的按钮 */ JPanel panelnorth = new JPanel(); JButton butadd = new JButton("添加"); JButton butremove = new JButton("移除"); JButton butpause = new JButton("暂停"); panelnorth.add(butadd); panelnorth.add(butremove); panelnorth.add(butpause); this.add(panelnorth, BorderLayout.NORTH); /* * 添加中间的画板 */ JPanel panelcent = new JPanel(); panelcent.setBackground(Color.WHITE); this.add(panelcent, BorderLayout.CENTER); /* * 创建监听类对象 */ balllistener bl1 = new balllistener(panelcent); /* * 调用事件监听方法 */ butadd.addActionListener(bl1); butremove.addActionListener(bl1); butpause.addActionListener(bl1); this.setVisible(true); } }