Flash MX Prototyping Basics - Self Containment
(Page 4 of 4 )
You may be wondering what is so different about this than just using onEnterFrame elsewhere? Well, say you had 20 movie clips that you wanted to be able to reverse. Using the guts of the prototype alone, you would have to have 20 sets of it, one for each movie you wanted to reverse. Maybe you would have the code inside each movie clip. Maybe in an attempt to be more efficient, you even have a single movie clip with a child and you use attachMovie to instantiate it on to the stage from the library 20 times and each instance has a different movie loaded into the child.
You only had to type the code once then didn't you? Yes, but how many copies of it does Flash hold in memory? You got it: 20. Now with prototyping, guess how many copies of it Flash holds in memory: 40! Just kidding, you probably guessed this as well by now, the answer is one.
Hopefully you are beginning to see the potentials of prototyping. Having a prototype like the last one is all well and good, but what about when you want to get rid of it. That's easy enough. Let's clean up the previous prototype:
MovieClip.prototype.alternateDirection = function(activated) {
if (activated) {
this.onEnterFrame = function() {
if (!this.hitTest(_root._xmouse, _root._ymouse, false)) {
this._currentframe == this._totalframes ? this.stop() : this.gotoAndStop(this.nextFrame());
} else {
this._currentframe == 1 ? this.stop() : this.gotoAndStop(this.prevFrame());
}
};
} else {
delete this.onEnterFrame;
}
};// Turn on the reverse code
myMovie.alternateDirection(true);
// Turn it off
// myMovie.alternateDirection(false);
There are a few differences here. A variable is passed into the function called "activated". When activated the onEnterFrame event is set, when de-activated the onEnterFrame event is cleared. To remove the event you delete it. In the above this is expressed as:
delete this.onEnterFrame;
The last change is that the hitTest function is used in place of the two button events that were used earlier. hitTest can be used to check whether a movie intersects another movie or two points on the stage. It uses the later version here to check against the mouse _x and _y co-ordinates. The logic is still the same -- if the mouse is over the movie, play this way, otherwise...
Something you might notice is that the hand cursor doesn't show up when you use hitTest here. If you like having it, then all you have to do is add a mouse event to the movie clip. It doesn't need to have any code in it.
If you want to make full use of the prototype, then this is an opportunity to turn the reversing code on and off. Add this if statement to the beginning of the prototype:
this.onRelease = function() {
activated ? this.alternateDirection(false) : this.alternateDirection(true);
};
This will call the prototype function when the mouse is clicked on the movie and set the value of activated. If you look at the way the code is structured, you will see that onEnterFrame cannot be set multiple times without first deleting it. That means we can call alternateDirection(true) five times and only the first call will actually do anything noteworthy.
Here's the full source code for the example program. To use it, create a new movie clip with a white background that is 780x438. Copy and paste the following into the first (and only) key frame:
///////////
// Prevent the movie from being re-scaled.
// This keeps the animated clip at it's original dimension
Stage.scaleMode = "noScale";
MovieClip.prototype.centerAlign = function(maxWidth, maxHeight) {
this._x = (maxWidth/2)-(this._width/2);
this._y = (maxHeight/2)-(this._height/2);
};
MovieClip.prototype.alternateDirection = function(activated) {
this.onRelease = function() {
activated ? this.alternateDirection(false) : this.alternateDirection(true);
};
if (activated) {
this.onEnterFrame = function() {
if (!this.hitTest(_root._xmouse, _root._ymouse, false)) {
this._currentframe == this._totalframes ? this.stop() : this.gotoAndStop(this.nextFrame());
} else {
this._currentframe == 1 ? this.stop() : this.gotoAndStop(this.prevFrame());
}
};
} else {
delete this.onEnterFrame;
}
};
movieBlock = _root.createEmptyMovieClip("blankCanvas", 1);
movieBlock.loadMovie("shift.swf");
_root.onEnterFrame = function() {
if (blankCanvas._width>0) {
blankCanvas.createEmptyMovieClip("blankCanvas", 3);
blankCanvas.centerAlign(780, 438);
blankCanvas.alternateDirection(true);
delete _root.onEnterFrame;
}
};
Remember that if you're going to use your own clip, then change the file name in the loadMovie statement.
| DISCLAIMER: The content provided in this article is not warranted or guaranteed by Developer Shed, Inc. The content provided is intended for entertainment and/or educational purposes in order to introduce to the reader key ideas, concepts, and/or product reviews. As such it is incumbent upon the reader to employ real-world tactics for security and implementation of best practices. We are not liable for any negative consequences that may result from implementing any information covered in our articles or tutorials. If this is a hardware review, it is not recommended to open and/or modify your hardware. |