Warp 1.5: Technical stuff

There are many similarities between the ways I implemented the scrolling backgrounds in Warp 1.5 and Warp. Though it's perhaps slightly more straighforward this time and it works as follows.

All graphics are drawn and manipulated on a single Image object, with a Graphics Context, 288 pixels wide and 1024 pixels high. The top part (A) is basically what you see on the screen. The middle part (B) is the area where the scrolling background is drawn and updated. The bottom part (C) is where the building blocks of the current level are stored, to be copied onto (B) when needed. All moving objects are drawn on (A), which is then shown in the applet area.

I create the illusion of a scrolling background by copying a portion (D) of (B) onto (A) in each turn of the animation loop, always selecting (D) 4 pixels higher than in the previous turn. You can think of (D) as a viewing window that gradually moves upward.

Obviously, this process can't go on forever. When (D) reaches the top of (B) it has to move down to the bottom again, in such a way that there will be no visible discontinuity. I manage that by updating (B) in a special way. Note that (B) is a little over twice the size of (D).

Since the user only sees the (D) part of (B), that's the only portion of the background map that has to be fully accurate. What is outside is of no concern as long as it's ready when (D) finally reaches it. The building blocks are 32x32 pixels in size and (D) moves upward at a rate of 4 pixels per animation frame, which means a new block row has to be finished every 8 frames. I update the nearest block row above (D) that's fully out of view. Then I copy that one to the nearest row below (D). If you think about it for a while, you realize this gets the result that when (D) has reached the top of (B), there is an identical copy of the viewable area just below it. Hence, if (D) jumps down again, there is no difference in what the user sees and the scrolling can continue from there.

(This explanation does not cover the two special cases at the start and at the end of a level, when only part of the screen appears to scroll and the rest is stationary with a few moving stars. That felt a little too messy to be properly described in this limited space.)

Now, for all of this to work smoothly on relatively slow computers, it is necessary to balance the workload of the applet so that roughly the same amount of graphical manipulation is done in each animation frame. Since there is no way to spread a 9-block row update evenly over 8 frames, I don't bother to make it completely even. In some of those cyclic frames I deliberately do less and save the extra time for "low priority updates" -- typically drawing the broken remains of exploded background objects (which are put in a queue) and the player's score.