I've been looking for this online, but I can't seem to find how to rotate a bunch of lines. I made a "plane" with the Graphics.drawLine()
function, but I want to know how to rotate the whole thing 90 degrees to the right when it hits a wall. Here is my current code:
我一直在网上寻找这个,但我似乎无法找到如何旋转一堆线。我使用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
}
}
1 个解决方案
#1
2
You need to change it everytime you change the direction, so, you need to move your g.drawLine(...)
calls inside each if
conditions...
每次更改方向时都需要更改它,因此,如果条件允许,则需要在每个内部移动g.drawLine(...)调用...
But while rotating the plane, you also need to take care of the "bounds" or the limits of the screen, so, I modified if (x == 0)
and ... && x > 0
conditions to have a gap of 20
instead...
但是在旋转飞机时,你还需要注意屏幕的“边界”或限制,所以,我修改了if(x == 0)和... && x> 0条件,以便有20的间隙代替...
Let's start for the plane going from left to right:
让我们从左到右开始飞机:
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);
This is telling us that:
这告诉我们:
- Your plane's body length is 20
- Your wings are 15 units from the back
- Your tail is right on the back
你飞机的体长是20
你的翅膀距离背部15个单位
你的尾巴就在后面
So, to change it to move from left to right, we need to invert the wings and tail positions...
因此,要改变它从左向右移动,我们需要反转机翼和尾部位置......
- Plane lenght is still the same
- Wings are now 5 units from the back
- Tail is now on the front
飞机长度仍然相同
翅膀现在从后面5个单位
尾巴现在在前面
Then, we have this code:
然后,我们有这个代码:
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)
And for when going down:
下降的时候:
- Body's length is now on Y axis
- Wings should be at 15 units from the back
- Tail is at the back
身体长度现在在Y轴上
翅膀应该从后面15个单位
尾巴在后面
So we have:
所以我们有:
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
And applying same logic as when going from right to left:
并应用与从右到左相同的逻辑:
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);
Then your paintComponent(...)
method looks like this:
然后你的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;
}
}
}
And that's it! Here's an image showing how it looks like:
就是这样!这是一个显示它的样子的图像:
Additional tips:
-
Don't call
frame.setSize()
but overrideMovePlane
's JPanelgetPreferredSize()
to return a fixed size of300, 300
.不要调用frame.setSize(),而是覆盖MovePlane的JPanel getPreferredSize()以返回固定大小300,300。
-
Always place your GUI in the Event Dispatch Thread (EDT) by wrapping your
main
method like this:始终将GUI放在事件调度线程(EDT)中,方法是将主方法包装为:
public static void main(String args[]) { SwingUtilities.invokeLater(new Runnable() { @Override public void run() { //Your code here } }); }
-
Related to tip #1, call
frame.pack();
instead offrame.setSize()
after overridingJPanel
'sgetPreferredSize()
:)与提示#1相关,请调用frame.pack();覆盖JPanel的getPreferredSize()后,而不是frame.setSize():)
#1
2
You need to change it everytime you change the direction, so, you need to move your g.drawLine(...)
calls inside each if
conditions...
每次更改方向时都需要更改它,因此,如果条件允许,则需要在每个内部移动g.drawLine(...)调用...
But while rotating the plane, you also need to take care of the "bounds" or the limits of the screen, so, I modified if (x == 0)
and ... && x > 0
conditions to have a gap of 20
instead...
但是在旋转飞机时,你还需要注意屏幕的“边界”或限制,所以,我修改了if(x == 0)和... && x> 0条件,以便有20的间隙代替...
Let's start for the plane going from left to right:
让我们从左到右开始飞机:
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);
This is telling us that:
这告诉我们:
- Your plane's body length is 20
- Your wings are 15 units from the back
- Your tail is right on the back
你飞机的体长是20
你的翅膀距离背部15个单位
你的尾巴就在后面
So, to change it to move from left to right, we need to invert the wings and tail positions...
因此,要改变它从左向右移动,我们需要反转机翼和尾部位置......
- Plane lenght is still the same
- Wings are now 5 units from the back
- Tail is now on the front
飞机长度仍然相同
翅膀现在从后面5个单位
尾巴现在在前面
Then, we have this code:
然后,我们有这个代码:
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)
And for when going down:
下降的时候:
- Body's length is now on Y axis
- Wings should be at 15 units from the back
- Tail is at the back
身体长度现在在Y轴上
翅膀应该从后面15个单位
尾巴在后面
So we have:
所以我们有:
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
And applying same logic as when going from right to left:
并应用与从右到左相同的逻辑:
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);
Then your paintComponent(...)
method looks like this:
然后你的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;
}
}
}
And that's it! Here's an image showing how it looks like:
就是这样!这是一个显示它的样子的图像:
Additional tips:
-
Don't call
frame.setSize()
but overrideMovePlane
's JPanelgetPreferredSize()
to return a fixed size of300, 300
.不要调用frame.setSize(),而是覆盖MovePlane的JPanel getPreferredSize()以返回固定大小300,300。
-
Always place your GUI in the Event Dispatch Thread (EDT) by wrapping your
main
method like this:始终将GUI放在事件调度线程(EDT)中,方法是将主方法包装为:
public static void main(String args[]) { SwingUtilities.invokeLater(new Runnable() { @Override public void run() { //Your code here } }); }
-
Related to tip #1, call
frame.pack();
instead offrame.setSize()
after overridingJPanel
'sgetPreferredSize()
:)与提示#1相关,请调用frame.pack();覆盖JPanel的getPreferredSize()后,而不是frame.setSize():)