我正在尝试绘制游戏地图,它具有带有 x 和 y 位置的图块对象。 瓷砖的图像由 1 类保存,我在完成缩放后调整它们的大小。 我想以双精度绘制图像,事实上我正在使用 AffineTransform 来翻译它们,并且还以双精度缩放。
在 Camera 类中,我将缩放变量设置为双倍。 当zoom为0时,似乎一切都好,但是当我移动鼠标时,这个错误仍然发生。 (因为相机根据鼠标距中心的距离移动)
我正在一个名为 GameScreen 的面板上绘制所有内容,我有多个 ScreenPainter 类,我可以在其中绘制不同的内容,然后在该面板上绘制所有内容。
游戏屏幕类:
public class GameScreen extends JPanel {
private static GameScreen INSTANCE;
private static Graphics2D graphics2D;
private List<ScreenPainter> painters = new ArrayList<>();
public GameScreen() {
INSTANCE = this;
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
graphics2D = (Graphics2D) g;
graphics2D.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE);
for (ScreenPainter painter : painters) painter.paint();
for (BAText text : new ArrayList<>(TextRegistry.getTexts().values())) {
if (text != null) text.drawText(graphics2D);
}
//if (BlueArchangels.STATE == GameState.PAUSE) MenuRegistry.getExitMenu().paint(graphics);
graphics2D.dispose();
}
public void updatePainters() {
painters = new ArrayList<>(ScreenPainterManager.getPainters());
}
public static GameScreen INSTANCE() {
return INSTANCE;
}
public static Graphics2D getGraphics2D() {
return graphics2D;
}
}
MapPainter类中的方法
@Override
public void paint() {
if (grids == null) {
assignValue();
return;
}
double cellWidth = getCellWidth(), cellHeight = getCellHeight();
boolean zooming = Camera.zooming();
for (Map.TileGrid tileGrid : grids) {
int offsetX = tileGrid.getOffsetX(), offsetY = tileGrid.getOffsetY();
for (Map.Tile tile : tileGrid.getAllTiles()) {
BufferedImage image = tile.getTileImage();
if (image == null) continue;
double width = cellWidth, height = cellHeight;
double x = width * (tile.x + offsetX), y = height * (-tile.y - offsetY);
AffineTransform transform = new AffineTransform();
// Ground tiles are already at the same size as the cell.
if (!tile.isGround()) {
double w = image.getWidth(), h = image.getHeight();
// Check how many times the cell stays inside the image, to scale it later.
double timesX = w / width, timesY = h / height;
// Calculate the target size of the tile.
width = width * timesX;
height = height * timesY;
// Scale the size to the target size.
transform.scale(width / w, height / h);
// Now with the target size, we calculate the exact location to place it in its cell at (x; y).
// Otherwise, when scaled it will be placed on another cell and not its original.
// Now we correct the position by placing the x coordinate and
// the bottom part of the tile in the middle of the cell.
x += -(width / 2D) + (cellWidth / 2D);
y += -height + (cellHeight / 2D);
}
if (Camera.isOutCamera(x, y, width, height)) continue;
if (zooming) {
// If zooming and the tile is ground, scale it to the correct size while waiting for resizing.
if (tile.isGround()) {
//transform.scale(width / image.getWidth(), height / image.getHeight());
x += -(width / 2) + (cellWidth / 2);
y += -(height / 2) + (cellHeight / 2);
}
wasZooming = true;
} else {
// Once the game is no more zooming, update the ground tile sizes and draw them without scaling.
if (wasZooming) resizeMapTiles();
wasZooming = false;
}
transform.translate(Camera.toX(x), Camera.toY(y));
if (zooming) {
// If zooming and the tile is ground, scale it to the correct size while waiting for resizing.
if (tile.isGround()) transform.scale(width / image.getWidth(), height / image.getHeight());
}
int degrees = tile.getRotation();
if (degrees != 0) transform.rotate(Math.toRadians(degrees), width / 2D, height / 2D);
ScreenPainter.drawImage(image, transform);
}
}
}
知道为什么会发生这种情况吗? 问题视频
我找到了这些线路的主要问题。 (据我测试)
问题是以双精度绘制的,我将缩放变量编辑为整数,问题大大减少了,现在当我尝试移动时会出现问题,因为当我绘制时位置也是双精度的使用整数位置,问题不会出现。
现在另一个问题是,如何解决双精度问题?是渲染问题吗?舍入问题?有人有过这样的经历吗?
我终于发现问题了,三周后...
您在视频中看到的问题是由 JPanel 不透明引起的(我不知道为什么会导致该问题)。
要修复这个恼人的错误,只需将 JPanel 设置为 not opaque。
解决此问题的最佳方法
重写 isOpaque 方法以确保它始终为 false:
@Override
public boolean isOpaque() {
return false;
}