碰撞圆代码

package zhang.start;

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

//视图层
public class AlgoFrame extends JFrame {
    private final int canvasWidth;
    private final int canvasHeight;

    public AlgoFrame(String title) {
        this(title, 1024, 768);
    }

    public AlgoFrame(String title, int canvasWidth, int canvasHeight) { //canvas 可绘制区域
        super(title);

        this.canvasWidth = canvasWidth;
        this.canvasHeight = canvasHeight;

        AlgoCanvas canvas = new AlgoCanvas();
        setContentPane(canvas);     //将canvas设置为窗口的内容面板
        pack();                     //进行布局整理,自动调整窗口大小

        setResizable(false);                                //不允许用户改变窗口的大小
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);     //点击X 窗口关闭
        setVisible(true);                                   //让窗口显示
    }

    public int getCanvasWidth() {
        return canvasWidth;
    }

    public int getCanvasHeight() {
        return canvasHeight;
    }

    private Circle[] circles;
    //绘制什么
    public void render(Circle[] circles) {
        this.circles = circles;    //将数据的对象传进来
        this.repaint();     //将JFrame中所有的控件重新刷新一遍
        //AlgoCanvas清空  重新调用paintComponent这个方法
    }

    //具体的绘制不方式在JFrame中 而是发生在Content Pane中
    private class AlgoCanvas extends JPanel {       // 面板     只供内部使用

        //双缓存   用户在屏幕上不会看到画布清空的那一瞬间
        public AlgoCanvas() {
            super(true);
        }

        @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, 1);
            AlgoVisHelper.setColor(g2d, Color.magenta);
            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());

            }

            //具体绘制
//            AlgoVisHelper.setStrokeWidth(g2d,5);
//
//            AlgoVisHelper.setColor(g2d,Color.magenta);
//            AlgoVisHelper.fillCircle(g2d,canvasWidth/2,canvasHeight/2,200);   //先画实心圆
//
//            AlgoVisHelper.setColor(g2d,Color.green);
//            AlgoVisHelper.strokeCircle(g2d,canvasWidth/2,canvasHeight/2,200);
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(canvasWidth, canvasHeight);    //画布的大小
        }
    }


}

package zhang.start;

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

public class AlgoVisHelper {

    private AlgoVisHelper() {
    }   //用户不能实例化这个类

    public static void setStrokeWidth(Graphics2D g2d,int w){
        g2d.setStroke(new BasicStroke(w,BasicStroke.CAP_ROUND,BasicStroke.JOIN_ROUND)); //线段端点、拐点圆形
    }

    public static void strokeCircle(Graphics2D g2d,int x,int y ,int r){
        Ellipse2D circle = new Ellipse2D.Float(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.Float(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 is sleeping");
        }

    }

}

package zhang.start;
import java.awt.*;
import java.awt.event.*;

//控制层   将视图层和数据层连接起来
public class AlgoVisializer {

    private final Circle[] circles;
    private AlgoFrame frame ;
    private boolean isAnimated = true ;

    public AlgoVisializer(int sceneWidth,int sceneHeight , int N) {
        //初始化数据
        circles = new Circle[N];
        int R = 50;    //圆的半径
        for (int i = 0; i < circles.length; i++) {
            int x = (int) (Math.random() * (sceneWidth - 2 * R)) + R;
            int y = (int) (Math.random() * (sceneHeight - 2 * R)) + R;
            int vx = (int) (Math.random() * 11) - 5;  //生成-5~5的随机数
            int vy = (int) (Math.random() * 11) - 5;  //生成-5~5的随机数
            circles[i] = new Circle(x, y, R, vx, vy);
        }

        //初始化视图
        //事件队列      Gui创建的代码放到新的线程中     事件分发线程  事件派生队列 、避免线程之间发生的错误
        EventQueue.invokeLater(
                () -> {
                    frame = new AlgoFrame("Wlcome", sceneWidth, sceneHeight);
                    frame.addKeyListener(new AlgoKeyListener());    //监听用户的键盘事件
                    frame.addMouseListener(new AlgoMouseListener());
                    //The Event Dispatch Thred  还要处理很多响应问题
                    //塞给事件派生队列的任务时无穷长的时间 ,导致阻塞了整个队列   其他部分无法相应
                    // Tasks on the event dispatch thread must finish quickly
                    //将动画的循环放进一个新的线程中
                    new Thread(
                            () -> {
                                run();
                            }
                    ).start();
                }
        );

    }

    //动画逻辑
    public void run(){
        while (true) {
            //绘制数据
            frame.render(circles);
            AlgoVisHelper.pause(20);    //控制速度
            //更新数据
            if (isAnimated){
                for (Circle circle : circles) {
                    circle.move(0, 0, frame.getCanvasWidth(), frame.getCanvasHeight());
                }
            }
        }
    }

    //添加键盘的响应事件   implements KeyListener  |   extends KeyAdapter
    private class AlgoKeyListener extends KeyAdapter {
        @Override
        public void keyReleased(KeyEvent e) {
            if (e.getKeyChar() == ' '){    //用户按了那个键
                isAnimated = !isAnimated ;
            }
        }
    }

    //添加鼠标的响应事件
    private class AlgoMouseListener extends MouseAdapter{
        @Override
        public void mousePressed(MouseEvent e) {
            e.translatePoint(0,-(frame.getBounds().height - frame.getCanvasHeight()) );
            for(Circle circle : circles) {
                if (circle.contain(e.getPoint()))
                    circle.isFilled = !circle.isFilled ;
            }
        }
    }


    public static void main(String[] args) {
        int sceneWidth = 800;
        int sceneHeight = 800;
        int N = 10;    //圆的数量
        AlgoVisializer algoVisializer = new AlgoVisializer(sceneWidth, sceneHeight, N);
    }

}

package zhang.start;

import java.awt.*;

//数据层
public class Circle {
    public int x , y ;
    public Boolean isFilled = false ;
    private int r ;
    private 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 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 point) {
        return (x - point.x) * (x - point.x) + (y - point.y) * (y - point.y) <= r * r ;
    }
}

你可能感兴趣的:(数据结构)