java中的360度移动示例

时间:2014-11-22 12:16:54

标签: java swing rotation rotateanimation

是否可以在没有任何游戏引擎的情况下简单地在java(swing)中进行360度移动?我只有这个尝试:

public class Game extends JPanel implements Runnable {

    int x = 300;
    int y = 500;
    float angle = 30;
    Game game;

    public static void main(String[] args) {
    JFrame frame = new JFrame();
    frame.add(new Game());
    frame.setSize(600, 600);
    frame.setVisible(true);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }

    public Game() { 
    setSize(600, 600);

    Thread thread = new Thread(this);
    thread.start();
    }

    @Override
    public void paint(Graphics g) {
    g.setColor(Color.WHITE);
    g.drawRect(0, 0, 600, 600);
    g.setColor(Color.CYAN);
    g.fillOval(x, y, 10, 10);
    g.dispose();
    }

    @Override
    public void run() {
    while(true) {
        angle += -0.1;
        x += Math.sin(angle);
        y--;
        repaint();
        try {
        Thread.sleep(50);
        } catch (InterruptedException ex) {}
    }
    }

}

如下图所示,我不知道如何处理旋转运动,这是输出:

image http://screenshot.cz/GOXE3/mvm.jpg

4 个答案:

答案 0 :(得分:3)

实际上,这很有可能。

我首选的方法是实际利用Graphics转换,这样您就不必进行任何计算,而是全部留给Graphics

顺便说一下:

  • 由于您没有创建Graphics对象,因此请勿对其进行处理。
  • 覆盖paintComponent()而不是paint()
  • 调用super.paintComponent()
  • 始终是一个很好的模式

小演示示例:

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Shape;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.geom.AffineTransform;
import java.awt.geom.Area;
import java.awt.geom.RoundRectangle2D;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;

import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;
import javax.swing.Timer;

public class TestRotate {

    public static class ShapeAndColor {
        private final Shape shape;
        private final Color color;

        public ShapeAndColor(Shape shape, Color color) {
            super();
            this.shape = shape;
            this.color = color;
        }

        public Shape getShape() {
            return shape;
        }

        public Color getColor() {
            return color;
        }

    }

    public static class RotatingShapesPanel extends JComponent {

        private List<ShapeAndColor> shapes;

        private double rotation = 0.0;

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            Graphics2D g2d = (Graphics2D) g;
            AffineTransform translate = AffineTransform.getTranslateInstance(-getWidth() / 2, -getHeight() / 2);
            AffineTransform rotate = AffineTransform.getRotateInstance(rotation);
            AffineTransform t = AffineTransform.getTranslateInstance(getWidth() / 2, getHeight() / 2);
            t.concatenate(rotate);
            t.concatenate(translate);
            g2d.setTransform(t);
            AffineTransform scale = AffineTransform.getScaleInstance(getWidth(), getHeight());
            for (ShapeAndColor shape : shapes) {
                Area area = new Area(shape.getShape());
                g2d.setColor(shape.getColor());
                area.transform(scale);
                g2d.fill(area);
            }
        }

        public void setShapes(List<ShapeAndColor> shapes) {
            this.shapes = shapes;
            repaint();
        }

        public double getRotation() {
            return rotation;
        }

        public void setRotation(double rotation) {
            this.rotation = rotation;
            repaint();
        }

    }

    protected void initUI(final boolean useBorderLayout) {
        final JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        List<ShapeAndColor> shapes = new ArrayList<>();
        Random r = new Random();
        for (int i = 0; i < 10; i++) {
            double x = r.nextDouble();
            double y = r.nextDouble();
            double w = r.nextDouble();
            double h = r.nextDouble();
            w = Math.min(w, 1 - x) / 2;
            h = Math.min(h, 1 - y) / 2;
            double a = Math.min(w, h) / 10.0;
            RoundRectangle2D.Double shape = new RoundRectangle2D.Double(x, y, w, h, a, a);
            Color color = new Color(r.nextInt(256), r.nextInt(256), r.nextInt(256));
            shapes.add(new ShapeAndColor(shape, color));
        }
        final RotatingShapesPanel panel = new RotatingShapesPanel();
        panel.setShapes(shapes);
        frame.add(panel);
        frame.setSize(600, 600);
        frame.setVisible(true);
        Timer t = new Timer(0, new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                double rotation = panel.getRotation() + 0.02;
                if (rotation > Math.PI * 2) {
                    rotation -= Math.PI * 2;
                }
                panel.setRotation(rotation);
            }
        });
        t.setRepeats(true);
        t.setDelay(10);
        t.start();
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                new TestRotate().initUI(true);
            }
        });
    }

}

答案 1 :(得分:0)

改变几行......

int basex = 300;   // midpoint of the circle
int basey = 400;
int radius = 100;  // radius
int x;
int y;
float angle = 0;  // Angles in radians, NOT degrees!

public void run() {
  while(true) {
    angle += 0.01;
    x  = (int)(basex + radius*Math.cos(angle));
    y  = (int)(basey - radius*Math.sin(angle));
    repaint();
    try {
        Thread.sleep(50);
    } catch (InterruptedException ex) {}
  }
}

不确定你在那里尝试编码,但这是圆形运动的正确公式。

答案 2 :(得分:0)

你的程序存在一些问题:

int x = 300;
int y = 500;

您应该使用像double这样的浮点数据类型来存储坐标。当您想要绘制它们时,可以将它们强制转换为int。如果将它们存储在int中,则会失去精确度。

x += Math.sin(angle);
y--;

这不起作用,因为y递减而不是使用Math.sin(angle)计算。 (我们为Math.cosx

这是你的固定代码(省略了未更改的部分):

double x = 300;
double y = 500;
float angle = 30;
double radius = 10D; // new variable to increase the radius of the drawn circle
Game game;

// main method

// constructor

@Override
public void paint(Graphics g) {
    // ... stuff omitted
    g.fillOval((int)x, (int)y, 10, 10); // you can cast to int here
    g.dispose();
}

@Override
public void run() {
    while (true) {
        angle -= 0.1; // is the same as `angle += -0.1`
        x += radius * Math.cos(angle);
        y += radius * Math.sin(angle);
        repaint();
        // ... try catch block
    }
}

此电流逆时针绘制圆圈。如果要顺时针绘制它,请将角度更改为:

angle += 0.1;

答案 3 :(得分:0)

要计算一个点周围的旋转,你需要一个旋转中心点(cx,cy),该点与中心的半径或距离,你需要角度(弧度,而不是度数),你需要使用正弦和余弦来计算点绕中心旋转时点的偏移量。

int cx, cy, radius; // I'll let you determine these
double theta = Math.toRadians(30);
double dtheta = Math.toRadians(-0.1);

double dx = Math.cos(theta) * radius;
double dy = Math.sin(theta) * radius;
int x = (int)(cx + dx);
int y = (int)(cy + dy);

repaint();
theta += dtheta; // step the angle