“运动世界”---小球漫步(3)

本文介绍了如何使用Java实现小球漫步的多线程动画效果,通过创建面板类、监听器类、小球类和线程类,实现小球的动态漫步。代码的模块化设计便于后期修改和理解,最终运行结果展示小球漫步的视觉效果,为编程带来成就感。
摘要由CSDN通过智能技术生成

明白了简单的小球运动后,再来看看小球是如何“漫步”的!----多线程的初步运用
                下面是多个小球的“漫步”图:

写出这样一个效果,我们需要建立四个类:面板类监听器类小球类线程类

【在不同的类中我们编写相对应的内容,这样做,一是,可以方便我们以后的修改;二是,有助于我们自己,对整个过程有一个自己的逻辑或认知。】    

 

面板类(ThreadUI)

public class ThreadUI  {
    public void ui(){
	    JFrame jframe = new JFrame();
		jframe.setSize(1500, 900);
		jframe.setLocationRelativeTo(null);
					
		Balllistener1 bl = new Balllistener1();
		jframe.addMouseListener(bl);
		jframe.addMouseMotionListener(bl);
		jframe.setVisible(true);
		
		Run run = new Run();                                //只能创建一个新的线程对象
		bl.allball = run.allball;                                //小球列表赋值给监听器上的列表
		run.start();                                                 //启动线程
		
		Graphics g = jframe.getGraphics();
		
		//传值传参数		
		run.setCS(jframe,g); 
		bl.setC(jframe, g);
		
	}
   	 
	 //主方法
	public static void main(String[] args){
		 ThreadUI threadui = new ThreadUI();		 
		 threadui.ui();		 
	 }

}
```

  监听器类(Balllistener1)


```
public class Balllistener1 implements ActionListener,MouseListener {	
	JFrame jframe;
	Graphics graph;
	int x1,y1;
	ArrayList<Ball> allball ;
	
    //传参(获取JFrame上的画图板与画布)
    public void setC(JFrame jframe,Graphics graph){
    	this.jframe = jframe; 
    	this.graph = graph;
    }
    
	public void actionPerformed(ActionEvent e){
	}	
	public void mouseClicked(MouseEvent e){	   
	   }	
	   
	public void mousePressed(MouseEvent e){
	    	x1 = e.getX();
	    	y1 = e.getY();
	    	
	    	// 每次按下鼠标出现五个小球 
	    	for(int i=0; i<5;i++) {      	
	    	Ball ba = new Ball(jframe,x1,y1,allball);
	    	allball.add(ba);
	    	}
	    }	    	
	public void mouseReleased(MouseEvent e){		
	}	    
	public void mouseEntered(MouseEvent e){		
	}	    
	public void mouseExited(MouseEvent e){		
	}
```

小球类(Ball)

public class Ball {
	Random rand = new Random();
		int r = rand.nextInt(255);              //随机产生颜色值
		int g = rand.nextInt(255);
		int b = rand.nextInt(255);
		int R = rand.nextInt(100);            //随机产生小球的大小(R为直径大小)
		int speedX = rand.nextInt(120);    //随机产生速度值
		int speedY = rand.nextInt(120);
		int height = 900;                              //边界宽度
		int width = 1500;                              //边界长度
		int life = 100;                                // 小球生命值
		int x,y;                                   //在界面上绘制时的x,y
		JFrame jframe;
		ArrayList<Ball> allball;         
		Graphics p;
		
		//传参(在鼠标监听器中执行)
		public Ball(JFrame jframe,int x,int y,ArrayList<Ball> allball){		
			this.x=x;
			this.y=y;
			this.allball=allball;
			this.jframe=jframe;		
		}
			
		//绘制小球
		public void drawball(Graphics graph){
			Color color = new Color(r,g,b);		
		    graph.setColor(color);
			graph.fillOval(x-R, y-R, R, R);
		}
				
		//返回小球的生命值---即在画图板上运动的时间
		public boolean islive(){
			return life>0;
		}
		//返回半径大于30的小球
		public boolean isR(){
			return R>30;
		}
		
		//小球碰壁并改变运动方向
		public void Change(){
			 if(y >= height){                           //球碰撞的下限
				 speedY *=-1;                         //速度反向
			 }else if(y <=50){
				 speedY *=-1;
			 }
			 if(x >= width){
				 speedX *=-1;
			 }else if(x <=50){
				 speedX *=-1;
			 }
			 x += speedX;                         //改变小球横轴方向
	//		 y -= speedY;                         //改变小球纵轴方向
			 life--;                                      //生命减小
		}
}	
```

线程类(Run)

public class Run extends Thread{
	Graphics g;       // 画布板上的画布
	int x,y;
	JFrame jframe;
	ArrayList<Ball> allball = new ArrayList<>();       //列表存储画的小球---列表可以随着小球的增加,列表长度增加
	
	//缓存--把小球都先缓存在缓存图片上----可以消除界面闪烁的状况
	BufferedImage buffer = new BufferedImage(1500,900, BufferedImage.TYPE_INT_ARGB);
	Graphics p = buffer.getGraphics();            // 获取缓存画布

    //传参(获取JFrame上得监听器与画图板)
    public void setCS(JFrame jframe,Graphics g){
    	this.jframe = jframe; 
    	this.g = g;
    }
    
    //小球线程
	public void run(){	
		 while(true){
			 try {
					Thread.sleep(100);
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			 
			 //清除痕迹
				p.setColor(jframe.getContentPane().getBackground());   //获得界面颜色(后画的会覆盖前画的)--用于清除之前画的小球
				p.fillRect(0, 0, jframe.getWidth(), jframe.getHeight());
				
			//把画的小球存入列表
			 for(int i=0; i<allball.size(); i++){
				 Ball ball = allball.get(i);			 
					ball.drawball(p);                      // 调用小球类中画球与改变方向的方法(用缓存画布画小球)
					ball.Change();
									 				
				 if(!ball.islive()){                         //小球生命值不大于0,则移除(见小球类)
					 allball.remove(i);					 
				 }if(!ball.isR()){                            //小球大小不大于30,则移除-----(见小球类)
					 allball.remove(i);
				 }				 
			 }
			 g.drawImage(buffer, 0, 0, null);			 //用画图板上的画布,整体画出列表中的小球
		}
	}
}

完成以上代码,最终小球“漫步”也就实现了~

【无论看代码还是写代码的过程都可能是枯燥乏味的,但每当看到代码运行之后的结果,感觉都会是很有成就的吧~】

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值