Rock Generation in VoR
Given the speed at which rocks are moving, we can compute the average rate at which rocks are leaving the screen. The argument goes like this:
Unidirectional Movement -- Number and Speed of Rocks
If we have a rock moving horizontally at one screen per second, then obviously it will leave the screen one second after it was generated. Thus if we generate one rock every second, we will have one on the screen at all times.
If we want N rocks on the screen, we need to generate N times as many, at even intervals.
If our rocks had speed S, then we would need to generate S times as many. For instance, if they were going at 5 screens per second, then a rock would leave the screen 1/5th of a second after it was generated, so we would need to generate 5 rocks a second to maintain one rock on the screen at all times.
So our rock generation rate is: N * S.
But of course we want to handle rocks going at different speeds. Since at higher speeds we need to generate rocks more often to keep one on screen, we have to skew the probability distribution. Taking the square root gives us the correct distribution. So if we have min speed `s' and max speed `S', and a random number `r' in the range [0, 1), then to generate a random speed between s and S, we do:
sqrt(s*s + r*(S*S - s*s))
This gives us a total rock generation rate of: N * sqrt(s*s + r*(S*S - s*s))
Movement in Multiple Directions
Handling movement along both axes (x/y) turns out to be relatively simple; we can just handle them separately. First, assume that we are generating rocks only on the top edge, and losing them only on the bottom edge. When rocks hit the left or right edges, they are simply wrapped over to the other edge. Note that in this case, we can ignore the horizontal speed -- the vertical speed is the only thing which determines how long it takes for a rock to cross the screen vertically and be lost.
Now, let's take a square screen; we want to maintain N rocks on it, all moving at velocity (1, 1). Take a moment here to visualize the diagram, or draw it on a piece of paper if necessary. Note that if we weren't wrapping the rocks left/right, all the rocks generated on the top edge would leave on the right edge. Thus to maintain N rocks on screen without wrapping, we would have to generate the same number of rocks on the left edge as we do on the top edge. But, since the x speed is the same as the y speed, this is exactly what we would get if we used our single-axis generation rate formula from above on both axes.
Consider also a similar case, but with all rocks moving at velocity (0.5, 1). Then half of the rocks generated at the top edge leave at the right edge, so we need to generate half as many rocks on the left edge. Again, this is what we would expect.
You should be able to see that this will happen no matter what direction a rock is traveling. So as long as we generate even speed distributions along both axes, we can simply use the formula `N * (Smin+Smax) / 2` to find the rock generation rate along each axis.
Summary Remarks
And that's basically it. There are a couple of housekeeping details in the actual code. For instance, rock speeds must be relative to the screen, while VoR is conceptualized as having the rocks moving at small speeds centered around zero, while the screen scrolls by them. So we must convert to screen-relative speeds. Then we must divide by constants KH and KV (horizontal and vertical) to convert the speeds from game units (pixels per 1/20th second) to screens per second. And finally, if the min and max speeds have different signs, then we need to split the range in two and generate rocks coming in from both sides of the screen.