精华内容
下载资源
问答
  • java小球碰撞边框反弹并且互相碰撞消失
  • Java小球碰撞反弹

    2021-01-27 16:22:14
    1,小球碰壁反弹、小球相互碰撞反弹。 2,使用缓冲绘图解决闪屏问题。 3,增加暂停按钮,实现界面动、停控制。 一,创建一个类ShowUI实现窗体界面 package com.yzd0126.BallsRebound; import java.awt.Color; ...

    本次我们主要实现了三个功能:
    1,小球碰壁反弹、小球相互碰撞反弹。
    2,使用缓冲绘图解决闪屏问题。
    3,增加暂停按钮,实现界面动、停控制。
    一,创建一个类ShowUI实现窗体界面

    package com.yzd0126.BallsRebound;
    
    import java.awt.Color;
    import java.awt.FlowLayout;
    import java.awt.Graphics;
    import java.util.ArrayList;
    import java.util.List;
    
    import javax.swing.JButton;
    import javax.swing.JFrame;
    
    public class ShowUI extends JFrame{
    	//展示界面
    	public void UI() {
    		this.setSize(800,600);//设置界面大小
    		this.setTitle("球球碰撞");
    		this.setLocationRelativeTo(null);//界面位于屏幕中央
    		this.setLayout(new FlowLayout());//使用流式布局
    		this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//退出时关闭		       
    		this.setVisible(true);//界面设置可见		
    	}
    	
    	//主函数  程序入口
    	public static void main(String[] args) {
    		ShowUI showui = new ShowUI();
    		showui.UI();
    	}
    
    }
    

    二,创建小球类Ball
    1,在创建完Ball类之后,在界面类ShowUI中创建一个全局用来保存所有小球的动态数组balls。

    //全局用来存储小球对象的数组
    	List<Ball> balls = new ArrayList<>();
    

    之所以将ArrayList向上转型为List,是因为这样写体现了面向接口编程的思想。List是一个接口,ArrayList是实现List接口的一个具体实现类,能够降低程序的耦合度,当我们发现代码使用的集合不正确应该使用的是LinkedList时,只需要修改以下一行代码就可:

    List<Ball> balls = new LinkedList<>();
    

    因为之后所有的操作都是针对List这个接口定义的方法,而与实现类的独特方法无关,如果我们一开始直接使用ArrayList类型而不向上转型,那么之后如果涉及到ArrayList类独特的方法时需要修改的地方比较多,不便于程序的维护。

    2,在Ball类中定义每个小球需要的属性以及方法
    关于运动小球的属性有:小球外接圆左上角坐标lx、ly,小球速度vx、vy,小球直径R、小球颜色color,小球球心rx、ry,画笔参数g。
    关于运动小球的方法有:
    2.1构造方法传参,随机生成小球位置、速度、颜色。

    	//构造函数   传参
    	public Ball(Graphics g,List balls) {
    		this.g=g;
    		this.balls=balls;
    		Random random = new Random();
    		//随机产生小球坐标  速度  颜色
    		lx=random.nextInt(600);
    		ly=random.nextInt(200)+50;
    		vx=(float) (random.nextInt(4)+2);
    		vy=(float) (random.nextInt(3)+2);
    		color=new Color(100+random.nextInt(90),100+random.nextInt(90),100+random.nextInt(90));
    	}
    

    2.2判断小球是否碰到边界。

    	//判断小球是否碰到边界   碰撞了返回true  没碰撞返回false
    	public Boolean isknockbound() {
            //小球球心坐标
    		rx=lx+R/2;
    		ry=ly+R/2;
    		//是否碰到边界       因为缓冲画布不能遮挡鼠标   故下方距离应该往上提arguemwnt
    		Boolean b1=((rx)<=(R/2))||((rx)>=(SCREENX-R/2))||((ry)<=(R/2))||((ry)>=(SCREENY-R/2-arguement));
    		if(b1) {
    			return true;
    		}
    		return false;
    	}
    

    2.3判断小球之间是否相互碰撞。
    小球之间的相互碰撞和碰壁略有不同,碰壁对于每个边界只有一种情况,但是对于球之间的碰撞有可能该球和左边的球碰也有可能是和右边的球碰,因此碰完速度改变的方向也不同,在该方法中直接改变小球速度。

    	//判断小球之间是否碰撞  碰撞了返回true   没碰撞返回false
    	public Boolean isknockballs() {
    		  for (int i = 0; i < balls.size(); i++)   //判断小球间是否发生碰撞
              {
                  Ball ball = (Ball) balls.get(i);
                  //排除取到两个相同的球
                  if (this.equals(ball))
                      continue;
                  //发生了碰撞
                  if ((ball.lx-lx) * (ball.lx-lx) + (ball.ly-ly) * (ball.ly -ly) <= R*R) 
                  {
                	  //获取于自己发生碰撞的小球之间的夹角(反正切)  角度只能再-pi/2~pi/2   因此还需判断两球x坐标关系
                	  double degree = Math.atan((ly - ball.ly) / (lx - ball.lx));
                      if (lx > ball.lx)      //如果自己的x坐标大于发生碰撞的小球的x坐标,由数学知识可知自己应该往正向运动
                      {
                          vx = (float) Math.cos(degree)+2;
                          vy = (float) Math.sin(degree)+2;
                      }
                      else    //如果自己的x坐标小于发生碰撞的小球的x坐标,由数学知识可知应该朝负向运动
                      {
                          vx = (float) -Math.cos(degree)-2;
                          vy = (float) -Math.sin(degree)-2;
                      }
                     return true;
    
                  }
              }
    		return false;
    	}
    

    2.4小球移动方法。
    小球的基本移动方法是:位置=位置+速度。

    	//移动方法
    	public void move() {	
    		lx=lx+vx;//位置=位置+速度
    		ly=ly+vy;	
    	}
    

    但小球发生了碰撞之后移动方法要发生变化,要对小球的速度进行操作。当与边界发生碰撞时速度直接取反,当小球之间发生碰撞时直接在isknockballs方法中直接对速度进行改变。

    		//如果小球碰到边界  则反弹  速度取反
    		if(isknockbound()) {
    			vx=-vx;
    			vy=-vy;
    		}//如果小球之间相互碰撞   按情况改变速度  在isknockballs()方法中改变
    		else if(isknockballs()) {
    			
    		}
    

    2.5画小球方法。
    将画笔的颜色指定为生成该小球对象时的颜色,在指定位置画出小球。

    	//画方法
    	public void draw(Graphics g) {
    		  g.setColor(color);
    		  g.fillOval((int)lx, (int)ly, R, R);
    	}
    

    三,在线程中重写run()方法,使用缓存画图
    1,使用构造方法,将小球参数传入,使的全局使用的参数一致。

    	Graphics g;
    	Color color;
    	List balls;
    	//构造方法  传参
    	public MyThread(Graphics g,Color color,List balls) {
    		this.g=g;
    		this.color=color;
    		this.balls=balls;
    	}
    

    2,重写run()方法,将画的操作全部放在缓存中,每隔10ms在缓存中将所有的小球取出移动、画完之后,再在界面中展示出来,这样可以解决闪屏问题。

    	//重写run方法
    	public void run() {
    		//创建缓存
    		BufferedImage buffer = new BufferedImage(800,600,BufferedImage.TYPE_INT_ARGB);
    		//获取缓存上的画布
    		Graphics bgriphics = buffer.getGraphics();
    		//使线程不终止
    		while(true) {
    				//清屏
    				bgriphics.setColor(Color.BLACK);
    				bgriphics.fillRect(0, 0 , 800,600);
    				bgriphics.setColor(color);
    				for(int i=0;i<balls.size();i++) {
    					Ball ball=(Ball) balls.get(i);
    					ball.move();
    					ball.draw(bgriphics);			
    				}
    				//显示缓存  在界面上 将所有缓存上用bufferGraphics画完的图形只用一次用之前界面上的画笔g展现处理啊
    				g.drawImage(buffer, 0, 65,null);//0,65为图形左上角坐标     65为了不遮挡鼠标
    				
    		    //每过10ms利用缓存将数组中全部的小球移动+画出+清屏
    			try{
    				Thread.sleep(10);
    			}catch(Exception ef) {};
    
    		}
    	}
    

    四,创建监听,实现暂停功能
    1,在线程类Mythread中定义一个Boolean类型的变量isgo,根据isgo的状态判断是否执行清屏、画等操作,而不是让线程终止,因为线程一旦终止便无法再开启。同时加入IsGo()方法,每调用一次改变一次isgo状态,这样就能够实现暂停和开始的切换。

    Boolean isgo=false;//参数   判断是否然后小球动起来
    	
    	//按钮调用此方法    每按下一次  改变一次isgo状态
    	public void IsGo() {
    		isgo=!isgo;
    	}
    	
    	//重写run方法
    	public void run() {
    		//创建缓存
    		BufferedImage buffer = new BufferedImage(800,600,BufferedImage.TYPE_INT_ARGB);
    		//获取缓存上的画布
    		Graphics bgriphics = buffer.getGraphics();
    		//使线程不终止
    		while(true) {
    			//根据每过10ms  根据isgo状态判断是否让小球动起来
    			if(isgo) {
    				//清屏
    				bgriphics.setColor(Color.BLACK);
    				bgriphics.fillRect(0, 0 , 800,600);
    				bgriphics.setColor(color);
    				for(int i=0;i<balls.size();i++) {
    					Ball ball=(Ball) balls.get(i);
    					ball.move();
    					ball.draw(bgriphics);			
    				}
    				//显示缓存  在界面上 将所有缓存上用bufferGraphics画完的图形只用一次用之前界面上的画笔g展现处理啊
    				g.drawImage(buffer, 0, 65,null);//0,65为图形左上角坐标     65为了不遮挡鼠标
    			}
    		    //每过10ms利用缓存将数组中全部的小球移动+画出+清屏
    			try{
    				Thread.sleep(10);
    			}catch(Exception ef) {};
    
    		}
    	}
    

    2,创建监听类MyListener,对鼠标动作进行监听
    2.1,界面添加按钮绑定监听

    		//创建按钮   添加到界面上
    		JButton jbutton=new JButton("start");
    		this.add(jbutton);
    		//创建监听器对象
    		MyListener mylistener=new MyListener(jbutton);
    		//按钮绑定监听
    		jbutton.addActionListener(mylistener);
    

    2.2,在ShowUI类中创建线程对象thread,将线程对象传入MyListener类中,鼠标每点击一次,线程对象thread都调用一次MyThread中的IsGo()方法,改变isgo状态,同时通过count计数取余改变按钮上的字。

    		//创建线程   
    		MyThread mythread=new MyThread(g,color,balls);
    		//创建监听器对象
    		MyListener mylistener=new MyListener(jbutton,mythread);
    
    package com.yzd0126.BallsRebound;
    
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    
    import javax.swing.JButton;
    
    public class MyListener implements ActionListener{
    	private int count=0;//取余  用来切换按钮上的字
    	JButton jbutton;
    	MyThread mythread;
    	public MyListener(JButton jbutton,MyThread mythread) {
    		this.jbutton=jbutton;
    		this.mythread=mythread;
    	}
    	   public void actionPerformed(ActionEvent e) {
    		   //每按下一次按钮  就要调用线程的IsGo方法  切换isgo状态   判断是否执行画操作
    		   mythread.IsGo();
    		   //count计数   取余切换按钮上的字符
    		   count++;
    		   if(count%2==1) {
    			   jbutton.setText("stop");
    		   }else
    		   {
    			   jbutton.setText("start");
    		   }
    	   }
    
    }
    

    五,启动线程,实现功能
    在ShowUI类中一次性添加20个小球,然后启动线程运行程序。

    		//一次添加20个小球进去 
    		for(int i=0;i<20;i++) {
    			Ball ball=new Ball(g,balls);
    			balls.add(ball);
    		}
    				//启动线程
    		mythread.start();
    

    在这里插入图片描述

    展开全文
  • java实现小球碰撞反弹

    千次阅读 2018-01-29 15:57:30
    接下来就是让这个小球动起来,我们让这个小球向右移动,我们用线程和异常来实现。代码如下: 1.Thread t=new Thread(my);//新建线程 t.start();//开始线程 2.implements Runnable 3.public void run() {//...

    首先我们要在一个窗口里面显示这个功能,因此引入JFrame类然后创建一个窗口代码如下:

    JFrame win=new JFrame();//新建窗口  
    win.setLocation(250,100);//设置窗口位置  
    win.setSize(800,600);//设置窗口大小  
    win.show();//显示窗口
    win.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//设置关闭退出

    显示如下:
    java实现小球碰撞反弹
    要实现这个功能做基础的就是要有一个小球,就像人吃饭这句话,少了人这个主角,说什么都是白说。世间所有事物都是对象,具有属性和操作,没有对象就没有一切。就下来我们就来生成一个小球,这里用到Panel类,创建一个MyPanel类继承于Panel类然后创建一个画画方法。代码如下:

    class MyPanel extends Panel{
    public void paint(Graphics g) {
    g.setColor(Color.yellow);
    g.fillOval(100, 40, 80, 80);
    }
    }

    创建一个对象my,添加进win窗口里。代码如下:

    MyPanel my=new MyPanel();
    win.add(my);

    效果如下:
    java实现小球碰撞反弹

    接下来就是让这个小球动起来,我们让这个小球向右移动,我们用线程和异常来实现。代码如下:

    1.Thread t=new Thread(my);//新建线程  
    t.start();//开始线程  
    
    2.implements Runnable  
    
    3.public void run() {//运行方法  
            while(true){  
                repaint();//重新画圆  
                try {  
                    Thread.sleep(10);十毫秒运行一次  
                }  
                catch(Exception e) {  
    
                }  
            }  
        }  
    
    4.g.fillOval(x++, 40, 80, 80);//修改每次的横坐标  

    效果
    java实现小球碰撞反弹
    一步一步来,接下来我们要实现的目标就是让小球碰到边界可以反向走s。
    核心代码:

    [java] view plain copy
    int fly=1;  
    [java] view plain copy
    if (fly==1) {  
                x++;  
            }  
            if(fly ==2) {  
                x--;  
            }  
            if(x>720) {  
                fly=2;  
                y=y+70;  
            }  
            if(x<0) {  
                fly=1;  
                y=y+70;  
            }  

    效果
    java实现小球碰撞反弹
    好装备的差不多了,下面就开始实现完整功能了。
    效果如下:
    java实现小球碰撞反弹
    完整代码:

    [java] view plain copy
    package Ball;  
    
    import java.awt.Color;  
    import java.awt.Graphics;  
    import java.awt.Panel;  
    
    import javax.swing.JFrame;  
    
    public class Ball {  
    
        public static void main(String[] args) {  
            // TODO Auto-generated method stub  
            JFrame win=new JFrame();//新建窗口  
            win.setLocation(250,100);//设置窗口位置  
            win.setSize(800,600);//设置窗口大小  
            win.show();//显示窗口  
            win.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//设置关闭退出  
            MyPanel my=new MyPanel();  
            win.add(my);  
            Thread t=new Thread(my);  
            t.start();  
        }  
    
    }  
    
    class MyPanel extends Panel implements Runnable{  
            int x=0,y=0;  
            int flyx=1,flyy=1;  
        public void paint(Graphics g) {  
            g.setColor(Color.yellow);  
            g.fillOval(x, y, 70, 70);  
        //  System.out.println("23");  
            if (flyx==1) {  
                x++;  
            }  
            if(flyx ==2) {  
                x--;  
            }  
            if(flyy==1) {  
                y++;  
            }  
            if(flyy==2) {  
                y--;  
            }  
            if(x>730) {  
                flyx=2;  
            }  
            if(x<0) {  
                flyx=1;  
            }  
            if(y<0) {  
                flyy=1;  
            }  
            if(y>530) {  
                flyy=2;  
            }  
        }  
        public void run() {  
            while(true){  
                repaint();  
                try {  
    
                    Thread.sleep(10);  
                }  
                catch(Exception e) {  
    
                }  
            }  
        }  
    }  

    第一次写博客,写的不够详细,或者有错的地方欢迎大家的添加和指正,大家一起交流,我是个初学者,希望不要介意。

    转载于:https://blog.51cto.com/10972685/2066435

    展开全文
  • J2ME中小球碰撞检测之后自动反弹,算法设计非常精巧
  • 相信大家都对屏幕保护中的小球碰撞动画深有印象吧,许多色彩缤纷的小球在屏幕上滚动,碰撞,然后一直重复如此过程......现在就让我们自己尝试去做一下吧,或许你做的比它的要更好呦!  不必说,最重要也是最先弄的...

           相信大家都对屏幕保护中的小球碰撞动画深有印象吧,许多色彩缤纷的小球在屏幕上滚动,碰撞,然后一直重复如此过程......现在就让我们自己尝试去做一下吧,或许你做的比它的要更好呦!

           不必说,最重要也是最先弄的,自然是要产生小球啦,因此就要先创建一个球的线程类。这里先放上一些关于线程创建的知识,有助于大家巩固记忆啦。

     

    线程的创建有两种方式,分别为继承Thread类(已经实现了Runnable接口)与实现Runnable接口。

    1.Thread类

    常用方法包括:start()、interrupt()、join()、run()方法等。start()方法用于启动线程,run()方法为线程实现功能的方法,可以根据需求覆写run()方法。

    构造函数8个,常用4个:

    Thread thread=new Thread();                                  //无参的Thread类构造函数
    Thread thread=new Thread(Runnable simple);                   //参数为实现Runnable接口类对象的构造函数
    Thread thread=new Thread("ThreadName");                      //参数为线程名称的构造函数
    Thread thread=new Thread(Runnable simple,"ThreadName");      //无参的Thread类构造函数

    2.Runnable接口

    它只有一个方法就是run()方法,实现Runnable()接口后必须覆写run()方法。

    嗯,如上所说,先创建一个球的线程类:

    import java.awt.Color;
    import java.awt.Graphics;
    import java.awt.Graphics2D;
    import java.util.Random;
    
    import javax.swing.JPanel;
    
    
    public class MyThread extends Thread{
    
    	private JPanel panel;
    	private int x,y;//坐标位置
    	private int radius=50;//球半径
    	private int vx,vy;//横纵坐标该变量
    	private Color color;
    	
    	public MyThread(JPanel panel)
    	{
    		this.panel=panel;		
    		Random random=new Random();//创建一个随机类变量
    		vx=random.nextInt(20)+10;
    		vy=random.nextInt(10)+5;
    		radius=random.nextInt(10)+20;
    		color=new Color(random.nextInt(256),random.nextInt(256),random.nextInt(256));
    	}
    	
    	//重写run的方法
    	public void run()
    	{
    		Random random=new Random();
    		
    		//Graphics g=panel.getGraphics();//获得窗体界面
    		Graphics2D g2=(Graphics2D)panel.getGraphics();
    		
    		panel.setBackground(Color.BLACK);
    		while(true)
    		{
    			try{
    				Thread.sleep(100);//调用线程睡眠方法,让线程能暂缓进行
    			}catch(InterruptedException e ){
    				e.printStackTrace();
    			}
    			
    			//覆盖小球先前的轨迹
    			g2.setColor(panel.getBackground());//获得窗体背景颜色
    			g2.fillOval(x, y, 2*radius, 2*radius);
    					
    			x+=vx;
    			y+=vy;
    			
    			g2.setColor(color);
    			g2.fillOval(x, y, 2*radius, 2*radius);
    			
    			
    		    
    			
    			//若小球碰撞到面板边缘,则反弹
    			if(x<0||x>panel.getWidth()-2*radius)
    			{
    				vx=-vx;
    			}
    			if(y<0||y>panel.getHeight()-2*radius)
    			{
    				vy=-vy;
    			}
    		}
    	}
    }
    

     这里大概要注意两点吧:

     

    1.要覆盖小球先前的轨迹,不然所有时刻的轨迹都会显现在窗体上。

    2.考虑小球出界时的情况,设定反弹条件

     

    之后当然就是写一个测试类

     

    import java.awt.BorderLayout;
    import java.awt.Dimension;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    
    import javax.swing.JButton;
    import javax.swing.JFrame;
    import javax.swing.JPanel;
    
    
    public class TestFrame {
    
    	private JPanel centerpanel;
    	/**
    	 * @param args
    	 */
    	public static void main(String[] args) {
    		// TODO Auto-generated method stub
            TestFrame tf=new TestFrame();
            tf.init();
    	}
    	//初始化界面的方法
       public void init()
       {
    	   JFrame jf=new JFrame("线程入门");
    	   jf.setSize(800, 600);
    	   jf.setDefaultCloseOperation(3);
    	   jf.setResizable(false);
    	   
    	   JPanel northpanel=new JPanel();
    	   northpanel.setSize(800, 200);
    	   
    	   JButton jbu=new JButton("开始");
    	   //jbu.setPreferredSize(new Dimension(50,50));
    	   jbu.addActionListener(al);
    	   northpanel.add(jbu);
    	   
    	   jf.add(northpanel,BorderLayout.NORTH);
    	   
    	   centerpanel=new JPanel();
    	   jf.add(centerpanel,BorderLayout.CENTER);
    	   
    	   jf.setVisible(true);
       }
       ActionListener al=new ActionListener(){
    
    	@Override
    	public void actionPerformed(ActionEvent e) {
    		
    		MyThread thread=new MyThread(centerpanel);//创建一个线程
    		thread.start();//启动线程
    	}};
    }
    

     

     

    提醒下的是,最好创建两个面板,北边面板放按钮,中间面板当画布,这里小球运动时就不会影响到按钮的轮廓。

     

    这样操作完后,就能产生许许多多的小球啦。



     

     

     

     

     

    展开全文
  • 之前已经能产生许多小球,但是会发现小球小球接触后,其中一个球的形状就消失了一部分,没有起到碰撞的效果,所以接下来就继续完成操作。   考虑到碰撞情况,无法就是考虑两球球心间距离与它们半径之和的比较...

    之前已经能产生许多小球,但是会发现小球和小球接触后,其中一个球的形状就消失了一部分,没有起到碰撞的效果,所以接下来就继续完成操作。



     

    考虑到碰撞情况,无法就是考虑两球球心间距离与它们半径之和的比较关系,前者小于后者就发生碰撞,反之则没有发生。当然如果只有一个球,自然不会发生碰撞的哈!

    //分析碰撞情况
    			for(int i=0;i<al.size();i++)
    			{
    				Ball ball=al.get(i);//获取小球
    				if(ball==this)
    				{
    					continue;//重新开始循环,考虑下一个球
    				}
    				int xx=Math.abs((x+radius)-(ball.x+ball.radius));//两个球心所在纵线的距离
    				int yy=Math.abs((y-radius)-(ball.y-ball.radius));//两个球心所在水平线的距离
    				int len=(int)Math.sqrt(xx*xx+yy*yy);//球心之间的距离
    				if(len<radius+ball.radius)
    				{
    					int temp=vx;
    					vx=ball.vx;
    					ball.vx=temp;
    					
    					int temp1=vy;
    					vy=ball.vy;
    					ball.vy=temp1;
    					
    				}
    				
    			}

     

     

    这样就能实现小球碰撞的效果,只是还想球能够停止,然后又能动起来,或者是沿着窗体滚动,怎样弄呢?

    不妨设置三个标记,分别是暂停,停止,绕行标记,当符合标记,则按相应标记进行。此外补充说明,在测试类中要创建一个ArrayList类对象,保存所有出现的球,然后就可以随意地取出。

     

    下面是改进后的球的线程类代码;

     

    import java.awt.Color;
    import java.awt.Graphics;
    import java.util.ArrayList;
    import java.util.Random;
    
    import javax.swing.JPanel;
    
    
    public class Ball extends Thread{
    
    	private int x,y;//小球所在最小正方形的左上角坐标
    	private int vx,vy;//小球的各分向速度
    	private int radius;//小球的半径
    	private Color color;
    	private JPanel jpa;//画布所在面板
    	private ArrayList<Ball>al;//存储球的队列
    	private boolean PauseFlag;//暂停标志
    	private boolean StopFlag;//停止标志
    	private boolean RoundFlag;
    	/
    	private static final int FORWARD = 0;
    
    	 private static final int BACKWARD = 1;
    
    	 private static final int DOWN = 2;
    
    	 private static final int UP = 3;
    
    	 private int direction = FORWARD;
    	
    	//构造函数,传入放置画布的面板和存储所有球队列,而且设置球的参数
    	public Ball(JPanel jpa,ArrayList al)
    	{
    		this.jpa=jpa;
    		this.al=al;
    		Random rad=new Random();
    		vx=rad.nextInt(20)+2;
    		vy=rad.nextInt(25)+3;
    		radius=rad.nextInt(30)+10;
    		color=new Color(rad.nextInt(256),rad.nextInt(256),rad.nextInt(256));
    	}
    	
    	//添加暂停的方法
    	public void setPause(boolean flag)
    	{
    		PauseFlag=flag;
    	}
    	//添加环绕的方法
    	public void setRound(boolean flag)
    	{
    		RoundFlag=flag;
    	}
    	
    	public void run()
    	{
    		Graphics g=jpa.getGraphics();//获取画布
    		while(true)
    		{
    			try{
    				Thread.sleep(50);
    			}catch(InterruptedException e)
    			{
    				e.printStackTrace();
    			}
    		
    			//如果暂停标志为true,则循环在此处结尾,从头重新开始
    			if(PauseFlag)
    			{
    				continue;
    			}
    			
    			
    			//清屏操作
    			g.setColor(jpa.getBackground());
    			g.fillOval(x, y, radius*2, radius*2);
    			
    			
    			if(RoundFlag)
    			{
    				if (x+radius*2>jpa.getWidth() && direction == FORWARD)
    				    direction = DOWN;
    				   if (y+radius*2>jpa.getHeight() && direction == DOWN)
    				    direction = BACKWARD;
    				   if (x - radius * 2 <= 10 && direction == BACKWARD)
    				    direction = UP;
    				   if (y -radius*2 <=10&& direction == UP)
    				    direction = FORWARD;
    
    				   // compute angle start & extent
    				   if (direction == FORWARD) {
    				    x += 1;
    				    y = 0;
    				   }
    				   if (direction == DOWN) {
    				    x = jpa.getWidth() - 2*radius;
    				    y += 1;
    				   }
    				   if (direction == BACKWARD) {
    				    x -= 1;
    				    y = jpa.getHeight() - radius * 2+1;
    				   }
    				   if (direction == UP) {
    				    x = 0;
    				    y -= 1;
    				   }
    			}
    			
    			
    			
    			
    			//如果重置标志为true,则跳出循环
    			if(StopFlag)
    			{
    				return;
    			}			
    			
    			
    			//分析碰撞情况
    			for(int i=0;i<al.size();i++)
    			{
    				Ball ball=al.get(i);//获取小球
    				if(ball==this)
    				{
    					continue;//重新开始循环,考虑下一个球
    				}
    				int xx=Math.abs((x+radius)-(ball.x+ball.radius));//两个球心所在纵线的距离
    				int yy=Math.abs((y-radius)-(ball.y-ball.radius));//两个球心所在水平线的距离
    				int len=(int)Math.sqrt(xx*xx+yy*yy);//球心之间的距离
    				if(len<radius+ball.radius)
    				{
    					int temp=vx;
    					vx=ball.vx;
    					ball.vx=temp;
    					
    					int temp1=vy;
    					vy=ball.vy;
    					ball.vy=temp1;
    					
    				}
    				
    			}
    			//更改坐标情况 
    			x+=vx;
    			y+=vy;
    			
    			//小球出界反弹
    			if(x+radius*2>jpa.getWidth()||x<0)
    			{
    				vx=vx*(-1);
    			}
    			if(y+radius*2>jpa.getHeight()||y<0)
    			{
    				vy=vy*(-1);
    			}
    			
    			g.setColor(color);
    			g.fillOval(x, y, 2*radius, 2*radius);
    		}
    	}
    }
    

     

     

    然后是主界面类:

     

    import java.awt.BorderLayout;
    import java.awt.Color;
    import java.awt.FlowLayout;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.util.ArrayList;
    
    import javax.swing.JButton;
    import javax.swing.JFrame;
    import javax.swing.JPanel;
    
    
    public class BallJFrame {
    
    	/**
    	 * @param args
    	 */
    	public static void main(String[] args) {
    		BallJFrame bj=new BallJFrame();
    		bj.init();
    
    	}
    	
    	public void init()
    	{
    		final JFrame jf=new JFrame();
    		jf.setTitle("小球碰撞");
    		jf.setSize(500, 500);
    		jf.setDefaultCloseOperation(3);
    		jf.setLayout(new BorderLayout());
    		jf.setResizable(false);
    		
    		final ArrayList<Ball> arraylist=new ArrayList<Ball>();
    		
    		final JPanel jpa=new JPanel();
    		jpa.setBounds(0,30,500,450);
    		jpa.setBackground(Color.BLACK);//设置面板背景色为黑色
    		jf.add(jpa,BorderLayout.CENTER);
    		
    		ActionListener al=new ActionListener(){
                   						
    			public void actionPerformed(ActionEvent e) {
    				String str=e.getActionCommand();
    				
    				   if(str.equals("Add"))
    				   {
    					   Ball ball=new Ball(jpa,arraylist);
    					   ball.start();
    					   arraylist.add(ball);
    				   }
    				   if(str.equals("Stop"))
    				   {
    					   for(int i=0;i<arraylist.size();i++)
    					   {
    						   Ball ball=arraylist.get(i);
    						   ball.setPause(true);
    					   }
    				   }
    				   
    				   if(str.equals("Resume"))
    				   {
    					   for(int i=0;i<arraylist.size();i++)
    					   {
    						   Ball ball=arraylist.get(i);
    						   ball.setPause(false);
    					   }
    				   }
    				   
    				   if(str.equals("Round"))
    				   {
    					   for(int i=0;i<arraylist.size();i++)
    					   {
    						   Ball ball=arraylist.get(i);
    						   ball.setRound(true);
    					   }
    				   }
    			}
    			
    		};
    		
    		JPanel jpa2=new JPanel(new FlowLayout());
    		jpa2.setBounds(0,0,500,80);
    		
    		JButton jbu_add=new JButton("Add");
    		jbu_add.addActionListener(al);
    		jpa2.add(jbu_add);
    		
    		JButton jbu_stop=new JButton("Stop");
    		jbu_stop.addActionListener(al);
    		jpa2.add(jbu_stop);
    		
    		JButton jbu_resume=new JButton("Resume");
    		jbu_resume.addActionListener(al);
    		jpa2.add(jbu_resume);
    		
    		JButton jbu_round=new JButton("Round");
    		jbu_round.addActionListener(al);
    		jpa2.add(jbu_round);
    		
    		
    		jf.add(jpa2,BorderLayout.NORTH);
    		jf.setVisible(true);
    	}
    
    }
    

     这样就既能实现小球碰撞的效果,然后又能让它们暂停,重新动起来,或者绕着滚·····你可以尝试弄出更多的效果,继而超越屏保的视觉效果!

     



     

     

     

     

    展开全文
  • 相信大家都对屏幕保护中的小球碰撞动画深有印象吧,许多色彩缤纷的小球在屏幕上滚动,碰撞,然后一直重复如此过程......现在就让我们自己尝试去做一下吧,或许你做的比它的要更好呦!不必说,最重要也是最先弄的,...
  • java小球弹性碰撞

    千次阅读 2013-10-16 00:30:45
    源码: package E3;...import java.awt.Color; import java.awt.Dimension; import java.awt.Graphics; import java.awt.Image; import java.awt.Panel; import java.awt.event.KeyEvent; import java.awt.ev
  • java实现小球碰撞

    千次阅读 2018-11-03 00:29:01
    小球碰到窗体边缘的时候会产生反弹,当两个小球接触时会产生碰撞,双方交换速度,向相反方向移动。我们可以选择相应的颜色来改变下一个发射的小球颜色。当按下清除可以清除屏幕上的小球,当按下添加则会继续产生...
  • java碰撞小球

    2015-11-10 13:56:03
    import java.awt.BorderLayout; import java.awt.Color; import java.awt.Dimension; import java.awt.Graphics; import java.awt.Rectangle; import java.awt.event.ActionEvent; import java.awt
  • 多线程小球碰撞java线程第二节 多线程小球碰撞(粗糙)UIButtonListenerAddThread java线程第二节 多线程小球碰撞(粗糙) UI import java.awt.Color; import java.awt.FlowLayout; import java.awt.Graphics; import ...
  • Java碰撞小球游戏

    2019-05-15 23:50:27
    import java.awt.*; public class 小球 extends JFrame/*继承swing里面的窗口类*/ { //加载图片 Image ball = Toolkit.getDefaultToolkit().getImage("images/ball.jpg");/*得到系统默认的工...
  • 桌球游戏 此项目是“高淇300集”中的“37分钟零基础制作桌球小游戏”自己的实现与改进,增加了小球的减速运动。减速运动和真实物理模型还有差距,真实情况下小球应该不是做匀减速运动,日后...import java.awt.*; i...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 419
精华内容 167
关键字:

java小球碰撞反弹

java 订阅