I would appreciate some help with camera movement and zoom. Is there any easier way with cleaner 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 java.awt.Graphics2D;
import java.awt.Point;
import java.awt.event.MouseEvent;
import java.awt.event.MouseWheelEvent;

public class Camera {

public boolean isEnabled = true;
public int offsetX = 0;
public int offsetY = 0;
public float zoom = 1;
private Point mouseLocation;
private int maxOffsetXZoom = 200;
private int maxOffsetYZoom = 150;
private final int OFFSET_X_MAX = 200;
private final int OFFSET_Y_MAX = 150;
private final float ZOOM_MAX = 1.2F;
private final float ZOOM_MIN = 0.7F;

public Camera() { }

public void draw(Graphics2D g) { }

public void update() { }

public void mousePressed(MouseEvent e) { mouseLocation = e.getPoint(); }

public void mouseReleased(MouseEvent e) { }

public void mouseMoved(MouseEvent e) { }

public void mouseDragged(MouseEvent e)
    int newoffsetX = offsetX - (mouseLocation.x - e.getX());
    int newoffsetY = offsetY -  (mouseLocation.y - e.getY());

    if(newoffsetX > maxOffsetXZoom) offsetX = maxOffsetXZoom;
    else if(newoffsetX  < -maxOffsetXZoom + (OFFSET_X_MAX-maxOffsetXZoom) * 4) offsetX = -maxOffsetXZoom + (OFFSET_X_MAX-maxOffsetXZoom) * 4;
    else offsetX = newoffsetX;

    if(newoffsetY  > maxOffsetYZoom) offsetY = maxOffsetYZoom;
    else if(newoffsetY < -maxOffsetYZoom - 25 + (OFFSET_Y_MAX-maxOffsetYZoom) * 4) offsetY = -maxOffsetYZoom - 25 + (OFFSET_Y_MAX-maxOffsetYZoom) * 4;
    else offsetY = newoffsetY;

    mouseLocation = e.getPoint();

public void mouseScrolled(MouseWheelEvent e)
    if (e.getWheelRotation() < 0) {
        if(zoom<ZOOM_MAX) zoom += 0.05;
    } else {
        if(zoom>ZOOM_MIN) zoom -= 0.05;
    maxOffsetXZoom = (int) (OFFSET_X_MAX * zoom);
    maxOffsetYZoom = (int) (OFFSET_Y_MAX * zoom);
    if(offsetX > maxOffsetXZoom) offsetX = maxOffsetXZoom;
    else if(offsetX  < -maxOffsetXZoom + (OFFSET_X_MAX-maxOffsetXZoom) * 4) offsetX = -maxOffsetXZoom + (OFFSET_X_MAX-maxOffsetXZoom) * 4;

    if(offsetY  > maxOffsetYZoom) offsetY = maxOffsetYZoom;
    else if(offsetY < -maxOffsetYZoom - 25 + (OFFSET_Y_MAX-maxOffsetYZoom) * 4) offsetY = -maxOffsetYZoom - 25 + (OFFSET_Y_MAX-maxOffsetYZoom) * 4;

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.


I'm going to assume your indentation got messed up on posting, but just in case, you should indent all of the code inside of the Camera class an additional time.

First off, I like that you used constants at the top of your code! To ensure that they look and act like constants, you should make them private, static, final, and named in UPPERCASE_FORMAT. Furthermore, I would recommend separating your constants from your class variables (such as mouseLocation and offsetX).

I'm not entirely sure how your functions are being called. It looks like you are implementing MouseMotionListener, so I would definitely add that to your class declaration.

If that is true, then I don't see the purpose of the drag variable. The mouseDragged function is only going to get called if the mouse is actually being dragged, so assigning a boolean when the mouse is pressed and released appears redundant.

Also, I'd recommend considering whether you want to use BigDecimal. If round needs to be fast, then you don't want to use BigDecimal at all. There are other techniques for rounding to the nth digit that can be found here

| improve this answer | |
  • \$\begingroup\$ Thank you, I changed the constants, removed the useless drag boolean and also removed void round and left the float unrounded (I rounded it only because it looked better like 1.05 than 1.050000001, but it will not be visible outside of debug anyways). Functions like mouseDragged are called by my engine which has various listeners. \$\endgroup\$ – Ladas125 Jul 15 '15 at 17:26

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.