【问题标题】:Java (Swing) - How to rotate a bunch of lines?Java (Swing) - 如何旋转一堆线?
【发布时间】:2017-05-15 17:47:52
【问题描述】:

我一直在网上寻找这个,但我似乎找不到如何旋转一堆线。我用Graphics.drawLine() 函数制作了一个“平面”,但我想知道当它撞到墙上时如何将整个物体向右旋转 90 度。这是我当前的代码:

/* MovePlane
 * Moves plane to the right, down, left, up, and repeats using Timer object
 */

import java.awt.event.*;
import java.awt.*;
import javax.swing.*;


public class MovePlane extends JPanel implements ActionListener {
   private int delay = 5;
   private Timer timer;

   private int x = 10;      // x position
   private int y = 10;      // y position

   private boolean right = true;
   private boolean up = true;

   public MovePlane() {
       timer = new Timer(delay, this);
       timer.start();       // start the timer - infinite
   }

   public void actionPerformed(ActionEvent e) {
    // will run when the timer fires
       repaint();
   }

   public void paintComponent(Graphics g) {
       // both paint and paintComponent work - difference?
       super.paintComponent(g);    // call superclass's paintComponent 
       g.drawLine(x,y,x+20,y);               // body - drawn in terms of x
       g.drawLine(x+15,y-5,x+15,y+5);    // wing
       g.drawLine(x,y-2,x,y+2);  
       if (right && up) {
            x++;
            if (x == getWidth()-25) {
                right = false;
                up = false;
            }
       } else if (!right && !up) {
            y++;
            if (y == getHeight()-10) {
                up = true;
            }
       } else {
            if (x <= getWidth()-15 && x > 0) {
                x--;
            }
            if (x == 0) {
                y--;
            }
            if (y == 10) {
                right = true;
            }
       }
    }

    public static void main(String args[]) {
        JFrame frame = new JFrame("Move Plane");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        MovePlane bp = new MovePlane(); 
        frame.add(bp);
        frame.setSize(300, 300); // set frame size
        frame.setVisible(true); // display frame
    }

}

【问题讨论】:

  • 使用AffineTransform for example,虽然这只是旋转Image,但基本概念是相同的,您可以“转换”Graphics 上下文以及在它之后绘制的任何内容应用到它的转换

标签: java swing


【解决方案1】:

每次更改方向时都需要更改它,因此,您需要在每个 if 条件中移动 g.drawLine(...) 调用...

但是在旋转平面时,你还需要注意“边界”或屏幕的限制,所以,我修改了if (x == 0)... &amp;&amp; x &gt; 0 条件,改为有20 的间隙。 .

让我们从从左到右的飞机开始:

g.drawLine(x, y, x + 20, y);               // body - drawn in terms of x
g.drawLine(x + 15, y - 5, x + 15, y + 5);    // wing
g.drawLine(x, y - 2, x, y + 2);

这告诉我们:

  • 你的飞机机身长度是 20
  • 你的翅膀距离后面 15 个单位
  • 你的尾巴就在后面

所以,要将其更改为从左向右移动,我们需要反转机翼和尾部位置...

  • 平面长度仍然相同
  • 机翼现在距离后面 5 个单位
  • 尾巴现在在前面

然后,我们有这个代码:

g.drawLine(x, y, x + 20, y);               // Body length 20
g.drawLine(x + 5, y - 5, x + 5, y + 5);    // Wing's are 5 units from the front
g.drawLine(x + 20, y - 2, x + 20, y + 2);  // Tail is on the front (at body's length)

以及下降时:

  • 身体的长度现在位于 Y 轴上
  • 机翼应该距离后面 15 个单位
  • 尾巴在后面

所以我们有:

g.drawLine(x, y, x, y + 20);               // Body is now on Y axis
g.drawLine(x - 5, y + 15, x + 5, y + 15);    // Wings are 15 units from the back
g.drawLine(x - 2, y, x + 2, y); // Tail is on the back

并应用与从右到左时相同的逻辑:

g.drawLine(x, y + 20, x, y);
g.drawLine(x - 5, y + 5, x + 5, y + 5);
g.drawLine(x - 2, y + 20, x + 2, y + 20);

那么您的paintComponent(...) 方法如下所示:

public void paintComponent(Graphics g) {
    // both paint and paintComponent work - difference?
    super.paintComponent(g);    // call superclass's paintComponent
    if (right && up) {
        g.drawLine(x, y, x + 20, y);               // body - drawn in terms of x
        g.drawLine(x + 15, y - 5, x + 15, y + 5);    // wing
        g.drawLine(x, y - 2, x, y + 2);
        x++;
        if (x == getWidth() - 25) {
            right = false;
            up = false;
        }
    } else if (!right && !up) {
        g.drawLine(x, y, x, y + 20);               // body - drawn in terms of x
        g.drawLine(x - 5, y + 15, x + 5, y + 15);    // wing
        g.drawLine(x - 2, y, x + 2, y);
        y++;
        if (y == getHeight() - 25) {
            up = true;
        }
    } else {
        if (x <= getWidth() - 15 && x > 20) {
            g.drawLine(x, y, x + 20, y);               // body - drawn in terms of x
            g.drawLine(x + 5, y - 5, x + 5, y + 5);    // wing
            g.drawLine(x + 20, y - 2, x + 20, y + 2);
            x--;
        }
        if (x == 20) {
            g.drawLine(x, y, x, y + 20);               // body - drawn in terms of x
            g.drawLine(x - 5, y + 5, x + 5, y + 5);    // wing
            g.drawLine(x - 2, y + 20, x + 2, y + 20);
            y--;
        }
        if (y == 10) {
            right = true;
        }
    }
}

就是这样!这是一张显示其外观的图片:

其他提示:

  1. 不要调用frame.setSize(),而是覆盖MovePlane的JPanel getPreferredSize()以返回固定大小的300, 300

  2. 始终将您的 GUI 放在 Event Dispatch Thread (EDT) 中,方法是像这样包装您的 main 方法:

    public static void main(String args[]) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                //Your code here
            }
        });
    }
    
  3. 与技巧 #1 相关,在覆盖 JPanelgetPreferredSize() 后调用 frame.pack(); 而不是 frame.setSize() :)

【讨论】:

    猜你喜欢
    • 2010-12-19
    • 1970-01-01
    • 1970-01-01
    • 2022-11-20
    • 2012-01-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多