Hi - i am making a simple slideshow in AS2 (Flash CS3). I got all the core logic working fine in a FLA frame action - now trying to externalize it into a class. The first snag I hit was in trying to setTimeout -- when I passed a class method as the setTimeout function, it no longer could talk to the class variables/methods. I fixed this by passing along an instance of the class to the class method called by setTimeout something like this:
setTimeout(myMethod,delay,classInstance);
Now I've got a similar problem with my Tween.onMotionFinished() handler -- i want it to call another method in my class but it doesn't know what the class is or how to access it.
How should this be accomplished? I've tried a similar trick in which I try to stash a class instance inside the tween (through bracket syntax eg. myTween["classInstance"] = this; but this doesn't seem to work.
Is this a case where I basicallyneed to create an event listener in my class & then just send an event out when the tween finishes? Or is there a simpler way to let the tween know about the class (without relying on instance names of the class itself)?
I'm still new to OOP so not completely got my head around what can/can't access my class methods/variables especially when I'm creating objects like Tweens inside my class.
here's my current SlideShow.as class:
Code:
/*
imports
*/
import mx.transitions.Tween;
import mx.transitions.easing.*;
/*
class to create a crossfading slideshow from an on-stage MC comprised of a framesequence of slides.
*/
class com.pixelfarminteractive.slides.SlideShow
{
/*
variables
*/
private var _slideshowMC:MovieClip;
private var _slideshowOldMC:MovieClip;
private var _easeType = mx.transitions.easing.Regular.easeOut;
private var _easeTime:Number;//stored in sec
private var _holdTime:Number;//stored in millisec
private var _currentSlideNum:Number;
private var _numSlides:Number;//how many frames in the slideshowMC?
private var _crossFade:Tween;
/*
constructor
*/
public function SlideShow(slideMC:MovieClip,easeTimeSec:Number,holdTimeSec:Number,numSlides:Number)
{
_slideshowMC = slideMC;
_slideshowOldMC = _slideshowMC.duplicateMovieClip("slideshowOld_mc",_slideshowMC._parent.getNextHighestDepth());
_easeTime = easeTimeSec;
_holdTime = 1000*holdTimeSec;
_numSlides = numSlides;
_currentSlideNum=1;
}
private function tweenTo(mc:MovieClip, attribute:String, dest:Number):Tween {
return new Tween(mc, attribute, _easeType, mc[attribute], dest, _easeTime, true);
}
public function start():Void{
_global['setTimeout'](fadeInNext,_holdTime,this);
//setInterval(fadeInNext,_holdTime,this);
trace("starting Slideshow in "+_holdTime+" milliseconds. currentSlideNum = "+_currentSlideNum);
}
public function fadeIn(n:Number):Void{
//function to fade in the corresponding slide# of slideshow_mc
trace("fadeIn _slideshowOldMC = "+_slideshowOldMC+" _slideshowMC="+_slideshowMC);
_slideshowOldMC.gotoAndStop(_slideshowMC._currentframe);
_slideshowMC._alpha=0;
_slideshowMC.gotoAndStop(n);
_slideshowMC._alpha=100;
_crossFade = tweenTo(_slideshowOldMC,"_alpha",0);
_crossFade["thisClass"] = this;
_crossFade.onMotionChanged = function(){
trace("_crossFade.position="+this.position);
}
_crossFade.onMotionFinished = function(){
//_slideshowOldMC.removeMovieClip();
_global['setTimeout'](this["thisClass"].fadeInNext,this["thisClass"]._holdTime,this["thisClass"]);
}
}
public function fadeInNext(c):Void{
var thisClass=c;
if (_currentSlideNum+1>_numSlides){
_currentSlideNum=1;
trace("fadeinNext starting over");
}else{
_currentSlideNum++;
trace("fadeinNext advancing to "+thisClass._currentSlideNum);
}
trace("fadeinNext _currentSlideNum="+_currentSlideNum);
thisClass.fadeIn(_currentSlideNum);
}
}
and then I just create a slideshow from an existing framesequence MC (who has stop() on frame 1) in the FLA thusly:
Code:
import com.pixelfarminteractive.slides.SlideShow;
//SlideShow(slideMC:MovieClip,easeTimeSec:Number,holdTimeSec:Number,numSlides:Number)
var ss = new SlideShow(slideshow_mc,2,2,4);
ss.start();
"Art washes from the soul the dust of everyday life."
- Pablo Picasso
a Tween object created by a class instance doesn't know which class instance created it. More accurately, it can't access non-static class variables from the class that created it.
As such, there seem to be two ways around this...
1) if only one class instance at a time is required, I can add a static pointer to the class so that at least it can hit class methods again. something like this line at the top:
private static var _self:Object;
and this line in the constructor:
_self = this;
Then, in the onMotionFinished handler, _self.fadeInNext() would work without passing a class instance in.
NOTE: as soon as I would create a second class instance, _self would (for all handlers) then refer to the second class instance and not the first.
2) if multiple class instances at a time are required, I can just finish debugging the above code which apparently had a few other issues that are now resolved. This approach basically makes sure that any external objects created (e.g. Tween) are handed the specific class instance that created them. It's a bit hacky (giving a Tween object an internal thisClass attribute pointing to the class instance. Tween.thisClass is obviously not in the language reference but can be hammered in via that square bracket notation) so it works.
If anyone is interested, attached is a demo of both approaches. I'd recommend using SlideShow class since it's more flexible; SlideShowStatic works if you only need one.
"Art washes from the soul the dust of everyday life."
- Pablo Picasso
Matt,
Thanks for the post, this is really helpful. I want to add something to this actionscript, is it possible to have it randomly instead of sequential?
Thanks so much.
i didn't test it but it should be something like that.
Originally Posted by millerium
Matt,
Thanks for the post, this is really helpful. I want to add something to this actionscript, is it possible to have it randomly instead of sequential?
Thanks so much.
"Art washes from the soul the dust of everyday life."
- Pablo Picasso
mweir,
Thanks for the reply. the code :"_currentSlideNum = Math.ceiling(_numSlides*Math.random());" is not working. It's just showing the 1st image then that's it, it stops. Thank you so much, I am waiting for your immediate reply.
mweir,
Thanks for the reply. the code :"_currentSlideNum = Math.ceiling(_numSlides*Math.random());" is not working. It's just showing the 1st image then that's it, it stops. Thank you so much, I am waiting for your immediate reply.
Everything is working great, except, the random function doesn't seem to make it through the entire batch of photos before it repeats images. I'm not savvy enough to figure this out. I did notice their is a method which loads an array but I wasn't sure how to incorporate that. Any help would be huge - thanks!
Everything is working great, except, the random function doesn't seem to make it through the entire batch of photos before it repeats images. I'm not savvy enough to figure this out. I did notice their is a method which loads an array but I wasn't sure how to incorporate that. Any help would be huge - thanks!
This one is actually great on first round, but the second round and so on is just the same as first round of numbers. The one that I need is like this:
1st round: 1 to 5: 2, 1, 5, 4, 3
2nd round: 1 to 5 but different random: 4, 2, 1, 5, 3
3rd round: 1 to 5: 1, 4, 3, 5, 2
and so on.....
Thanks for the immediate response. By the way there is a little bug on this one, it appears twice the first image once you run the flash. It only happens only once (just the first image) and then as slides goes on, it is normal. I hope you get what I meant. It seems like the first image is twice longer as the other images and you can notice the tween of text (coz I add a text on the other layer). If the holdtime speed is = to 2 then the first image that will appear is like 4. thank you for your immediate response.