Another infinite menu question :)

One little bit of explanation for the swonking function in that .fla I posted. My comments were a bit brief in the code, so here’s a fuller explanation. Who knows, maybe this will be useful to somebody.

Consider this code:


// create an empty holder clip
this.createEmptyMovieClip("holder_mc", 0);

// load an image or clip into holder_mc
this.holder_mc.loadMovie("myClip.swf", 1);

// check how much is loaded
var bytesLoaded = this.holder_mc.getBytesLoaded();
var bytesTotal = this.holder_mc.getBytesTotal();
if (bytesLoaded < bytesTotal) {
  trace("all bytes are not yet loaded");
} else {
  trace("all bytes are loaded");
} // end if (bytesLoaded < bytesTotal)

Interestingly enough, this code will trace “all bytes are loaded”. That is, bytesLoaded < bytesTotal will evaluate to false. If you trace bytesLoaded and bytesTotal, you’ll see, however, that both are equal to 0. bytesLoaded will obviously equal 0, but bytesTotal equalling 0 is unexpected. In any case, the if-statement’s condition evaluates to “if (0 < 0)”, which is false.

If, on the other hand, you execute the if-statement on the next frame (or if you use a setInterval() to execute the if-statement again a few milliseconds later), then bytesTotal does not equal 0; rather, it equals the total amount of bytes of the loading clip/image. That’s the number we’re after, not 0.

The conclusion to be drawn is that the first time around the loading process has not initialized yet. The parser executes the if-statement so quickly that the loading process doesn’t have time to start.

This is because all loading processes in Flash are asynchronous: the parser doesn’t wait for the loading to be completed before it moves to the next line of code. Instead, it sends a “load” call to the Flash Player to start loading, but the parser in the meantime just keeps stepping through the code. Hence, the if-statement gets executed before the Flash Player really gets a chance to initialize the loading process.

To counter this you have to do what is informally called “swonking”, checking over and over again whether or not the movie is loaded. Since the first time around the swonking check returns a 0 for both bytesLoaded *and * bytesTotal, we have to accomodate for that first moment when both are equal at 0.

You’ll see in my code that the swonking function first tests whether or not bytesTotal == 0. If so, then the swonking function does nothing and it waits until the setInterval() executes the swonking function again. This will happen as many times as needed until bytesTotal finally does not equal 0 but rather equals the number of bytes of the loading clip/image. Only then does the swonking function start checking “if (bytesLoaded < bytesTotal)”.

It would be nice to just call an onLoad event handler for loading clips like we can for LoadVars or XML:


// load the image
this.holder_mc.loadMovie("myClip.swf", 1);

// do this when the movieclip loads
this.holder_mc.onLoad = function() {
  trace("clip/image has loaded!");
} // end clip.onLoad()

Unfortunately, onLoad necessarily has to work differently for movieclips because if you call an “onLoad” as a method of a movieClip, then that movieClip must already be loaded (holder_mc.onLoad() would check whether holder_mc is loaded, which of course it is, since I called the onLoad function off the clip in the first place). The onLoad event handler for movieclips serves a different purpose than swonking. (Note: you can use onClipEvent(load) for swonking in the Flash 5 style if you’re privy to that, but I’m a pretty straight MXer)

In any case, swonking is more difficult for loading images and clips since the onLoad event handler for movieClips serves a different purpose and thus can’t be used to swonk. So we’re stuck with this strange “if bytes are all loaded” function. Hopefully the next version will have a nice event handler that’s native, something like “onLoadedInto()” or whatnot. For now, we’re stuck with checking the bytes loaded.

Hope this makes my code in the .fla more understandable.

aurelius, i wasnt able to make it work while loading multiple movies. The setInterval refused to take in a variable as a parameter. And I was going around in circles :sigh: Or I was doing it wrong. I found an elegant and short way of going around it. Here it is for those interested.

[AS]
movieWidth = 60;
procede = 1;
// a binary counter to determine if next movie is to be loaded or wait for current one to load
moviecnt = 0;
pauseLoad = setInterval(loadPics, 100);

function loadPics() {
if (procede) {
tempMC = _root.createEmptyMovieClip(“image”+moviecnt, moviecnt);
tempMC.loadMovie(“image”+moviecnt+".jpg");
tempMC._x = (moviecnt*movieWidth);
moviecnt++;
procede = 0;
} else if (tempMC.getBytesLoaded()>=tempMC.getBytesTotal()) {
procede = 1;
tempMC.id = moviecnt;
tempMC.onPress = function() {
trace(“movie “+this.id+” pressed”);
};
if (moviecnt>=9) {
clearInterval(pauseLoad);
}
}
}
[/AS]

you hane to change the _root to _parent if you are calling it from another file.

cheers

looks like this project shall never be complete. one bug after another. oh BTW thanks you your efforts and LIB’s, i have managed to make those images appear as clickable. can be viewed at http://www.geocities.com/ckatre/ under the photo gallary section.

now another problem: How do I unload the movie?
as u are aware i have dynamically loaded those buttons - image1.jpg to image10.jpg. Now when a button say “home” in the parent is clicked i want that scrollbar to unload. I have tried the following in the main file:

[AS]
for (i=i;i<=10;i++) {
_root.scrollmenu.unloadMovie(“image”+i+".jpg");
}
_root.scrollmenu.unloadMovie(“scrollmenu.swf”);
_root.removeMovieClip(“scrollmenu”);
[/AS]

Do I need to first unload those clips in the child movie and then unload the child swf file? I removed the for loop from the above script and tried, but it still does not unload.

Another thing, is there any way to control the individual properties of these dynamically loaded images. (The code is in the above post) I tried to modify the property of one image - but that attempt was not successful.

Try using:


TempMC.removeMovieClip();

The syntax is: clipToRemove.removeMovieClip(); This will remove the clip and everything inside it.

As for not being able to modify the properties, its because you’re trying to set the _x property before the clip is loaded. You have to wait until it’s totally loaded before you can set the clips properties (go back to the .fla I posted earlier, notice that none of the clip properties get modified until after the clip has totally loaded).

ok got it. thanks. since i am calling it from the main movie the syntax was

[AS]
for (i=1;i<=10;i++) {
_root[“image”+i].removeMovieClip();
}
[/AS]

actually i was talking about setting of properties after the movies have loaded. anyways, i just work it out somehow.

I was thinking of this code:


tempMC.loadMovie("image"+moviecnt+".jpg");
tempMC._x = (moviecnt*movieWidth);

Setting _x here shouldn’t work because the movie hasn’t loaded yet. Was that what you were talking about?

actually, i was looking controlling an individual image in the scroll.swf from main.swf using variables (for eg: “image”+someNumber). But I got it done within the scroll.swf itself.

But tell you what. … that movie width thing worked always … even with my earlier codes, that was no issue. what i think is that it would immediately take on any property. but in order for you to change a property, the movie has to load completely. thats the only explanation i can think of.

u can see the effect at http://geocities.com/ckatre/… photo gallery

thanks for your help. i’ll again bug you if i run into a wall :wink:

and regarding the unloading the images from scroll.swf i got it done from the main.swf. I posted the script in my earlier post.

Inspite of all frustrations i encountered writing the code, it was fun learning flash and partiularly actionscript. without this forum, my learning curve would have been closer to the y-asis. :slight_smile:

cheers

Photo gallery looks good!

thank you! with LIB & your help :slight_smile: