hipon
hipon

Reputation: 31

not smooth scrolling in AS3

I'm trying to make a side scrolling game in AS3, but when i try to make simple endless scrolling background, the animation is not smooth. can anyone solve this?

here's the link to the swf(30fps) :

http://megaswf.com/serve/1221647

the code : `package{

import flash.display.*;
import flash.events.*;
public class testscroll extends MovieClip{
    public function testscroll(){
        var bg = new bg1();
        var bg2 = new bg1();
        addChild(bg);
        addChild(bg2);
        bg2.x = 500;
        bg2.addEventListener(Event.ENTER_FRAME,mainloop);
        bg.addEventListener(Event.ENTER_FRAME,mainloop);
    }
    public function mainloop(e:Event){
        var target = e.currentTarget as MovieClip;
        target.x -= 5;
        if(target.x<=-500){
            target.x = 500;
        }
    }
}

} `

Thanks

Upvotes: 3

Views: 2816

Answers (3)

Oliver Turner
Oliver Turner

Reputation: 1392

Have a look at this:

http://megaswf.com/serve/1368761/

It takes a different approach of drawing the original mc to a bitmap and then drawing a moving source rect into a static bitmap.

package 
{
    import flash.display.Bitmap;
    import flash.display.BitmapData;
    import flash.display.Sprite;
    import flash.display.StageAlign;
    import flash.display.StageScaleMode;
    import flash.events.Event;
    import flash.geom.Point;
    import flash.geom.Rectangle;

    [SWF(backgroundColor="#FFFFFF", frameRate="60", width="500", height="400")]
    public class Main extends Sprite
    {
        [Embed(source="assets/swf/assets.swf", symbol="Background")]
        private var Background:Class;

        private var __app_w:int = 500;
        private var __app_h:int = 400;
        private var __src_rect:Rectangle = new Rectangle(0, 0, __app_w, __app_h);
        private var __src_bmpd:BitmapData;
        private var __dest_bmpd:BitmapData = new BitmapData(__app_w, __app_h);
        private var __dest_pt:Point = new Point();


        /* Constructor
        ----------------------------------------------------------------------------------------------*/
        public function Main()
        {
            stage.addEventListener(Event.RESIZE, _onStageResized, false, 0, true);
            stage.align     = StageAlign.TOP_LEFT;
            stage.scaleMode = StageScaleMode.NO_SCALE;

            // Initialise
            __src_bmpd       = _bmpd;            
            scrollRect       = __src_rect;
            cacheAsBitmap    = true;
            opaqueBackground = 0xFFFFFF;

            addChild(new Bitmap(__dest_bmpd)) as Bitmap;
            addEventListener(Event.ENTER_FRAME, _onEnterFrame, false, 0, true);
        }

        private function _onStageResized(event:Event):void
        {            
            x = (stage.stageWidth >> 1)  - (__app_w >> 1);
            y = (stage.stageHeight >> 1) - (__app_h >> 1);
        }

        public function _onEnterFrame(event:Event):void
        {
            __src_rect.x = (__src_rect.x == __app_w) ? 0 : __src_rect.x + 2;                
            __dest_bmpd.copyPixels(__src_bmpd, __src_rect, __dest_pt);
        }

        private function get _bmpd():BitmapData
        {
            var mc:Sprite = new Sprite(),
                b1:Sprite = mc.addChild(new Background()) as Sprite,
                b2:Sprite = mc.addChild(new Background()) as Sprite,
                bmpd:BitmapData;

            b1.x = 0;
            b2.x = b1.width;

            bmpd = new BitmapData(mc.width, mc.height, false); 
            bmpd.draw(mc);

            return bmpd;
        }
    }
}

Upvotes: 0

Oliver Turner
Oliver Turner

Reputation: 1392

The below uses blitting to reduce the load on the processor and a useful trick that restricts the redrawn area to the minimum visible portion.

I've commented fairly extensively outside of the topic too: I realise that this is a rough and ready test but they may be useful for someone.

package 
{
    import flash.display.*;
    import flash.geom.Rectangle;
    import flash.utils.setTimeout;
    import flash.utils.setInterval;
    import flash.events.Event;

    // Best practice naming convention: CamelCase for classes
    public class TestScroll extends Sprite
    {
        private var __bmp:Bitmap;


        public function TestScroll()
        {           
            __bmp = addChild(new Bitmap(_bmpd)) as Bitmap;

            // These two instructions act in concert to 
            // reduce the area redrawn onEnterFrame
            // to that defined by the scrollRect
            cacheAsBitmap = true;
            scrollRect = new Rectangle(0, 0, 500, 400);

            // Always a good habit to set the value for useWeakReference to true
            // when adding event listeners: helps with garbage collection.
            // See http://gskinner.com/blog/archives/2006/07/as3_weakly_refe.html
            // That said, ALWAYS remove your listeners as soon as they're no longer required:
            // http://gingerbinger.com/2010/07/actionscript-3-0-events-the-myth-of-useweakreference/
            addEventListener(Event.ENTER_FRAME, _onEnterFrame, false, 0, true);
        }

        public function _onEnterFrame(event:Event):void
        {
            // Running @ 60fps: reduced move rate               
            __bmp.x = (__bmp.x > -500) ? __bmp.x - 2 : 0;
        }

        // Personal preference of mine: break out basic instantiation
        // into subfunctions to keep the constructor as terse as possible
        // Renamed the references to the library items in line with naming 
        // convention for classes: bg1 -> Background
        private function get _bmpd():BitmapData
        {
            var mc:Sprite = new Sprite(),
                b1:Sprite = mc.addChild(new Background()) as Sprite,
                b2:Sprite = mc.addChild(new Background()) as Sprite,
                bmpd:BitmapData;

            b2.x = 500;

            bmpd = new BitmapData(mc.width, mc.height, true, 0);
            bmpd.draw(mc);

            return bmpd;
        }
    }
}

See http://jacksondunstan.com/articles/629 for a fuller explanation of the scrollRect / cacheAsBitmap technique.

Upvotes: 0

George Reith
George Reith

Reputation: 13476

Try taking this part of your code:

target.x -= 5;

and making it a lower value such as:

target.x -= 1;

As right now you are shifting 5 pixels in every frame which may appear choppy. This will slow down the speed of the scroll but make it appear smoother. You may want to fiddle with the fps to alter the speed.

Also if your background isn't a bitmap already you should cache it as a bitmap to improve speed (it is easier to scroll a bitmap than a vector).

Upvotes: 2

Related Questions