我试着用Java.Swing做一个动画,但是帧率很低,而且不稳定

bd1hkmkf  于 2023-04-04  发布在  Java
关注(0)|答案(1)|浏览(109)

我想模拟物理与实体相互作用在jave.我想动画的模拟.我读了一个教程,如何使动画与Java.Swing一切正常,但模拟的帧率是低,即使我不模拟很多东西.即使我的笔记本电脑不是更强大的一个,它的stills能够正常计算这个模拟.
这是我模拟的实体

public class Point {

    private int x; 
    private int y;
    private int[] speed = new int[2]; 

    public Point(int x, int y) {
        this.x = x;
        this.y = y;
    }

    public int[] get_position() {
        return new int[]{this.x, this.y};
    }

    public int[] get_speed() {
        return this.speed;
    }

    public void modify_position(int x, int y) {
        this.x = x;
        this.y = y;
    }

    public void modify_speed(int speed_x, int speed_y) {
        this.speed[0] = speed_x;
        this.speed[1] = speed_y;
    }

    public void add_position(int speed_x, int speed_y) {
        this.x += speed_x;
        this.y += speed_y;
    }
}

下面是JPanel代码

import javax.swing.*;

import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.event.*;
import java.util.ArrayList;

public class SimulationPanel extends JPanel implements ActionListener {

    public ArrayList<Point> listPoints = new ArrayList<Point>();

    private int width = 1000;
    private int height = 1000;

    public SimulationPanel() {
        
        Point p1 = new Point(10, 10);
        Point p2 = new Point(20, 20);
        Point p3 = new Point(30, 30);

        p1.modify_speed(5, 1);
        p2.modify_speed(1, 5);
        p3.modify_speed(5, 5);

        listPoints.add(p1);
        listPoints.add(p2);
        listPoints.add(p3);
        setPreferredSize(new Dimension(width, height));
        Timer timer = new Timer(40, this);
        timer.start();
    }

    public void actionPerformed(ActionEvent e) {
        if (e.getSource() instanceof Timer) {
            for (Point p : listPoints) {
                p.add_position(p.get_speed()[0], p.get_speed()[1]);
            }
            repaint();
        }
    }

    @Override
    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D g2 = (Graphics2D) g.create();
        g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        g2.setColor(java.awt.Color.RED);        
        for (Point p : listPoints) {
            g2.fillOval(p.get_position()[0], p.get_position()[1], 10, 10);
        }
        g2.dispose();
    }
}

最后是JFrame文件

import javax.swing.*;

public class SimulationFrame {

    public SimulationFrame() {
        JFrame simulationFrame = new JFrame();
        simulationFrame.setContentPane(new SimulationPanel());
        simulationFrame.pack();
        simulationFrame.setLocation(0, 0);
        simulationFrame.setVisible(true);
        simulationFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }

    public static void main(String[] args) {
        new SimulationFrame();
    }
}

我试图优化我的代码,以增加帧速率水平,但似乎没有工作

kmpatx3s

kmpatx3s1#

我对你的代码做了一些小改动。
1.我调用了SwingUtilitiesinvokeLater方法来启动应用程序。此方法确保Swing组件在Event Dispatch Thread上创建和执行。
1.我将simulationFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);移动到了正确的位置。JFrame方法必须以特定的顺序调用。
1.我降低了点的速度。如果你想要平滑的运动,你应该在一个时间段内只移动像素或像素的分数。为了弥补速度较慢,我降低了摆动Timer时间。最小摆动Timer时间是5毫秒。
下面是完整的可运行代码。我把你的附加类放在内部类中,这样我就可以把代码编译、运行和发布为一个块。

import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.Timer;

public class SimulationFrame {

    public SimulationFrame() {
        JFrame simulationFrame = new JFrame();
        simulationFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        simulationFrame.setContentPane(new SimulationPanel());
        simulationFrame.pack();
        simulationFrame.setLocation(0, 0);
        simulationFrame.setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                new SimulationFrame();
            }
        });
    }

    public class SimulationPanel extends JPanel implements ActionListener {

        private static final long serialVersionUID = 1L;

        public ArrayList<Point> listPoints = new ArrayList<Point>();

        private int width = 1000;
        private int height = 1000;

        public SimulationPanel() {

            Point p1 = new Point(10, 10);
            Point p2 = new Point(20, 20);
            Point p3 = new Point(30, 30);

            p1.modify_speed(2, 1);
            p2.modify_speed(1, 2);
            p3.modify_speed(2, 2);

            listPoints.add(p1);
            listPoints.add(p2);
            listPoints.add(p3);
            setPreferredSize(new Dimension(width, height));
            Timer timer = new Timer(20, this);
            timer.start();
        }

        public void actionPerformed(ActionEvent e) {
            if (e.getSource() instanceof Timer) {
                for (Point p : listPoints) {
                    p.add_position(p.get_speed()[0], p.get_speed()[1]);
                }
                repaint();
            }
        }

        @Override
        public void paintComponent(Graphics g) {
            super.paintComponent(g);
            Graphics2D g2 = (Graphics2D) g.create();
            g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                    RenderingHints.VALUE_ANTIALIAS_ON);
            g2.setColor(java.awt.Color.RED);
            for (Point p : listPoints) {
                g2.fillOval(p.get_position()[0], p.get_position()[1], 10, 10);
            }
            g2.dispose();
        }
    }

    public class Point {

        private int x;
        private int y;
        private int[] speed = new int[2];

        public Point(int x, int y) {
            this.x = x;
            this.y = y;
        }

        public int[] get_position() {
            return new int[] { this.x, this.y };
        }

        public int[] get_speed() {
            return this.speed;
        }

        public void modify_position(int x, int y) {
            this.x = x;
            this.y = y;
        }

        public void modify_speed(int speed_x, int speed_y) {
            this.speed[0] = speed_x;
            this.speed[1] = speed_y;
        }

        public void add_position(int speed_x, int speed_y) {
            this.x += speed_x;
            this.y += speed_y;
        }
    }
}

相关问题