Tricks of the Trade

I posted this before in Random but I think it could use to be here as well.

Writing MX applications from Flash 5
Lets say you’re stranded off somewhere and you desperately need to create an MX swf and make darn good use of the Drawing API in MX (or anything else MX) but all you have at your disposal is Flash 5. What do you do? You code your movie in Flash 5. But that wont work, will it? No, not right off, it wont. The Flash player when playing that movie will see that it is a Flash 5 movie and play it accordingly, however, what you can do is change the value which the player sees as being the movie version from flash 5 to flash MX, then anything you’ve written in Flash 5 thats now in that Flash 5 swf, can be read as though it were made in MX. To do this, you’ll need a hex editor. A free one I use for windows (small light and fast) is frhed which can be found here. Though it may not be the editor of choice for more massive projects since it is just some guys personal learning excursion ;).

Anyway, what you would do is open the Flash 5 swf in a hex editor and change the last character in the first block of values (4th group of 2) from a 5 to a 6. ie.

46 57 53 05

to

46 57 53 06

Then you will fool the flash player into thinking the swf is Flash 6 format and it will run methods like moveTo and lineTo to actually draw on the screen - things that can be written just as easily in Flash 5, just not seen unless the swf is converted to be of Flash 6 (so note if you ever need to try this, testing your movie wont let you see Flash 6 (MX) actions).

putting
lineStyle(0,0,100)
lineTo(200,200)
in your Flash 5 movie, publishing it, converting the swf as described above, will create a flash (MX) movie built in flash 5 which draws a line from 0,0 to 200,200.

ASnative function handlers for the MX Drawing API. These will allow you to program the Drawing API functions in Flash 5.

// [MovieClip.prototype] beginFill
MovieClip.prototype.beginFill = ASnative(901, 1)

// [MovieClip.prototype] beginGradientFill
MovieClip.prototype.beginGradientFill = ASnative(901, 2)

// [MovieClip.prototype] moveTo
MovieClip.prototype.moveTo = ASnative(901, 3)

// [MovieClip.prototype] lineTo
MovieClip.prototype.lineTo = ASnative(901, 4)

// [MovieClip.prototype] curveTo
MovieClip.prototype.curveTo = ASnative(901, 5)

// [MovieClip.prototype] lineStyle
MovieClip.prototype.moveTo = ASnative(901, 6);

// [MovieClip.prototype] endFill
MovieClip.prototype.endFill = ASnative(901, 7)

// [MovieClip.prototype] clear
MovieClip.prototype.clear = ASnative(901, 8)

I just referenced them really quick above. You may need to finagle them a bit to get them to work, but in the Flash 6 Player, these ASnative functions are direct handlers to the API elements. You should be able to pass in the variables as you normally would, ie. mc.moveTo(x,y)

cheers.

for more on ASNative see
http://chattyfig.figleaf.com/flashcoders-wiki/index.php?ASNative

_name as a variable/argument
One thing you can do to possibly help you streamline some actions in flash is to base your unique actions off of a movieclip/button name.

For example, suppose you have 3 buttons in your movie and you need them each to load in one of 3 images named bob.jpg, joe.jpg, or terry.jpg. What you can do is name your buttons bob, joe and terry and then do something this.


openNameImg = function(){
	getURL(this._name +".jpg", "_blank");
}
bob.onRelease = joe.onRelease = terry.onRelease = openNameImg;

each use the same function but get different results based on their name opening up the corresponding image.

Basically all your doing is treating the _name as a string variable you set using the property panel :-\ but it can be helpful none the less.

Be aware that _name is NOT read-only and can be changed during runtime.

*Originally posted by senocular *
**Be aware that _name is NOT read-only and can be changed during runtime. **

Changing the instance name during run-time…?

*Originally posted by h88 *
**Changing the instance name during run-time…? **

if you want

Easy strip HTML tags
put your html (nothing too complicated ;)) into a dynamic, html-enabled, textfield as .htmlText, then extract .text and your tags are stripped. Seems obvious but can be overlooked.

Non object Object objects

Every object you make inherits from the generic object Object. So if you have any object prototypes, all objects of whatever type they are will have access to them since they inherit from the object Object.

If you dont want your object to inherit from the object object (such as the object you get in return from Color.getTransform()) then you can do one of two things.

  1. create your object with the Object object but without the new keyword:
    myObject = Object();

  2. nullify the proto of your object so it doesnt reference and prototype object.
    myObject = new Object();
    myObject.proto = null;

This can be helpfull, for example, if you want to cycle through an object with a for…in and not have to worry about prototype functions popping up in the loop and without the need to mess around with ASSetPropFlags.

Now in the case of something like Color.getTransform(), if you need it to reference some prototype function, you can set the getTransform object’s proto to be any object prototype you want so it has access to those methods i.e.
Object.prototype.getbb = function(){ trace(this.bb); }
c = new Color(my_mc).getTransform();
c.proto = Object.prototype;
c.getbb(); // traces bb prop of getTransform object

Note: using proto = null will remove all prototype references, not just the object Object protos

[SIZE=3]Prevent Caching while loading your TextFiles through LoadVars (Another Trick)[/SIZE]

I have found somewhere a new trick and thought that I should share it here:

//Create a new LoadVars class:

myLoadVars = new LoadVars();

//Create a dummy Random Variable through new Date and getTime

myLoadVars.random = new Date().getTime();

//Now here comes the trick

myLoadVars.sendAndLoad(“TextFile.txt”, myLoadVars, “GET”);

//so now it would look like ‘TextFile.txt?’ then it attaches the ‘random’ variable

myLoadVars.onLoad = function(success){
trace(this.message)
}

//Notice that you can’t use one LoadVars object for this method,

**Please Note that this Won’t work on Local TextFiles!

Check updates page 3.**

*Originally posted by h88 *
Please Note that this Won’t work on Local TextFiles!

Which is why you check the _url of the movie before doing that :wink: something like


String.prototype.noCache = function(){
	return (_url.substr(0,4) != "file") ? this + "?"+new Date().getTime() : this;
}
// ...
loadMovieNum(("myMovie.swf").noCache() ,1);

Good idea, This thread is the coolest so far!

It’s not going to work. sendAndLoad will load the textfile using GET (And here goes the trick), and therefore,‘textfile.txt?’ (With ‘?’), it needs some work tho, but i guess am going now.

Ok, here (edited):

_global.GetMethod = function () {
return (_url.substr(0, 4) == “file”) ? “POST” : “GET”;
};
myLoadVars = new LoadVars();
myLoadVars.preventCache= new Date().getTime();
myLoadVars.onLoad = function(success){
trace(success ? this.message : “error”);
}
myLoadVars.sendAndLoad(“TextFile.txt”, myLoadVars, GetMethod());

The subject say’s it all, really neato code by Jonas. :slight_smile:

// MovieClip.onDoubleClick Event v1.0
// by Jonas Galvez (jonas@onrelease.org)

MovieClip.prototype.addProperty("onDoubleClick",
    function() { return this.$onDoubleClick },
    function(f) { this.$onDoubleClick = f; Mouse.addListener(this); }
);
Mouse.onMouseDown = function() {
    if(this.last_click == undefined) this.last_click = 300;
    if(getTimer() - this.last_click < 300)
        this.broadcastMessage("$onDoubleClick");
    this.last_click = getTimer();
};
Mouse.addListener(Mouse);

// this.onDoubleClick = function () {
//     trace("DoubleClick!");
// };

$onDoubleClick

I can only assume you got AS mixed up with PHP here. Would I be correct? If so, you might want to change that :stuck_out_tongue:

If not… then what is the $ for?

It is an indicator to anyone else using the code that these are ‘internal’ properties. Other than that, it’s just a character and we can use them with the variable names.

That dbl click code doesnt check for tripple click (clicking three times fast will result in 2 doubleclicks)


MovieClip.prototype.addProperty("onDoubleClick",
	function() { return this.$onDoubleClick },
	function(f) { this.$onDoubleClick = f; Mouse.addListener(this); }
);
Mouse.onMouseDown = function() {
	if(this.last_click && getTimer() - this.last_click < 300) this.broadcastMessage("$onDoubleClick");
	else this.last_click = getTimer();
};
Mouse.addListener(Mouse);

wont be a double double on a tripple :wink:

^ Clicking once will result in a doubleclick, once the movie is immediately exported!

so did the other one :stuck_out_tongue:

Custom MovieClip Properties (MX)
These Ive been using a lot. They make it easier for you to manipulate movieclips with new properties defined by you. Example: _left, _right, _top, _bottom, _xcenter and _ycenter:


MovieClip.prototype.addProperty("_left",
	function(){
		return this.getBounds(this._parent).xMin;
	},
	function(x){
		this._x += x - this.getBounds(this._parent).xMin;
	}
);
MovieClip.prototype.addProperty("_right",
	function(){
		return this.getBounds(this._parent).xMax;
	},
	function(x){
		this._x += x - this.getBounds(this._parent).xMax;
	}
);
MovieClip.prototype.addProperty("_top",
	function(){
		return this.getBounds(this._parent).yMin;
	},
	function(y){
		this._y += y - this.getBounds(this._parent).yMin;
	}
);
MovieClip.prototype.addProperty("_bottom",
	function(){
		return this.getBounds(this._parent).yMax;
	},
	function(y){
		this._y += y  - this.getBounds(this._parent).yMax;
	}
);
MovieClip.prototype.addProperty("_xcenter",
	function(){
		var b = this.getBounds(this._parent);
		return (b.xMax+b.xMin)/2;
	},
	function(x){
		var b = this.getBounds(this._parent);
		this._x += x - (b.xMax+b.xMin)/2;
	}
);
MovieClip.prototype.addProperty("_ycenter",
	function(){
		var b = this.getBounds(this._parent);
		return (b.yMax+b.yMin)/2;
	},
	function(y){
		var b = this.getBounds(this._parent);
		this._y += y - (b.yMax+b.yMin)/2;
	}
);

(the formatting is a little off here in the forums so the code looks a little weird ;))

These all simplify the use getbounds by making these properties associated with movieclips that allow you to check or set those properties. _left, _right, _top, and _bottom represent those positions of the movieclip’s bounding box whereas _xcenter and _ycenter are the absolute center positions of the movieclip (which may or may not be equivalent to _x and _y depending on whether or not the registration of the movieclip is at the center or elsewhere).

I think the biggest advantage comes in the ability to easily set the _top or _left of a movieclip etc. This makes alignment a snap.

I recently posted my little point class on layer51 protos too. Nothing special, but its something I use a lot. It adds to the movieclip object _loc, _mouseLoc, _cursorLoc and _direction.
You can find it here http://proto.layer51.com/d.aspx?f=919

Same concept there, using Flash MX’s addProperty function to add properties to movieclips making your life easier.