First you need to have a camera position in your game. The virtual "camera" in a 2D game is simply a rectangle that's positioned somewhere in your 2D world.
An example - your world is 10,000 * 10,000 pixels big and your drawing surface (the window you paint in or the entire screen in full screen mode) is 1000 * 1000. Then you might define your camera to have a position of (200, 300) and a size of (1000, 1000). Everything inside that rectangle is displayed on the screen.
Most of the time it's sufficient to just remember the camera position and forget about it's size because the Graphics object doesn't need to know if an object is inside the visible area. Drawing stuff outside the screen is not causing any problems. So you can simply always draw all objects.
Additionally to the position you also need to store the zoom level of the camera.
The draw method will then look like this.
1 2 3 4 5 6 7 8 9 10
| public void draw(Graphics g) { g.scale(getZoomLevel(), getZoomLevel()); g.translate(-cameraPos.getX(), -cameraPos.getY()); for(Entity e:entities) { if(e!=null) { e.draw(g); } } } |
It's convinient to use vectors for positions.
So cameraPos should be of type org.newdawn.slick.geom.Vector2f.
So replace
1
| public float zX=0, zY=0; |
with
1
| public cameraPos = new Vector2f(0,0); |
Also it's important to remember that a game always has two coordinate systems. So you need to know which vectors are relative to the screen (absolute screen coordinates) and which vectors are relative to the coordinate system of your game.
cameraPos is always relative to the game.
Furthermore org.newdawn.slick.Graphics uses a coordinate system where (0, 0) is the upper left corner of the screen/window.
org.lwjgl.input.Mouse however puts (0, 0) at the lower left corner.
This video here demonstrates that.
http://thenewboston.org/watch.php?cat=54&number=10So you need to convert your coordinates so (0, 0) is always at the upper left corner.
You could do that like this.
1 2 3
| static Vector2f getMousePos() { return new Vector2f(Mouse.getX(), gameContainer.getHeight()-1-Mouse.getY()); } |
Now for the mouseWheelZoom method. I assume you call that every frame?
Try this
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| public void mouseWheelZoom() { int mouseWheel = Mouse.getDWheel(); if(mouseWheel==0) { return; } if(mouseWheel != 0) { Vector2f mousePosAbs = getMousePos(); Vector2f mousePosRel = mousePosAbs.copy().scale(1/zoomLevel).add(cameraPos); if (mouseWheel>0) { addZoomLevel(zoomStep); } else { addZoomLevel(-zoomStep); } cameraPos = mousePosRel.sub(mousePosAbs.scale(1/zoomLevel)); } } |
I wasn't able to test those modifications since I don't have all of your code but I hope it works.