我使用以下代码生成正弦波:
这个动画的速度慢 - 快 - 慢。
代码:
public static final double SINE_TO_180 = 114.58865012930961, TIMES = 180, SINE_OF_90 = Math.sin(Math.toRadians(90));
public static void main(String[] args) throws Exception{
float velc = 200;
float angle = 45;
float resistance = 0f;
double multiple = (velc * 2.5 / SINE_TO_180);
int offset = 0;
double y = 0;
double x = 0;
double h = 0;
double cos = Math.cos(Math.toRadians(angle));
double sin = Math.sin(Math.toRadians(angle));
for(int i = offset; i < TIMES + 1 + offset; i ++){
y += ((Math.sin(Math.toRadians(i * 2)))) * multiple * sin;
if(y >= h)
h = y;
x += Math.sin(Math.toRadians(i)) * multiple * ((1 - resistance) * 1.5) * Math.abs(cos);
// x += multiple * cos;
// if(i + offset < TIMES / 2){
// x += Math.sin(Math.toRadians(i)) * multiple * ((1 - resistance) * 1.5);
// }else{
// x += Math.sin(Math.toRadians(TIMES / 2)) * multiple * (1 - resistance);
// }
}
y = Math.round(y);
//do round x?
x = Math.round(x);
System.out.println("X: " + x);
JFrame frm = new JFrame("Projectile!");
frm.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
BufferedImage b = new BufferedImage((int)x + 1, (int)h + 1, BufferedImage.TYPE_INT_RGB);
Graphics g = b.getGraphics();
y = 0;
x = 0;
JLabel l = new JLabel(new ImageIcon(b));
frm.add(l);
frm.pack();
frm.setVisible(true);
for(int i = offset; i < TIMES + 1 + offset; i ++){
y += ((Math.sin(Math.toRadians(i * 2)))) * multiple * sin;
x += Math.sin(Math.toRadians(i)) * multiple * ((1 - resistance) * 1.5) * Math.abs(cos);
// x += multiple * cos;
// if(i + offset < TIMES / 2){
// x += Math.sin(Math.toRadians(i)) * multiple * ((1 - resistance) * 1.5);
// }else{
// x += Math.sin(Math.toRadians(TIMES / 2)) * multiple * (1 - resistance);
// }
g.setColor(Color.red);
g.drawLine((int)x, (int)(h - y), (int)x, (int)(h - y));
l.setIcon(new ImageIcon(b));
frm.repaint();
Thread.sleep((int)(1000.0 / 24.0));
}
ImageIO.write(b, "png", new File("C:\\proj.png"));
}
现在我想将正弦动画更改为快速 - 慢速 - 它在峰值处慢,所以我尝试了以下结果并得到了这个:
我会期望它只是动画速度不同。代码:
public static void main(String[] args) throws Exception{
float velc = 200;
float angle = 45;
float resistance = 0f;
double multiple = (velc * 2.5 / SINE_TO_180);
int offset = 0;
double y = 0;
double x = 0;
double h = 0;
double cos = Math.cos(Math.toRadians(angle));
double sin = Math.sin(Math.toRadians(angle));
for(int i = offset; i < TIMES + 1 + offset; i ++){
y += (1 - Math.sin(Math.toRadians(i * 2))) * multiple * sin;
if(y >= h)
h = y;
// x += Math.sin(Math.toRadians(i)) * multiple * ((1 - resistance) * 1.5) * Math.abs(cos);
x += 2;
// x += multiple * cos;
// if(i + offset < TIMES / 2){
// x += Math.sin(Math.toRadians(i)) * multiple * ((1 - resistance) * 1.5);
// }else{
// x += Math.sin(Math.toRadians(TIMES / 2)) * multiple * (1 - resistance);
// }
}
y = Math.round(y);
//do round x?
x = Math.round(x);
System.out.println("X: " + x);
JFrame frm = new JFrame("Projectile!");
frm.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
BufferedImage b = new BufferedImage((int)x + 1, (int)h + 1, BufferedImage.TYPE_INT_RGB);
Graphics g = b.getGraphics();
y = 0;
x = 0;
JLabel l = new JLabel(new ImageIcon(b));
frm.add(l);
frm.pack();
frm.setVisible(true);
for(int i = offset; i < TIMES + 1 + offset; i ++){
y += (1 - Math.sin(Math.toRadians(i * 2))) * multiple * sin;
x += 2;
// x += Math.sin(Math.toRadians(i)) * multiple * ((1 - resistance) * 1.5) * Math.abs(cos);
// x += multiple * cos;
// if(i + offset < TIMES / 2){
// x += Math.sin(Math.toRadians(i)) * multiple * ((1 - resistance) * 1.5);
// }else{
// x += Math.sin(Math.toRadians(TIMES / 2)) * multiple * (1 - resistance);
// }
g.setColor(Color.red);
g.drawLine((int)x, (int)(h - y), (int)x, (int)(h - y));
l.setIcon(new ImageIcon(b));
frm.repaint();
Thread.sleep((int)(1000.0 / 24.0));
}
ImageIO.write(b, "png", new File("C:\\proj2.png"));
}
任何人都知道我做错了什么,因为我希望结果与第一个不同的动画速度相同?
答案 0 :(得分:3)
如果你想要一个平滑的动画,我会分开数据和动画;
首先创建你的数据 - 它是一个(数学)函数[意思是f(x) - &gt; y],所以你可以简单地使用一个数组来获取数据
private int endOfX = 100; //adjust as you wish
private int[] data;
public void calculateData(){
data = new int[amendOfX ountPixels];
for(int x = 0; x < endOfX ; x++){
y = x*x; //this is an example, use your mathematical function here
}
}
所以 - 现在您可以轻松使用此数据来提供流畅的动画
public class AnimationOfFunction(){
public static void main(String[] args){
new AnimationOfFunktion().createAndShowGui(); //as from java tutorials
}
private BufferedImage img;
private Graphics gr;
private void createAndShowGui(){
calculateData(); first of all we create the data!
JFrame frame = new JFrame();//then create your frame here
JPanel panel = createContent(); //create your drawing panel here
frame.add(panel);//adding drawing panel
frame.pack(); //setting the proper size of frame
frame.setVisible(true); //show frame
startAnimation(panel); //this is important - after showing the frame you start your animation here!
}
}
所以 - 这将是您申请的开始,现在该怎么办?首先创建一个合适的绘图面板:
private JPanel createContent(){
//create a anonym class
@surpress serial
JPanel panel = new JPanel(){
@override
public void paintComponent(Graphics gr){
super.paintComponent(gr);
gr.drawImage(img, 0,0, null);
}
}
panel.setPreferredSize(new Dimension(img.getWidth(), img.getHeight() ));
return panel;
}
最重要的是 - 你必须开始动画:
private void startAnimation(final JPanel panel){
//create a anonym class
Runnable r = new Runnable(){
private int py = 0; //previous values
private int py = 0; //previous values
@overrdie
public void run(){
for(int x = 0; x < endOfX ; x++){
int y = data[x];
//now we have x and y, so you can plot your function;
gr.drawLine(px, py, x,y); //you can scale here
int sleeptime = calculateSleepTime(px,py, x,y);
Thread.sleep(sleeptime);
//set the previouse values;
px = x;
py = y;
//important - repaint your panel to create an 'animation'
panel.repaint();
}
}
}
//having that runnable we must start that runnable within an thread
Thread thread = new Thread(r);
thread.setDaemon(true);
thread.start();
}
所以剩下要做什么了?我们必须计算睡眠时间:如果两点之间的距离是“大”的话。我们睡得更久,如果距离很短,我们睡得更少......
public int calculateSleeptime(int px, int py, int x, int y){
int distance = (y-py)*(y-py)+(x-px)*(x-px);
distance = (int)(Math.sqrt(distance);
int sleepTime = distance*100; //play with this value!
return sleeptime;
}
我已经编写了所有代码,我没有任何IDE来检查它是否包含任何拼写错误或编译错误,请为自己做,以及我没有启动BufferedImage img ang Graphics gr。但显而易见,你已经可以做到了!