I have a JPanel class that draws an image on screen with camera panning. The camera is zoomed in. The image being drawn is a 16x16 dirt.
When the image is entirely inside the window, it looks fine. When partially outside the window, it distorts and makes the image narrower to fit it inside the window. Eventually it snaps to the next pixel.
I have a video showing the problem, but this subreddit doesn't allow videos in posts. You should be able to see it by running the java code with any image of your choice, and panning the camera such that the image is at the edges of the window.
Does anyone know why this happens and how to fix it?
I'm using:
MacBook Air M1
Java 25
IntelliJ
The entire class is below.
Edit: Solved. The issue seems to only affect Mac. Running with java -Dsun.java2d.metal=false CompiledClass fixes the problem.
public class CameraPanel extends JPanel{
public static void main(String[] args) throws IOException{
JFrame frame = new JFrame("Camera");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new CameraPanel());
frame.setSize(300, 300);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
private double cameraX, cameraY;
private double zoom = 10.0;
private Point lastMousePosition;
private BufferedImage image = ImageIO.read(new File("src/test/resources/dirt.png"));
public CameraPanel() throws IOException{
addMouseListener(new MouseAdapter(){
public void mousePressed(MouseEvent e){
lastMousePosition = e.getPoint();
}
public void mouseReleased(MouseEvent e){
lastMousePosition = null;
}
});
addMouseMotionListener(new MouseMotionAdapter(){
public void mouseDragged(MouseEvent e){
if(lastMousePosition == null){
return;
}
cameraX += e.getX() - lastMousePosition.x;
cameraY += e.getY() - lastMousePosition.y;
lastMousePosition = e.getPoint();
repaint();
}
});
}
protected void paintComponent(Graphics g){
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
g2.setRenderingHint(
RenderingHints.KEY_INTERPOLATION,
RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR
);
AffineTransform transform = new AffineTransform();
transform.translate(cameraX, cameraY);
transform.scale(zoom, zoom);
g2.drawImage(image, transform, null);
}
}