# Spieler auf besonderer Bahn bewegen



## .basti (6. Apr 2022)

Hallo zusammen,
ich will mal fragen wie man einen Spieler automatisch auf einer "besonderen" Bahn bewegen lassen kann. Anhand meines Spiels um ein roundRect herum?


----------



## mihe7 (7. Apr 2022)

Hier mal was zusammengeschustert, kann sein, dass es auch einfacher geht, das entzieht sich allerdings meiner Kenntnis.


```
import java.awt.*;
import java.awt.event.*;
import java.awt.geom.*;
import static java.awt.geom.PathIterator.*;
import java.util.ArrayList;
import java.util.List;
import javax.swing.*;

public class Test {

    static class Drawing extends JComponent {
        private Shape rect;
        private List<Point2D> points;
        private int current;
        
        public Drawing(Shape rect, List<Point2D> points) {
            this.rect = rect;
            this.points = points;
        }
        
        public void next() {
            current = (current + 1) % points.size();
            repaint();
        }
        
        public void paintComponent(Graphics g) {
            g.setColor(Color.BLACK);
            g.fillRect(0, 0, getWidth(), getHeight());
            g.setColor(Color.WHITE);
            
            Graphics2D g2 = (Graphics2D) g;
            g2.draw(rect);
            
            g.setColor(Color.RED);
            Point2D point = points.get(current);
            g2.fill(new Arc2D.Double(point.getX() - 5, point.getY() - 5,
                    10d, 10d, 0d, 360d, Arc2D.CHORD));
        }
        
    }
    
    private Timer timer;
    
    public void show(Shape rect, List<Point2D> points) {
        Drawing drawing = new Drawing(rect, points);
        
        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        frame.addWindowListener(new WindowAdapter() {
            public void windowClosing(WindowEvent e) {
                if (timer != null) {
                    timer.stop();
                }
            }
        });
                    
        frame.add(drawing);
        frame.setSize(600, 400);
        frame.setVisible(true);
        
        timer = new Timer(250, e->drawing.next());
        timer.start();
    }
    
    private static List<Point2D> points(PathIterator it) {
        List<Point2D> points = new ArrayList<>();

        float[] last = new float[]{0f, 0f};
        
        while (!it.isDone()) {
            float[] coords = new float[6];
            int type = it.currentSegment(coords);
            int lastPoint = 0;
            switch (type) {
                case SEG_MOVETO:
                    points.add(new Point2D.Float(coords[0], coords[1]));
                    break;
                case SEG_LINETO:
                    points.addAll(pointsOnLine(last[0], last[1], coords[0], coords[1]));
                    break;
                case SEG_CUBICTO:
                    points.addAll(pointsOnCubicCurve(last[0], last[1], 
                            coords[0], coords[1], coords[2], coords[3],
                            coords[4], coords[5]));
                    lastPoint = 2;
                    break;
            }
                        
            last[0] = coords[2*lastPoint];
            last[1] = coords[2*lastPoint+1];

            it.next();
        }
        return points;
    }    

    private static List<Point2D> pointsOnLine(float... points) {
        List<Point2D> result = new ArrayList<>();
        result.add(new Point2D.Float(points[0], points[1]));        
        for (float t = 0f; t < 1f; t += .2f) {
            float r = 1 - t;
            result.add(new Point2D.Float(
                    r*points[0] + t*points[2],
                    r*points[1] + t*points[3]));        
        }
        return result;
    }
            
                    
    private static List<Point2D> pointsOnCubicCurve(float... coords) {
        List<Point2D> result = new ArrayList<>();
        for (float t = 0f; t < 1f; t += .2f) {
            result.add(pointOnCubicCurve(t, coords));
        }
        result.add(pointOnCubicCurve(1f, coords));
        return result;
    }
    
    private static Point2D pointOnCubicCurve(float percent, float... coords) {
        return new Point2D.Float(
                coordinateOnCubicCurve(percent, coords[0], coords[2], coords[4], coords[6]),
                coordinateOnCubicCurve(percent, coords[1], coords[3], coords[5], coords[7]));

    }
    
    private static float coordinateOnCubicCurve(float t, float... b) {
        float r = 1 - t;
        return r*(r*(r*b[0] + t*b[1]) + t*(r*b[1] + t*b[2])) +
                t*(r*(r*b[1] + t*b[2]) + t*(r*b[2] + t*b[3]));
    }
        
    public static void main(String[] args) {
        RoundRectangle2D rect = new RoundRectangle2D.Double(
                10, 10, 300, 200, 50, 50);
        PathIterator it = rect.getPathIterator(new AffineTransform());
        
        SwingUtilities.invokeLater(() -> new Test().show(rect, points(it)));
    }
    
}
```


----------

