IV. THE FLASH FILES

a. What we need
Ok. So we want to make a class that load a random image file.
The name of the image file is sent by the php file.
We want a dynamic textfield displaying how many bytes are load in total bytes.

We will add some extra stuff:

  • the background will be able to refresh itself every X seconds.
  • the container will hold TWO containers. Then we will load image the first time in the first sub container, the second in the second sub container, the third in the first sub container... In fact we are using modulo 2. Why? Because while loading the movie we want the background to be displayed. If we are not using this way, when loading a new background inside the container, no background will be displayed during the loading time.

So we will use that object/type inside the class:
  • LoadVars object for loading php file
  • MovieClip for the main container and the sub container
  • MovieClipLoader and listener to get the bytes loaded and all the event (start loading, while loading, end loading, displaying movieclip, on error loading)
  • Numbers var to hold the delay, start time of the delay, and the ID of the interval calling the function that will check if the delay is passed.
  • textField which displaying the info
    This is all we can know for now I think.


b. Add new method to MovieClip class

MovieClip.prototype.scaleToStage= function () {
 
 //get the value that help me rescaling the mc

this._xscale = 100;

this._yscale = 100;
 
var W = this._width;

var H = this._height;

var RW = Stage.width;

var RH = Stage.height;

//rescaling
 
this._xscale = (RW/W)*100;

this._yscale = (RH/H)*100;

this._x = 0;

this._y = 0;

}


Some brief explanations:
Why did we use the OLD WAY to add new method to the MovieClip?
Because we need to be able to create new empty movie clip at runtime, and if we are using the new way (means defining a new class extended MovieClip) we are not able to associate at runtime the new class to the MovieClip object created (update 2006: this is no more true ,check for MCE).
This function is rescaling the MovieClip to the stage's size and setting _x and _y to 0.

c. The loadBackground class
Ok so let's start declaring our loadBackground class now:
class froggies.loadBackground {

        private var _nDelay:Number;
 
        private var _nSICheck:Number;

        private var _nStartTime:Number;
 
        private var _nModulo:Number;

        private var _oBackground:Object;

        private var _mcBackground:MovieClip;

        private var _mcFirstBackground:MovieClip;

        private var _mcSecondBackground:MovieClip;

        private var _mclBackground:MovieClipLoader;

        private var _sFolder:String;

        private var _tfDispInfo:TextField;

        function loadBackground (mcBackground, tfDispInfo, nDelay, sFolder) {

                //getting the properties send by the user

                _nDelay = nDelay;

                _mcBackground = mcBackground;

                _tfDispInfo = tfDispInfo;

                _sFolder = sFolder;

                _nStartTime = null;

                _nSICheck = null;

                _nModulo = -1;

                _oBackground = new Object();

                _mclBackground = new MovieClipLoader();

                _mcFirstBackground = _mcBackground.createEmptyMovieClip("mc0", 0);

                //if you want to change background every X milliseconds then need another mc to make transition without waiting the loading

                if (_nDelay != -1) _mcSecondBackground = _mcBackground.createEmptyMovieClip("mc1", 1);

                _oBackground._owner = this;
 
                //defining my object

                _oBackground.onLoadStart = function (cible_mc) {

                        cible_mc._visible = false;

                        cible_mc.gotoAndStop(1);

                        this._owner._tfDispInfo.text = "Loading starting";

                        this._owner._tfDispInfo._visible = true;

                }

                _oBackground.onLoadProgress = function (cible_mc, loadedBytes, totalBytes) {

                        cible_mc._visible = false;

                        cible_mc.gotoAndStop(1);

                        this._owner._tfDispInfo.text = "Loading "+Math.ceil(loadedBytes/1024)+" / "+Math.ceil(totalBytes/1024)+" kbytes";

                }

                _oBackground.onLoadComplete = function (cible_mc) {

                        cible_mc._visible = false;

                        cible_mc.gotoAndStop(1);

                        this._owner._tfDispInfo._visible = false;

                }

                _oBackground.onLoadInit = function (cible_mc) {

                        //scale the mc to the size of the stage;

                        this._owner._mclBackground.removeListener(this._owner._oBackground);

                        cible_mc.swapDepths(1);

                        cible_mc._parent.scaleToStage();

                        cible_mc._visible = true;

                        cible_mc.gotoAndPlay(1);

                        if(this._owner._nDelay != -1) this._owner.nextBackground(cible_mc);

                }

                _oBackground.onLoadError = function (cible_mc, errorCode) {

                        this._owner._mclBackground.removeListener(this._owner._oBackground);

                }

                Init();

        }


        private function Init():Void {

                newBackground();

        }


        private function newBackground ():Void {

                _tfDispInfo._visible = true;

                _tfDispInfo.text = "Loading php file";

                var _lvBackground:LoadVars = new LoadVars();

                _lvBackground._owner = this;

                //who's the next container?

                _nModulo++;

                var num:Number = _nModulo%2;

                //to make url unique

                var dMyDate:Date = new Date();

                var unique:Number = dMyDate.getTime();

                _lvBackground._nextContainer = _mcBackground["mc"+num];

                //loading the php file that returning the background

                _lvBackground.onLoad = function (ok):Void {

                        if(ok) {

                                /*********************************************************

                                Add the listener to the MoveiClipLoader object and

                                load the background inside the movieclip background
 
                               **********************************************************/

 
                               this._owner._mclBackground.unloadClip(this._nextContainer);

                               this._owner._mclBackground.addListener(this._owner._oBackground);
 
                               this._owner._mclBackground.loadClip(this._owner._sFolder+this.thefile, this._nextContainer);

                        }

                }

                _lvBackground.load(_sFolder+"listfile.php?"+unique);

        }


        private function nextBackground ():Void {

                _nStartTime = new Date().getTime();

                _nSICheck = setinterval(checktime, 48, this);

        }


        private function checktime (_owner):Void {

                var nNow:Number = new Date().getTime();

                if (nNow - _owner._nStartTime > _owner._nDelay) {

                        clearInterval(_owner._nSICheck);

                        _owner.newBackground();

                }

        }

}



d. How this class is working?
We are creating a new class inside which is inside froggies package (class froggies.loadBackground ).
We are defining all the properties (var/object) used in this class. All are private (protected in fact).
Then is coming the constructor where we are setting up all the properties.

Four properties are setting up by parameters. It's the delay (if equal to -1 means no delay so no reloading), the MovieClip (container) which is holding the two sub containers, the textField which is displaying the bytes loaded, and the folder where the files (image and php) are.
The other are the

  • _nStartTime: we will call another background if currentTime - _nStartTime > _nDelay -,
  • _nSICheck which is holding the ID of the setinterval which is calling the function that checking if currentTime - _nStartTime > _nDelay
  • _nModulo that let us know in which sub container we have to load the new background, _oBackground which is the listener for the MovieClipLoader,
  • _mclBackground which is the MovieClipLoader.

Ok then we are adding a new property to the _ oBackground object defining its parent: (_oBackground._owner = this;).

Then we are defining all the methods of this object:

  • onLoadStart , we are hiding the sub container, stopping it at frame 1, adding text on textField and showing it
  • onLoadProgress , we are hiding the sub container, stopping it at frame 1, and displaying inside the textField the bytes loaded on total bytes
  • onLoadcomplete , we are hiding the sub container, stopping it at frame 1, and make the textField invisible.
  • onLoadInit , we are removing the link between this listener and the sub container, putting the sub container to front, scaling the sub container to the stage's size, making it visible and playing it, and calling the function that check for the next background
  • onLoadError , we are just removing the link between the listener and the MovieClipLoader.

Then we are calling Init() function. Why making a function with just one call to another one? Because when we will do the screensaver class the Init will not be the same, but the constructor will be. That's all. If we are putting the newBackground call inside the constructor we must rewrite ALL the constructor for the screensaver class. We will see that later.
Ok now the functions (methods) of the class. I put comments on the code, so I think it's enough. That's why here I'm telling briefly what the function are doing.
 

  • newBackground is loading the php file, getting the random filename and then loading inside the sub container this file.
  • nextBackground is setting up _nStartTime to now and calling with interval checktime.
  • checktime is taking the current time and if currentTime - _nStartTime > _nDelay then call the newBackground methods.