所以我使用了http://zetcode.com/tutorials/javagamestutorial/basics/中的教程,我正在使用Donut程序.对于任何不熟悉的人都会这样做http://zetcode.com/img/gfx/javagames/donut.png 我想让椭圆围绕窗口的中心旋转,使它看起来像是在一个圆圈中移动.
到目前为止,代码是来自网页的代码.
package donut; import javax.swing.*; import java.awt.*; import java.awt.geom.AffineTransform; import java.awt.geom.Ellipse2D; public class Board extends JPanel{ public void paint(Graphics g) { super.paint(g); Graphics2D g2 = (Graphics2D) g; RenderingHints rh = new RenderingHints(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); rh.put(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY); g2.setRenderingHints(rh); Dimension size = getSize(); double w = size.getWidth(); double h = size.getHeight(); Ellipse2D e = new Ellipse2D.Double(0, 0, 80, 130); g2.setStroke(new BasicStroke(1)); g2.setColor(Color.gray); for (double deg = 0; deg < 360; deg += 5) { AffineTransform at = AffineTransform.getTranslateInstance(w / 2, h/2); at.rotate(Math.toRadians(deg)); g2.draw(at.createTransformedShape(e)); } while(true) { } } }
我通常可以得到关于如何做到这一点的理论(我对编程很新,特别是GUI和图形),但我不知道这次是怎么回事.也许,RotateAnimation或类似的东西?希望我不会被标记为一个菜鸟
你不能在paint方法中做循环,因为它会立即竞争所有循环,导致没有aniation.在paint中或在事件线程中的任何地方进行一段时间(真实)循环将阻止您的程序进行绘制,这会使您的程序瘫痪到静止状态.代替:
使用Swing Timer来驱动动画.
在类中创建Ellipse实例,而不是在绘制方法中创建.
在Timer中增加您的旋转角度和调用repaint()
.
覆盖paintComponent不绘制
只做这种方法的绘画,没有逻辑.逻辑进入你的计时器.
在paintComponent方法中,使用Timer更改的角度进行仿射变换并绘制正确的椭圆.
在这个网站上搜索Java Swing动画的例子,因为这已被多次询问,导致许多示例程序(由我编写).
例如:
import java.awt.*; import java.awt.event.*; import java.awt.geom.*; import javax.swing.*; @SuppressWarnings("serial") public class RotateEllipse extends JPanel { private static final double ELLIPSE_W = 80; private static final double ELLIPSE_H = 130; private static final int PREF_W = 400; private static final int PREF_H = 400; private static final Stroke STROKE = new BasicStroke(5f); private static final Color ELLIPSE_COLOR = Color.red; private static final Color BACKGROUND = Color.black; private static final double ELLIPSE_X = PREF_W / 2 - ELLIPSE_W / 2; private static final double ELLIPSE_Y = PREF_H / 2 - ELLIPSE_H / 2; private static final int TIMER_DELAY = 15; private static final double DELTA_THETA = Math.toRadians(2); private Ellipse2D ellipse2D; private AffineTransform transform = new AffineTransform(); private double theta = 0; public RotateEllipse() { ellipse2D = new Ellipse2D.Double(ELLIPSE_X, ELLIPSE_Y, ELLIPSE_W, ELLIPSE_H); setBackground(BACKGROUND); new Timer(TIMER_DELAY, new TimerListener()).start(); } public Dimension getPreferredSize() { return new Dimension(PREF_W, PREF_H); } @Override protected void paintComponent(Graphics g) { super.paintComponent(g); Graphics2D g2 = (Graphics2D) g.create(); g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); g2.setStroke(STROKE); g2.setColor(ELLIPSE_COLOR); g2.setTransform(transform); g2.draw(ellipse2D); g2.dispose(); } private class TimerListener implements ActionListener { @Override public void actionPerformed(ActionEvent e) { theta += DELTA_THETA; transform = AffineTransform.getRotateInstance(theta, ELLIPSE_X + ELLIPSE_W / 2, ELLIPSE_Y + ELLIPSE_H / 2); repaint(); } } private static void createAndShowGUI() { RotateEllipse paintEg = new RotateEllipse(); JFrame frame = new JFrame("RotateEllipse"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.getContentPane().add(paintEg); frame.pack(); frame.setLocationRelativeTo(null); frame.setVisible(true); } public static void main(String[] args) { SwingUtilities.invokeLater(new Runnable() { public void run() { createAndShowGUI(); } }); } }