弹球碰撞分析

上次已经完成了弹球碰壁问题,还没有发表,今天刚刚完成了弹球之间的碰撞。下面我来分析一下的弹球程序。

 

声明两个按钮,声明一个静态变量,m用来记录按钮的值

 

JButton a,b;
static int m=0;
	

 创建一个队列,装入弹球的线程

 

public static java.util.ArrayList arr=new java.util.ArrayList();

 显示界面的方法:在窗体上添加了2个面板,进度条、按钮都在面板1上,弹球在面板2 上运动。点击按钮会有不同的值,这个值会被控制进度条、控制弹球、和弹球的监听器类使用,以控制弹球运动和进度条。

 

 

public void showt(){
		this.setTitle("弹球");
		this.setSize(550,600);
		JPanel p1=new JPanel(),
			   p2=new JPanel();//创建2个面板
		//给面板设置位置
		this.add(p1,BorderLayout.NORTH);
		this.add(p2,BorderLayout.SOUTH);
		p1.setBounds(0,0,550, 20);
		p2.setBounds(0,20,550, 500);
		JProgressBar p=new JProgressBar();//创建一个进度条对象
		p.setMaximum(2000);//设置进度条的最大值是300
		a=new JButton("开始");
		b=new JButton("暂停");
		//将进度条、按钮添加到面板1上
		p1.add(p);
		p1.add(a);
		p1.add(b);
		p1.setBackground(Color.blue);//面板1的背景为蓝色
		this.setResizable(true);//是否能最大化
		this.setDefaultCloseOperation(3);//关闭窗体是退出程序
		this.setLocationRelativeTo(null);//窗体居中显示
		this.setVisible(true);//窗体可见
		this.validate();
		//得到画布对象
		Graphics g = this.getGraphics();
		int a1=0,b1=1,c=2,d=3;
		//创建线程
		Tan t1=new Tan(a1,g);
		arr.add(t1);//将线程1加入队列中
		//启动线程
		t1.start();
		System.out.println("第一个线程已启动");
		Tan t2=new Tan(b1,g);
		arr.add(t2);//将线程2加入队列中
		//启动线程
		t2.start();//start()调用run()方法
		System.out.println("第二个线程已启动");
		Tan t3=new Tan(c,g);
		arr.add(t3);//将线程3加入队列中
		t3.start();//启动线程
		System.out.println("第三个线程已启动");
		Tan t4=new Tan(d,g);
		arr.add(t4);//将线程4加入队列中
		t4.start();//启动线程
		System.out.println("第四个线程已启动");
		Progressj tt=new Progressj(p);//创建控制进度条的线程
		tt.start();//启动线程
		Jian ji=new Jian(arr);//创建一个弹球的监视器线程对象
		ji.start();//启动线程
		System.out.println("监视线程已启动");
		ActionListener ac=new ActionListener(){
			public void actionPerformed(ActionEvent e){
				if(e.getSource()==a){m=1;}//点击“开始”按钮,m的值为1
				else if(e.getSource()==b){ m=0;}//点击“暂停”按钮,m的值为0
			}
		};
		//给按钮添加监视器
		a.addActionListener(ac);
		b.addActionListener(ac);
	}

 进度条的类:这个类用来控制进度条

 

public class Progressj extends Thread{
	JProgressBar p;
	static int x=0;
	public Progressj(JProgressBar p){
		this.p=p;
	}
	public void run(){
		jin();
	}
	public void jin(){
		while(true){
			p.setValue(x);//设置进度条的当前值
		   if(Mainr.m==1&&x<2000)	{x+=5;
		   }
			try{
				Thread.sleep(200);
				}catch(Exception e){
				}
		}
	}
}

 弹球运动的类:当弹球碰到壁后就改变运动方向,当不同方向的球碰撞后,就反方向运动。

注意:在每一个方向的弹球运动方法中,当弹球碰撞后(即t1为非零的值),要先改变t1的值,再调用弹球另一个方向运动的方法。因为每一个弹球的运动都是一个线程,在时间没有结束时吗,会不停的执行下去,若在调用弹球方向运动方法后改变t1的值为0,那么,弹球碰撞后会分开,但碰到壁后就停止消失,再两个弹球出现在碰撞的地方,分开,再运动。


 

public class Tan extends Thread {
	int a;//a代表哪一个弹球线程
	Graphics g;
	int m,n,k;//k记录弹球的运动方法
	int t1=0,t2,t3;
	Color co;//弹球的颜色
public Tan(int a,Graphics g){
	this.a=a;
	this.g=g;
}
public void run(){
	if(a==0) { 
		rightstoleft(505,60,Color.green);
		}//右上角到左下角的初始球
	if(a==1) {
		leftstoright(5,60,Color.red);}//从左上角到右下角
	if(a==2) {
		rightsytoleft(505,555,Color.yellow);}//从右下角到左上角
	if(a==3) {
		leftsytoright(5,555,Color.pink);}//从左下角到右上角
}
//从右上角到左下角(x,y)为弹球的坐标,b代表哪个弹球
public void  rightstoleft(int x,int y,Color c){
	boolean a=true;
	while(a){
		g.clearRect(x+2, y-1,  40, 40);
		g.setColor(c);		
		g.fillOval(x, y, 40, 40);
		 if(Mainr.m==1&&Progressj.x<2000)	{x-=2;y++;}
		if(x<=6&&x>=5&&y<555) {leftstoright(x,y,c); a=!a;	}//然后左上右下,a的值变化,该方法执行结束,进行下一个方法
		if(y==555&&x>5) {rightsytoleft(x, y,c);a=!a;	} //从右下角到左上角
		if(x==5&&y==555) {leftsytoright(x,y,c);a=!a;	}//从左下角到右上角
		//当弹球在此方向运动的时候发生碰撞:t1=1,则返回,即从左下方向右上方运动。
		if(t1==1) {t1=0;leftsytoright(t2,t3,c);a=!a;}//要先将t1=0,再才能够调用弹球运动的方法
		//暂停一下
		try{ Thread.sleep(15);
		}
		catch(Exception e){	
		}
		m=x;n=y;
		k=1;co=c;
	}
}
//从左上角到右下角
public  void leftstoright(int x,int y,Color c){
	boolean a=true;
	while(a){
		g.clearRect(x-2, y-1,  40,40);
		g.setColor(c);
		g.fillOval(x, y, 40, 40);
		 if(Mainr.m==1&&Progressj.x<2000)	{
		 x+=2;y++;}
		 if(x>=504&&x<=505&&y<555) {rightstoleft(x,y,c); a=!a;	}//然后右上左下 
		 if(y==555&&x<505) {leftsytoright(x,y,c); a=!a;	}//然后左下右上
		 if(x==505&&y==555) {rightsytoleft(x, y,c); a=!a;	}//从右下角到左上角
			//当弹球在此方向运动的时候发生碰撞:t1=2,则返回,即从右下方向左上方运动。
		if(t1==2) {t1=0;rightsytoleft(t2,t3,c);a=!a;	}
		//暂停一下
		try{ Thread.sleep(5);
		}
		catch(Exception e){	
		}
		m=x;n=y;
		k=2;co=c;
	}
}
//从右下角到左上角
public void rightsytoleft(int x, int y,Color c){
	boolean a=true;
	while(a){
		g.clearRect(x+1, y+2,  40, 40);
		g.setColor(c);
		g.fillOval(x, y, 40, 40);
		 if(Mainr.m==1&&Progressj.x<2000)	{x--;y-=2;}
		 if(x==5&&y>60) {leftsytoright(x,y,c); a=!a;	}//从左下角到右上角
		 if(x==5&&y==60) {leftstoright(x,y,c); a=!a;	}//从左上角到右下角
		 if(y>=60&&y<=61&&x>5) {rightstoleft(x,y,c); a=!a;	}//然后右上左下
		    //当弹球在此方向运动的时候发生碰撞:t1=3,则返回,即从左上方向右下方运动。
		if(t1==3) {t1=0;leftstoright(t2,t3,c);a=!a;	}
		//暂停一下
		try{   Thread.sleep(10);
		}
		catch(Exception e){	
		}
		m=x;n=y;k=3;co=c;
	}
}
//从左下角到右上角
public void  leftsytoright(int x,int y,Color c){
	boolean a=true;
	while(a){
		g.clearRect(x-2, y+1,  40, 40);
		g.setColor(c);
		g.fillOval(x, y, 40, 40);
		 if(Mainr.m==1&&Progressj.x<2000)	{x+=2;y--;}
		 if(x>=504&&x<=505&&y>60) {rightsytoleft(x,y,c); a=!a;	}//然后右下左上
		 if(x==505&&y==60) {rightstoleft( x,y,c); a=!a;	}//然后右上左下
		 if(y==60&&x<505) {leftstoright(x,y,c); a=!a;	}//从左上角到右下角
			//当弹球在此方向运动的时候发生碰撞:t1=4,则返回,即从右上到左下运动。
		if(t1==4) {t1=0;rightstoleft(t2,t3,c);a=!a;	}
		//暂停一下
		try{ Thread.sleep(20);
		    }
		catch(Exception e){	
		}
		m=x;n=y;k=4;co=c;
	}
}
	//碰撞的情况方法
	public void pu(int t1,int t2,int t3,Color c){
		//t1为传过来的k,t2,t3为弹球的位置
		this.t1=t1;
		this.t2=t2;
		this.t3=t3;
	}
}

 弹球的监听器线程:获得队列中的数据,比较两个弹球的坐标,看是否在碰撞区内,在碰撞区内,调用tan 线程内处理碰撞情况的方法。

 

public class Jian extends Thread{
	java.util.ArrayList arr;
	//传递队列
	public Jian(java.util.ArrayList arr){
		this.arr=arr;
	}
	public void run(){
		bijiao();
	}
	public void bijiao(){
		while(true){
			for(int i=0;i
					//获得弹球的运动方向值,坐标,颜色
					int x1=t1.m,
						y1=t1.n,
						x2=t2.m,
						y2=t2.n,
						k1=t1.k,
						k2=t2.k;
					Color c1=t1.co,
						  c2=t2.co;
					 if(Mainr.m==1&&Progressj.x<2000){//在没有暂停并且时间还没有结束情况下
						if(k1!=k2&&Math.abs(x1-x2)<=40&&Math.abs(y1-y2)<=40){//在碰撞区内
							t1.pu(k1,x1,y1,c1);//调用tan类中的方法,用来实现碰撞
							t2.pu(k2,x2,y2,c2);
						}
					 }
				}
			}
			try{
				Thread.sleep(200);
			}catch(Exception e){
				e.printStackTrace();
			}
		}
	}
}

 

下面这张图片是界面刚刚出来是弹球还没有运动是的图片


弹球碰撞分析_第1张图片

下面这张图片是弹球运动过程中,被暂停后图片。你可以看到图中的粉红色弹球和红色的弹球离得很近。她们是碰撞后刚刚分开的图片


弹球碰撞分析_第2张图片

 

下面的这张图片是在弹球运动时,打印出的弹球运动位置。上面有一行显示了“1<<<<3>>>311与293相等”,是红球和粉红弹球碰撞是的结果311和293是代表两球的x 坐标,1和3 代表他们在队列中的位置。下面也显示了碰撞后他们各自的运动方向

 
弹球碰撞分析_第3张图片

 

你可能感兴趣的:(弹球碰撞分析)