JavaSwing气泡碰撞动画

算法可视化教学视频上的demo感觉很有意思,就自己模仿写了一下,再添加了一个气泡间碰撞的判断(自己写的有bug,气泡生成位置重叠就会卡住)。

程序入口

import java.awt.*;

public class Main {


     public static void main(String[] args) {
          int sceneWidth=600,sceneHeight=600;//窗口大小
          int N=10;//气泡数量
          int r=20;//气泡半径
          Circle[] circles=new Circle[N];//存储气泡的数组
          for(int i = 0;i<N;i++){
               Circle circle=new Circle( (int)(Math.random()*(sceneWidth-2*r)+r),(int)(Math.random()*(sceneHeight-2*r)+r),r,(int)(Math.random()*7-4),(int)(Math.random()*6-3));
               circles[i]=circle;
          }
          EventQueue.invokeLater(new Runnable() {
               @Override
               public void run() {
                    AlgoFrame algoFrame=new AlgoFrame("algoframe",sceneWidth,sceneHeight);

                   new Thread(new Runnable() {
                         @Override
                         public void run() {
                              while (true){
                                   algoFrame.render(circles);
                                   try {
                                        Thread.sleep(10);
                                   } catch (InterruptedException e) {
                                        e.printStackTrace();
                                   }
                                   for(Circle circle:circles){
                                        circle.move(0,sceneWidth,0,sceneHeight-25);
                                        AlgoVisHelper.checkCircleCollision(circle,circles);
                                   }
                                   }
                         }
                    }).start();

               }
          });
     }
}

绘图工具类

import java.awt.*;
import java.awt.geom.Ellipse2D;

public class AlgoVisHelper {
    private AlgoVisHelper(){};
    public static void setStrokeWidth(Graphics2D g2D,int width){
         int strokeWidth=width;
          g2D.setStroke(new BasicStroke(width,BasicStroke.CAP_ROUND,BasicStroke.JOIN_ROUND));
    }
    public static void setColor(Graphics2D g2D,Color color){   g2D.setColor(color);}
    public static void strokeCircle(Graphics2D g2D,int x,int y,int r){
        Ellipse2D cirlce=new Ellipse2D.Float(x-r,y-r,2*r,2*r);
        g2D.draw(cirlce);
    }
    public static void fillCircle(Graphics2D g2D,int x,int y,int r){
        Ellipse2D cirlce=new Ellipse2D.Float(x-r,y-r,2*r,2*r);
        g2D.fill(cirlce);
    }
    public static void checkCircleCollision(Circle circle,Circle[] circles){//气泡间碰撞检测
        for(Circle circlel:circles){
            if(circle.x==circlel.x&&circle.y==circlel.y)
                continue;
            double a=Math.sqrt((circle.x-circlel.x)*(circle.x-circlel.x)+(circle.y-circlel.y)*(circle.y-circlel.y));
            int b=(int)a;
            if (a<=(circle.getR()*2)){
                circle.vy=-circle.vy;
                circle.vx=-circle.vx;
            }

        }

    }
}

气泡实体类

public class Circle {
    public int x;//圆的中心x坐标
    public int y;//圆的中心y坐标
    private int r;//圆的半径
    public int vx,vy;//圆的速度
    public Circle(int x,int y,int r,int vx,int vy){
        this.x=x;
        this.y=y;
        this.r=r;
        this.vx=vx;
        this.vy=vy;
    }
    public int getR(){  return r;}
    public void move(int minX,int maxX,int minY,int maxY){
        x+=vx;
        y+=vy;
        checkBorderCollision(minX,maxX,minY,maxY);
    }
    public void checkBorderCollision(int minX,int maxX,int minY,int maxY){//边界碰撞检测
        if (x<(minX+r)){  x=r;   vx=-vx;}
        if(x>=(maxX-r)){ x=maxX-r;  vx=-vx;}
        if (y<(minY+r)){  y=r;   vy=-vy;}
        if(y>=(maxY-r)){  y=maxY-r; vy=-vy;}
    }

}

Frame类

import javax.swing.*;
import java.awt.*;
import java.awt.geom.Ellipse2D;

public class AlgoFrame extends JFrame {
   private int width;
   private int height;
   private Circle[] circles;
   public AlgoFrame(String title,int width,int height){
       super(title);
       this.width=width;
       this.height=height;
       AlgoCanvas algoCanvas=new AlgoCanvas();
       algoCanvas.setPreferredSize(new Dimension(width,height));
       setContentPane(algoCanvas);
       pack();
       setResizable(false);
       setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
       setVisible(true);
   }

   public int getWidth(){return width;}
   public int getHeight(){ return height;}
   public void render(Circle[] circles){
      this.circles=circles;
      repaint();
   }
   private class AlgoCanvas extends JPanel{
       @Override
       protected void paintComponent(Graphics g) {
           super.paintComponent(g);
           Graphics2D g2d=(Graphics2D)g;
           //开启抗锯齿
           RenderingHints renderingHints=new RenderingHints(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
           g2d.addRenderingHints(renderingHints);
           //具体绘制
           AlgoVisHelper.setStrokeWidth(g2d,2);
           AlgoVisHelper.setColor(g2d,Color.BLUE);
           for(Circle circle:circles){
               AlgoVisHelper.strokeCircle(g2d,circle.x,circle.y,circle.getR());
           }
       }
       @Override
       public Dimension getPreferredSize(){
                    return new Dimension(width,height);
       }
   }

}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值