2015-09-04 3 views
2

Я хотел бы повернуть прямоугольник, когда, например, y положение достигнет указанной позиции. Я хотел бы вести прямоугольник как автомобиль на перекрестке - просто поверните, например. правильно. Я предпочитаю просто повернуть и продолжить.Как повернуть прямоугольник после достижения указанной позиции?

Проект кодекса выглядит следующим образом:

Graphics2D g2d = (Graphics2D) g.create(); 
g2d.setPaint(new Color(150, 150, 0)); 

//1. when rectangle achieve 500 on y dimension just rotate left/right 
if(y==500) { 
    _rotate = true; 
    g2d.rotate(Math.toRadians(90.)); 
} 
if(_rotate) { //if rotate, continue way on x dimension 
    ++x ; 
    g2d.fillRect(x, y, 20, 40); 
} else { //else go to the north 
    --y; 
    g2d.fillRect(x, y, 20, 40); 
} 
+0

* "Как вращать прямоугольник после определенного времени?" * Можете ли вы быть более конкретным? Я не могу понять, если вы спрашиваете, какой из двух предложенных методов лучше, или как заставить рендеринг обновляться через определенное время или .. ?? –

+1

Вы могли бы взглянуть на [это] (http://stackoverflow.com/questions/26898536/moving-jlabel-to-other-jlabels-gui/26899099#26899099) и [это] (http: // stackoverflow. com/questions/28619150/move-image-in-a-spiral-fashion-in-java/28619554 # 28619554), которые предоставляют примеры анимаций, основанных на временной шкале, например [this] (http://stackoverflow.com/questions/31958932/how-do-i-rotate-objects-images-independent-in-java/31959926 # 31959926), который имеет вращающиеся прямоугольники. Возможно, вам также захочется провести некоторое исследование пути – MadProgrammer

ответ

2

Существует много информации, которая отсутствует из вашего вопроса.

Для того, чтобы повернуть фигуру, вам нужно знать несколько вещей, вам нужно знать, что это текущая позиция, и это следующая целевая позиция, тогда вы можете просто вычислить угол между этими двумя точками.

Вопрос тогда, как вы рассчитываете эти позиции. Существует множество способов достижения этого, следующий простой процесс, следующий за процессом.

Во-первых, мы генерируем путь, который нам нужно выполнить, мы используем API Shape для вычисления точек вдоль пути. Мы используем простую анимацию, основанную на времени (а точнее, зацикливание по точкам, мы вычисляем прогресс по пути, вычисляя количество времени, в которое играли анимацию, деленное на количество времени, которое мы хотим принять) и выбираем точку, которая лучше всего соответствует нашему текущему прогрессу.

Мы используем AffineTransform для поворота формы игрока и перевода полученного результата Shape в нужное положение. Ease

FollowMe

import java.awt.Dimension; 
import java.awt.EventQueue; 
import java.awt.Graphics; 
import java.awt.Graphics2D; 
import java.awt.Rectangle; 
import java.awt.Shape; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import java.awt.event.KeyEvent; 
import java.awt.geom.AffineTransform; 
import java.awt.geom.Path2D; 
import java.awt.geom.PathIterator; 
import java.awt.geom.Point2D; 
import java.util.ArrayList; 
import java.util.List; 
import javax.swing.AbstractAction; 
import javax.swing.ActionMap; 
import javax.swing.InputMap; 
import javax.swing.JFrame; 
import javax.swing.JPanel; 
import javax.swing.KeyStroke; 
import javax.swing.Timer; 
import javax.swing.UIManager; 
import javax.swing.UnsupportedLookAndFeelException; 

public class PathFollow { 

    public static void main(String[] args) { 
     new PathFollow(); 
    } 

    public PathFollow() { 
     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 { 

     private Shape pathShape; 
     private List<Point2D> points; 
     private Shape car; 

     private double angle; 
     private Point2D pos; 
     private int index; 

     protected static final double PLAY_TIME = 5000; // 5 seconds... 

     private Long startTime; 

     public TestPane() { 

      Path2D path = new Path2D.Double(); 
      path.moveTo(0, 200); 
      path.curveTo(100, 200, 0, 100, 100, 100); 
      path.curveTo(200, 100, 0, 0, 200, 0); 

      pathShape = path; 

      car = new Rectangle(0, 0, 10, 10); 

      points = new ArrayList<>(25); 
      PathIterator pi = pathShape.getPathIterator(null, 0.01); 
      while (!pi.isDone()) { 
       double[] coords = new double[6]; 
       switch (pi.currentSegment(coords)) { 
        case PathIterator.SEG_MOVETO: 
        case PathIterator.SEG_LINETO: 
         points.add(new Point2D.Double(coords[0], coords[1])); 
         break; 
       } 
       pi.next(); 
      } 

//   System.out.println(points.size()); 
//   pos = points.get(0); 
//   index = 1; 
      Timer timer = new Timer(40, new ActionListener() { 
       @Override 
       public void actionPerformed(ActionEvent e) { 

        if (startTime == null) { 
         startTime = System.currentTimeMillis(); 
        } 
        long playTime = System.currentTimeMillis() - startTime; 
        double progress = playTime/PLAY_TIME; 
        if (progress >= 1.0) { 
         progress = 1d; 
         ((Timer) e.getSource()).stop(); 
        } 

        int index = Math.min(Math.max(0, (int) (points.size() * progress)), points.size() - 1); 

        pos = points.get(index); 
        if (index < points.size() - 1) { 
         angle = angleTo(pos, points.get(index + 1)); 
        } 
        repaint(); 
       } 
      }); 
      timer.start(); 
     } 

     @Override 
     public Dimension getPreferredSize() { 
      return new Dimension(200, 200); 
     } 

     @Override 
     protected void paintComponent(Graphics g) { 
      super.paintComponent(g); 
      Graphics2D g2d = (Graphics2D) g.create(); 
      g2d.draw(pathShape); 

      AffineTransform at = new AffineTransform(); 

      if (pos != null) { 

       Rectangle bounds = car.getBounds(); 
       at.rotate(angle, (bounds.width/2), (bounds.width/2)); 

       Path2D player = new Path2D.Double(car, at); 

       g2d.translate(pos.getX() - (bounds.width/2), pos.getY() - (bounds.height/2)); 
       g2d.draw(player); 

      } 

      g2d.dispose(); 
     } 

     // In radians... 
     protected double angleTo(Point2D from, Point2D to) { 
      double angle = Math.atan2(to.getY() - from.getY(), to.getX() - from.getX()); 
      return angle; 
     } 

    } 

}