6
\$\begingroup\$

I am attempting to create a game where the camera follows the player, always making sure the player is in the center of the screen. How would I go about this? This game is a 2D Java game, made with no engine.

I found an opensource game demonstrating what I want but I cannot work out how to add that to my game. The game is here, if you need it.

Thanks

\$\endgroup\$

4 Answers 4

9
\$\begingroup\$

First, you need to define the size of the viewport (the camera resolution), for simplicity, let's assume the camera viewport is the size of the screen, we have a 800*600 screen.

Next, you need to define the maximum and minimum offsets of your camera. Assuming you have a world with a size of 1600*1200, the maximum offset would be 800 on X and 600 on Y and 0 on both axis for the minimum offsets. The general formulas to determine the offsets is:

offsetMaxX = WORLD_SIZE_X - VIEWPORT_SIZE_X
offsetMaxY = WORLD_SIZE_Y - VIEWPORT_SIZE_Y
offsetMinX = 0
offsetMinY = 0

Now, over frames, you need to calculate the actual position of the camera. A position that would make the player being centered on the screen. The position need to be calculated relatively to the player position.

camX = playerX - VIEWPORT_SIZE_X / 2
camY = playerY - VIEWPORT_SIZE_Y / 2

Don't forget to check if the camera position do not exceed the maximum and minimum offsets.

if camX > offsetMaxX:
    camX = offsetMaxX
else if camX < offsetMinX:
    camX = offsetMinX
if camY > offsetMaxY:
    camY = offsetMaxY
else if camY < offsetMinY:
    camY = offsetMinY

Now that you know the position of the camera, you will to translate the world to this position. When you open a plain window and start drawing stuffs, the area you see start at 0,0. To create the illusion of a camera following the player, you will need to set your drawing area position (the screen in your example) to the camera position.

I don't know what framework/engine you are using but the easiest way to do it is to translate the whole graphic context by the opposite of the current offsets. You will need to know how to access your graphic context and apply a translation to it.

In slick2d, it could look like this:

public void render(..., Graphics g) {
    g.translate(-cam.x, -cam.y)
    //render the rest of your game
}
\$\endgroup\$
2
  • \$\begingroup\$ Thanks! Got it all working now! I started using Slick2D anyway. \$\endgroup\$
    – Nijokijun
    Commented Nov 26, 2012 at 13:11
  • 1
    \$\begingroup\$ @nathan can you please explain why you need those offsets? (offsetMaxX, offsetMaxY, offsetMinX, offsetMinY) \$\endgroup\$
    – user3871
    Commented Jul 16, 2013 at 15:33
2
\$\begingroup\$

I am by no means an authority on this, but one way I've figured out to do this is to create a camera object. The camera would have position, movement vector and dimension variables, along with functions to determine the local position and visibility of other game entities, and to move the camera itself.

Basically, each game entity has a position variable and a local position variable. Every frame, you check to see if the entities are visible, and if they are, get their local positions. (Look into QuadTrees to make this process more efficient.) Then you simply draw the visible objects at their local position.

The only other thing you have to do is create a way to control where and how the camera moves. For a 2D side scroller or and isometric game, just feed the cameras move function the player movement vector every frame to keep the player in the center of the screen.

Hope this helps, Peter

\$\endgroup\$
0
\$\begingroup\$

Have the position at which object is drawn offset by the x and y position of the player and minus half the screen width/height.

ob1.x -= player.x+screen.width;
ob2.y -= player.y+screen.height;

Loop that for every object

\$\endgroup\$
0
\$\begingroup\$

The way that I did it was by taking the player's x co-ord and y co-ord, made them negative and added them to screen width/height divided by two

FactoryWU.frame.GP.cam.locationX = (int) (-FactoryWU.world.player.getXInt()+((this.getWidth()/cam.zoomLevel)/2)-(10*cam.zoomLevel));
FactoryWU.frame.GP.cam.locationY = (int) (-FactoryWU.world.player.getYInt()+((this.getHeight()/cam.zoomLevel)/2)-(10*cam.zoomLevel));

So all what you have to do is add all of your objects co-ords to the cam.locationX or Y

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .