Expressing your camera using bounds
If I noticed correctly, you are currently expressing your camera as a focuspoint (= center of the camera) and a zoom level (how closely zoomed in you are). I'm also assuming your game is two-dimensional, with assets rendered in the XY-plane, and the camera looking along the Z-axis.
While parametrizing your camera like this could definitely work, you could also think of it differently. Instead of stating what where your camera is looking at, you could specify what area you want to be onscreen. In this case, you would parameterize your camera in terms of bound. On the X-axis, you have the left bound and the right bound. On the Y-axis, you have the top bound and the bottom bound. (Assuming the X-axis is your horizontal axis, pointing to the right, and the Y-axis is your vertical axis, pointing upward.)
Using this parameterization, you are always 100% what is being shown onscreen. Note that you can always translate back and forth between this representation and your original one (this requires the "scale" parameter to be split in a "xScale" and "yScale", as scaling is not necessarily uniform).
World coordinates and Screen coordinates
Your question basically relates to moving from world coordinates to screen coordinates.
- The world coordinates of an asset express its place in your game world. You could think of this as the position where you place the asset with your map editor. They remain unchanged if you move the camera around.
- The screen coordinates of an asset express its location on your screen. You can think of this as follows: assume you jump into your game and take a photograph of the scene, through the lens of your camera. The place where your asset ends up on the photograph, are the screen coordinates of the asset. They are affected by the camera. If you move the camera to the left, your asset will move to the right in screen coordinates.
Lets assume your screen has a width of screen_w (e.g. 800 pixels), and a height of screen_h (e.g. 600 pixels). To translate a single point from world coordinates to screen coordinates, you'd do the following:
x_screen = screen_w * (x_world - cam_left_bound) / (cam_right_bound - cam_left_bound)
y_screen = screen_h * (y_world - cam_bottom_bound) / (cam_top_bound - cam_bottom_bound)
If you use a y-axis that points downward, this last line becomes:
y_screen = screen_h * (y_world - cam_top_bound) / (cam_bottom_bound - cam_top_bound)
For example, a point that is exactly at the left bound of your camera will have a screen x-coordinate of 0. A point exactly at the right bound of your camera will have a screen x-coordinate of screen_w. Other points will evaluate to their correct position as well.
Solution: Calculating the bounds of your assets
The above explains how to find where a single point would end up in screen coordinates. You can use this information to figure out where an asset goes as well.
Again, rather than thinking of an asset as a centerpoint on top of which a scalable sprite is drawn, you could think of it in terms of bounds. If you know the left, right, top and bottom bounds of your sprite (in screen coordinates), you know exactly where and how to draw it. In essence, you are just drawing a rectangle on your screen, and you are drawing the asset inside of this rectangle.
Thus, to figure out how to draw your asset in screen coordinates, do the following:
- Use the left, right, top and bottom bounds of your asset in world space (these are 2 x-coordinates and 2 y-coordinates)
- Transform these coordinates to screen coordinates
- Draw your asset on a rectangle that uses those screen coordinate bounds
In summary, you might find your problem easier by thinking in terms of bounds, rather than a position and a scaling factor. Thinking of the "position finding problem" as a transformation between world space and screen space may also help you. In fact, transformations between different coordinate systems or spaces are ubiquitous in 2D and 3D rendering for games! The difference is that they use matrices rather than separate equations, as these are easier when combining multiple transformations (e.g. translations, rotations and scalings).