有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java如何从存储x、y值和整数索引之间的时间变化的两个数组列表创建动画?

我目前正在进行一个三体模拟(重力),我通过随机猜测dt(时间步长并将其放入一个迭代方程来计算每个新的x和y值在每次迭代之后,我将每个x和y值保存在一个ArrayList中,该列表覆盖了我输入变量的时间dt我对Java非常陌生,我会很感激每一个答案,尽管考虑到我对noobie的了解,我会更感激一个更简单的答案。(我是一个16岁的非英语国家的人,我为任何错误道歉) 我已经导入了ArrayList、List和LinkedList,我的x和y列表的一个例子是

List<Double> xlistobject1 = new ArrayList<Double>();
List<Double> ylistobject1 = new ArrayList<Double>();

在while循环迭代过程中:

xlistobject1.add(xobject1); // where xobject1 and yobject1 are the x and y
ylistobject1.add(yobject1); // coordinates

我已经研究了制作动画的最佳方法,但对我来说没有任何效果。我真的不能把我的脑袋放在画布、JFrame等等上面,因为它们需要很多关于这个话题的先验知识。由于时间跨度已经由n个迭代次数*dt定义,我想你不能在列表中的每个位置上画一个点,然后按play键,因为要创建一个相对平滑的动画,你必须在这个中加入一个计时器来设置一个固定的动画长度,比如30秒,这意味着你将时间重新缩放到这个固定长度上,最终会丢失精确坐标的信息,因为我的显示器只能显示1920x1080像素

我已经有了:

我复制了Eclipse安装中唯一一个可用的框架(在文本底部),并删除了已经存在的移动部分,试图移动到循环列表中的x和y值,直到我的列表被清除。在那之后,我会重新调整模拟的时间(n-counter*dt),使其适合20秒,每秒30帧,这样模拟有600个时间步,所以如果我没有出错,你必须除以(n-counter*dt)/600来获得x和y比例因子。我的主要问题是我的想法在Java中的实现。我希望我没有把你搞糊涂,也没有说废话。谢谢你的帮助!:) 这是我的“动画”——代码:

import java.util.ArrayList;
import java.util.List;
import java.util.LinkedList;
import java.util.Vector;
import java.util.Stack;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Graphics;

import javax.swing.JFrame;
import javax.swing.JPanel;

final public class Test
{

JFrame frame;
DrawPanel drawPanel;

private int oneX = 7;
private int oneY = 7;

public static void main(String... args)
{
    new Test().go();
}

private void go()
{
    frame = new JFrame("Test");
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    drawPanel = new DrawPanel();

    frame.getContentPane().add(BorderLayout.CENTER, drawPanel);

    frame.setResizable(false);
    frame.setSize(1920, 1000);
    frame.setLocationByPlatform(true);
    frame.setVisible(true);
    moveIt();
}

class DrawPanel extends JPanel
{
    private static final long serialVersionUID = 1L;

    public void paintComponent(Graphics g)
    {
        g.setColor(Color.BLUE);
        g.fillRect(0, 0, this.getWidth(), this.getHeight());
        g.setColor(Color.RED);
        g.fillRect(3, 3, this.getWidth() - 6, this.getHeight() - 6);
        g.setColor(Color.WHITE);
        g.fillRect(6, 6, this.getWidth() - 12, this.getHeight() - 12);
        g.setColor(Color.BLACK);
        g.fillRect(oneX, oneY, 6, 6);
        // Object 1
   !    for i = 0 to xlistobject1.count - 1
   !    //move circle to x=xlistobject1.item(i)
   !    //move circle to y=ylistobject1.item(i)
                next

                try
                { 
                     Thread.sleep(10);
                }
                catch (Exception e)
               {
                e.printStackTrace();
               }
               frame.repaint();
    }
}

}

########################################################## 我做了一些改变: -我现在有了一个存储坐标的Point2d列表,而不是坐标列表

动画部分的代码:

    import java.awt.BorderLayout;
    import java.awt.Color;
    import java.awt.Graphics;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import javax.swing.JFrame;
    import javax.swing.JPanel;
    import javax.swing.Timer;
    
   final public  class altanim {
    
        JFrame frame;DrawPanel drawPanel; public static int ni=1;  public static Boolean returnt=false;  public static Double plus1x, plus2x, plus3x, plus1y, plus2y, plus3y;
        public static Double zugriff1x=0.0, zugriff2x=0.0, zugriff3x=0.0, zugriff1y=0.0,zugriff2y=0.0, zugriff3y=0.0, nialtx3=0.0,nialtx2=0.0, nialtx1=0.0, nialty1=0.0, nialty2=0.0, nialty3=0.0;
        
            public static void main(String... args)  { 
            new altanim().go();
            }
            
            public void go()  {     
        if (returnt==false) {
        frame=new JFrame("3-Körper-Problem: Simulation:");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        drawPanel = new DrawPanel();
            frame.getContentPane().add(BorderLayout.CENTER, drawPanel);
            frame.setResizable(true);frame.setSize(3000,1600);
        frame.setLocationByPlatform(true);
        frame.setVisible(true);
        frame.setGlassPane(drawPanel);
        frame.setLocationRelativeTo(null);    
                     returnt=true;}
    
                Timer timer = new Timer(10, new ActionListener() { 
                    @Override public void actionPerformed(ActionEvent e) {
    if (!(leololwjkr2.listepunkteobjekt1.size()==0) && ni<leololwjkr2.listepunkteobjekt1.size()-1) {
    System.out.println(ni+2+"...");       zugriff1x=leololwjkr2.listepunkteobjekt1.get(ni).getX();
    zugriff2x=leololwjkr2.listepunkteobjekt2.get(ni).getX();
    zugriff3x=leololwjkr2.listepunkteobjekt3.get(ni).getX();      zugriff1y=leololwjkr2.listepunkteobjekt1.get(ni).getY();
    zugriff2y=leololwjkr2.listepunkteobjekt2.get(ni).getY();
    zugriff3y=leololwjkr2.listepunkteobjekt3.get(ni).getY();
    ni++ ;
            plus1x=zugriff1x; 
    plus2x=zugriff2x; 
    plus3x=zugriff3x; 
    plus1y=zugriff1y; 
    plus2y=zugriff2y; 
    plus3y=zugriff3y;
        } 
else {System.out.println("Fertig"); 
try {Thread.sleep(3000);} catch (Exception e4) {System.out.println(e);}         drawPanel.repaint();    }  }   }); timer.start();   }
    
        
        class DrawPanel extends JPanel { private static final long serialVersionUID = 1L; 
        
        public void paintComponent(Graphics g) {        
            System.out.println("nächstes...");                        
            g.setColor(Color.BLUE);  g.fillRect(0, 0, this.getWidth(), this.getHeight());g.setColor(Color.RED);   g.fillRect(3, 3, this.getWidth() - 6, this.getHeight() - 6);g.setColor(Color.WHITE); g.fillRect(6, 6, this.getWidth() - 12, this.getHeight() - 12);           // Rahmen
                     g.setColor(Color.BLUE);g.drawLine(zugriff1x.intValue(), zugriff1y.intValue(), plus1x.intValue(), plus1y.intValue());
                     g.setColor(Color.RED);g.drawLine(zugriff2x.intValue(), zugriff2y.intValue(), plus2x.intValue(), plus2y.intValue());
                     g.setColor(Color.GREEN);g.drawLine(zugriff3x.intValue(), zugriff3y.intValue(), plus3x.intValue(), plus3y.intValue()); } 
        } 
    }

############### 我的问题是底部的油漆组件没有任何作用,我想不出解决方案。请看一看。:)


共 (1) 个答案

  1. # 1 楼答案

    需要了解的重要一点是paintComponent方法只是绘制组件,因为它当时看起来不是一个制作动画的地方

    我对你的代码做了两个小改动,让你有了这个想法:

    1. paintComponent中删除循环和睡眠

    2. 添加了一个计时器,可以修改oneXoneY,并触发DrawPanel的重新绘制

    你会想做更复杂的x和y坐标更新,你会想在paintComponent中画更多的东西,但我希望这能让你开始

    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.awt.BorderLayout;
    import java.awt.Color;
    import java.awt.Graphics;
    
    import javax.swing.JFrame;
    import javax.swing.JPanel;
    import javax.swing.Timer;
    
    final public class SwingTest
    {
    
        JFrame frame;
        DrawPanel drawPanel;
    
        private int oneX = 7;
        private int oneY = 7;
    
        public static void main(String... args)
        {
            new SwingTest().go();
        }
    
        private void go()
        {
            frame = new JFrame("Test");
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    
            drawPanel = new DrawPanel();
    
            frame.getContentPane().add(BorderLayout.CENTER, drawPanel);
    
            frame.setResizable(false);
            frame.setSize(1920, 1000);
            frame.setLocationByPlatform(true);
            frame.setVisible(true);
            // added this timer, which updates every 100ms
            Timer timer = new Timer(100, new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    // move the box
                    oneX += 1;
                    oneY += 1;
                    drawPanel.repaint();
                }
            });
            timer.start();
        }
    
        class DrawPanel extends JPanel
        {
            private static final long serialVersionUID = 1L;
    
            public void paintComponent(Graphics g)
            {
                g.setColor(Color.BLUE);
                g.fillRect(0, 0, this.getWidth(), this.getHeight());
                g.setColor(Color.RED);
                g.fillRect(3, 3, this.getWidth() - 6, this.getHeight() - 6);
                g.setColor(Color.WHITE);
                g.fillRect(6, 6, this.getWidth() - 12, this.getHeight() - 12);
                g.setColor(Color.BLACK);
                g.fillRect(oneX, oneY, 6, 6);
                // removed your loop
            }
        }
    }
    

    未来需要考虑的另一个技巧是:为每个要显示的对象创建一个类,并拥有该类的实例列表,而不是对象的每个属性的单独列表。这样,当你创建一个新对象时,只需要一个插入操作,列表中的一个get就可以为你提供绘制或更新它所需的所有属性