首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 綜合教學

Java Swing 繪製動態愛心軌跡:參數方程、雙緩衝、線程動畫與資源加載最佳實踐

     編輯:Java 綜合教學

Swing 繪製動態愛心:從數學曲線到完整動畫

利用心臟線參數方程 x = 16 sin³θ, y = 13 cosθ - 5 cos2θ - 2 cos3θ - cos4θ,配合 Swing 定時重繪、雙緩衝、類路徑資源加載,實現一朵花瓣飛舞組成愛心的動畫效果。

核心繪圖組件 DrawLove

public class DrawLove extends JPanel {
    private Image petalImage;
    private double theta = 0;
    private final double scale = 15; // 縮放係數
    private final int centerX = 580, centerY = 240; // 畫布中心

    public DrawLove(String imagePath) {
        try {
            // 類路徑加載圖片(打包 JAR 後依然有效)
            petalImage = ImageIO.read(getClass().getClassLoader().getResourceAsStream(imagePath));
        } catch (IOException e) { e.printStackTrace(); }
        setLayout(null);
    }

    public void addTheta(double delta) { this.theta += delta; }
    public double getTheta() { return theta; }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        if (petalImage == null) return;
        Graphics2D g2 = (Graphics2D) g;
        // 參數方程計算座標
        double x = centerX - scale * (16 * Math.pow(Math.sin(theta), 3));
        double y = centerY - scale * (13 * Math.cos(theta) - 5 * Math.cos(2*theta) - 2 * Math.cos(3*theta) - Math.cos(4*theta));
        g2.drawImage(petalImage, (int)x, (int)y, null);
    }
}

動畫線程控制

public class LoveAnimation implements Runnable {
    private final DrawLove love;
    private final JFrame frame;
    private final int frameDelay = 30; // ms
    private final double thetaStep = 0.03; // 每幀角度增量

    public LoveAnimation(DrawLove love, JFrame frame) {
        this.love = love; this.frame = frame;
    }

    @Override
    public void run() {
        while (love.getTheta() < 2 * Math.PI) {
            love.addTheta(thetaStep);
            love.repaint(); // 觸發 paintComponent
            love.revalidate();
            try { Thread.sleep(frameDelay); } catch (InterruptedException ignored) {}
        }
        // 動畫結束清理
        SwingUtilities.invokeLater(() -> frame.getContentPane().remove(love));
    }
}

主程序啟動

public class Main {
    public static void main(String[] args) {
        JFrame frame = new JFrame("Love Animation");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(800, 600);
        frame.setLocationRelativeTo(null);

        DrawLove love = new DrawLove("petal.png"); // src/resources/petal.png
        frame.getContentPane().add(love);
        frame.setVisible(true);

        new Thread(new LoveAnimation(love, frame)).start();
    }
}

關鍵技術點總結

  1. 參數方程:心臟線方程產生平滑愛心軌跡,theta 從 0 到 2π 掃描一周。
  2. 雙緩衝:JPanel 默認開啟雙緩衝,repaint() 異步合併繪圖請求,無閃爍。
  3. 資源加載:getClass().getClassLoader().getResourceAsStream() 支持 IDE 運行、JAR 打包、WebStart 等多種部署方式,避免絕對路徑失效。
  4. 線程安全:動畫線程僅修改 theta、調用 repaint(),實際繪圖在 EDT (Event Dispatch Thread) 執行,符合 Swing 單線程規則。
  5. 性能優化:可預先計算軌跡點座標數組,動畫時直接索引,減少三角函數重複計算。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved