2

I try to develop a simple flash game using a doublebuffer to draw the animations.

The redraw happens when Event.ENTER_FRAME is fired.

The backbuffer used for doublebuffering is of type BitmapData.

The animation is very simple: I draw a 20x20-pixel Bitmap into the backbuffer with increasing x coordinate, so that it should move smoothly from the left to the right side of my canvas. This basically works fine, but if you look closely, you will see significant disruptions in this movement. This does not seem to be related to the frame rate, since its constantly over 60. The disruptions of the smooth moving are not acceptable for an animations, but I'm quite sure I've done nothing wrong with the doublebuffering, so I'm scared this could be a flash-player problem or something... I would be very relieved if this were not the case

Please have a look at the swf showing the simple animation:

https://dl.dropbox.com/u/55967135/test.swf

(Btw. the disruptions of the animation also don't disappear when the movement is based on the time between two frames - by now its constant 2 pixels per frame.)

I've uploaded a very lightweight flash builder project including the whole sourcecode for the swf above: https://dl.dropbox.com/u/55967135/test.zip

    public function enterFrame():void               
      {

           // Calculate the time since the last frame  (NOT USED IN THE EXAMPL PROGRAM)                   
           var thisFrame : Date = new Date();               
           var dT : Number = (thisFrame.getTime() - lastFrame.getTime())/1000.0;               
           lastFrame = thisFrame;          

           // erase backBuffer
           backBuffer.fillRect(backBuffer.rect, 0xFFFFFFFF);


           // set new postion of the small testimage
           if (this.pos > 600 || this.pos < 0) {
                this.direction = !this.direction;
           }

           // increase / decrease vertical position
           if (this.direction) {
                this.pos += 2;
           } else {
                this.pos -= 2;
           }

           //trace(pos);
           // draw small test image at postion "offset"
           backBuffer.copyPixels(     this.testGraphic.bitmap.bitmapData, 
                                         this.testGraphic.bitmap.bitmapData.rect, 
                                         new Point(pos, 0.0));               
      }

The enterFrame() is a method of my class GraphicsController, which handles the doublebuffering. It is launched by the applications enterFrame(event) method:

        public function enterFrame(event:Event):void
           {
                GraphicsController.Instance.enterFrame();     
                myCanvas.graphics.clear();
                myCanvas.graphics.beginBitmapFill(GraphicsController.Instance.backBuffer, null, false, false);                              
                myCanvas.graphics.drawRect(0, 0, this.width, this.height);                              
                myCanvas.graphics.endFill();
                stage.invalidate();
           }  

Help would be GREATLY appreciated

Thank you

2 Answers2

1

Runs perfectly smooth for me on chrome, but I know the effect that you describe. I experienced it in an application of mine in Firefox but I was using the display list instead of a bitmapdata. My problem was because of moving the display objects by less than a pixel and flash wasn't happy with that. As soon as I scaled the objects to 0.99 it was fixed.

You could try graphing out dT and seeing if it is stable. It should be 16.6666(or 0.0166) since you are running at 60fps if it is fluctuating then something is causing the enter frame event to be pushed back.

This might be useful too : http://www.craftymind.com/2008/04/18/updated-elastic-racetrack-for-flash-9-and-avm2/

Barış Uşaklı
  • 13,440
  • 7
  • 40
  • 66
1

First, your backBuffer is fine as is, you just lock() it prior to updating, then unlock() it after you've done updating. Next, why redrawing graphics, when you can use a Bitmap object instead? So, you retain GraphicsController.enterFrame() as is, adding a backBuffer.lock(); and backBuffer.unlock(); calls in the beginning and end of the method code, and you use a single Bitmap object at your initialization phase which will get automatically updated during the enterFrame call. Everything else in application's enterFrame() will be rendered useless.

Basically what I'm speaking of, is changing your canvas from type Shape into type Bitmap, that bitmap will be hardlinked to GraphicsController's backBuffer and will be autoupdated.

Vesper
  • 18,599
  • 6
  • 39
  • 61