通过线程来实现动态的小球是一个比较复杂的过程,首先是能够让小球碰到壁后弹起来,这个方法的实现有一些技巧在里面,就是定义的的哥方方向变量,通过把方向赋予一定的值从而来使用switch语句或是if语句进行判断。以达到转变方向的过程。这是弹球的主要思想
首先是定义了一个面板类.
/**
* 定义一个画画类,用来生成面板和画画。
* @author 周建权 20130713
*
*/
public class Draw extends JFrame {
private JPanel jpanel;
private Graphics g;
/**
* @param args
*/
public static void main(String[] args) {
Draw draw = new Draw();
draw.initUI();
}
public void initUI(){
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setTitle("弹球");
this.setSize(600, 600);
this.setLayout(new BorderLayout());
JPanel jp = new JPanel();
jpanel = new JPanel();
this.add(jp,BorderLayout.NORTH);
this.add(jpanel,BorderLayout.CENTER);
JButton jbu1=new JButton("增加");
JButton jbu2=new JButton("继续");
JButton jbu3=new JButton("暂停");
JButton jbu4=new JButton ("随机删除");
JButton jbu5=new JButton("顺序删除");
JButton jbu6=new JButton("点鼠标删除");
jp.add(jbu1);
jp.add(jbu2);
jp.add(jbu3);
jp.add(jbu4);
jp.add(jbu5);
jp.add(jbu6);
jbu4.setForeground(Color.blue);
jbu1.setForeground(Color.blue);
jbu2.setForeground(Color.blue);
jbu3.setForeground(Color.blue);
jbu5.setForeground(Color.blue);
jbu6.setForeground(Color.blue);
this.setVisible(true);
ThreadListener l=new ThreadListener(jpanel);
jbu1.addActionListener(l);
jbu2.addActionListener(l);
jbu3.addActionListener(l);
jbu4.addActionListener(l);
jbu5.addActionListener(l);
jbu6.addActionListener(l);
/**
* 打算添加图片,还没实现此功能。
*/
jpanel.setUI(new PanelUI(){
ImageIcon image=new ImageIcon();
public void paint(Graphics g,JComponent c){
g.drawImage(image.getImage(),0,0,null);
}
});
}
}
接着就是实现小球主要功能的方法了。小球的各个功能都以此为基础
/**
* 线程类
* @author 周建权 2013.7.18
*
*/
public class DrawThread extends Thread {
private Graphics g;
private JPanel jp;
private static ArrayList<DrawThread> ball = new ArrayList<DrawThread>();
//定义方向
private static final int UP=1;
private static final int DOWN=2;
private static final int LEFT=3;
private static final int RIGHT=4;
//定义小球位置
private int x,lastx;
private int y,lasty;
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;
}
// 定义半径
private int radius;
public int getRadius() {
return radius;
}
public void setRadius(int radius) {
this.radius = radius;
}
//定义停止暂停
private boolean pauseFlag=false;
private boolean stopFlag=false;
//定义速度
private int xspeed;
private int yspeed;
//球的运动方向
private int xdirection=RIGHT;
private int ydirection=DOWN;
//定义颜色
private Color co;
public DrawThread(JPanel jpanel){
this.jp=jpanel;
this.g=jpanel.getGraphics();
}
public static ArrayList<DrawThread> getList() {
return ball;
}
/**
* run函数
*/
public void run(){
init();
while(true){
try{
Thread.sleep(200);
}catch(Exception ef){}
if(pauseFlag==true){
continue;
}
if(stopFlag==true){
clear();
return;
}
clear();
move();
draw();
}
}
/**
* 定义变量的初始值
*/
public void init(){
Random random=new Random();
xspeed=30+random.nextInt(20);
yspeed=10+random.nextInt(40);
radius=15+random.nextInt(30);
co=new Color(random.nextInt(256),random.nextInt(256),random.nextInt(256));
}
/**
* 小球移动的方法
*/
public void move(){
if(x<radius/2){xdirection=RIGHT;}
else if(x>jp.getWidth()-3*radius/2){xdirection=LEFT;}
if(y<radius/2){ydirection=DOWN;}
else if(y>jp.getHeight()-3*radius/2){ydirection=UP;}
lastx=x;
lasty=y;
if(this.xdirection==LEFT){
x-=this.xspeed;
if(collsion(LEFT)){
xdirection=RIGHT;
}
}
else if(this.xdirection==RIGHT){
x+=this.xspeed;
if(collsion(RIGHT)){
xdirection=LEFT;
}
if(this.ydirection==UP){
y-=this.yspeed;
if(collsion(UP)){
ydirection=DOWN;
}
}
else if(this.ydirection==DOWN){
y+=this.yspeed;
if(collsion(DOWN)){
ydirection=UP;
}
}
}
}
public void fillcircle(int x,int y,int radius){
g.fillOval(x-radius, y-radius, 2*radius, 2*radius);
}
/**
* 绘制小球的方法
*/
public void draw(){
g.setColor(co);
fillcircle(x, y, radius);
int r=co.getRed();
int G=co.getGreen();
int b=co.getBlue();
int radius=this.radius;//很诡秘的代码。
while(radius>3){
radius-=2;
G+=10;
r+=10;
b+=10;
if(G>255){G=255;}
if(r>255){r=255;}
if(b>255){b=255;}
Color d=new Color(r,G,b);
g.setColor(d);
fillcircle(x,y,radius);
}
}
/**
* 擦除小球的方法
*/
public void clear(){
g.setColor(this.jp.getBackground());
fillcircle(x, y, 2*radius);
}
/**
* 定义一个设置暂停布尔值的方法
* @param flag
*/
public void setPause(boolean flag){
pauseFlag=flag;
}
/**
* 设置停止方法中的布尔值一直为true,线程不可重复开始,停止后直接退出
*/
public void setStop(boolean flag){
this.stopFlag = flag;
}
/**
* 定义一个碰撞方法,该方法用于判断两个小球是否碰撞。
* @param direction
* @return若两球碰撞则返回true,若不碰撞则返回false
*/
private boolean collsion(int direction){
for(int i=0;i<ball.size();i++){System.out.println(ball.size());
DrawThread Thread=ball.get(i);
if(this==Thread){
continue;}
int m=Math.abs(this.getX()-Thread.getX());
int n=Math.abs(this.getY()-Thread.getY());
int o=(int)Math.sqrt(m*m+n*n);
if(o<=this.radius+Thread.radius);
if(direction==LEFT||direction==RIGHT)
Thread.xdirection=direction;
else {Thread.ydirection=direction;
}
int xsp=this.xspeed;
int ysp=this.yspeed;
this.xspeed=Thread.xspeed;
this.yspeed=Thread.yspeed;
Thread.xspeed=xsp;
Thread.yspeed=ysp;
x=lastx;
y=lasty;
return true;
}
return false;
}
}
下面就是添加监听器了
/**
* 创建一个按钮监听器,按钮画小球
*
* @author 周建权 2013.7.14
*
*/
public class ThreadListener extends Thread implements ActionListener {
private JPanel jp;
private Graphics g;
public ThreadListener(JPanel jp) {
this.jp = jp;
}
// 创建一个队列,用来存放线程
ArrayList<DrawThread> allBall = new ArrayList<DrawThread>();
public void actionPerformed(ActionEvent e) {
String s = e.getActionCommand();
if (s.equals("增加")) {
DrawThread Thread = new DrawThread(jp);
// allBall.add(Thread);
Thread.start();
allBall.add(Thread);
}
if (s.equals("继续")) {
for (int i = 0; i < allBall.size(); i++) {
DrawThread Thread = allBall.get(i);
Thread.setPause(false);
}
}
if (s.equals("暂停")) {
for (int i = 0; i < allBall.size(); i++) {
DrawThread Thread = allBall.get(i);
Thread.setPause(true);
}
}
if (s.equals("随机删除")) {
int m = allBall.size();
System.out.println(allBall.size());
Random random = new Random();
int n = random.nextInt(m);
System.out.println(n);
DrawThread Thread = allBall.remove(n);
Thread.setStop(true);
System.out.println(n);
}
if (s.equals("顺序删除")) {
if (!allBall.isEmpty()) {
DrawThread Thread = allBall.remove(0);
Thread.setStop(true);
}
}
if(s.equals("点鼠标删除")){System.out.println("怎么不可以删除");
MouseListener mouse=new MouseListener(){
public void mouseClicked(MouseEvent e){
System.out.println(allBall.size());
for(int i=0;i<allBall.size();i++){
DrawThread Thread=allBall.get(i);
int x=Math.abs(Thread.getX()-e.getX());
int y=Math.abs(Thread.getY()-e.getY());
if(x<Thread.getRadius()&&y<Thread.getRadius()){
allBall.remove(i);
Thread.setStop(true);
Thread.clear();
}
}
}
public void mousePressed(MouseEvent e){}
public void mouseReleased(MouseEvent e){}
public void mouseEntered(MouseEvent e){}
public void mouseExited(MouseEvent e){}
};jp.addMouseListener(mouse);
}
}
}
一个弹球就做好了。还有待改进的是两个小球之间的效果,这个弹出来的效果一点也不好。。。