Question with using Prototypes

Ok… here is then general idea: I want to creat a prototype function in my maintime line so any MC can call it. I am looking to have many different navigation MC’s use it… what I am trying to do is use the MCs like buttons, so I want to create some effects on rollover then reverse them on rollout. Such as a size increas on over then animate out when mouse leaves (of course all the animation will be in actionscript within the prototype)… the effects are not what I am having a problem with, it is the syntax of the prototype, and how to work it with onRollOver and onRollOut…

Also, I thought about possibly just defining a function in the maintimeline and having the MCs call it on rollover and rollout… would this be a better way of doing it?

PEace

If you’re using rollOvers, functions suffice, no need to use prototypes. But it depends on your code too…

pom :asian:

you’ll probably want to create a class that will contain all the methods and prevent them from being available to movies that don’t need them.

there’s built in ways to add objects to classes in mx, but i’ve never explored that as dave yang’s code has never let me down.

here’s a sample:


// dave yang's inheritance code
MovieClip.prototype.setClass = function(c, args) {
	this.sup = c;
	this.__proto__ = c.prototype;
	this.sup(args);
	delete this.sup;
};

// the class constructor
MCbutton = function(){
	this.class = "MCbutton";
}

// link the prototype chain back to MovieClip's
MCbutton.prototype.__proto__ = MovieClip.prototype;

// a grow prototype
MCbutton.prototype.grow = function(){
	this.onEnterFrame = function(){
		if((this._xscale = this._yscale +=10)>140){
			this.onEnterFrame = null;
		}
	}
}

// a shrink prototype
MCbutton.prototype.shrink = function(){
	this.onEnterFrame = function(){
		if((this._xscale = this._yscale -= 10)<100){
			this._xscale = this._yscale =100;
			this.onEnterFrame = null;
		}
	}
}

// assign the prototypes to events
MCbutton.prototype.onRollOver = MCbutton.prototype.grow;
MCbutton.prototype.onRollOut = MCbutton.prototype.shrink;

// set clip "sqr" to class MCbutton
sqr.setClass(MCbutton);

you can define other things in the constructor that everything in the class will have. there’s no reason that you have to define a class variable, i just had to put something in there, and it can be handy to be able to ask your objects what class they belong to.

ok… well I am going to have each menu item resize with a spring effect, then ‘bounce’ back to size on rollout… also might add an alpha or color change that matches the spring effect. Would functions suffice for this or would you recommend prototypes?

ahhhh… you must have posted when I was typing… I’ll look into the code you gave me! Thanks

hmmmm I have never really worked with classes and inheritance before, so I am having some problems getting yor code to work… I have a MC called sqr to be set into the class, and the code seems to respond fine, BUT instead of action on over and out, it grows and shrinks repeatidly if you keep your mouse over it.

Peace

The obvious problem with prototypes set to define “movieclip” is as sbeener said, all mcs would inherit them.

As is the case of joso, where he had set a prototype, but a variable in the definition was being used by all mcs, and the spring to mouse and bounce back effect was going a bit mad.

I changed his code for it to work, by defining new variables on the onClipEvent (load) for the mcs, but although I’ve never really explored classes - I think the code sbeener posted would come in very handy.

ok it seems to be working better now… I am going to play wth it for a bit… thanks!!

Peace

Ou la la. Come back here, Supra. You won’t get out with it so easily. I’ve started looking into inheritance, but you lost me completely here.[list][]Why does your setClass function take 2 arguments, but when you use it you only use the class?[]Still the setClass function: what is the use of this.sup?[*]Why do you need this line: this.proto = c.prototype? I think there’s something I have misunderstood, because for me this means that you link the proto of the object to the prototype of the super class, but I don’t remember seing it in the examples I’ve seen…[/list]Help!!

pom :asian:

I’m mixing everything up!!!

pom :frowning:

Last thing, I read that Macromedia recommends the use of this code to inherit:

SubClass.prototype=new SuperClass();

Why can’t we use this here?

hum… I’m rating this thread, I fell it’s gonna be interesting… :slight_smile:

ok here is the code I am using for the “grow” portion of the prototype… I am trying to have each MC using the prototype grow to a certain scale, but doso with a bouncy effect… I’ve done it with motion many times, but never with the scale of an MC… so far this is my code - and as I am sure you guessed… its not working! I am pretty sure I referencing wrong somewhere in the code… but for the life of me I just cant see it!

MCbutton.prototype.grow = function(){
	this.onEnterFrame = function(){
		this.acceleration = 10;
		this.friction = .5;
		this.targetScale = 200;
		MCbutton.scaleMe = function() {
			var scaleDiff = this.targetScale - this._xscale;
			this.scaleSpeed += scaleDiff/this._parent.acceleration;
			this.scaleSpeed *= this._parent.friction;
			this._yscale = this._xscale += this.scaleSpeed
		}
		MCbutton.checkscale = function() {
			if (Math.abs(this.targetScale-this._xscale)<0.2) {
				if (Math.abs(this.scaleSpeed)<0.2) {
					this._xscale = this._yscale=this.targetScale;
					delete this.onEnterFrame;
				}
			}
		}
	}
}

Also I am trying to addapt code I already used in another project so I probably didnt change everything that needed to be changed.

Peace

as for your question Ilyas: hmmmmm :-\

ryall - i think where your using “_parent”, you actually meant “this”. it’s all one movieclip right?

if you really do mean _parent, you need to write this._parent so flash knows whose parent you’re talking about.

ily -

Why does your setClass function take 2 arguments, but when you use it you only use the class?

this is in case you want to pass arguments to the class constructor. then you can spec as many arguments as you like in an array, and pass that array to the class constructor.

in this case, there are no arguments to pass to MCbutton(), so that argument is never used. but you might use the same method to set another clip to a different class that does take arguments.

Still the setClass function: what is the use of this.sup?

ok, this is dave’s code and i’m guessing here, but i think that the class function needs to be run relative to the clip. thus this.sup is set to c (which is the class argument passed to this function) and then run as this.sup (passing it the arguments if there are any). then deleted since you don’t need that reference hanging about anymore.

Why do you need this line: this.proto = c.prototype? I think there’s something I have misunderstood, because for me this means that you link the proto of the object to the prototype of the super class

close, not the super class, but the class - MCbutton. we then link to the super class by linking MCbutton.prototype.proto to MovieClip’s prototype chain.

ryall, just noticed something else, you’re defining those functions but not actually running them!

try defining them somewhere else (so they don’t redefine every enter frame) and call them. that will make your code cleaner too.

also no reason to define acceleration, friction, and targetScale over and over. just define them once. maybe even in the class constructor.

ok grrrrr… please take a look at this - it is my full code… I changed the things you suggested sbeener… but I may have not changed them properly, the class and prototype stuff keeps confusing me on what is happening… also I have only tried to put the elastic motion in for the over event (the out is still a simple scale down)… anyway please take a look again and tell me what you think:



		// dave yang's inheritance code
MovieClip.prototype.setClass = function(c, args) {
	this.sup = c;
	this.__proto__ = c.prototype;
	this.sup(args);
	delete this.sup;
};

MCbutton.scaleMe = function() {
			var scaleDiff = this.targetScale - this._xscale;
			this.scaleSpeed += scaleDiff/this.acceleration;
			this.scaleSpeed *= this.friction;
			this._yscale = this._xscale += this.scaleSpeed
		}
MCbutton.checkscale = function() {
	if (Math.abs(this.targetScale-this._xscale)<0.2) {
		if (Math.abs(this.scaleSpeed)<0.2) {
				this._xscale = this._yscale=this.targetScale;
				delete this.onEnterFrame;
				}
			}
		}
		

// the class constructor
MCbutton = function(){
	this.class = "MCbutton";
	this.acceleration = 10;
	this.friction = .5;
	this.targetScale = 200;
}

// link the prototype chain back to MovieClip's
MCbutton.prototype.__proto__ = MovieClip.prototype;

// a grow prototype
MCbutton.prototype.grow = function(){
	this.onEnterFrame = function(){
		MCbutton.scaleMe();
		MCbutton.checkscale();
		
	}
}

// a shrink prototype
MCbutton.prototype.shrink = function(){
	this.onEnterFrame = function(){
		if((this._xscale = this._yscale -= 5)<100){
			this._xscale = this._yscale =100;
			this.onEnterFrame = null;
		}
	}
}

// assign the prototypes to events
MCbutton.prototype.onRollOver = MCbutton.prototype.grow;
MCbutton.prototype.onRollOut = MCbutton.prototype.shrink;

// set clip "sqr" to class MCbutton
sqr.setClass(MCbutton);
sqr1.setClass(MCbutton);
sqr2.setClass(MCbutton);
sqr3.setClass(MCbutton);
sqr4.setClass(MCbutton);


PS as you can see form the last few lines it is more than one movie clip, BUT they are all being assigned to the same class so I dont need parent right? they should all just inherit the actions of the prototypes for the class MCbutton?

Peace

OK, I’m creating a new thread so that we don’t mix everything up.

you’re really close.

don’t forget to write Class.**prototype.**methodName when defining prototypes! also, prototypes for a class must be defined after the class constructor (function MCbutton()).

when you define a method in a class’s prototype chain, it exists locally to objects of that class. so to call it from an object of that class, you can write: this.myMethod(); you don’t need to path to the class constructor.

thus,


MCbutton.prototype.grow = function(){
    this.onEnterFrame = function(){
        MCbutton.scaleMe();
        MCbutton.checkscale();
    }
}

should read


MCbutton.prototype.grow = function(){
    this.onEnterFrame = function(){
        this.scaleMe();
        this.checkscale();
    }
}

i think that’s all i changed before it started working for me!

ahhhhh… I know I am am sooo close and getting closer, ok I believe I made the changes properly… it works now - well kind of: it scales large on rollover and back down on rollout… BUT when it scales up it doesnt do so with an elastic/springy effect (the whole reason I added those functions)… possibly there is something wrong with how I wrote the scaling functions?! grrrrrr this is really getting frustrating being so close - yet so far…

Thanks soooo much for you help, I really appreciate it here is the changed code:


// dave yang's inheritance code
MovieClip.prototype.setClass = function(c, args) {
    this.sup = c;
    this.__proto__ = c.prototype;
    this.sup(args);
    delete this.sup;
};

// the class constructor
MCbutton = function(){
    this.class = "MCbutton";
    this.acceleration = 10;
    this.friction = .5;
    this.targetScale = 200;

MCbutton.prototype.scaleMe = function() {
            var scaleDiff = this.targetScale - this._xscale;
            this.scaleSpeed += scaleDiff/this.acceleration;
            this.scaleSpeed *= this.friction;
            this._yscale = this._xscale += this.scaleSpeed
        }
MCbutton.prototype.checkscale = function() {
    if (Math.abs(this.targetScale-this._xscale)<0.2) {
        if (Math.abs(this.scaleSpeed)<0.2) {
                this._xscale = this._yscale=this.targetScale;
                delete this.onEnterFrame;
                }
            }
        }
}

// link the prototype chain back to MovieClip's
MCbutton.prototype.__proto__ = MovieClip.prototype;

// a grow prototype
MCbutton.prototype.grow = function(){
    this.onEnterFrame = function(){
        this.scaleMe();
        this.checkscale();
        
    }
}

// a shrink prototype
MCbutton.prototype.shrink = function(){
    this.onEnterFrame = function(){
        if((this._xscale = this._yscale -= 5)<100){
            this._xscale = this._yscale =100;
            this.onEnterFrame = null;
        }
    }
}

// assign the prototypes to events
MCbutton.prototype.onRollOver = MCbutton.prototype.grow;
MCbutton.prototype.onRollOut = MCbutton.prototype.shrink;

// set clip "sqr" to class MCbutton
sqr.setClass(MCbutton);
sqr1.setClass(MCbutton);
sqr2.setClass(MCbutton);
sqr3.setClass(MCbutton);
sqr4.setClass(MCbutton);

as you can see I added the *.prototype also I moved the definitions after the constructor… whats gooooing onnnn!!!
:evil: :frowning: … :-\ …:stuck_out_tongue:

It’s a matter of settings

MCbutton = function(){
    this.class = "MCbutton";
    this.k = .2;
    this.friction = .9;
    this.targetScale = 200;

MCbutton.prototype.scaleMe = function() {
            var scaleDiff = this.targetScale - this._xscale;
            this.scaleSpeed += scaleDiff*this.k;
            this.scaleSpeed *= this.friction;
            this._yscale = this._xscale += this.scaleSpeed;
        }

And I changed your variable acceleration into k, because that’s what it is :slight_smile:

pom :asian: