An explanation of two fundamental aspects of the Lander drawing routines
There are two important aspects to Lander that you will bump into again and again when dealing with the game's 3D graphics: the camera, and the landscape offset. In this article we take a look at what's involved.
The camera
----------
As the ship flies around in Lander, the landscape moves around beneath the ship, but the ship itself generally appears in the same place in the middle of the screen, only moving lower down the screen when the ship drops closer to ground level. So when the ship takes off from the launchpad, for example, the landscape stays in the same place on the screen until the ship has risen far enough to reach this central screen position, where it stays until it drops in altitude once again.
For example, here's the ship on the launchpad:
And here it is taking off:
These screenshots are from different games so the 3D objects are different, but if you ignore those and look at the position of the ship on-screen, you will notice that it's lower down the screen when it's on the launchpad, and much closer to the score bar when we're taking off. As we fly higher, the ship will remain in the centre of the screen, but if we drop down towards the ground, the ship will also drop down the screen.
This tracking mechanism is implemented by the game's camera, whose 3D world coordinates are stored in (xCamera, yCamera, zCamera). Note that this isn't a camera position in the true sense, as the camera in Lander is actually on the other side of the ship from us, the viewer; in fact, it is always five tiles into the screen, along the z-axis, from the ship's highest flying position.
The camera is always at this position, even when the ship is dropping down the screen to land; our view does not pan down with the ship as it lands, because the camera position does not move. So it's in this sense that the camera in Lander acts like a camera... it's just that its position is defined as being on the other side of the ship. You can also think of the camera as an origin for the viewing position within the landscape, or an anchor for the bubble of world that follows the player's ship.
The camera's coordinates change as the landscape moves around, as the camera position is a point within the 3D world. We can therefore use these coordinates to define where in the wider world the ship is currently flying, and when we want to draw objects, particles and landscape tiles on-screen, we can subtract the camera's coordinates from the 3D world coordinates of these objects to get the camera-relative positions of each of these objects. Because the camera position is always fixed relative to the viewer (as it's always at the back of the visible bubble, five tiles behind the ship's highest flying position), we can therefore work out where to draw them on-screen.
In short, when you see the phrase "camera-relative coordinates", then we're talking about coordinates that are relative to our little bubble, rather than the 3D world. Similarly, when you see the camera coordinates being added or subtracted from another coordinate, then you're seeing the frame of reference changing between the 3D world and the local bubble that we see on-screen. Coordinates are either "camera-relative" or "3D world coordinates", and the camera position within the 3D world is how we convert from one to the other.
The landscape offset
--------------------
The landscape offset is a fixed-size vector that lives in the landscapeOffset variable, and it defines how far the landscape is pushed away from the viewer in order to achieve the effect of looking down on the landscape from a distance. If we didn't push the landscape away at all, then it would be as if the viewer were standing on the corner of the landscape, rather than viewing the landscape like a three-dimensional diorama on a distant table under a reading lamp.
The landscape offset implements this act of "pushing away" as a 3D vector, and it's defined in the LANDSCAPE_X, LANDSCAPE_Y and LANDSCAPE_Z configuration variables as the distance in the three axes that we want to push the landscape away from the viewer. By default the landscape offset is set to push the landscape away by 20 tiles into the screen and along the z-axis, and by half the landscape width to the left and along the x-axis (we do the latter because the coordinate origin is in the middle of the screen rather than at the left edge, so without moving the landscape, the landscape corner would be in the middle of the screen).
Like the position of the camera, the landscape offset equates to a fixed point on the screen - in this case it's the far-left corner of the landscape - but unlike the camera it is stored in camera-relative coordinates rather than world coordinates.