1
votes

I am new to action script. I tried to create an endless scrolling background that goes from up to down the stage, vertically of course. I tried to do it with creating a movie clip, putting the image in a movie clip and applying some code, it worked like a charm, but i noticed some leaks. Therefore i tried another method i found on the stack committee, which suggested using the newBitmapData method. The question i found consisted that a background will move from left to right, i tried it, it was perfect.
I tried to comprehend all the variables and factors in it in order to change it and make it scroll from top to bottom, but i get stuck every time with a weird behavior from the flash file. I am sure i am doing something wrong. I would really appreciate the help.. i am eager to learn.
THis is is stack source committee link i got the answer from :
The link and the answer

Here is the same code that i am trying to implement, copied from the link :

package  {
    import flash.display.MovieClip;
    import flash.display.Bitmap;
    import flash.display.BitmapData;
    import flash.events.Event;
    import flash.geom.Rectangle;
    import flash.geom.Point;


    public class EndlessBG extends MovieClip{
        //this one stays stationary, we're getting the pixels for the right side of the pic from here
        private var _source:BitmapData;
        //this is the one moving to the left (the pixels for the right side are not visible except for once a cycle);
        private var _movingPixels:BitmapData;
        private var _canvas:Bitmap;
        private var _xOffset:int = 0;
        private var _rect:Rectangle = new Rectangle();;
        private var _point:Point = new Point();

        public function EndlessBG() {
            super();
            _source = new BathroomStillLife();
            _canvas = new Bitmap(new BitmapData(_source.width, _source.height));
            _canvas.bitmapData.draw(_source);
            _canvas.x = stage.stageWidth/2 - _canvas.width/2;
            _canvas.y = 5;
            addChild(_canvas);
            addEventListener(Event.ENTER_FRAME, gameLoop);
            setGeometryDefaults();
            _movingPixels = new BitmapData(_source.width, _source.height);
            _movingPixels.copyPixels(_source, _rect, _point);
            //turn this on to watch red pixels be drawn where the source pixels are coming in
            //_source = new BitmapData(_source.width, _source.height, false, 0xFF0000);
        }

        private function gameLoop(e:Event):void {
            _xOffset--;//where the background is moving to
            if (_xOffset < -_source.width) {
                _xOffset = 0;
                //this doesn't seem to work correctly:
                //_movingPixels.scroll(_source.width, 0);
                _movingPixels = new BitmapData(_source.width, _source.height);
                _movingPixels.copyPixels(_source, _rect, _point);
            }
            trace(_xOffset);
            setGeometryDefaults();
            _movingPixels.scroll(-1, 0);
            //draw the moved part of the canvas
            _canvas.bitmapData.copyPixels(_movingPixels, _rect, _point);
            //If we stop here, we get a smear to the right
            //so, get the remaining pixels directly from the source
            //1) reset our rect and point to be to the right side
            _rect.x = 0;
            _rect.width = -_xOffset;
            _point.x = _source.width + _xOffset;
            //2) copy from the source
            _canvas.bitmapData.copyPixels(_source, _rect, _point);
        }
        private function setGeometryDefaults():void {
            _rect.x=0;
            _rect.y=0;
            _rect.width = _source.width;
            _rect.height = _source.height;
            _point.x = 0;
            _point.y = 0;
        }

    }

}

I really Appreciate the help...eager to learn.

2
Suggestion: Instead of doing complicated bitmap operations, have 2 pictures on your stage, one above the other. Scroll them with the same speed. Once an image is below your screen, so to speak, move it above your screen.user2655904
thank you for your reply.. i would rather doing it by code, it would be a win win situation, i would learn and keep it better :)Elias Rahme
Fair point, I'll try it myself and post an answer if I succeed.user2655904
many Thanks! i appreciate it @DodgerThudElias Rahme
The _xOffset is moving things from right to left. So you need to edit the code to have a _yOffset that operates in the vertical dimension (so, for example, if the code now does something relative to x, it needs to be y, and if it says width, it needs to be height).Amy Blankenship

2 Answers

1
votes

In general, you only want to move or show-and-hide bitmaps when your animation is running. You shouldn't draw or copypixels when the animation is running. You do that stuff during "loading" because it can slow your fps. Convert everything to bitmaps and get rid of all source graphics (jpg, png, text, and vector images) before your animation starts.

For a scrolling background, you should use two copies of a bitmap in a movieclip and move the movieclip.

You should put the repeatable background image (jpg, png) in a movieclip or creat the background in a movieclip using vectors. Draw that movieclip to a bitmap. Remove the original movieclip. Make two copies of the bitmapdata. Stack the two end-to-end in a movieclip. Then scroll the movieclip the length of the background image - start at 0 and scroll until the second copy of the background reaches 0. Then reset the first to 0.

Here's example code that does the above:

public function Main() {

    nBackgroundSpeed = 1;

    iBitmapWidth = mcBackground.mcBackgroundSource.width;
    iBitmapHeight = mcBackground.mcBackgroundSource.height;

    var bdBackground: BitmapData = new BitmapData(iBitmapWidth, iBitmapHeight, true, 0x00000000);
    bdBackground.draw(mcBackground.mcBackgroundSource, null, null, null, null, true);
    var bmpBackground0: Bitmap = new Bitmap(bdBackground, "auto", false);
    var bmpBackground1: Bitmap = new Bitmap(bdBackground, "auto", false);

    mcBackground.removeChild(mcBackground.mcBackgroundSource);
    mcBackground.mcBackgroundSource = null;

    mcBackground.addChild(bmpBackground0);
    bmpBackground0.x = 0;
    bmpBackground0.y = 0;

    mcBackground.addChild(bmpBackground1);
    bmpBackground1.x = 0;
    bmpBackground1.y = iBitmapHeight;

    addEventListener(Event.ENTER_FRAME, fEnterFrame);
}


private function fEnterFrame(event: Event): void {
    if (mcBackground.y > (0 - iBitmapHeight)) {
        mcBackground.y -= nBackgroundSpeed;
    } else {
        mcBackground.y = 0;
    }
}

Let me know of any questions.

0
votes

I'm not all too familiar with adobe Air, but this was a problem I also had. I'm using flashdevelop, though, along with the FlashPunk library (both are entirely free) and I found a solution here.

Best of luck!