I had this idea that it would be really cool to create a backdrop for Eufloria levels. Perhaps a high-tech looking green grid. What I wanted is to create a sort of parallax scrolling effect.
Here is an example of one-dimensional Parallax Scrolling:
As well as the foreground, there are a few different layered backgrounds, and as you travel through the level, they move with the terrain - but at slower speeds, as if they were far away.
Any parallax scrolling system for Eufloria would necessarily need to be 2D because you can scroll up and down, as well as left and right.
Also, you would need some way of deciding what to do when the user zooms in and out.
My feeling is that the backdrop should zoom in with the rest of the game field, but to a lesser degree...governed by that particular backdrop layer's depth value. That means if the screen is really zoomed in, the zoom value will be something like 0.05 and the X and Y values will end up being extremely high - resulting in a slightly closer look at the backdrop when zoomed in, and a slightly further away view when we're zoomed all the way out.
I propose the system be split into 2 parts; the Paralax engine itself, and a section that contains the code for the backdrop artwork. The parallax engine's job would be to shift each point that is drawn on the backdrop by an amount proportional to the various offsets and zoom levels that we are monitoring. By splitting it in this way, you could create an artwork "template" and that would allow others to create their own artwork to use as parallax layers.
1) PARALLAX ENGINE
Read the parameters for the current view; how many layers have been defined? What are their depths? How zoomed in are we? Where is the screen centred?. Use these to calculate vertical and horizontal offsets for each layer as follows:
Left or Right by an amount equal to the horizontal screen offset from the center divided by the amount we are zoomed in or out.
Up or Down by an amount equal to the vertical screen offset from the center divided by the amount we are zoomed in or out.
Then, for each point that we wish to draw, divide both X and Y values by the SHIFT VALUE. The SHIFT VALUE is calculated by taking the zoom value and dividing it by the layer depth value for that particular layer. This is necessary so that we shift far away (ie deep) layers less than layers close to the foreground.
2) BACKDROP ARTWORK
Render each backdrop layer by creating a standardised vector image with all the drawing points as parallax-engine-approved variables, declaring a layer depth for each parallax layer, and shifting each "draw point" by the Shift Value calculated by the engine.
It would be possible to add multiple layers with different depths, I think. For example, for the deepest layer, you could have a starfield, and for an intermediate layer you could have a green Tron-style grid. This would look really awesome when scrolling around the map, hopefully.
To pad this idea out some more, I'm going to attempt to list the variables you would need to keep track of.
First of all, you would need a complicated data structure to store the information about the artwork of the parallax layer..
You could create a couple of matrices for this - lets call them matrix X and matrix Y. Lets take Matrix X as our example, each column in this would represent a whole parallax layer, and each cell within a particular column would contain sequential drawing point coordinate pairs.
For example, if I have a parallax layer containing a single line drawn from coordinates 50,50 to coordinates 100,100, and a second parallax layer containing two lines - one from 125,500 to 15,-400 and the other line -100,350 to -75,175, this is what the matrices would look like:
| 50 | 125|
| 100| 15 |
| nil| 175|
| 50 | 500|
| nil| 350|
| nil| 175|
Then we know that to draw the line, we just work down the column and use odd numbers as the draw start point, and even numbers as the draw end point.
Columns = parallax layers
Pairs of values going down each column = the coordinates of the lines.
Ok, so what other variables are there? Well, we need to know how zoomed in we are. GetCameraZoom() I believe returns a value for that.
We need to know where the screen is centred - we need to know for both X and Y.
We need to know the depth of each layer because this is needed in order to calculate the Shift Value.
Ultimately, we divide each draw point by the Shift Value, and this is what causes what is drawn onscreen to move about realistically like something very far in the distance might do.
Please let me know whether you think this would work the way I am proposing, or if you can spot any flaws in my pseudo-maths. :>