How to make a camera follow a player

So I tried asking people at the stackoverflow forum and all I get are downvotes. So I’m hoping I get some help here.
Basically im trying to achieve what my title says. I can achieve this but as soon as I thrown in a scale factor it all gets messed up. By messed up I mean that the camera no longer centers itself on the player. Here is my camera class:

import java.awt.*;

public class Camera{

double x, y;
double sX, sY;

public Camera(double x, double y, double sX, double sY){
this.x = x;
this.y = y;
this.sX = sX;
this.sY = sY;
}

public void set(Graphics bbg){
Graphics2D g2 = (Graphics2D)bbg;
g2.translate(x,y);
g2.scale(sX,sY);
}

public void unset(Graphics bbg){
Graphics2D g2 = (Graphics2D)bbg;
g2.translate(-x, -y);
}

public void scale(double sx, double sy){
sX = sx;
sY = sy;
}

public void Update(Cell cell){
scale(1,1);
x = ((-cell.x + cell.mass * 0.5) + Game.width * 0.5)* sX;
y = ((-cell.y + cell.mass * 0.5) + Game.height * 0.5)* sY;
}

public double toWorldX(int x){
return x - this.x / sX;
}

public double toWorldY(int y){
return y - this.y / sY;
}
}

So I ask you, how can I factor in a scale factor to my camera object?

Just like any game, the camera doesn’t exist. You move the world around and have the player in a certain position (usually fixed unless you hit the side of the world.)

That doesn’t really answer my question. I just need to factor in the scale factor which I don’t know how to do.

Shouldn’t it be:


  public double toWorldX(int x){
    return (x - this.x) / sX;
  }
  
  public double toWorldY(int y){
    return (y - this.y) / sY;
  }

^This

@OP, remember that arithmetic is done in a certain order. Multiplication and division are done before addition and subtraction no matter if the addition/subtraction is earlier in the problem.

So y - this.y / sY is actually y - (this.y / sY) and that is not what you want

Here is a general way of doing what you want, no matter which affine transformations you are applying to your camera:


public class Camera {
    private AffineTransform view = new AffineTransform();
    private AffineTransform invView = new AffineTransform();
    private AffineTransform old;

    double x, y;
    double sx, sy;

    protected void apply(AffineTransform t) {
        t.scale(sx, sy);
        t.translate(-x, -y);
    }

    public void set(Graphics2D g) {
        old = g.getTransform();

        view.setTransform(old);
        apply(view);

        invView.setTransform(view);
        try {
            invView.createInverse();
        } catch (NoninvertibleTransformException e) {
            /* Not possible to happen with the transformations you are doing. */
        }

        g.setTransform(view);
    }

    public void unset(Graphics2D g) {
        g.setTransform(old);
    }

    public Point2D toWorld(Point2D pointInViewSpace, Point2D destPointInWorldSpace) {
        invView.transform(pointInViewSpace, destPointInWorldSpace);
        return destPointInWorldSpace;
    }
}

Not tested, though.

This really helped. Thank you!