We need to handle the case when it’s time to display the picture but the picture is not done loading. So even though it’s time to display it, we need to wait somehow until we actually can display it. So instead of having one function loading and displaying pictures we should have two separate functions instead so we can control what happens when. Also the first picture is a special case since we need to display it as soon as we can, so we need a special way to handle it. So let’s get started.

private var isPictureReady:Boolean;

//a new boolean variable to keep track of the loading state of the picture

private var isDisplayTime:Boolean;

//a new boolean variable to keep track of the timer state

We changed our completeHandler function, we now load directly the first picture and then let the engine load and time the next ones:

private function completeHandler(e:Event):void{

xml_pictures = XML(xml_loader.data);

number_of_picture = xml_pictures.PICTURES.PICTURE_PATH.length();

display_time = 5;

picture_loader =new Loader();

//create a new loader

picture_loader.load(new
URLRequest(xml_pictures.PICTURES.PICTURE_PATH[0].toString()));

//load the first picture

picture_loader.contentLoaderInfo.addEventListener(Event.COMPLETE,display_picture);


// add an event so we know when the picture is ready

current_index++;

//increase already our current_index so we’ll load

//the second picture next time

}

We create a display_picture function which will set the current time, add the picture to the display list and start the cycle over:

private function display_picture(e:Event = null){

current_time = getTimer();

//our timing starts from here

picture_holder.addChild(picture_loader);

//show the picture

while(picture_holder.numChildren>2){

//we only need two pictures at a time

picture_holder.removeChildAt(0);

}

get_next_picture();

//start loading the next picture

}

And of course our revisited get_next_picture function:

private function get_next_picture():void{

isPictureReady = false;

//set the boolean to false

isDisplayTime = false;

//set the boolean to false

if(current_index == number_of_picture){

current_index = 0;

}

display_timer = new Timer(25);

//create a new timer

display_timer.addEventListener(TimerEvent.TIMER,check_target_time);

//check the timing

display_timer.start();

//start the timer

picture_loader = new Loader();

//create a new loader

picture_loader.load(new URLRequest(xml_pictures.PICTURES.PICTURE_PATH[current_index].toString()));

//load the picture

picture_loader.contentLoaderInfo.addEventListener(Event.COMPLETE,picture_ready);

//when the picture is loaded run this new function picture_ready

current_index++; }

The new picture_ready function:

private function picture_ready(e:Event){

isPictureReady = true;

//the picture is loaded so set the boolean to true

if(isDisplayTime){

//if this boolean is true then that means the timer ran out

//so display the picture

display_picture();

}

}

and finally the modified check_target_time function:

private function check_target_time(e:TimerEvent):void{

if(getTimer()>current_time+(display_time*1000)){

display_timer.removeEventListener(TimerEvent.TIMER, check_target_time);

isDisplayTime = true;

//check this boolean to true so we know it's time to display the picture

if(isPictureReady){

//if the picture is ready then display it

display_picture();

}

}

}

Our slide show now handles in a perfect timely manner the displaying of the pictures. Now of course we still have a bit of work to do. We set the target time in the code so we need to change that so we can pass the time we want from the XML. We also do not handle the case where a picture does not load (probably because of a wrong path). Finally we probably should wrap all that up in a class. So let’s finish that up in the next page.