Java (Swing) - 如何旋转一堆线?

标签 java swing

我一直在网上寻找这个,但我似乎找不到如何旋转一堆线。我用 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
    }

}

最佳答案

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

但是在旋转平面时,您还需要注意“边界”或屏幕的限制,因此,我修改了 if (x == 0)。 .. && x > 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;
        }
    }
}

就是这样!这是显示其外观的图像:

enter image description here

其他提示:

  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 相关,在重写 JPanel 后调用 frame.pack(); 而不是 frame.setSize()getPreferredSize() :)

关于Java (Swing) - 如何旋转一堆线?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43985781/

相关文章:

java - 并行运行器跳过测试内的循环迭代

java - Java NetBeans 无法识别 .isBlank()

java - Synth 的 JPanel 状态

java - 在java中的Jtable中获取多个原始数据

java - 当我可以在 Spring JPA 中编写方法时为什么还需要 @Query

Java regex - 如何获取空格和字符?

java - Hadoop - 连接到 JobTracker

java: 结果集错误

java - 按钮大小 (Java)

java - 文本显示两次而不是一次