Better Flash Navigation using AS3 Classes

Source File: 

In this article, you will learn a much better, more object oriented way to structure a Flash application than the typical "frames on the main timeline" scheme that you see so often everywhere. This better way might be summed up in a few words as "MovieClips as screens." This is so far superior to "Frames as screens," that I think you will be as amazed as I was, when I line out for you exactly why. Read on!

Great article! Now I need to do something else...

I'm really loving the technique! Thanks so much. 

I've run into a situation that I don't understand. I want to have a navbar on stage at all times, and then by clicking on a button in that navbar, cause another screen to load. How do I call a handler in my Main object (that adds and removes children) from my navbar object? I have tried just calling my gotoHome() function in the Main script from the NavBar script, but I get errors.

PopUpManager gone in Flash CS4 AS3

Hi,


 


I love the article and I too want to lever coding rather than use the timeline. I have one small problem, I want my code to be nimble and want to create dynamic dialog boxes rather than designe a bunch of swf files, or library object and then call them from the code. AS2 had a class called PopUpManager, and it looks like Adobe in favor of Flex have depresiated this  class in Flash CS4 AS3. Have you seen an alternative in your travels? I would really like your input.


 


JLM

Jody Hall's picture

JLM, Thank you for your

JLM,

Thank you for your comment. Here is my humble take:

PopUpManager was part of the V2 component set. It allowed you to (fairly) easily create and pop up an instance of one of the other component classes. The component set in Flash never went over very big, however, as far as I know and from what I've read and heard. The intention was to make a set of components so that the average person, programmer or not, might be able to just jump in and start making applications with them. It didn't quite work out that way. And if you did get the hang of the components, you still wound up with applications that looked like somebody used components, as they were notoriously almost impossible to skin.

I don't want to pretend to know components inside out, because I don't. Nor do I know their full history. But Flash still comes with components, and they apparently kept the most popular ones, and weeded out the not-so-popular. And they brought back the UIScrollbar because of popular demand. And they made them all a lot easier to skin.

I have mostly for the most part shied away from components, except I experiment with them sometimes. My advice, though, is that you should write your own popup window class, that extends Sprite. You will be able to customize it a lot better, and get the look you want right off the bat. Just ask yourself what would be the parts of it? A background, a dynamic textbox for content text, a dynamic textbox for the title bar, a "close" button, etc.... Those would be its properties. What would be its methods? In other words, what should you be able to tell it to do from the outside? Well, you should be able to set its title and text, you should be able to make it open and close, and you should be able to size and position it. Also you might make it autosize itself depending on the size of the content textbox. One tricky aspect is going to be how to make it "modal." A modal window won't let you interact with the rest of the application until you dismiss it.

Designing classes is fun, when you start getting the hang of it. I am still intermediate myself, but I'm coming along okay. I think (hope!) that's the appeal of my tutorials, I am one of you, your fellow traveller.

Jody

navigation from Main.as

Like another reader, I am also very curious about how to use a menu/navigation bar that stays on the stage to switch between 'screens.'


Right now I've got it set up so that the menu buttons are on the main Fla file's stage, and the AS to switch screens is in my equivalent version of Main.as. No action script is in the main Fla file, and all of the buttons are being called by their instance name. In the Fla file, my buttons are movie clips, similar to the button array tutorial you also have here.  After I added an event listener to button, this is the code I used.


function homeHandler(event:MouseEvent):void {  
 removeChild(currentScreen);
 addChild(home);
 currentScreen = home;


}


(at one point I had a line above remove child that read: home = new Home();          But that also brought no changes so it's commented out)
Right now, I don't get any errors, but things also don't work. I can even see the frame changes within the button-movie-clips when I mouse over or click on the buttons.


Do you have any suggestions or hints to offer? Thank you!!!

Jody Hall's picture

Buttons in Main Class

eheidner (and lucky),

You can have your buttons on the main timeline, then just program those stage instances in your document class. Then all your screen switching is done from the main class, and maybe that is neater. But if you have screens that are the same size as the stage, when you use addChild() to display them, they will go on top of the display list and cover up your navigation buttons. To get around this, you might use addChildAt(screenName, 0) so that you always add a screen to the display at the lowest depth, then it will tuck neatly behind your buttons. Of course, in this case, you will have to design your screens to allow for the fact that the buttons will now be covering up a portion of your screen.

I have put together a wham-bam simple example of what I am talking about, complete with button disabling and all that. structure_tutorial_buttons_in_main.zip. Don't expect any great designing in this one, it's just to demonstrate the stucture. The Main.as document class is commented as to what's going on.

You'll notice I just used separate buttons, but if you wanted to make those buttons part of a container navigation bar, you could do that too. Just nest them inside a container movie clip, and use dot syntax to program the nested buttons.

Another idea might be to have a "fly out" menu that doesn't cover up much of the stage until you mouse over it. I guess any number of variations are possible.

Hope that helps!

Thank you so much! This is

Thank you so much! This is extremely helpful and exactly what I was hoping to do! :)


(I had given up on listing the buttons in an array because it doesn't seem to matter how many times I read about arrays with movie clips, I can't seem to code them right, so that part is especially useful!!)

I Need Alert Component

I'm following your tutorials and very eager to learn tricks and tips post by you. Really Thanks a lot. And I need Alert component in AS3.0 best reference site can any body helping me in welcome!.. Thanks and regards, Logeshkumar P.

Logeshkumar P.
http://linelogesh.blogspot.com

Thank you... Cheers, JLM

Thank you...


Cheers,


JLM

Possible improvement

Hello -

Thanks for this tutorial. I am using it on an actual project and am hopeful it will make it efficient and will improve my OO skills in the process. I came up with an idea that could be a slight improvement and am interested in hearing what you think of it. I thought I'd try consolidating all the goto functions into one like this:

public function gotoScreen(screen):void {
 removeChild(currentScreen);
 addChild(screen); currentScreen = screen;
}

 

That would cause you to change the class code to be (for example):

MovieClip(parent).gotoScreen(MovieClip(parent).learn);

Do you think there are any possible issues that could come up as a result of doing it this way? 

 

 

Jody Hall's picture

Re: Possible Improvement

fhickler,

Thanks for the nice comments, and I'm glad to see you are finding the information useful. It would seem from what you suggested that the different screens would have to know about each other, so I don't think that would do. But if you have an example, I'd love to see it!

Anyway, there are probably tons of variations on this that are possible, and this was intended to be a starting point. In fact, you've got me thinking of ways to improve it right now. Like maybe an "addScreen" method in the main class? Also in the tutorial, I used screens that were centered on their registration point, but now I keep thinking that may not necessarily be the best way of doing things.

You will find your own (specific) best ways of working--the main thrust of the tutorial, though, remains true, that the general methodology outlined here is easier and more fun to work with than frames on the main timeline.

Wondering about the old object

Cool tutorial.

 

on the last page of the tutorial, when you explaind about "reset" the drag page by instanciating a new Drag object.

 

I wonder, what happens to the "old" Drag object? Does he still holds its value, or is it become ready for garbage?

 

Tzachi

Jody Hall's picture

The old object becomes

The old object becomes eligible for garbage collection when it loses its reference. And it loses its reference when you set the same variable equal to a NEW object.

The garbage collector can't be forced, it deletes the old object unpredictably. And only when all references to it have been removed.

Intro.swf and Intro.as ??

 I'm trying to follow the idea with a little different method:

Instead of linking a library symbol "Intro" to a class named "Intro", I'm trying to link a swf named "Intro.swf" to a class "Intro".

 

The idea is to load from the main movie a swf called Intro.swf that all its code is written in a linked class (Intro.as ?)

 

But it doesn't work.

 

Any help?

 Is it that i have to write

 Is it that i have to write the Intro (Intro.as) as the document class of the Intro.fla ?

 

Jody Hall's picture

That's right

Yes, the Intro.as file would have to be the document class of the Intro.fla file. You will also have to use a loader object to load the external swf.

add a loader

Hi Jody,

It's a very good article that really encouraged me start developing in AS3 instead of AS2.

Now it's very clear for me how to structure a site with classes and don't get that # 1009 errors anymore.

But what if I want to add a loader movieclipe that plays while my Intro clip is loading or being added to stage? Is there a way to do it using this same structure you show in the article?

Thank You

Marcos

 

 

jamestagal's picture

Excellent Introduction to using classes for Navigation!

Normal
0

false
false
false

EN-US
X-NONE
X-NONE

MicrosoftInternetExplorer4


Hello Jody,

Your article has really been an eye-opener to say the least! More like a revelation better describes it! I am fairly new to Flash and writing Actionscript so having some of the basics has helped me get a handle on the concepts/code in your tutorial! But this approach to organising a Flash project makes so much sense! And as you have so wonderfully illustrated how it works. And as you say it’s not too difficult to conceive and do. I haven't come across anything else (Flash tutorials) that incorporates the use of Classes to navigate through "screens" offering a better alternative to timeline navigation. In a way, it has pointed out to me how my project could be improved because I was experiencing all the same problems you mentioned at the beginning of your article. Also I wanted to praise you for was how well you are able to explain some of the more complex concepts, very logically and clearly, not losing a newbie like myself.

You have made me rethink how I have been developing my first Flash project so that I am now going to rework it following your method. Here's a link to a demo of what I've done so far. www.eddiesoft.id.au/Ben/WaterWise.html

My one uses the timeline with frame labels for navigation but it shouldn't be too difficult to change using your method. Thanks again for this fantastic tutorial! I have also just finished reading your tutorial on AS3 Dropdown Menu with Reusable Classes and will try to incorporate that too.

I was thinking about how I could incorporate some other custom graphics or objects in the Dropdown Menu instead drawing the shapes as you have shown in that tutorial?  

Regards, Ben.

Jody Hall's picture

You made my day

Ben,

I appreciate all the nice comments! You really made my day!

(Sorry I am just now getting around to replying. I've been away from my own site for too long!)

If you read to the end of the dropdown menu tutorial, you will see that I showed at the end how to make it use MovieClip instances because they qualify as Sprites, and the menu's "addItem()" method only requires that you send it a Sprite instance. And of course you know that you can literally incorporate whatever custom graphics you want in a MovieClip, including other MovieClips and buttons. You can put whatever you want in the dropdown menu.

Jody

Sharing between classes

Like the others before me I want to say "great job" on this tutorial. And thank you for the time you take to explain what the code is doing in depth in-stead of skimming over the information. I look forward to working through some of your others.


I have one question... in the text you state "Classes are all nice and encapsulated that way. By default, they don't share information with each other, and later I will show you how to make them share with each other just the information you want." I may have missed how you share information between classes. What I am looking for is if I create a variable in a class and need to access that information in another class how does that happen?

Jody Hall's picture

Walt, Classes communicate

Walt,

Classes communicate with each other mainly through "getters" and "setters." Another way is by dispatching events. Sorry if I failed to bring that out in the tutorial. Keep reading, and find out how getters and setters work, and you will have no problem getting your classes to communicate with each other.

Jody

emmanuelulloa's picture

MovieClips as Screens approach.

Jody this is a really great tutorial! As a Flash Educator it helps a lot to teach this approach. I also implemented something like your approach in my application Simple Class Generator for AS3.

sewingbuttons's picture

AS3 Classes Tutorials

The Tutorial by Jody Hall was by far the best Flash tutorial I have ever come across. As a java developer, I needed to get back to the basics with Flash and tie it all together where it made sense, with classes and functions and packages. This tutorial absolutely made it for me!! Thanks, I'll be looking for your book and anything else you write. Your writing style was the absolute best and so easy to follow. Totally talented teacher!

Thanks!

Jody Hall's picture

Thank you

sewingbuttons,

Thanks for your comments. I think those are probably the nicest compliments I've ever received, and they certainly made my day when I first read them! I took a Java class at a local community college a long time ago, but at the time I just didn't get the whole object-oriented thing, and I didn't really become proficient in Java, even though I got an A in the class (and my final project was kind of cool, but I remember the way I did it was mostly by brute force programming!). Later I also took a class on Visual Basic, and I got a better idea of OOP through that. But mostly the OOP stuff didn't start clicking in my mind until later when I was learning Flash, but the earlier Java training (and VB) was not a complete loss, because now I can see what they were talking about.

BTW, I just finished a new tutorial that might be right up your alley: Flash - The Big Picture. It deals with classes, packages, the classpath, and how they all relate to Flash.

--Jody Hall

Better Flash Navigation

Thanks for a great tutorial. I'm a sailor not a programmer so I struggle with anything needing coding. I like to try my hand at different things though and this tutorial really got me going.

Using your method I have been successful at updating a learning aid (drag/drop type) from AS2 to AS3. As you can imagine the AS3 version is a complete redesign.

There's one aspect I have not been able to figure out.

There are three stages:(repeated in both English and French)

Stage 1 is a static page where the client learns the names and locations of stuff.

Stage 2 is a drag and drop page with flyback if name not placed correctly and sticking if correct.

Stage 3 is a test level. Visually exactly the same as stage 2 BUT the words need to stick wherever they are put with no opportunity to change once dropped.

All navigation is working fine but I don't know how to change the Drag.as files to achieve stage 3 functionality in AS3.

Any suggestions will be greatly appreciated

Gandhi Quote

Live like you will die tomorrow

Learn like you will live forever

Jody Hall's picture

It's like that with anything

Ynot sailing,

Anyone will struggle with anything the first time(s) they try it. And the person who's been doing it for ten years (or more) will make it look easy. If I tried sailing I would be lost and probably not make it back to the shore.

But if a person decides they like something well enough to want to get good at it, and they persist, they will succeed at whatever it is. You just have to decide (or discover) that you really, really like it. Our trouble is (and I am guilty of this too!) that we always want to master something practically overnight! I'm waxing philosophical here, but I think it's true.

As for your code you are having trouble with, you will overcome by really studying the lines of code and what they do. The fact that they are in a class or on the timeline or whatever isn't so important, what matters is what the line of code is telling the computer to do. So the code that I put into a class will still work in other contexts.

There are lines of code that tell the object being dropped to go back to where it started. Take those lines out. There are lines of code that disable the object from being picked up and dragged again. Leave those lines in. Result: the object will stay wherever you drag it to, and you won't have the opportunity to drag it again.

Anyway, if you are still really stuck, write to me using the contact form on this website. I'll write you back and then you can send me your files, and I will help you.

Jody

Midnight Posts

Hi Jodi

I really should not post anything at midnight :-))

Got back to it this morning and had no problem sorting out what I needed to do.

The learning aid is now fully working and in much better shape than it ever was using AS2.

But of course along the way I found out a few more things that did not work.

Here's the link to what I have achieved so far www.ynotsailing.com/Flash/BoatParts.html

The next steps are:

1. Design a "Congrats" page for when the client scores 100%. (Particle effects fireworks tutorials here I come!)

2. Find a way to list the items that were incorrectly placed for those who do not score 100%. (I suspect I will need to know a lot more about arrays and such to do this ugh!)

Thanks to the guidance I got from your tutorial I'm beginning to think I may keep my sanity or at least what's left of it.

I've made more progress in the last couple of days than in many previous months.

Your style and way of explaining things are superb. If I was in the business of teaching Flash I would hire you in heartbeat :-))

Thanks again

Tony (aka Ynot)

Gandhi Quote

Live like you will die tomorrow

Learn like you will live forever

Getting out of "IF"

Hi Jody

I've hit a road block and would like some help please. I've been struggling with this for the last couple of days without success. Like Edison I found lots of ways that do not work :-)

I've modified the dropMe function to add a score counter for each correct hit and an if statement to display the score in a dynamic text field when all the objects have been placed.

All works well as long as I have the dynamic text field on frame 1 of the dragMe movieClip.

I tried to put it on another  keyframe on the dragMe MC and added a gotoAndPlay statement using a frame label.

I get a "TypeError: Error #1009: Cannot access a property or method of a null object reference.     at TestEnglish/dropMe()" message.

If I comment out score_txt.text = "Scored " + scoreCounter + "/26"; the gotoAndPlay works fine.

As stated earlier if I have the dynamic text field score_txt on frame one of dragMe movieClip it correctly displays the score.

Ultimately I want to be able to display different info depending on the score achieved.

For example if the client does not score 100% they will be given guidance on what they did not place correctly. (I'm in the process of learning how to do this part but cannot progress until this current problem is fixed). When the score 100% they will go to a congrats page (fireworks; I'm looking forward to playing with particles but need to be able to walk before I start running :-)).

So here's my questions.

1. What do I have to do to get the If statement to either take me to another frame on the dragMe MC timeline and address the dynamic text field

OR

2. Take me to a completely new movieClip.

OR

3. Is there another way to achieve what I am trying to do.

Thanks in anticipation

Tony

Gandhi Quote

Live like you will die tomorrow

Learn like you will live forever

EventListening - On the caller or in the class.

Hi Jody,

A lot learned here again.

If you wanted another/different level/kind of flexibility would it be appropriate to move the handling of events to the objects (continents) themselves?

The thought I have is if you wanted to have different sets of objects with the same functionality (Learn, Drag) would it be appropriate to put the code on the objects themselves - the continents instead of in the class that is calling them - Intro, Drag, and Learn.

Lets say that you wanted to be flexible and wanted to be able to do countries as well as continents. At that point would you want to have the Learn screen call a layout function which built each object with all the abilities needed to function? Would it be better to create the individual object (area = continent, country) its own class and have it manage its own events (tooltips and interactions) and placement instead of having the parent (Learn, Drag) do that? So an object (continent, country) would create itself, position itself based on set locations or some algorithm called when it is created, and set up its event listeners for dragging and tooltips, etc.

package {
import flash.*;

	public class Layout extends MovieClip {
		protected var thing: Thing;
		protected var things: Array = new Array();
		// Bunch of other variable declarations. Left out for clarity.

        public function Layout {
		thingsTotal = thingsPerRow * thingsPerCol;
		// Layout things in a rectangle pattern 
			for (var i:uint = 0; i < spinnersTotal; i++)
			{
				thing[i] = new Thing();
				stage.addChild(things[i]);
				things[i].addEvents();
				things[i].x = (centerStageX - (PerRow * things[i].width / 2)) + deltaX * (things[i].width + thingsXSpacing);
				things[i].y = deltaY * (things[i].height + thingYSpacing) + thingYBegin;
			}
		}
	}
}

package {
		public class Thing extends MovieClip {
			public function Thing() {
				buttonMode = true;
				addEventListener(Event.ADDED_TO_STAGE, init);
			}
		
			protected function init(event:Event):void {
				removeEventListener(Event.ADDED_TO_STAGE,init);
			}

			public function addEvents() {
				stage.addEventListener(Event.ENTER_FRAME, spin);
				addEventListener(MouseEvent.MOUSE_DOWN, activate);
				stage.addEventListener(MouseEvent.MOUSE_UP, select);			
			}

			// Works. Things spin.
			protected function spin(event:Event):void {
				wedge_ring.rotation += wedge_ring_spin_speed;
			}

			// Not working. Getting Argument error 2025 for setChildIndex. 
			protected function activate(event:MouseEvent):void {
				currentItem = event.currentTarget;
				setChildIndex(currentItem, numChildren - 1);
				startDrag();
			}

			// Not getting hit yet because of the previous functions issues.
			protected function select(event:MouseEvent):void {
				stopDrag();
			}
		}
	}
}

The idea being that things could be laid out in any arrangement but the main class wouldn't have to deal with handling events each time. Different from this example in that each screen has different interaction (drag or tooltip).

- Thanks, Karl

Jody Hall's picture

If there's a better way, go for it.

Karl,

The purpose of the article was to point out the problems with timeline navigation systems, and to present a much better alternative with MovieClips as "screens." The Intro, Learn, and Drag screens made good examples, and I probably strayed from the main subject matter myself in describing them in detail. They could have been just blank screens, and I could have still made my point, but I also went into things like tooltips, drag and drop, etc. I just wanted to show how all this code was encapsulated into each screen's class and was independent of everything else. Again, as opposed to the timeline alternative. In comparison, the "MovieClip as screen" approach seems light years ahead to me.

Beyond that, I'm not opposed to anyone coming up with any kind of architecture they want, or even discarding this one if they find something better. I'm always exploring other ideas myself, usually with the thought of making things easier or simpler, if at all possible.

The reason I don't make each object responsible for its own events like you suggest (and I have tried it) is because it tends to require each object to also know about all the other objects. If I am making a drag and drop matching game, for example, and the events are inside the object, how will I evaluate whether it hit its intended target when it drops? I would have to make the class somehow aware of all the other objects (or at least the one it's intended to match) in order to do my evaluation right there in the class. This means that every object that's going to be dragged will need a reference to all the other objects as well. OR I could dispatch an event letting my outside code know that the object has dropped. But in that case, I'm doing the evaluation from outside the class anyway, so (in my thinking anyway) the whole thing might as well be programmed from the outside, because the parent object has all these references that are needed.

So that doesn't sound easier or more flexible to me, it sounds like a lot more hassle than just programming it from outside the class. Once again, though, I am not opposed to someone taking off with this and trying it. If you'd like to do that, I'd be glad to see it, and maybe I will learn something new too, which is always good!

Jody

I'll let you know which way I go.

Jody,

Thanks for the response. Your thoughts on where the game play needs to implemented is what I'll need to think about.

I'll let you know where I end up.

- Thanks, Karl

Thank you for the article,

Thank you for the article, learned a lot. He was learning to program in C + + and I dropped by the flash was a great choice was very easy to learn about classes, now do not want to stop programming in flash.

Jody...you ROCK!

I am brand new to flash. I read an entire 550 page book on CS5 by katherine ulrich, which was a good foundation on the CS5 basics and some AS. read tons of miscellaneous articles by developers and watched youtube videos on how to create menus, apps, screens, etc. they ALL go down the timeline route, which is going to be too complex for the application i am building. i was getting so frustrated that i could not find anyone who could describe alternative structure options. i kept getting the dreaded null reference error. pulling my hair out until i stumbled on your article in a forum that you posted to.

the fog lifted as soon as i started reading. So simple and logical...yet so few people use this technique. i love it! even the programmer that i hired and paid $10k to already, has managed to build a super complex web of screens that is nearly impossible to change sequences or add new screens into the mix. and when i wanted him to add a screen into the mix...and then go back to the other screen without losing the state of that prior screen, he threw up his hands. your article breathed new life into my project! thank you so much. I dropped a small donation on you, but will do some more as i learn more from you.

Finally, the simplistic and thourough way you write is so refreshing. nothing worse than reading someones article or advice that says "put in this huge block of code...and don't worry about why the code works...just know that it does". love that you explain every line and its purpose.

I learned more in the 2 hours of going through your article and tutorial than anything i have read in my prior 30 hours of training.

I am anxious to read through the rest of your stuff.

Chi(xmiller)

Jody Hall's picture

Thank you so much

Chi,

I often say that someone's comment made my day (and I always mean it). This one was like that--only times ten. Anyway, it's always good to know someone appreciated and got a definite, measurable benefit from an article of mine. It lets me know I struck a chord with someone, and I really appreciate the feedback.

I was not familiar with the Katherine Ulrich book (just now looked it up on Amazon), but there is another QuickStart guide by Russell Chun that I often recommend as a good introduction to Flash and AS3. Everyone else always recommends "Essential Actionscript 3.0" by Colin Moock, which is a fantastic book, but in my humble opinion, too deep for beginners and not centered enough on Flash.

I have seen quite a few massive timeline navigational nightmares that people have created. And yet, sometimes when I suggest they adopt the "MovieClips as screens (w/classes)" thing, they somehow think it's going to be too hard to learn how to do it. I don't really have the time to show them, at least not one person at a time, so that's why I wrote the article.

I am glad that you intend to keep reading. Click the "All tutorials" link at the top of the page. "Streamlining your AS3 code" is a good, simple article to start with, as it spells out several techniques I have found myself using over and over in my own projects. "Flash: The Big picture" will give you a much better idea of how Flash works with classes, packages and the classpath, and how you might structure your folders for your projects. Presently I am considering writing a tutorial on using the PureMVC framework, because very little of what's out there is centered on Flash as opposed to Flex.

Stay tuned, and thanks again! You've encouraged me more than you know.

Update on my progress...

Jody,

Thanks for the other references. I will definately check those out.

Just wanted to let you know, I built a set of basic login screens last week that interface with my sql backend, allow logging in, registering a new account, receiving a temporary generated password if you lost yours and updating your profile. I had them all linked together horribly with a timeline. Every time I wanted to add new functionality i was pulling my hair out. Tonight I ripped em apart and put back together using your movieClips as screens technique! Worked so easily and smoothly! I no longer have to keep track of the spaghetti of links to and from. I can come and go as I please and I love being able to maintain the state or wipe it clean. And debugging for errors seems so much easier.

Not to mention I kind of smile each time I look at my scene stage and its completely blank ;->

I also went through your event dispatch tutorial. Another cool technique that I already know where i am going to put it to use in my game. I am still super wet behind the ears, but for the first time I feel like I can do this.

Have a good weekend. I am sure I will be pinging you for help at some point, but for now I have been able to find and fix bugs as I go.
Cheers,
Chi

my weekly question(s) ;->

Hi Jody,

I do most of my coding on the weekend, hence my saturday questions. I am getting close to having my app complete, but have a couple nagging questions that I can't quite figure out.

1) Passing a variable between objects. Lets pretend in your example above you have a String type variable in the Learn object.

var example:String = "test";

Now lets say you want to use that variable in the drag.as object.

trace(example);

Of course as written, we will get the error message of "1120: Access of undefined property example", since their is no variable named "example" in drag.as.
My understanding is the I need to dispatch an event to pass the variable, but i m struggling with the syntax. Any help is appreciated.

2) this is a followup to a prior question you helped me with. I needed to activate keyboard buttons for an object, and I did that by including the keyboard event listener in the function associated with for ADDED_TO_STAGE event. It is mostly working, but when first enter the object. requires one mouseclick first, then it works fine from then on. let me know if you have any thoughts. i will also go reread you advice last time.

Thanks much,
Chi
-

Jody Hall's picture

Several ways of doing what you want

Chi,

The question of how to make your objects "talk" to each other is one that everybody struggles with at first, and there are many debates about best practices and the cleanest ways of doing this, but the fact is that there are many, many ways.

If learn (lowercase "l") is the instance of Learn, initially the name "learn" is known only to the Main document class, because that's what instantiated it. So learn can have a public getter method (in it's class, "Learn") called either getExample() or get example() depending on whether you want to make the method look like a property from the outside, but I'll just use getExample() for now:

public function getExample():String {
return "test";
}

That's the easy part. Now any object that has a reference to the learn screen can just call the getTest() method to access the data. And therein lies the tricky part. How does the drag screen call the learn screen without having a reference to it? It doesn't. So how does the drag screen GET a reference to the learn screen? There are a couple of different ways that this might happen:

1. Since the Main document class has a reference to both objects, because it instantiated them both, it can give the drag object a reference to the learn object, but the drag object would have to have written into its class a way of storing a reference to learn (perhaps as a class member, or variable), and a way from the outside of setting it:

//inside the Drag class:
private var _learn:Learn;
public function set learn(value:Learn):void {
this._learn = value;
}
Then Main would first create the instance of learn, then create the instance of drag, and send the drag instance the reference to learn:

//inside Main:
private var learn:Learn;
private var drag:Drag;
//
public function Main() {
learn = new Learn();
drag = new Drag();
drag.learn = learn;
}

Admittedly this is a lot of extra work, but when it's done, drag "knows" about learn (but still not the other way around), and they are what programmers call "tightly coupled." Now the drag screen can call the getExample() method on its stored reference to learn anytime it wants to:

trace( _learn.getExample() ); //or anything else it wants to do with the value.

This is without a doubt the long way around, but it might be useful if there was a lot of stuff about learn that drag needed to know (if it needed frequent access).

2. Another way to go would be to make a way in Main so that both learn and drag can get references to each other:

//inside Main (I'll just do one):
public function getLearn():Learn {
return learn;
}

For this to work, the problem becomes how do learn and drag get a reference to Main? Here's one way that relies on the display list:

//from inside of the Drag class
Main(parent).getLearn().getExample();

Because both learn and drag are on Main's display list, the "parent" reference becomes a convenient way to fetch a reference to the Main document class's instance.

3. Yet another way is to create public static variables in Main that reference both learn and drag, like so:

//inside Main
public static var learn:Learn;
public static var drag:Drag;

public function Main() {
learn = new Learn();
drag = new Drag();
}

And now whenever either learn or drag want to refer to each other, they can do so using these public static vars in Main like so:
//inside of the Drag class:
trace( Main.learn.getExample() );

4. Yet another way is to give Main a public static way to share a reference to itself:
//inside main:
public static var me:Main;
public var learn:Learn; //I'll just do one, again, & just making it public for simplicity, but you might rather use a getter
public function Main() {
me = this;
learn = new Learn();
}
// from the drag class:
Main.me.learn.getExample();

Notice when you want to reference static variables, you precede the dot with the name of the class, because the variable belongs to the class, and not to any instances.

Believe it or not, there are yet more ways, and the way you mentioned of dispatching an event would work also, but you would have to make your own custom event that extended the Event class, so that it could carry along the data, and even then the two objects would have to either know about each other, OR you would have to rely on event "bubbling" through the display list, so that you could set the event on a higher level object (perhaps even the stage).

I hope this is enough to help you out, and I suspect it is. I should have made this into a tutorial!

And no worries, I'm a weekend warrior myself, so it all works out!

Jody

Wow, way more answers than I expected

Jody,

Fantastic information. You definately could make this a tutuorial entitled "Passing variables between classes". I had no idea the variety that existed. Number 2 was the easiest for me to get my hands around and since I just need to pass 1 or 2 items, it was very straightforward and did the job.

Thanks a million!
Chi

Adding a Validator Class?

Hi Jody,

Hope thanksgiving treated you well. I found the following code for validation technique for registration screens. I have tried to add this in as a class into my code (which looks just like your tutorial), but i can't get it to work. Any thoughts on how you would add this into your tutorial as another screen?

http://active.tutsplus.com/tutorials/actionscript/validating-various-inp...

thanks, Chi