PDA

View Full Version : Simulated download refuses to display content...


Jawnee
09-01-2008, 12:22 PM
Hey guys, truly strange behavior here which is baffling me. I'll keep the backstory short and sweet. Initially I wrote some code to display a banner slideshow at the top of my flash website using a UILoader and a timer object. The UILoader would load an image and when the image was done loading I would start a timer. Once the timer was done (the image had been displayed as long as necessary) the UILoader would load the next image. As you can imagine this worked fine on my machine, but with a simulated download on a 56k modem setting I hit a snag. The minute the timer was up and it was time to load the next image, the image previously displayed would disappear as the new image was loading leaving the banner blank. Sure I could display a preloader progressbar here as filler but that seemed silly. "Surely there is a way to load an image, display it and immediately load another, but not display it unless the timer has finished..." I thought.

So here is my current code using a standard Loader object and the same timer, with a rewrite to make the display of the Loader dependent on the timer being completed. The entire code hinges on a boolean value timeUp which = true when the timer completes and is reset to false when the image is actually displayed. It works like a charm from my machine, but for some reason when I do a simulated download, despite the fact that the output seems fine, nothing is ever displayed.

Code

var slideShowXml:String = "bannerSS.xml";
var slideLoader:Loader = new Loader();

var myTimer:Timer = new Timer(8000);
var timeUp:Boolean = true;
var slideCount:Number;
var curSlide:Number = 0;
var prevSlide:Number = 0;
var slideXml:XML;
var slideList:Array = new Array()

// Check timer progress
myTimer.addEventListener(TimerEvent.TIMER, onTimerFinished);
// Check image load progress
slideLoader.contentLoaderInfo.addEventListener(Eve nt.COMPLETE, onImageLoadComplete);

function onTimerFinished(evt:Event):void {
timeUp = true;
myTimer.stop();
}

// Pull in image information from XML for slideshow
var xmlLoader:URLLoader = new URLLoader();
xmlLoader.addEventListener(Event.COMPLETE, onSlideInfoLoaded);
xmlLoader.load(new URLRequest(slideShowXml));

function onSlideInfoLoaded(evt:Event):void {

slideXml = XML(evt.target.data);
slideCount = slideXml.slide.length() - 1;

for (var j:uint = 0; j <= slideCount; j++){
var slide:Object = {slideLabel:slideXml.slide[j].@label.toString(),
slideImage:slideXml.slide[j].@data.toString(),
slideCaption:slideXml.slide[j].@caption.toString()};

slideList.push(slide);
}

trace("LOADED list of images, preparing to display first slide");
showSlide(evt);

}

function randomRange(max:Number, min:Number = 0):Number
{
return Math.round(Math.random() * (max - min) + min);
}

function showSlide(evt:Event):void {

prevSlide = curSlide;

// Avoid displaying the same slide twice in a row
do {
curSlide = randomRange(0, slideCount);
} while (curSlide == prevSlide);

trace("Loading slide: " + curSlide.toString() + " - " + slideList[curSlide].slideImage.toString());
slideLoader.load(new URLRequest(slideList[curSlide].slideImage));
caption.htmlText = "<p class='content' align='right'>" + slideList[curSlide].slideCaption + "</p>";
}

function onImageLoadComplete(evt:Event):void {
//pb.visible = false;
trace("Loading of slide: " + curSlide.toString() + " complete!");
if (timeUp) {
trace("TIMER UP WHEN LOAD FINISHED - DISPLAYING IMAGE");
bannerSSContent.addChild(slideLoader);
slideLoader.x = -292.5;
slideLoader.y = -72.5;

trace("Banner now has " + bannerSSContent.numChildren + " children.");
//new Tween(bannerSSFader, "alpha", None.easeNone, 1, 0, 2, true);
timeUp = false;
myTimer.start();
showSlide(evt);
} else {
trace("TIMER NOT UP, WAITING...");
//The slide is loaded but the timer isn't ready so we wait
addEventListener(Event.ENTER_FRAME, onFrameTimerCheck);

}

}

function onFrameTimerCheck(evt:Event):void {
if(timeUp) {
trace("TIMER FINISHED, DISPLAYING NOW...");
removeEventListener(Event.ENTER_FRAME, onFrameTimerCheck);
bannerSSContent.addChild(slideLoader);
slideLoader.x = -292.5;
slideLoader.y = -72.5;
trace("Banner now has " + bannerSSContent.numChildren + " children.");
//new Tween(bannerSSFader, "alpha", None.easeNone, 1, 0, 2, true);
timeUp = false;
myTimer.start();
showSlide(evt);
}
}

My basic goal was to create the following logic:

Begin Load Image
When done...
if timer is up
display image
Begin Load new image
if timer is not up
wait on timer
when timer up...
display image
Begin Load new image

Noticing that the number of children never increases I'm guessing the source of my issue is in the way I'm actually trying to add my newly loaded images to the stage. I think each time a load completes I need to actually create a NEW object from the loader content and then add that new object to the stage. I haven't managed to figure out how to do that yet...

Output from standard run (not a simulated download)
LOADED list of images, preparing to display first slide
Loading slide: 12 - Beautiful Clouds
Loading of slide: 12 - Beautiful Clouds complete!
TIMER ALREADY EXPIRED - DISPLAYING IMAGE
Banner now has 2 children.
Make call to load next image
Loading slide: 6 - Whangarei Beach, New Zealand
Loading of slide: 6 - Whangarei Beach, New Zealand complete!
TIMER NOT UP, WAITING...
TIMER FINISHED, DISPLAYING NOW...
Banner now has 2 children.
Make call to load next image
Loading slide: 28 - Mount Victoria Hike
Loading of slide: 28 - Mount Victoria Hike complete!
TIMER NOT UP, WAITING...
TIMER FINISHED, DISPLAYING NOW...
Banner now has 2 children.
Make call to load next image
Loading slide: 35 - Black Water Rafting
Loading of slide: 35 - Black Water Rafting complete!
TIMER NOT UP, WAITING...

As usual any suggestions would be welcome! Thanks in advance!

EDIT: As a last attempt before bed I've also tried taking the loader content and casting it to a new bitmap object (since I'm loading a picture each time) and then adding that bitmap to the container bannerSSContent(which is a movieclip btw) but I get an error the very moment the loader tries to continue and load the second image.

Code Change
var newImage:Bitmap = Bitmap(slideLoader.content);
bannerSSContent.addChild(newImage);
newImage.x = -292.5;
newImage.y = -72.5;

Error:
ArgumentError: Error #2025: The supplied DisplayObject must be a child of the caller.
at flash.display::Loader/unload()
at index4_fla::MainTimeline/showSlide()
at index4_fla::MainTimeline/onImageLoadComplete()