小球碰撞之多线程实现

                                                       小球碰撞游戏

  小球碰撞,首先需要创建一个窗体,相信大家都会创建窗体。然后从窗体上获取画布。紧接着大家都会想到也都会做的就是在  创建一个监听器然后画一个圆。接着我们就会考虑怎么让这个圆动起来,怎么重绘,怎么使圆看起来更漂亮,看起来像一个球一样,又怎么让小球碰在一起又弹开。然后大家会处理一些细节问题,如可以让球可以停下来,然后可以让球恢复过来,怎么加背景。(加动态背景在下篇博客中我将要再写)

      首先创建窗体,我们会考虑到在窗体上加几个按钮,如有控制加小球的按钮,有控制小球停止的按钮,有恢复小球运动的按钮。在小球运动的时候显然小球会把按钮擦去。针对这个问题,我在窗体上加了3个JPanel。第一个面板可以直接加到窗体上,把面板1设置成borderlayout布局。然后将面板二加到面板上的North或者其他位置。把第三个面板加到第一个center位置。然后从面板3上获取画布。代码如下:

 

//在窗体上加一个面板,使窗体变成白色
		jpl=new MyJpanel();
		jpl.setBackground(Color.WHITE);
		this.add(jpl);
		//布置这个面板的布局便于让小球从撒小球这个按钮下面出来
		jpl.setLayout(new BorderLayout());
		//再在上一个面板的北方即上面加一个面板,使其更漂亮
		jp2=new MyJpanel();
		 //设置就jp2的布局
		jp2.setLayout(new FlowLayout());
		jp2.setBackground(Color.WHITE);
		jpl.add(jp2,BorderLayout.NORTH);
		jb=new JButton("撒小球");
		//把小球加到面板的上方
		jp2.add(jb);
		jb1=new JButton("暂停");
		//把小球加到面板的上方
		jp2.add(jb1);
		jb2=new JButton("恢复");
		//把小球加到面板的上方
		jp2.add(jb2);
		//在最底层的面板上中心位置再加一个面板
	   jp3=new MyJpanel();	
	   jp3.setBackground(Color.white);
	   jpl.add(jp3,BorderLayout.CENTER);

      接下来可以把面板一设置成流体布局,在上面加3个按钮,撒小球,暂停,恢复。在按钮上加上一个监听器,这个监听器继承接口ActionListener。获取按钮上的内容,如果获得按钮上的内容是撒小球时,则向下撒一个小球。要想实现每点击一下撒小球的按钮就出来一个球。则需要加一个创建一个小球范型。代码如下:

public static List<Ball> listballs = new ArrayList<Ball>();
String command = e.getActionCommand();
		if (command.equals("撒小球")) {
			Ball ball = new Ball(this.jp5,this.listballs);
			ball.start();
			listballs.add(ball);
		}

 这样就实现了每点击一下撒小球按钮就出现一个小球。接下来就要创建和写小球Ball类了。因为想要小球运动。这样的话我们就用到线程了。线程就是通过一个程序产生几个进程的效果。他是每隔一段时间就执行一下。因此就可以达到每隔一段时间小球到达一个位置,在这样连续下就可以看做小球的运动。怎么运用线程类呢?通过继承Thread类或继承Runable接口。调用他们的run方法并且重写run方法。代码如下:

// 运用线程
	public void run() {
		// 调用父类的run方法
		super.run();
		// 当判断一致成立时 ,也就是当判断为真时
		while (true) {
			if (!pauseflag) {
				continue;
			}

			try {
			
				
				//判断小球的碰撞
				
				Thread.sleep(100);
				move();
			} catch (InterruptedException e) {

				e.printStackTrace();
			}
			
		}

	}

 Thread.sleep(100);是指每隔0.1S就执行一下run方法中的内容。可以通过在run方法中改变球圆心(x,y)的坐标来改变球的位置。于是我在下面写了move函数。在该函数中可以写关于圆心坐标改变的表达式,也可以写关于小球碰撞的表达式。代码如下:

public void move(){
    	x+=stepx;
		y+=stepy;
		// 为什么把这个写到构造函数中就不可以了呢 构造函数只执行一次run方法是一直执行的
		// 一般在run方法中是无限循环执行的
		// 执行某项任务
		if (x <= r) {
			//System.out.println("1111");
			stepx =Math.abs(stepx);
		}
		//很不理解为什么要在这里写成y <= r
		if (y <= r) {
			stepy = Math.abs(stepy);
		}
		if (x >= (jp4.getWidth() - r)) {
			stepx = -Math.abs(stepx);
		}
		if (y >= (jp4.getHeight() - r)) {
			stepy = -Math.abs(stepy);
		}
		

 在move函数中stepx,stepy是在x,y方向上的增量。如果想要小球从不同的方向出来,可以随机取得一个stepx的值这样在同一个点小球的出来方向不同。如果执行执行程序时,每隔0.1sx,y就变化一下。

if (x <= r) {
			//System.out.println("1111");
			stepx =Math.abs(stepx);
		}

 这句代码表示,当小球碰到面板3的左侧时,改变x的增量。使其方向改变,其他3个判断句读者可以举一反三。但是这样出来的小球运动会出现问题。小球前面的轨迹不能擦除。我们可以想出两个办法擦去原来的轨迹,第一,可以写一个Clear方法,在draw小球前把原来的位置用背景的颜色填充。我是用第二个方法。第二个方法就是用重绘的方法加上线程。代码如下:

new Thread(){
			public void run(){
				while(true){
					//repaint会直接执行paint中的方法
					jp3.repaint();
					try{
						Thread.sleep(10);
					}catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}
				}
				
					
		}.start();

 

 

每个画布都有默认的paint方法。在这个线程里,每隔一段时间调用一下paint方法。而我是在paint方法中画的球。这样就每隔一段时间显示这个球在不同的位置。这样前面的痕迹就不会再出现了。就写到这里了,明天我将要续写,写上怎么把球画的有立体感,怎么把暂停,恢复怎么加动态背景。晚安,世界。                             

 

 

 

 

 

 

 

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值