GUI编程:键盘鼠标可控的泡泡撞击事件

这个程序总共创建了4个大类:
下面是程序运行的GIF动态图

运行GIF图片
通过键盘空格来控制泡泡的移动或者停止,通过鼠标点击来使得泡泡填充颜色,再次点击填充消失

1.AlgoFrame 继承JFrame类

import org.omg.PortableInterceptor.DISCARDING;

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

public class AlgoFrame extends JFrame {
    private  int canvasWidth;
    private  int canvasHeight;
    public  AlgoFrame(String title,int canvasWidth,int canvasHeight){
        super(title);
        this.canvasWidth = canvasWidth;
        this.canvasHeight = canvasHeight;
        AlgoCanvas canvas = new AlgoCanvas();
        canvas.setPreferredSize(new Dimension(canvasWidth,canvasHeight));
        setContentPane(canvas);
        pack();
        setSize(canvasWidth,canvasHeight);
        setResizable(false);
        setVisible(true);
    }
    public int getcanvasWidth(){return canvasWidth;}
    public int getCanvasHeight(){return canvasHeight;}
    private Circle[] circles;
    public void render(Circle[] circles){
        this.circles = circles;
        repaint();
    }
    private class AlgoCanvas extends JPanel{
        //zhi支持双缓存
        public AlgoCanvas(){
            super(true);
        }
        @Override//覆盖函数
        public void paintComponent(Graphics g){
            super.paintComponent(g);
            //g.drawOval(50,50,300,300);
            Graphics2D g2d = (Graphics2D)g;
            //抗锯齿
            RenderingHints hints  = new RenderingHints(RenderingHints.KEY_ANTIALIASING,
                                                       RenderingHints.VALUE_ANTIALIAS_ON);
            g2d.addRenderingHints(hints);
            //具体绘制
            AlgoVisHelper.setStrokeWidth(g2d,1);
            AlgoVisHelper.setColor(g2d,Color.red);
            for(Circle circle:circles)
                if(!circle.isFilled)
                AlgoVisHelper.strokeCircle(g2d,circle.x,circle.y,circle.getR());
                else
                    AlgoVisHelper.fillCircle(g2d,circle.x,circle.y,circle.getR());

        }
                   }
        @Override
        public Dimension getPreferredSize(){
            return  new Dimension(canvasWidth,canvasHeight);
        }

}

2.AlgoVisHelper算法绘制辅助函数类,即一个工具类


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

public class AlgoVisHelper {
    private AlgoVisHelper(){}
        public static void setStrokeWidth(Graphics2D g2d ,int w ){
            int strokeWidth = w;
            g2d.setStroke(new BasicStroke(strokeWidth,BasicStroke.CAP_ROUND,BasicStroke.JOIN_ROUND));
        }
        public static void strokeCircle(Graphics2D g2d,int x,int y,int r){
            Ellipse2D circle = new Ellipse2D.Double(x-r,y-r,2*r,2*r);
            g2d.draw(circle);
        }
    public static void fillCircle(Graphics2D g2d,int x,int y,int r){
        Ellipse2D circle = new Ellipse2D.Double(x-r,y-r,2*r,2*r);
        g2d.fill(circle);
    }

    public static void setColor(Graphics2D g2d,Color color ){
        g2d.setColor(color);
    }
    public static void pause(int t){
        try{
            Thread.sleep(t);
        }
        catch (InterruptedException e ){
            System.out.println("Error  in sleeping.");
        }
    }
    }

3.Circle类

添加相应的成员变量,(位置速度和半径)

import java.awt.*;

public class Circle{
    public int x,y;
    private int r;
    public int vx,vy;
    public boolean isFilled = false;
    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 miny,int maxx,int maxy){
        x +=vx;
        y +=vy;
        checkCollision(minx,miny,maxx,maxy);

    }
    private void checkCollision(int minx,int miny, int maxx,int maxy){
        if(x-r < minx){x = r;vx = -vx;}
        if(x+r >= maxx){x = maxx-r;vx = -vx;}
        if(y-r < miny){y = r;vy = -vy;}
        if(y+r >= maxy){y = maxy-r;vy = -vy;}
    }
    public boolean contain(Point p){
        return (x-p.x)*(x-p.x)+(y-p.y)*(y-p.y)<=r*r;
    }
}

4.AlgoVisualizer相当于一个控制类

同时控制数据以及视图(即circle 和 frame)

import java.awt.*;
import java.awt.event.*;

import static javafx.scene.input.KeyCode.R;

public class AlgoVisualizer {
    private Circle[] circles;
    private AlgoFrame frame;
    private  boolean isAnimated = true;
    public AlgoVisualizer(int  sceneWidth,int sceneHight,int N){
        circles = new Circle[N];

        int R = 50;
        for (int i =0;i<N;i++){
            int x =(int)(Math.random()*(sceneWidth-2*R)+R) ;
            int y =(int)(Math.random()*(sceneHight-2*R)+R) ;
            int vx =(int)(Math.random()*(10)-5) ;
            int vy = (int)(Math.random()*10)-5;
            circles[i] = new Circle(x,y,R,vx,vy);
        }

        EventQueue.invokeLater(() -> {
            frame = new AlgoFrame("Welcome",sceneWidth,sceneHight);
            frame.addKeyListener(new AlgoKeyListener());
            frame.addMouseListener(new AlgoMouseListener());
            new Thread(()->{
                run();
            }).start();
        });
    }
    private  void run(){
        while(true){
            //绘制数据
            frame.render(circles);
            AlgoVisHelper.pause(20);
            //geng更新数据
            if(isAnimated)
            for(Circle circle:circles)
                circle.move(0,0,frame.getcanvasWidth(),frame.getCanvasHeight());
        }

    }
    private class AlgoKeyListener extends KeyAdapter {
        @Override
        public void keyReleased(KeyEvent event){
            if ((event.getKeyChar() == ' '));
            isAnimated = !isAnimated;
        }
    }
    private  class AlgoMouseListener extends MouseAdapter{
        @Override
        public void mousePressed(MouseEvent event){
            event.translatePoint(0, -26);
            //System.out.println(event.getPoint());
            for (Circle circle:circles)
                if (circle.contain(event.getPoint()))
                    circle.isFilled = !circle.isFilled;
        }
    }
    public static void main(String[] args){
        int sceneWidth = 600;
    int sceneHeight = 600;
    int N = 10;
    AlgoVisualizer visualizer = new AlgoVisualizer(sceneWidth,sceneHeight,N);
}
}

这就是键盘鼠标可控的泡泡撞击事件的基本原理:有想交流的大佬们可评论区留言!

发布了8 篇原创文章 · 获赞 5 · 访问量 353

猜你喜欢

转载自blog.csdn.net/weixin_44269495/article/details/103475162