之前已经能产生许多小球,但是会发现小球和小球接触后,其中一个球的形状就消失了一部分,没有起到碰撞的效果,所以接下来就继续完成操作。
考虑到碰撞情况,无法就是考虑两球球心间距离与它们半径之和的比较关系,前者小于后者就发生碰撞,反之则没有发生。当然如果只有一个球,自然不会发生碰撞的哈!
//分析碰撞情况 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); } }
这样就既能实现小球碰撞的效果,然后又能让它们暂停,重新动起来,或者绕着滚·····你可以尝试弄出更多的效果,继而超越屏保的视觉效果!
相关推荐
在IT领域,尤其是在游戏开发与动画效果实现中,小球碰撞反弹算法是一个常见的技术要点,尤其是在J2ME(Java 2 Micro Edition)平台上的应用。本文将深入解析“小球碰撞反弹经典算法”这一主题,从算法的设计思路、...
标题“多线程之小球碰撞”涉及到的是计算机编程中的多线程技术,结合描述中的博文链接,我们可以推测这篇文章可能是通过一个模拟小球碰撞的示例来讲解多线程编程的概念和实践。在这个场景中,每个小球可以代表一个...
Java 第二阶段提升编程能力【线程(基础)】---- 代码 Java 第二阶段提升编程能力【线程(基础)】---- 代码 Java 第二阶段提升编程能力【线程(基础)】---- 代码 Java 第二阶段提升编程能力【线程(基础)】---- ...
通过JAVA运用多线程控制球的运动,通过窗口中的滑条,对球的大小和颜色进行选择后,随机从窗口左右两方择一进入,小球在遇到障碍或边界后会折回。
在"小球碰撞-炫彩版"这个项目中,开发者运用了Java编程语言来实现一个动态的、基于多线程的模拟系统。该系统的主要功能是展示一个小球在屏幕上不断摇摆,并与其他小球发生碰撞,同时球的颜色、速度和运动方向都会因...
在Java编程语言中,多线程是核心特性之一,它允许程序同时执行多个任务,从而提高了应用程序的效率和响应性。本实验通过“字符移动”和“小球碰撞”两个实例,深入浅出地展示了Java多线程的概念、创建与管理。 首先...
.......................................JAVA线程、线程池资料----下载不扣分,回帖加1分,欢迎下载,童叟无欺JAVA线程、线程池资料----下载不扣分,回帖加1分,欢迎下载,童叟无欺JAVA线程、线程池资料----下载不...
线程化小球动画的目的是让每个小球在屏幕上独立运动,互不干扰,从而实现流畅的动画效果。 要实现小球线程动画,我们需要以下关键步骤: 1. **创建小球类**:首先,定义一个表示小球的类,包含小球的位置、速度、...
这个题目可能是指在二维空间中模拟多个小球的物理碰撞,其中小球的运动不受用户控制,但可以通过调整代码中的参数(例如在manyballs类中)来改变小球的数量。 在Java编程中,实现这样的功能需要掌握以下几个关键...
在这个小球运行程序中,可能有多个线程分别控制不同小球的运动,使得小球们能够并行地在屏幕上移动。 描述中提到的“小球运行程序 (eclipse工程可导入)”,意味着这是一个已经构建好的Eclipse项目,用户可以直接...
在本篇中,我们将深入探讨"VC++课程设计之小球碰撞演示"这一主题,它涉及到计算机编程、图形渲染以及物理模拟等多个领域的知识。在这个项目中,学生利用Microsoft的Visual C++(VC++)集成开发环境,特别是MFC...
通过创建和管理多个线程,我们可以实现并发执行,使得小球在屏幕上同时运动。 要实现这个小球弹跳的多线程程序,我们需要以下步骤: 1. **创建线程类**:首先,我们需要定义一个表示小球运动的类,比如`...
Java多线程与线程安全实践-基于Http协议的断点续传 Java多线程与线程安全实践-基于Http协议的断点续传 Java多线程与线程安全实践-基于Http协议的断点续传 Java多线程与线程安全实践-基于Http协议的断点续传 Java多...
JAVA多线程与线程安全实践-基于Http协议的断点续传 JAVA多线程与线程安全实践-基于Http协议的断点续传 JAVA多线程与线程安全实践-基于Http协议的断点续传 JAVA多线程与线程安全实践-基于Http协议的断点续传 JAVA多...
Java多线程与线程安全编程实践-基于Http协议的断点续传.zip Java多线程与线程安全编程实践-基于Http协议的断点续传.zip Java多线程与线程安全编程实践-基于Http协议的断点续传.zip ...Java多线程与线程
Java多线程与线程安全实践-基于Http协议的断点续传Java多线程与线程安全实践-基于Http协议的断点续传Java多线程与线程安全实践-基于Http协议的断点续传Java多线程与线程安全实践-基于Http协议的断点续传Java多线程与...
Java多线程与线程安全实践-基于Http协议的断点续传.rarJava多线程与线程安全实践-基于Http协议的断点续传.rarJava多线程与线程安全实践-基于Http协议的断点续传.rarJava多线程与线程安全实践-基于Http协议的断点续传...
采用多线程的方式模拟小球碰撞的图形化方式