actionscript help for a non programmer who wants to do it the right way
June 29, 2006 11:11 AM   Subscribe

OK. So I have five movie clips on the stage named b1 - b5. When the user clicks on one the other four need to gotoAndPlay. I could write a function for one object then cut and paste and just change the names, but that seems inelegant. What I think I need to do is generate an array containing the five objects, then, when the user clicks on one of them, that one is removed from the array and triggers a function that loops through the remaining clips in the array and does the goto. Does that make sense? And if so, how would I do it? And if not, what is a better way? In other words, user clicks on movie named b1 and b2-b5 do something. user clicks on movie named b3 and b1,b2,b4, and b5 do something. Thanks!

OH. One other thing. After the stage is cleared of all but one clip (that's the animation that the goto goes to) the remaining clip must play an animation.

My level of experience ranks slightly below that of chipmunk's, so any example code w/ comments would be greatly appriciated.
posted by Grod to Work & Money (22 answers total)
 
In C++:

class clip { 
  public:
  void play() ;
  void gotoandPlay() ;
}  ;

clip arrayOfClips[ 5 ] ;

void onClick( int whichClip ) {
  const int clipCount = arrayOfClips / arrayOfClips[ 0 ]  ;
  if( whichClip >= clipCount ) 
    throw std::out_of_range( "There aren't that many clips, mr. programer" ) ;

  for( int i = 0 ; i <  ; ++i ) br>     if( i != whichClip ) 
       arrayOfClips[ i ].gotoandPlay() ;

    arrayOfClips[ whichClip ].play() ;
}

 

I don't know what language you're using, but this C++ code should be easy enough to follow. Of course, the definition of class clip is left to you; I'm "assuming" the clips don't need to be initialized, which of course isn't true.

Summary: you don't need to remove stuff from the array, you just need to call gotoAndPlay on all clips but the one selected, and then call play on that one.
posted by orthogonality at 11:34 AM on June 29, 2006


I don't quite understand your second-to-last paragraph, but the main part should go something like this:

var numClips:Number = 5;
var strPrefix:String = "b";

init();


//assigns the function playOthers to the onRelease
//event handler for each movieclip
function init():Void
{

for (var i:Number = 0; i < numclips; i++)br> {
_root[strPrefix + i].onRelease = playOthers;
} //end for

} //end function init


//makes each clip, except the one calling this function
//gotoAndPlay
function playOthers():Void
{

var mc:MovieClip;

for (var i:Number = 0; i < numclips; i++)br> {

mc = _root[strPrefix + i];

if (mc._name != this._name)
{
mc.gotoAndPlay("someFrame");
} //end if

} //end for

} //end function playOthers
posted by grumblebee at 11:35 AM on June 29, 2006


Sorry about my lack of indents. I never can figure out how to format code for AskMe.

By the way, I was assuming that your clips are numbers b0, b1, b2... If the first one is b1, not b0, then change the two for loops to the following:

for (var i:Number = 1; i <= numClips; i++)
posted by grumblebee at 11:37 AM on June 29, 2006


Argh, I forgot to escape the less than symbol.

  for( int i = 0 ; i < countClips ; ++i ) 
    if( i != whichClip ) 
       arrayOfClips[ i ].gotoandPlay() ;
posted by orthogonality at 11:37 AM on June 29, 2006


It sounds like this is an actionscript question.
posted by Lord_Pall at 11:39 AM on June 29, 2006


And I forgot two sizeof()s.
posted by orthogonality at 11:40 AM on June 29, 2006


Grod can you translate the c++ into actionscript or do you need a specific set of actionscript code?
posted by Lord_Pall at 11:41 AM on June 29, 2006


I also made use of the fact that Flash automatically builds an array called _root, which contains references to all items on the stage. So you don't need to create an array, as-long-as your clips have regular naming conventions (b0, b1, b2...).

In AS, the following two lines of code yield identical results:

_root.someMovieClip._width = 100;

_root["someMovieClip"]._width = 100;

My approach would fall apart if the clips have haphazard names. But that problem could be easily solved with an programmer-generated array.

Just add this declaration to the top:

var arrClips:Array=new Array();
arrClips = ["a","q","xyz","blah"]; //items are instance names of moviecliops

Then change the following:

for (var i:Number = 0; i < numclips; i++)br> {
_root[strPrefix + i].onRelease = playOthers;
} //end for

to

for (var i:Number = 0; i < arrclips.length; i++)br> {
arrClips[i].onRelease = playOthers;
} //end for


and



for (var i:Number = 0; i < numclips; i++)br> {

mc = _root[strPrefix + i];

if (mc._name != this._name)
{
mc.gotoAndPlay("someFrame");
} //end if

} //end for

to

for (var i:Number = 0; i < arrclips.length; i++) {br>
mc = arrClips[i];

if (mc._name != this._name)
{
mc.gotoAndPlay("someFrame");
} //end if

} //end for
posted by grumblebee at 11:44 AM on June 29, 2006


Response by poster: Lord_Pall Nope, I wasn't joking when I said non-programmer with the experience of a stunned chipmunk. I forgot to mention (I guess) that this is actionscript specific.

grumblebee neat, except I got this error:
**Error** Scene=Scene 1, layer=actions, frame=1:Line 13: ':' expected
_root[strPrefix + i].onRelease = playOthers;

**Error** Scene=Scene 1, layer=actions, frame=1:Line 16: Unexpected '}' encountered
} //end function init

Total ActionScript Errors: 2 Reported Errors: 2


and I don't quite understand everything you did, although I should be able to figure it out, maybe. Thanks, can you explain the error to me, too?
posted by Grod at 12:01 PM on June 29, 2006


Response by poster: Please, someone, explain how to fix it so the errors don't occur. I'm beating my head against the wall here.
posted by Grod at 1:04 PM on June 29, 2006


When you copied Grumblebee's code, did you copy the "br>" parts?

Those shouldn't be there, they're an artifact of askMefi's HTML parsing.

I don't know "actionscript" whatever that is, but judging from Grumblebee's code,

The "':' expected" comes from actionscript requiring a colon between a variable declaration and the variable (or function's) type, as in:

for (var i:Number = 0; i < arrclips.length; i++)

or

function init():Void

The unexpected bracket just means you have one more close bracket ("}") than you have open brackets ("{").

Carefully compare Grumblebee's code to your own, and make sure you have all the open brackets he has.
posted by orthogonality at 1:16 PM on June 29, 2006


I'm brain damaged. I read grumblebees stuff as c++. It's actionscript and it's been a long week.
heh
posted by Lord_Pall at 1:21 PM on June 29, 2006


Response by poster: Oh. I guess I am an idiot. Yeah, I copied the br> parts. Without them there I get no errors but I don't get anything else, either. I can click a movie till my finger falls off and it won't do jack. This is incredibly frustrating.
posted by Grod at 1:25 PM on June 29, 2006


Are you referring to an actual frame in the following line?
mc.gotoAndPlay("someFrame");

Are your movie clip instances named correctly?
posted by fishfucker at 1:33 PM on June 29, 2006


Well, work incrementally.

You do have the clips set up, right, and they do have regular names, or if they don't, you've declared an array with their names, right?

First, write a function that just pops up a message box (or whatever). Get your click handler to call that function.

Then figure out if you can get your click handler to pass an argument to the function (like a number, or a reference to the thing clicked).

Then add the clip gotoandplaying business to that function that shows a message box. If that works, add the playing of the clicked clip.

Just do one little piece at a time, don't try to do it all at once.
posted by orthogonality at 1:34 PM on June 29, 2006


Response by poster: fishfucker, yup.

orthogonality. I'm slightly confused. If I have one movie clip and attached an event handler to it like this:
b1.onRelease = someFunction;
when I click b1 that function will, um, function. But with grumblebee's code it looks like I don't have to write:
b1.onRelease = playOthers;
b2.onRelease = playOthers;
etc.
That's all taken care of, isn't it?
posted by Grod at 1:39 PM on June 29, 2006


Response by poster: so right now what I have looks like this:

b1.onRelease = killthecook;

//this works but it's stupid
function killthecook() {
b2.gotoAndPlay(29);
b3.gotoAndPlay(29);
b4.gotoAndPlay(29);
b5.gotoAndPlay(29);

}

/* this is commented out because it wasn't working

var numClips:Number = 5;
var strPrefix:String = "b";
init();


//assigns the function playOthers to the onRelease
//event handler for each movieclip
function init():Void {
for (var i:Number = 1; i < numclips; i++) {br> _root[strPrefix + i].onRelease = playOthers;
} //end for

} //end function init


//makes each clip, except the one calling this function
//gotoAndPlay
function playOthers():Void {
var mc:MovieClip;
for (var i:Number = 1; i < numclips; i++) {br> mc = _root[strPrefix + i];
if (mc._name != this._name) {
mc.gotoAndPlay(29);
} //end if
} //end for
} //end function playOthers
*/
sorry the indents didn't keep.
posted by Grod at 1:43 PM on June 29, 2006


Response by poster: and those stupid "br>" got inserted by mefi. huh.
posted by Grod at 1:49 PM on June 29, 2006


It's taken care of because Grumblebee's code assigns playOther to each instance's onRelease handler:

init(); // here Grumblebee CALLS init()


// here Grumblebee DEFINES init
//assigns the function playOthers to the onRelease
//event handler for each movieclip
function init():Void
{

for (var i:Number = 0; i < numclips; i++) {
_root[strPrefix + i].onRelease = playOthers;
// here the init function assign the function playOthers to the clip
// Grumblebee's code requires that the clips be named strPrefix + i;
// i is the number controlled by the for loop
// strPrefix was previously defined by Grumblebee to be "b"

} //end for

} //end function init


In the actual Playothers function:
Apparently, actionsctipt passes an implicit "this" reference. Grumblebee uses "this" to compare this._name to each clip's name, so as to not play the "this" clip.

I don't see Grumblebee calling play on teh clicked clip, possibly because that's a default action in actionscript?
posted by orthogonality at 1:50 PM on June 29, 2006


Best answer: I ironed out some kinks and got it to work. I sent an example file to Grod. Here's the script from it:

var numClips:Number = 4;
var strPrefix:String = "b";

init();


//assigns the function playOthers to the onRelease
//event handler for each movieclip
function init():Void
{
for (var i:Number = 0; i < numclips; i++) br> {
_root[strPrefix + i].stop();
_root[strPrefix + i].onRelease = playOthers;
} //end for
} //end function init


//makes each clip, except the one calling this function
//gotoAndPlay
function playOthers():Void
{
init();
var mc:MovieClip;
for (var i:Number = 0; i < numclips; i++)br> {
mc = _root[strPrefix + i];
if (mc._name != this._name) mc.gotoAndPlay("go");
} //end for
} //end function playOthers
posted by grumblebee at 2:44 PM on June 29, 2006


Grod, if you need any more help, I might be able to work on it late tonight or tomorrow. But I will be offline until then (starting now). So I hope my post above helps. Good luck!
posted by grumblebee at 2:47 PM on June 29, 2006


Response by poster: Thanks! It works great.
posted by Grod at 3:15 PM on June 29, 2006


« Older creature of habit log   |   Two sided jigsaw puzzle with numbered code Newer »
This thread is closed to new comments.