0

はい、AffineTransformationを使用できることは知っていますが、剣の画像を、1回転だけでなく、作成したキャラクター(グラフィックで描かれた黒いブロック)を中心に360度回転させたいと考えています。基本的にはTerrariaのような回転システムが欲しいです。キャラクターのxとyを取得する方法を知っているので、質問は次のとおりです。定義したポイントを中心に回転させるにはどうすればよいですか。私のコードはこのように設定されています

    f.addMouseListener(new MouseAdapter(){
    public void mouseClicked(MouseEvent e){
        swordSwinging=true;
    }
});

..。

if(swordSwinging){
    //swinging code goes here
}

repaint();
4

2 に答える 2

6

次のようなことを意味します...

ここに画像の説明を入力

(注意してください、赤い線は中心からの角度を示すためのガイドラインです。それは必要ありません;))

派手で豪華なものはgetSwordHandlePoint、ハンドルを配置する必要があるベクトルに沿ったポイントを計算するメソッドにあります...

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

        }
    }
}

今、私のトリガーは絶望的ですが、絶望的ではありません。私はネットからアルゴリズムを「借りて」、自分のニーズに合わせて微調整しました...

于 2012-10-19T10:09:41.990 に答える
1

Graphics2Dクラスにはメソッドがあり、一度に1度以上回転g2.rotate(...)する設定を呼び出してから、各変更の後にループ内で呼び出します(メソッド内にあり、ループが外側にある場合-forループ内で呼び出します) )。for loopg2.drawImage(...)paintComponent()repaint()

于 2012-10-19T04:37:25.087 に答える