Rotate Image around character (JAVA)

后端 未结 2 1400
小鲜肉
小鲜肉 2020-11-27 23:58

Yes, i do know you can use AffineTransformation, however i want my sword image to rotate around a character that i have made (black block drawn in graphics) 360 degrees vis

相关标签:
2条回答
  • 2020-11-28 00:17

    You mean something like...

    enter image description here

    (Please note, the red line is a guide line to indicate the angle from the center, you won't need it ;))

    The fancy, pancy stuff is in the getSwordHandlePoint method, which calculates the point along the vector at which the handle should be placed...

    public class TestSword {
    
        public static void main(String[] args) {
            new TestSword();
        }
    
        public TestSword() {
            EventQueue.invokeLater(new Runnable() {
                @Override
                public void run() {
                    try {
                        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                    } catch (ClassNotFoundException ex) {
                    } catch (InstantiationException ex) {
                    } catch (IllegalAccessException ex) {
                    } catch (UnsupportedLookAndFeelException ex) {
                    }
    
                    JFrame frame = new JFrame("Test");
                    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                    frame.setLayout(new BorderLayout());
                    frame.add(new SwordPane());
                    frame.pack();
                    frame.setLocationRelativeTo(null);
                    frame.setVisible(true);
                }
            });
        }
    
        public class SwordPane extends JPanel {
    
            private BufferedImage character;
            private BufferedImage sword;
            private double angle = 0;
    
            public SwordPane() {
                try {
                    character = ImageIO.read(new File("character.png"));
                    sword = ImageIO.read(new File("Sword.png"));
                } catch (IOException exp) {
                    exp.printStackTrace();
                }
    
                Timer timer = new Timer(100, new ActionListener() {
                    @Override
                    public void actionPerformed(ActionEvent e) {
                        angle += 10;
                        if (angle > 360) {
                            angle -= 360;
                        }
                        repaint();
                    }
                });
                timer.setRepeats(true);
                timer.setCoalesce(true);
                timer.start();
    
            }
    
            @Override
            public Dimension getPreferredSize() {
                int width = character.getHeight() + sword.getWidth();
                int height = character.getHeight() + sword.getWidth();
    
                return new Dimension(width * 2, height * 2);
            }
    
            protected Point getSwordHandlePoint() {
    
                int radius = 272; // This is the height of the character...
    
                int x = Math.round(getWidth() / 2);
                int y = Math.round(getHeight() / 2);
    
                double rads = Math.toRadians(angle - 180); // Make 0 point out to the right...
                // If you add sword.getWidth, you might be able to change the above...
                int fullLength = Math.round((radius / 2f)) - sword.getWidth();
    
                // Calculate the outter point of the line
                int xPosy = Math.round((float) (x + Math.cos(rads) * fullLength));
                int yPosy = Math.round((float) (y - Math.sin(rads) * fullLength));
    
                return new Point(xPosy, yPosy);
    
            }
    
            @Override
            protected void paintComponent(Graphics g) {
    
                super.paintComponent(g);
    
                Graphics2D g2d = (Graphics2D) g.create();
    
                int x = (getWidth() - character.getWidth()) / 2;
                int y = (getHeight() - character.getHeight()) / 2;
    
                g2d.drawImage(character, x, y, this);
    
                x = getWidth() / 2;
                y = getHeight() / 2;
    
                Point p = getSwordHandlePoint();
                g2d.setColor(Color.RED);
                g2d.drawLine(x, y, p.x, p.y);
    
                AffineTransform at = AffineTransform.getTranslateInstance(p.x, p.y);
                at.rotate(Math.toRadians(-angle));
                g2d.setTransform(at);
                g2d.drawImage(sword, 0, 0, this);
    
                g2d.dispose();
    
            }
        }
    }
    

    Now, my trig is hopeless, less then hopeless. I "borrowed" the algorithm off the net and tweaked for my own needs...

    0 讨论(0)
  • 2020-11-28 00:30

    The Graphics2D class, has a method g2.rotate(...), call a for loop setting the rotate at one degree more, at a time, then invoke g2.drawImage(...), in the loop, after the each change (if it's in the paintComponent() method, and the loop is outside - call repaint() in the for loop).

    0 讨论(0)
提交回复
热议问题