本次我们主要实现了三个功能:
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  没碰撞返回falsepublic Boolean isknockbound() {//小球球心坐标rx=lx+R/2;ry=ly+R/2;//是否碰到边界       因为缓冲画布不能遮挡鼠标   故下方距离应该往上提arguemwntBoolean 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   没碰撞返回falsepublic 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之小球碰撞反弹相关推荐

  1. Java反弹球两球相撞_java实现小球碰撞反弹

    java实现小球碰撞反弹 java实现小球碰撞反弹 首先我们要在一个窗口里面显示这个功能,因此引入JFrame类然后创建一个窗口代码如下: JFrame win=new JFrame();//新建窗口 ...

  2. 小球碰壁反弹加分_用Java实现小球碰壁反弹的简单实例(算法十分简单)

    用Java实现小球碰壁反弹的简单实例(算法十分简单) 核心代码如下: if(addX){ x+=3; }else{ x-=3; } if(addY){ y+=6; }else{ y-=6; } if( ...

  3. CCF软件认证题 java 201803-2 小球碰撞

    CCF软件认证题 java 201803-2 小球碰撞 问题描述 数轴上有一条长度为L(L为偶数)的线段,左端点在原点,右端点在坐标L处.有n个不计体积的小球在线段上,开始时所有的小球都处在偶数坐标上 ...

  4. java小球反弹_java实现小球碰撞反弹

    要实现这个功能做基础的就是要有一个小球,就像人吃饭这句话,少了人这个主角,说什么都是白说.世间所有事物都是对象,具有属性和操作,没有对象就没有一切.就下来我们就来生成一个小球,这里用到Panel类,创 ...

  5. html5使用canvas实现小球碰撞反弹实例

    使用 html5 中的 canvas, 实现小球相互碰撞并反弹,反弹算法比较简单. index.html <!DOCTYPE html> <html lang="en&qu ...

  6. javascript 小球碰撞反弹

    最近在学习JS,写一个小球弹来弹去的游戏 一.HTML部分 <!DOCTYPE html> <html>     <head>         <meta c ...

  7. 用Java实现小球碰壁反弹

    核心代码如下: if(addX){ x+=3; }else{ x-=3; } if(addY){ y+=6; }else{ y-=6; } if(x<=0||x>=(width-50)){ ...

  8. JS实现小球碰撞边界反弹-点击消失(详细解析实现思路)

    本篇文章给大家带来的是原生JS实现小球碰到边界就反弹,点击小球时小球被会销毁,并重新创建一个小球,让小球的数量一直保持在初始的数量,按照思路按步骤进行讲解,只需要源码的小伙伴可以定位到文本末尾直接复制 ...

  9. 小球自由落体及碰撞反弹

    目录 简述 构成 小球 按钮 运动轨迹 总结 简述 通过setInterval()定时刷新小球位置来完成小球运动状态,模拟自由落体加速度及碰撞反弹效果 构成 整体的物体很少,只有一个小球及一个开始按钮 ...

  10. js 小球碰壁反弹and小球碰撞

    好像好几天没有更博了呢,最近有点变懒了,这样不好,不好~~我们要做热爱学习的好孩子,嘻嘻,今天下午补上... 我们在学习js的时候,一个很经典的案例就是小球的碰壁反弹效果啦~简单的小球碰壁效果可以慢慢 ...

最新文章

  1. softmax实现cifar10分类
  2. 点击图片显示大图(有多张图片可以左右滑动)
  3. macOS安装Maven_IDEA集成Maven
  4. laravel windos 无法生成 appkey 的问题解决方法
  5. python 提取元组中的值_Python中的sqlite3提取与元组中的值相对应的条目 - python
  6. idea报错Cannot resolve jdk.tools:jdk.tools:1.7
  7. ERROR: libass not found using pkg-config2
  8. 计算机系统的日常运行维护,浅谈计算机系统的日常维护管理
  9. Hack the box -- 靶机渗透测试(TIER2)
  10. Java 实现word、excel、ppt、txt等办公文件在线预览功能!
  11. Word 排版:插入题注和引用题注
  12. 用Python做一个好玩的朋友圈九宫格抽奖
  13. crmeb阿里云短信配置
  14. Remember-Me功能
  15. 选择云服务器主要看那方面的参数和性能
  16. 软考新生必看!高项备考经验分享
  17. 数字化转型思考的延伸问题
  18. 用Vs调试STM32记事
  19. AI-DPL, you should know
  20. 教你如何拷贝IE浏览器的网址收藏夹

热门文章

  1. AVPlayer 音视频缓存方案
  2. Swift -- AVPlayerViewController播放本地视频并且通知重复播放
  3. 这几个小工具也太好用了
  4. MATLAB车牌识别GUI设计实现
  5. Mac下载安装maven
  6. 智汀、米家、苹果homekit智能门锁新体验,打开不一样的大门
  7. svn 合并分支 (svn操作手册)
  8. JEECG框架自定义下拉框
  9. 树莓派基础实验9:蜂鸣器实验
  10. python的scipy库无法使用_scipy库内存错误