Tutorial 2 Scrolling Bitmaps

Use the source Luke! Click here to download the tutorial

We're going to build upon our previous example of the static background art. In this example we're going to put together a simple scrolling background effect.

In the previous tutorial, Tutorial 1, Working with Offscreen Buffers, we loaded a png file for our background art into the backgroundBitmap object. The bitmap was 256 pixels wide by 192 pixels tall. For this example, we are going to create a new bitmap object, _scrollBitmap, whose dimensions are 512 pixels wide by 192 pixels tall. The _scrollBitmap object will contain the bitmapdata contents of the backgroundBitmap pasted twice into the buffer. What we will have looks like the figure below.



This example is expands the concepts of the previous tutorial by the _scrollBitmap object. Fronm the figure above you can see that the _scrollBitmap is simply twice the size of the background_Bitmap object. The _scrollBitmap will hold 2 copies of the background_Bitmap's data.

Creating the Scroll Bitmap
The following code snippet creates the _scrollBitmap object and copies the background_Bitmap bitmapdata into it. Again, the _scrollBitmap is twice the size of the background_Bitmap. The _scrollBitmap is 512 pixels wide by 192 pixels high. Let's create our _scrollBitmap.

// create the scroll buffer
_scrollBitmapData = new BitmapData(512, 192, false, 0x000000);
// create the scroll bitmap buffer
_scrollBitmap = new Bitmap(_scrollBitmapData);

Next we copy the background_Bitmap pixels into the first half of our _scrollBitmap buffer. We do this by setting the source copy rectangle to top left (0,0) and bottom right to (256,192). The copy destination point is (0,0) -we want to copy into the first half of the _scrollBitmap buffer.

// copy the background art to the scroll BitmapData buffer
// copy the sprite background to the scroll buffer
var srcRect = new Rectangle(0,0,256,192);
var dstPt = new Point(0,0);

// copy into the first half of the scroll buffer
_scrollBitmapData.copyPixels(background_Bitmap.bitmapData, srcRect, dstPt );


Now we copy the background_Bitmap pixels once again. But this time we copy the pixels to the last half of the _scrollBitmap buffer. The copy source rectangle is the same as we used in the previous step. The copy destination rectangle must reflect we are copying to the second half of the buffer. The new destination point is (255,0).

// copy in the second half of the scroll buffer
var srcRect = new Rectangle(0,0,256,192);
var dstPt = new Point(255,0);
_scrollBitmapData.copyPixels(background_Bitmap.bitmapData, srcRect, dstPt );


The _scrollBitmap is now ready for our scrolling test. Let's take a look at the next step we need to tackle and that is to create a sliding window to peak through.

Looking Through a Sliding Window

Some design decisions must be made here. Are we going to scroll the background to the right (x-positive direction) or do we want to scroll to the left (x-negative direction). Since I am backwards engineering the Gundam game for this demo we are going to scroll to the left, which is the screen x-negative direction. This will give the appearance of a forward motion as the background scrolls to the left.

Scrolling to the left means we need to start in the middle of the _scrollBitmap buffer and scroll the pixels to the left. If we were scrolling right, we would start with the pixles at the front of the buffer and scroll right. I am going to introduce a variable, scrollIndex, which represents the current front x-position of our scrolling window. Since we are scrolling to the left, we will initialize the scrollIndex to x-position 256. If you want to scroll backwards set this index to 0. Here is a snapshot of our function Render, that handles the sliding window effect.

// copy the background bitmap to the offscreen
// compose all animation on the offscreen bitmap
// and then drw it to the viewport (Flash on the browser)
var srcRect = new Rectangle(0,0,256,192);
var dstPt = new Point(0,23);

// copy the scroll background section to the offscreen
var srcRect = new Rectangle(
        scrollIndex, 0, 255 + scrollIndex, 191);
var dstPt = new Point(0,23);
gfx.Gfx_copyPixels_to_Offscreen(
        scrollBitmapData, srcRect, dstPt );

// update the scroll Index for next render
/*
// scroll to the right
if (scrollIndex > 255) {
    scrollIndex = 0;
} else {
    scrollIndex++;
}
*/
// scroll to the left
if (scrollIndex < 0) {
    scrollIndex = 256;
} else {
    scrollIndex--;
}

For finishing touches to give the sense of motion I have a sprite overlay of the deck of an aircraft carrier. This drawn to the _offscreenBitmap after the background is drawn.



The aircraft carrier sprite is stuffed into the same swf file as the background_Bitmap object. Using the same methods described in Tutorial 01. This is the foreground_Bitmap object in our code. The sprite is 256 pixels long and 142 pixels high.

// copy the foreground overlay (the aircraft carrier)
// copy the foreground to the viewport
var srcRect = new Rectangle(0,0,256,142);
var dstPt = new Point(0,75);
gfx.Gfx_copyPixels_to_Offscreen(
        foreground_Bitmap.bitmapData, srcRect, dstPt );


This is our finished product for this example.



But wait a minute! I thought you said this was a scrolling demo? The code as it sets will not animate on the screen. Flash requires a timer to be setup for our animation sequence. This is how you create a Timer object using HaXe.

updateTimer = new Timer( 10, 0 ); // T=10ms => f=
updateTimer.addEventListener(flash.events.TimerEvent.TIMER, update);
updateTimer.start();


The Timer will need to call our function Render. For further reading on Timers, ticks and Flash 9, take a look at: The Elastic Race Track

public function update(event:flash.events.TimerEvent){
    Render();
}

That's how the animation rendering is handled in this demo. If you comment out the function Render and call it from function main, you will see only one frame of animation. This is why the Timer is required in our animation sequence. Here is the command line syntax to compile the code.

haxe -swf GD_Game.swf -swf-version 9 -swf-lib swf/sprite_png_lib.swf -cp src -swf-header 256:224:30 -main Main

The html code will break up the compile line above into multiple lines -keep in mind this is a single command line. Not multiple!

Return to Home Page

Send comments to: mnorton wecare net