Solved

variable scope clarification for actionscript in flash cs3

Posted on 2009-05-18
18
469 Views
Last Modified: 2013-11-12
Hi,

I am creating a flash website using flash cs3 and actionscript 2.0. I am attempting to create a panel-based content navigation user interface. I am doing this by creating an empty movie clip in actionscript and attaching movie clips with content on them to the empty one in intervals equal to the width of the content panel. I then have buttons inside a "navBar" movie clip that I would like to be able to press and have the content movie clip with attached panels scroll to the appropriate corresponding content section.

My problem is that I don't think I completely understand variable scope in actionscript. I am adding the script to the only frame in my "main" movie clip which is the only object in "Scene 1" (which I believe is the _root). The buttons are on a different layer below the script layer in a movie clip entitled "navBar." I have them in the movie clip so that I can animate their entrance to the screen when the site loads.

How can I reference the buttons in the way that I need to add actions to them that will then allow them to control the content panel?

I have attached the code.
Thanks!

(Also a disclaimer: I am attempting to loosely follow a tutorial I found online. Parts of this code and ALL comments are creditable to http://www.flash-game-design.com/flash-tutorials/advancedWebsite-flash-tutorial.html")
/*An empty MovieClip is created, called 'content' which will later

be used to attach each section onto. The content MovieClip can then

be scrolled along the X axis, rather than moving

each individually section. */

this.createEmptyMovieClip("content", 1000);
 
 

/*The 'sectionBackground' MovieClip is attched and given the instance

name 'mask'. The mask MovieClip will be used to mask the content MovieClip. */

this.attachMovie("sectionBackground", "mask", 1001);
 
 

/*The mask and content MovieClip's are placed at the Y position where

we want the content to appear. */

mask._y = content._y = 227; //might need to change everything from here to...
 
 

/*The mask and a variable called target are placed at an X

position of where we want the content to appear. When the

website loads, to make it more interesting, the first section

will be displayed off screen and then scroll to the 'target'

position. The target value will later be used to hold a value

that the content must scroll to, each time it's associated menu

button is pressed. */

mask._x = target = 460;
 
 
 

//The content MovieClip is set to be masked by the mask MovieClip.

content.setMask(mask);
 
 
 

/*The content MovieClip is set to start at -1000 X position.

We'll later write some Actionscript to scroll the content

MovieClip from this value to the target value. */

content._x = -1000;
 
 
 

// A speed is set for how fast the section MovieClip will scroll at.

imageScrollSpeed = 10;
 

//should be loop here, but we're gonna brute force this one
 
 

	/*Using the loop, each menu item is attached the empty 'content'

	MovieClip, by referencing the identifier ('section_photoshp' etc) that

	we gave each section MovieClip earlier. Each section is assigned to a temporary

	variable called "section", that we can use to set its properties. */

	var section0 = content.attachMovie("section_demo", "section_demo", 100);

	var section1 = content.attachMovie("section_products", "section_products", 101);

	var section2 = content.attachMovie("section_pricing", "section_pricing", 102);

	var section3 = content.attachMovie("section_contract", "section_contract", 103);

	var section4 = content.attachMovie("section_contactus", "section_contactus", 104);
 

	/*The section's X position is set using it's width and multiplying it

	by the incrementing "i" in the loop. So since the each section is 588

	in width, the 1st section, from the menu array, will be placed at 0 (0x588)

	X position in the "content" empty MovieClip. The 2nd section will be placed 588 (1X588),

	and so on until "i" has reached the menu array length.*/

	section0._x = section0._width * 0;

	section1._x = section1._width * 1;

	section2._x = section2._width * 2;

	section3._x = section3._width * 3;

	section4._x = section4._width * 4;
 
 

	/*The content MovieClip, containing each section, also needs a target each

	time a subButton is pressed, so this is stored in the 'pos' property

	of each subButton. The target of the 1st section was set at the start,

	so it's now added to i - the section width. */

	_demoButton.pos = target + (0 * section._width); //change this?

	_productsButton.pos = target + (1 * section._width); //change this?

	_pricingButton.pos = target + (2 * section._width); //change this?

	_contractButton.pos = target + (3 * section._width); //change this?

	_contactUsButton.pos = target + (4 * section._width); //change this?
 
 

	_demoButton.onRelease = function(){

		//When the sub button is pressed the target variable will be set as the pos property

		target = this._demoButton.pos;

	};

	_productsButton.onRelease = function(){

		//When the sub button is pressed the target variable will be set as the pos property

		target = this.pos;

	};

	_pricingButton.onRelease = function(){

		//When the sub button is pressed the target variable will be set as the pos property

		target = this.pos;

	};

	_contractButton.onPress = function(){

		//When the sub button is pressed the target variable will be set as the pos property

		target = this.pos;

	};

	_contactUsButton.onPress = function(){

		//When the sub button is pressed the target variable will be set as the pos property

		target = this.pos;

	};
 
 
 

/*An onEnterFrame function is created which will execute any

code inbetween the braces {} repedly, at the frame rate of the movie. */

this.onEnterFrame = function() {
 
 

	/* This is the code used to move the "content" MovieClip to the "target"

	value minus the content's current X position divided by the scroll speed.*/

	content._x += (target - content._x) / imageScrollSpeed;
 

};

Open in new window

0
Comment
Question by:TTAsupport
  • 10
  • 8
18 Comments
 
LVL 22

Expert Comment

by:rascalpants
ID: 24413465

in AS 2.0 the best way to do this is to use the Delegate class...  it will keep the scope issues to a minimum...

see the below code for an example...


rp / ZA



import mx.utils.Delegate;
 

var myButton:MovieClip;
 

myButton.onRelease = Delegate.create( this, on_Click );
 

function on_Click():Void

{

   trace("you clicked on myButton");

}

Open in new window

0
 

Author Comment

by:TTAsupport
ID: 24413555
but how can i reference a button that I have already created and have exported for actionscript with a unique identifier?

If you see my source code, you can see what I have named the buttons I wish to use:
_demoButton
_productsButton
_pricingButton
_contractButton
_contactUsButton

These buttons are inside a movie clip entitled "navBar" and that is inside a movie clip entitled "main."

A have re-posted a portion of my source that includes the specific portion in question. Clearly I can't just say:
_demoButton.pos = target + (0 * section._width);

nor can I say:
_demoButton.onRelease = function(){
            //When the sub button is pressed the target variable will be set as the pos property
            target = this._demoButton.pos;
      };

because it doesn't work and I believe it is because I am not referencing these buttons correctly.
/*The content MovieClip, containing each section, also needs a target each

	time a subButton is pressed, so this is stored in the 'pos' property

	of each subButton. The target of the 1st section was set at the start,

	so it's now added to i - the section width. */

	_demoButton.pos = target + (0 * section._width); //change this?

	_productsButton.pos = target + (1 * section._width); //change this?

	_pricingButton.pos = target + (2 * section._width); //change this?

	_contractButton.pos = target + (3 * section._width); //change this?

	_contactUsButton.pos = target + (4 * section._width); //change this?
 

_demoButton.onRelease = function(){

		//When the sub button is pressed the target variable will be set as the pos property

		target = this._demoButton.pos;

	};

	_productsButton.onRelease = function(){

		//When the sub button is pressed the target variable will be set as the pos property

		target = this.pos;

	};

	_pricingButton.onRelease = function(){

		//When the sub button is pressed the target variable will be set as the pos property

		target = this.pos;

	};

	_contractButton.onPress = function(){

		//When the sub button is pressed the target variable will be set as the pos property

		target = this.pos;

	};

	_contactUsButton.onPress = function(){

		//When the sub button is pressed the target variable will be set as the pos property

		target = this.pos;

	};

Open in new window

0
 
LVL 22

Accepted Solution

by:
rascalpants earned 500 total points
ID: 24413638
you use the Delegate class....    you don't use "function".


this way you can create functions that your buttons can call, and the scope of everything is still contained correctly...


if your issue is that you are not able to access the "button"s from where you code is, you need to tell me where your code is located...


is SHOULD be on the first frame of the application...

and then in the case of what you said, you can reference the "button" like this...


var demo_btn:MovieClip = main.navBar._demoButton;

demo_btn.onRelease = Delegate.create( this, functionNameHere );


or even this way...

main.navBar._demoButton = Delegate.create( this, functionNameHere );

but this way is annoying to read.




rp / ZA


0
 

Author Comment

by:TTAsupport
ID: 24414457
ok, that makes a lot more sense.

also, hopefully this will clarify where my code is:

When I open my project, I am on "Scene 1"
I then double click and am in the "main" movie clip
my script is on a layer called "script" on frame 1 (the only frame) of the movie clip

"navBar" is in this this "main" movie clip

I will attempt your solution and see if I can get it to work. Do I need to put "_root" at the beginning of any of these, or can I just use the main.navBar.* to call them?

Thanks!
0
 

Author Comment

by:TTAsupport
ID: 24414489
oh and also, when I declare these variables, does it matter that all of the "_*Button" buttons are actual button symbols and not movie clips?
0
 
LVL 22

Expert Comment

by:rascalpants
ID: 24414575
here is what I would do...

move your code outside of the movieclip named "main"... put it in the first frame of the application.

also, just for good practice, you should put an identifier in the instance name...  so instead of using main, use "main_mc", and "navBar_mc"

the "_mc" is a way to let you know it is a MovieClip...   or you can use "myName_txt" for a text field...  or "_btn" for a button.  it just helps.


you dont need to use _root to reference anything, if you put the code in the right spot... which is in the first frame of your application.


rp / ZA
 
0
 

Author Comment

by:TTAsupport
ID: 24414736
ok, i have done this, but I'm still getting the same results as back at square one. if i change:

var demo_btn:MovieClip = main.navBar._demoButton;
to
var demo_btn:Button = main.navBar._demoButton;

then i get an error saying there is no such property with the name "pos". I note that because that's the only response I've gotten from the compiler since starting that even remotely comes close to acknowledging that I have even made variables...

...I now have no idea why these buttons won't execute the code I need them to

I will still accept your above answer as a solution because you answered my question as far as variable scope goes, but I won't close it yet because it won't work
0
 
LVL 22

Expert Comment

by:rascalpants
ID: 24414927
no need to close the question just yet....


why did you change MovieClip to Button?

but you only need to do that if you want to reference your code in a cleaner way...


have you placed your code on the first frame of the application yet?  my code assumes you take a that step...

otherwise you would reference it differently...


rp / ZA
 
0
 

Author Comment

by:TTAsupport
ID: 24414968
well, the buttons (such as _demoButton, _productsButton, etc.) are buttons in my library, not movie clips. that's why i took that step.

yes, my code is in the first frame.

I tried testing the movie again, and this time i went to debug > list variables. After looking at that output, I have reason to believe that the "*_btn" variables aren't instantiating. all of them come up "undefined"

ex:
_level10.instance5.demo_btn = undefined
0
How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

 
LVL 22

Expert Comment

by:rascalpants
ID: 24415034
you need to make sure you are giving everything instance names in the properties panel...

because you are getting "_level10.instance5" instead of something like  "_level0.main_mc.demo_btn"  means that is missing...


also in your code above, if you moved it to the first frame main timeline, then you need to change the references to the buttons and such to match.


rp / ZA
0
 

Author Comment

by:TTAsupport
ID: 24415209
oh, I see...

ok I have given instance names to everything and now it is showing up correctly as Variable _level0.main.demo_btn = [movieclip:_level0.main.navBar._demoButton]


however, I'm pretty sure my next issue is setting each button's "pos" to what I want to with this line of code:
demo_btn.pos = target + (0 * section._width);

I'm pretty sure this line is failing because for all 5 buttons the "list variables" output gives:

Variable _level0.main.navBar._demoButton.pos = NaN
0
 
LVL 22

Expert Comment

by:rascalpants
ID: 24415257

.pos is not a valid Flash property... unless you are just assigning a custom object to the movieclip...  

are you trying to set the x or y properties of the buttons?

if so you should use _x and _y


rp / ZA

0
 

Author Comment

by:TTAsupport
ID: 24415287
i'm hoping to just assign a custom object to the movieclip. am I using the correct syntax to do so?

I'm not trying to set the x or y properties of the buttons. that pos variable is used to store the location of the correct content panel for which the content below should scroll to when the corresponding button is pressed
0
 

Author Comment

by:TTAsupport
ID: 24415346
and by the pos variable storing the location of the correct content panel, I mean it holds a numerical value (int or double i guess... once again I'm not too familiar with actionscript, but it seems very similar to the programming languages ive used). my script uses that numerical value as a way to determine how far to scroll to get to the right content
0
 
LVL 22

Expert Comment

by:rascalpants
ID: 24415347

well, you should call it something like  ".posX" and ".posY"


I don't see how "target" is referenced anywhere... what is that from?


did you take this code from a callback function example and target is what is normally passed in to it?


rp / ZA
0
 

Author Comment

by:TTAsupport
ID: 24415367
target is way up at the top of my original code seen as attached. hopefully the comment is also helpful
/*The mask and a variable called target are placed at an X

position of where we want the content to appear. When the

website loads, to make it more interesting, the first section

will be displayed off screen and then scroll to the 'target'

position. The target value will later be used to hold a value

that the content must scroll to, each time it's associated menu

button is pressed. */

mask._x = target = 460;

Open in new window

0
 
LVL 22

Expert Comment

by:rascalpants
ID: 24415512

demo_btn.pos = target + (0 * section._width);

-------------------------

you need to use trace(); and find out if things like section and section._width are a number...

that is what NaN means...


rp / ZA

0
 

Author Comment

by:TTAsupport
ID: 24415520
actually... i somehow just got it to work... i changed a few variable names and now it works great... not sure whats up there... maybe I used an actionscript keyword or something.

thanks again for your help. i really appreciate it!
0

Featured Post

How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

Join & Write a Comment

Turn A Profile Picture Into A Cartoon Using Photoshop And Illustrator This tutorial will teach you how to make a cartoon style image out of a regular picture. I have tried to keep the tutorial as simple as possible. I used Adobe CS4 for this tuto…
I have been doing hardcore actionscripting for some time; and needless to say I have faced a lot of problems in just understanding others' code rather than understanding what the code executes. A programmer's life can become hell when there are a lo…
The purpose of this video is to demonstrate how to set up an RSS Feed on a WordPress Website. This will be demonstrated using a Windows 8 PC. Feedburner will be used for this demonstration. Go to your WordPress login page. This will look like the…
The purpose of this video is to demonstrate how to set up the permalinks on a WordPress Website. This will be demonstrated using a Windows 8 PC. Go to your WordPress login page. This will look like the following: mywebsite.com/wp-login.php : Go t…

747 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

13 Experts available now in Live!

Get 1:1 Help Now