/* Motion Class v1.2 Oct. 29, 2002 (c) 2002 Robert Penner The Motion class contains logic that is used by subclasses such as Tween, WaveMotion (ch.8), and MotionCam (ch.13). Dependencies: - ASBroadcaster (undocumented feature of Flash MX) - MovieClip.addListener() for onEnterFrame events (included in core_setup.as) Events: onMotionChanged onMotionFinished onMotionLooped onMotionStarted onMotionStopped onMotionResumed Discussed in Chapter 7 of Robert Penner's Programming Macromedia Flash MX http://www.robertpenner.com/profmx http://www.amazon.com/exec/obidos/ASIN/0072223561/robertpennerc-20 */ if (typeof MovieClip.addListener != 'function') trace (">> Error: MovieClip.addListener() missing (core_setup.as)"); ///////////////////////////////////////////////////////////////////////// /* constructor for Motion class obj: reference - the object which the Motion targets prop: string - name of the property (in obj) that will be affected begin: number - the starting value of prop duration: number - the length of time of the motion; set to infinity if negative or omitted useSeconds: boolean - a flag specifying whether to use seconds instead of frames */ _global.Motion = function (obj, prop, begin, duration, useSeconds) { this.setObj (obj); this.setProp (prop); this.setBegin (begin); this.setPosition (begin); this.setDuration (duration); this.setUseSeconds (useSeconds); this._listeners = []; this.addListener (this); this.start(); }; var MP = Motion.prototype; AsBroadcaster.initialize (MP); MP.start = function () { this.rewind(); MovieClip.addListener (this); this.broadcastMessage ("onMotionStarted", this); }; MP.stop = function () { MovieClip.removeListener (this); this.broadcastMessage ("onMotionStopped", this); }; MP.resume = function () { this.fixTime(); MovieClip.addListener (this); this.broadcastMessage ("onMotionResumed", this); }; MP.rewind = function (t) { this.$time = (t == undefined) ? 0 : t; this.fixTime(); }; MP.fforward = function () { this.setTime (this.$duration); this.fixTime(); }; MP.nextFrame = function () { if (this.$useSeconds) { this.setTime ((getTimer() - this.startTime) / 1000); } else { this.setTime (this.$time + 1); } }; MP.onEnterFrame = MP.nextFrame; MP.prevFrame = function () { if (!this.$useSeconds) this.setTime (this.$time - 1); }; MP.toString = function () { return "[Motion prop=" + this.prop + " t=" + this.time + " pos=" + this.getPosition() + "]"; }; //////// GETTER/SETTER METHODS /* return the position of the Motion at a certain time abstract method to be overridden */ MP.getPosition = function (t) {}; MP.setPosition = function (p) { this.$prevPos = this.$pos; this.$obj[this.$prop] = this.$pos = p; this.broadcastMessage ("onMotionChanged", this, this.$pos); }; MP.setTime = function (t) { this.prevTime = this.$time; if (t > this.duration) { if (this.$looping) { this.rewind (t - this.$duration); this.update(); this.broadcastMessage ("onMotionLooped", this); } else { if (this.$useSeconds) { this.$time = this.$duration; this.update(); } this.stop(); this.broadcastMessage ("onMotionFinished", this); } } else if (t < 0) { this.rewind(); this.update(); } else { this.$time = t; this.update(); } }; MP.getTime = function () { return this.$time; }; MP.setBegin = function (b) { if (b == undefined) this.$begin = this.$obj[this.$prop]; else this.$begin = b; }; MP.getBegin = function () { return this.$begin; }; MP.setDuration = function (d) { this.$duration = (d == null || d <= 0) ? Infinity : d; }; MP.getDuration = function () { return this.$duration; }; MP.setObj = function (o) { this.$obj = o; }; MP.getObj = function () { return this.$obj; }; MP.setProp = function (p) { this.$prop = p; }; MP.getProp = function () { return this.$prop; }; MP.setUseSeconds = function (useSecs) { this.$useSeconds = useSecs; }; MP.getUseSeconds = function () { return this.$useSeconds; }; MP.setLooping = function (b) { this.$looping = b; }; MP.getLooping = function () { return this.$looping; }; MP.getPrevPos = function () { return this.$prevPos; }; /////////// PRIVATE METHODS MP.fixTime = function () { if (this.$useSeconds) this.startTime = getTimer() - this.$time*1000; }; MP.update = function () { this.setPosition (this.getPosition (this.$time)); }; /////////// GETTER/SETTER PROPERTIES with (MP) { addProperty ("obj", getObj, setObj); addProperty ("prop", getProp, setProp); addProperty ("begin", getBegin, setBegin); addProperty ("duration", getDuration, setDuration); addProperty ("useSeconds", getUseSeconds, setUseSeconds); addProperty ("looping", getLooping, setLooping); addProperty ("prevPos", getPrevPos, null); addProperty ("time", getTime, setTime); addProperty ("position", function() { return this.getPosition(); }, function(p){ this.setPosition (p); } ); } delete MP; trace (">> Motion class loaded");