我正在尝试为我的游戏编辑器实现缩放工具。我正在使用Color []来存储所有“Colors / tiles”,我希望能够在我的JPanel中放大以查看所有关闭或远离的图块,即放大或缩小。这些是我想要的一些要求(任何例子都受到赞赏,它们不需要包括所有或任何要求。它们可以帮助您理解我的目标):
这是我编辑器的一个非常简单的版本。我添加了一些缩放测试代码,但它不起作用。我给你这个代码,所以你有必要从一开始就有必要。请参阅PaintComponent方法和mouseWheel侦听器。
已编辑:感谢@trashgod,您现在可以将颜色放置在正确的位置。请参阅MouseTest类! 撕裂了。
package stuff;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseWheelEvent;
import java.awt.event.MouseWheelListener;
import java.awt.geom.AffineTransform;
import java.awt.geom.NoninvertibleTransformException;
import java.util.Random;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.Scrollable;
import javax.swing.SwingUtilities;
public class ZoomPane extends JPanel implements MouseWheelListener, Scrollable {
private int width, height, screenWidth, screenHeight, tileSize;
private Color[] colorMap;
private double scale = 1.0;
// Zooming
AffineTransform at;
class MouseTest extends MouseAdapter {
public void mousePressed(MouseEvent e) {
try {
int newX = (int) at.inverseTransform(e.getPoint(), null).getX();
int newY = (int) at.inverseTransform(e.getPoint(), null).getY();
colorMap[(newX / tileSize) + ((newY / tileSize) * width)] = getRandomColor();
} catch (NoninvertibleTransformException e1) {
e1.printStackTrace();
}
repaint();
}
@Override
public void mouseDragged(MouseEvent e) {
super.mouseDragged(e);
try {
System.out.println("Dragging");
int newX = (int) at.inverseTransform(e.getPoint(), null).getX();
int newY = (int) at.inverseTransform(e.getPoint(), null).getY();
colorMap[(newX / tileSize) + ((newY / tileSize) * width)] = getRandomColor();
} catch (NoninvertibleTransformException e1) {
e1.printStackTrace();
}
repaint();
}
}
public ZoomPane(int width, int height, int tileSize) {
super();
this.width = width;
this.height = height;
this.screenWidth = width * tileSize;
this.screenHeight = height * tileSize;
this.tileSize = tileSize;
this.colorMap = new Color[width * height];
addMouseWheelListener(this);
addMouseListener(new MouseTest());
addMouseMotionListener(new MouseTest());
}
public void paintComponent(Graphics g) {
super.paintComponents(g);
final Graphics2D g2d = (Graphics2D) g.create();
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
// Scale
at = null;
at = g2d.getTransform();
// Translate code here?
at.scale(scale, scale);
g2d.setTransform(at);
final Rectangle clip = g2d.getClipBounds();
g2d.setColor(Color.DARK_GRAY);
g2d.fill(clip);
int topX = clip.x / tileSize;
int topY = clip.y / tileSize;
int bottomX = clip.x + clip.width / tileSize + 1 + (int) (tileSize * scale);
int bottomY = clip.y + clip.height / tileSize + 1;
// Draw colors
for (int y = topY; y < bottomY; y++) {
for (int x = topX; x < bottomX; x++) {
Rectangle r = new Rectangle(width, height);
if (r.contains(x, y) && colorMap[x + y * width] != null) {
g2d.setColor(colorMap[x + y * width]);
g2d.fillRect(x * tileSize, y * tileSize, tileSize, tileSize);
}
}
}
g2d.dispose();
}
private Color getRandomColor() {
Random rand = new Random();
return new Color(rand.nextInt(255), rand.nextInt(255), rand.nextInt(255));
}
@Override
public Dimension getPreferredSize() {
return new Dimension((int) (screenWidth), (int) (screenHeight));
}
@Override
public void mouseWheelMoved(MouseWheelEvent e) {
double delta = 0.05 * e.getPreciseWheelRotation();
if (scale + delta > 0)
scale += delta;
revalidate();
repaint();
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
JFrame frame = new JFrame("Zoom test");
// Frame settings
frame.setVisible(true);
frame.setPreferredSize(new Dimension(800, 600));
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JScrollPane pane = new JScrollPane(new ZoomPane(50, 50, 32));
frame.add(pane);
frame.pack();
}
});
}
@Override
public Dimension getPreferredScrollableViewportSize() {
repaint();
return null;
}
@Override
public int getScrollableBlockIncrement(Rectangle visibleRect, int orientation, int direction) {
repaint();
return 0;
}
@Override
public boolean getScrollableTracksViewportHeight() {
repaint();
return false;
}
@Override
public boolean getScrollableTracksViewportWidth() {
repaint();
return false;
}
@Override
public int getScrollableUnitIncrement(Rectangle visibleRect, int orientation, int direction) {
repaint();
return 0;
}
}
如果您尝试运行该程序,您将看到以下问题:
这是目前有效的方法:
正如你所看到的那样,我在顶部提到的大多数要求都可以在SO上的文章中找到,其中大多数都非常好并且描述得很好但是我不知道/不能实现它们以便我可以解决上面的问题。
我使用此缩放的目标就像here中的示例,除了绘制我的“Colors / tiles”而不是他绘制的矩形以及我正在使用AffineTransform。否则那个例子就是我的目标。
它不必使用他使用的任何代码。我会更喜欢使用AffineTransform。如果你们中的任何一个人知道如何以另一种方式实现我正在寻找的东西,那我就是全部的耳朵。我认为这个例子可能会让你们更容易理解我的目标。
我接受有关代码或实现的任何更改或评论,我会尽快回复并更改帖子。
非常感谢, Towni0