Skip to main content
1 of 5
Ladas125
  • 255
  • 2
  • 8

Java 2D camera movement and zoom

I would appreciate some help with camera movement and zoom.
Is there any easier way with more clean code or simply how can I improve it?

Window size: 800x600
Image size: 1200x900

This is my code so far (you can move with the camera only around the image and use zoom):

package game.engine.gui;

import game.engine.Engine;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.MouseEvent;
import java.awt.event.MouseWheelEvent;
import java.math.BigDecimal;

public class Camera {

public Point mouseLocation;
public boolean drag = false;
public boolean isEnabled = true;
public Rectangle view;
public int offsetX = 0;
public int maxOffsetX = 200;
public int maxOffsetXZoom = 200;
public int offsetY = 0;
public int maxOffsetY = 150;
public int maxOffsetYZoom = 150;
public float zoom = 1;
public float maxZoom = 1.2F;
public float minZoom = 0.7F;

public Camera() {
    view = new Rectangle(0,0,Engine.window.getWidth(),Engine.window.getHeight());
}

public void draw(Graphics2D g)
{
    
}

public void update()
{
    
}

public void mousePressed(MouseEvent e)
{
    if(e.getButton()==MouseEvent.BUTTON1)
    {
        mouseLocation = e.getPoint();
        drag = true;
    }
}

public void mouseReleased(MouseEvent e)
{
    drag = false;
}

public void mouseMoved(MouseEvent e)
{
    
}

public void mouseDragged(MouseEvent e)
{
    if(drag)
    {
        int newoffsetX = offsetX - (mouseLocation.x - e.getX());
        int newoffsetY = offsetY -  (mouseLocation.y - e.getY());
        
        if(newoffsetX > maxOffsetXZoom) offsetX = maxOffsetXZoom;
        else if(newoffsetX  < -maxOffsetXZoom + (maxOffsetX-maxOffsetXZoom) * 4) offsetX = -maxOffsetXZoom + (maxOffsetX-maxOffsetXZoom) * 4;
        else offsetX = newoffsetX;
        
        if(newoffsetY  > maxOffsetYZoom) offsetY = maxOffsetYZoom;
        else if(newoffsetY < -maxOffsetYZoom - 25 + (maxOffsetY-maxOffsetYZoom) * 4) offsetY = -maxOffsetYZoom - 25 + (maxOffsetY-maxOffsetYZoom) * 4;
        else offsetY = newoffsetY;
        
        mouseLocation = e.getPoint();
    }
}

public void mouseScrolled(MouseWheelEvent e)
{
    if (e.getWheelRotation() < 0) {
        if(zoom<maxZoom) zoom += 0.05F;
    } else {
        if(zoom>minZoom) zoom -= 0.05F;
    }
    zoom = round(zoom, 2);
    maxOffsetXZoom = (int) (maxOffsetX * zoom);
    maxOffsetYZoom = (int) (maxOffsetY * zoom);
    if(offsetX > maxOffsetXZoom) offsetX = maxOffsetXZoom;
    else if(offsetX  < -maxOffsetXZoom + (maxOffsetX-maxOffsetXZoom) * 4) offsetX = -maxOffsetXZoom + (maxOffsetX-maxOffsetXZoom) * 4;
        
    if(offsetY  > maxOffsetYZoom) offsetY = maxOffsetYZoom;
    else if(offsetY < -maxOffsetYZoom - 25 + (maxOffsetY-maxOffsetYZoom) * 4) offsetY = -maxOffsetYZoom - 25 + (maxOffsetY-maxOffsetYZoom) * 4;
}

public float round(float d, int decimalPlace) {
    BigDecimal bd = new BigDecimal(Float.toString(d));
    bd = bd.setScale(decimalPlace, BigDecimal.ROUND_HALF_UP);
    return bd.floatValue();
}
}

It works, but I think it's a huge mess and also if the image size was different it would require a lot of changes. I am using my own engine.
Thanks for any answers.

Ladas125
  • 255
  • 2
  • 8