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 楼答案
需要了解的重要一点是
paintComponent
方法只是绘制组件,因为它当时看起来不是一个制作动画的地方我对你的代码做了两个小改动,让你有了这个想法:
从
paintComponent
中删除循环和睡眠添加了一个计时器,可以修改
oneX
和oneY
,并触发DrawPanel
的重新绘制你会想做更复杂的x和y坐标更新,你会想在
paintComponent
中画更多的东西,但我希望这能让你开始未来需要考虑的另一个技巧是:为每个要显示的对象创建一个类,并拥有该类的实例列表,而不是对象的每个属性的单独列表。这样,当你创建一个新对象时,只需要一个插入操作,列表中的一个
get
就可以为你提供绘制或更新它所需的所有属性