在java中以螺旋方式移动图像

我正在尝试制作一个简单的动画介绍。 我有一个图像,我试图以顺时针螺旋运动从屏幕的左下角移动到屏幕的中心。 这是我现在使用的代码。 它只是将图像向上移动到中心:

static ImageLoader il = new ImageLoader(); private static BufferedImage logo = il.load("/logoNew.png"); private static Image power = il.gif("http://sofzh.miximages.com/java/KSnus.gif"); static double y = 1024.0; public static void render(Graphics g){ if(y>(486/2)-128){ y = y-0.25; } if(draw){ g.drawImage(logo,(864/2)-128,(int)y,null); g.setColor(Color.WHITE); g.drawImage(power,10,10,null); } } 

if(draw)语句由其他东西激活。 我该如何移动图像。 我只是在不同点上以不同方式递增x和y吗?

**编辑**我没有说明动议。 它从左下角到左上角到右上角到右下角到底部中心(中心)到屏幕的中心(中心)

动画是随着时间的推移运动的错觉。 通常情况下,我会使用Timing Framework (或Trident或Universal Tween Engine )作为动画的基础,这些可以为轻松和轻松提供更好的支持。

以下示例仅使用简单的javax.swing.Timer 。 我使用它是因为它与Swing一起使用更安全,因为它允许我从事件调度线程的上下文中更新UI的状态,但不阻止它(阻止它更新屏幕)。

以下示例使用时间轴和关键帧的概念。 也就是说,在某个时间点,必须发生一些事情。 然后,时间线提供了在这些“关键”时间点之间进行混合的方法。

我个人喜欢在抽象概念中工作,所以时间轴只是从0到1的百分比来衡量,这使我能够提供可变的时间跨度。 这允许我调整动画的速度而无需改变任何东西。

ネ

正如你(应该)能够看到的那样,最后两条腿只需要移动一半距离,所以它们比其他三条腿慢,所以从技术上讲,它们只需要一半的时间来完成……但是我我会把它留给你来解决数学问题;)

 import java.awt.Dimension; import java.awt.EventQueue; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.Point; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.image.BufferedImage; import java.io.File; import java.io.IOException; import java.util.Map; import java.util.TreeMap; import javax.imageio.ImageIO; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.Timer; import javax.swing.UIManager; import javax.swing.UnsupportedLookAndFeelException; public class Test{ public static void main(String[] args) { new Test(); } public Test() { EventQueue.invokeLater(new Runnable() { @Override public void run() { try { UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) { ex.printStackTrace(); } JFrame frame = new JFrame("Testing"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.add(new TestPane()); frame.pack(); frame.setLocationRelativeTo(null); frame.setVisible(true); } }); } public class TestPane extends JPanel { protected static final int PLAY_TIME = 6000; private Timeline timeline; private long startTime; private Point imgPoint; private BufferedImage img; public TestPane() { try { img = ImageIO.read(new File("C:/Neko.png")); imgPoint = new Point(0, 200 - img.getHeight()); timeline = new Timeline(); timeline.add(0f, imgPoint); timeline.add(0.2f, new Point(0, 0)); timeline.add(0.4f, new Point(200 - img.getWidth(), 0)); timeline.add(0.6f, new Point(200 - img.getWidth(), 200 - img.getHeight())); timeline.add(0.8f, new Point(100 - (img.getWidth() / 2), 200 - img.getHeight())); timeline.add(1f, new Point(100 - (img.getWidth() / 2), 100 - (img.getHeight() / 2))); Timer timer = new Timer(40, new ActionListener() { @Override public void actionPerformed(ActionEvent e) { long duration = System.currentTimeMillis() - startTime; float progress = (float) duration / (float) PLAY_TIME; if (progress > 1f) { startTime = System.currentTimeMillis(); progress = 0; ((Timer) (e.getSource())).stop(); } System.out.println(progress); imgPoint = timeline.getPointAt(progress); repaint(); } }); startTime = System.currentTimeMillis(); timer.start(); } catch (IOException exp) { exp.printStackTrace(); } } @Override public Dimension getPreferredSize() { return new Dimension(200, 200); } @Override protected void paintComponent(Graphics g) { super.paintComponent(g); if (img != null && imgPoint != null) { Graphics2D g2d = (Graphics2D) g.create(); g2d.drawImage(img, imgPoint.x, imgPoint.y, this); g2d.dispose(); } } } public static class Timeline { private Map mapEvents; public Timeline() { mapEvents = new TreeMap<>(); } public void add(float progress, Point p) { mapEvents.put(progress, new KeyFrame(progress, p)); } public Point getPointAt(float progress) { if (progress < 0) { progress = 0; } else if (progress > 1) { progress = 1; } KeyFrame[] keyFrames = getKeyFramesBetween(progress); float max = keyFrames[1].progress - keyFrames[0].progress; float value = progress - keyFrames[0].progress; float weight = value / max; return blend(keyFrames[0].getPoint(), keyFrames[1].getPoint(), 1f - weight); } public KeyFrame[] getKeyFramesBetween(float progress) { KeyFrame[] frames = new KeyFrame[2]; int startAt = 0; Float[] keyFrames = mapEvents.keySet().toArray(new Float[mapEvents.size()]); while (startAt < keyFrames.length && keyFrames[startAt] <= progress) { startAt++; } if (startAt >= keyFrames.length) { startAt = keyFrames.length - 1; } frames[0] = mapEvents.get(keyFrames[startAt - 1]); frames[1] = mapEvents.get(keyFrames[startAt]); return frames; } protected Point blend(Point start, Point end, float ratio) { Point blend = new Point(); float ir = (float) 1.0 - ratio; blend.x = (int) (start.x * ratio + end.x * ir); blend.y = (int) (start.y * ratio + end.y * ir); return blend; } public class KeyFrame { private float progress; private Point point; public KeyFrame(float progress, Point point) { this.progress = progress; this.point = point; } public float getProgress() { return progress; } public Point getPoint() { return point; } } } }