2014-11-22 56 views
1

是否可以在沒有任何遊戲引擎的情況下簡單地在java(swing)中進行360度移動?我只有這樣的嘗試:java中的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

+0

我沒有做3D圖形,檢查圖像。 – Pink 2014-11-22 12:24:50

回答

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) {} 
    } 
} 

不知道你試圖在那裏編碼,但這是一個循環運動的正確公式。

+0

謝謝這就是我要找的 – Pink 2014-11-22 12:42:03

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 
    } 
} 

這currenlty繪製逆時針圓圈。如果您想順時針畫出來,然後換角度:

angle += 0.1; 
+0

謝謝解釋 – Pink 2014-11-22 12:43:07

+0

這是錯誤的,因爲角度必須是弧度,餘弦隨x而正弦隨y。將x和y作爲'ints'也很好,但是你的代碼將圍繞點(0,0)旋轉x和y。 – 2014-11-22 12:44:32

+0

@DavidConrad'但你的代碼將圍繞點(0,0)旋轉x和y'它將圍繞'x'和'y'的初始座標旋轉。你說得對,'sin'和'cos'目前正在切換。 – Tom 2014-11-22 12:50:00

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 
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); 
      } 
     }); 
    } 

}