更新时间:2023-02-02 17:54:50
转换是(通常)复合
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2D = (Graphics2D)g;
Graphics g2 = g.create();
Graphics2D copy = (Graphics2D)g2;
copy.rotate(-angleRad, xPos, yPos);
copy.translate(0, -moveY);
g2D.translate(-moveX, 0);
copy.draw(player.shape);
for (Rectangle2D.Double r: DronePilot.rocksFloorArray) {
g2D.draw(r);
}
for (Rectangle2D.Double r: DronePilot.rocksCeilArray) {
g2D.draw(r);
}
for (Rectangle2D.Double r: DronePilot.roomsArray) {
g2D.draw(r);
}
}
在上面的代码中,您正在翻译原文图形
上下文和副本
。在此上下文中, copy
不受原件的影响,原件不受副本
的影响,但是,原始上下文是共享资源,因为您不重置翻译,每次都会继续获得翻译的上下文(复合)。
In your above code, you are translating both the original Graphics
context and the copy
. In this context, copy
won't be affected by the original and the original won't be affected by the copy
, BUT, the original context is a shared resource and since you don't reset the translation, you will continue to get a translated context each time (compounding).
As根据一般经验法则,对副本进行所有转换并在完成后将其丢弃。
As a general rule of thumb, do ALL transformations on a copy and dispose of it when you're done.
例如......
Graphics2D g2d = (Graphics2D)g.create();
AffineTransform at = AffineTransform.getTranslateInstance(playerPoint.x, playerPoint.y);
at.rotate(Math.toRadians(angle), player.getBounds2D().getCenterX(), player.getBounds2D().getCenterY());
g2d.setTransform(at);
g2d.setColor(Color.RED);
g2d.fill(player);
g2d.setColor(Color.BLACK);
g2d.draw(player);
g2d.dispose();
这基本上将对象的位置转换为玩家的位置,然后围绕中心旋转对象对象
This basically translates the position of the object to the player's position and then rotates the object about the centre of the object
你也可以应用一个转换,创建该上下文的副本并应用另一个转换,这将变得复杂(所以你可以翻译
一个上下文,复制它,然后旋转
副本,第一个翻译仍将应用于副本)
You could, also, apply one transformation, create a copy of that context and apply another transformation, which would become compounded (so you could translate
one context, copy it, and then rotate
the copy and the first translation would still applied to the copy)
这个令人难以置信的简单示例演示了两个基本示例......
This incredible simple example demonstrates two basic example...
图形
上下文和 AffineTransform
翻译和旋转玩家对象(关于它的中心点) Path2D
生成一个转换后的形状(这个例子生成两个对象,但你可以使用一个 AffineTransform
翻译和旋转并申请一次)。Graphics
context and a AffineTransform
to translate and rotate the player object (about it's centre point)Path2D
to generate a transformed shape (this example makes two objects, but you could use a single AffineTransform
translated and rotated and apply it once).在这两种情况下,他们都不要不会影响原始形状
In both cases, they don't affect the original shape
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.Shape;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.geom.AffineTransform;
import java.awt.geom.Path2D;
import java.awt.geom.Rectangle2D;
import java.util.Random;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
private Shape player;
private Point playerPoint;
private float angle;
private float deltaZ = 1.0f;
private int deltaX, deltaY;
public TestPane() {
player = new Rectangle(0, 0, 20, 20);
playerPoint = new Point(80, 80);
Random rnd = new Random();
deltaX = 1;
deltaY = -1;
Timer timer = new Timer(5, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
playerPoint.x += deltaX;
playerPoint.y += deltaY;
Shape rotatedPlayer = rotatedAndTranslatedPlayer();
Rectangle2D bounds = rotatedPlayer.getBounds2D();
if (bounds.getX() < 0.0) {
playerPoint.x = (int)(bounds.getX() * -1);
deltaX *= -1;
} else if (bounds.getX() + bounds.getWidth() >= getWidth()) {
playerPoint.x = getWidth() - (int)bounds.getWidth();
deltaX *= -1;
}
if (bounds.getY() < 0) {
playerPoint.y = 0;
deltaY *= -1;
} else if (bounds.getY() + bounds.getHeight() > getHeight()) {
playerPoint.y = getHeight() - (int)bounds.getHeight();
deltaY *= -1;
}
angle += deltaZ;
repaint();
}
});
timer.start();
}
@Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
protected Shape rotatedAndTranslatedPlayer() {
Path2D.Double rotated = new Path2D.Double(player, AffineTransform.getRotateInstance(
Math.toRadians(angle),
player.getBounds2D().getCenterX(),
player.getBounds2D().getCenterY()));
return new Path2D.Double(rotated, AffineTransform.getTranslateInstance(playerPoint.x, playerPoint.y));
}
// Simply paints the "area" that the player takes up when it's rotated and
// translated
protected void paintAutoTranslatedShape(Graphics2D g2d) {
g2d.setColor(Color.DARK_GRAY);
g2d.fill(rotatedAndTranslatedPlayer().getBounds2D());
}
// Uses a AffineTransform to translate and rotate the player
protected void paintPlayer(Graphics2D g2d) {
AffineTransform at = AffineTransform.getTranslateInstance(playerPoint.x, playerPoint.y);
at.rotate(Math.toRadians(angle), player.getBounds2D().getCenterX(), player.getBounds2D().getCenterY());
g2d.setTransform(at);
g2d.setColor(Color.RED);
g2d.fill(player);
g2d.setColor(Color.BLACK);
g2d.draw(player);
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
paintAutoTranslatedShape(g2d);
g2d.dispose();
g2d = (Graphics2D) g.create();
paintPlayer(g2d);
g2d.dispose();
}
}
}