I am working on a text adventure game which will have at least a few components (a text area for narrative and text input for user input) on the stage at all times. Therefore, I
Just to be clear. When you are writing stage you really mean the document class for your flash document. Stage is a class that every instance that has been added to the displaylist Have access to.
I would pass the textfields into the classes that needs to update them.
var tw : Typewriter = new Typewriter();
tw.inputField = myTI;
tw.textArea = myTA;
Or
var tw : Typewriter = new Typewriter(myTI, myTA);
The fact that they will be on stage at all times shouldn't stop you from creating specific classes for them.
Depending on your game structure, you could either create a MovieClip with your TextFields and link them to the Typewriter class, or simply create a class for the TextFields and use Events to modify the text content.
You're using external classes so there are no reason to keep any kind of logic inside Flash CS.
I think some dependency injection will solve this problem. When you instantiate your Typewriter
class, pass references to myTA
and myTI
. ex:
public function Main{
testTypeWriter(this.myTA, this.myTI);
}
Then your Typewriter
constructor should look like this:
public function TypeWriter(ta:TextArea, ti:TextArea){
this.myTA = ta;
this.myTI = ti;
}
This also has the benefit of making your application less tightly coupled, so for example you can reuse your Typewriter
class with a different text area and text input.
Edit
Some extra info that may help you in the future: you can access stage elements through the root object. But this only works with objects that have been added to the display list. Let's say that Typewriter
represents an object in the display list, you could then access myTA
like this:
MovieClip(root).myTA
(Change MovieClip
to Sprite
if that's what your document class extends).
However, since it seems that Typewriter
does not get added to the display list, I recommend using my first suggestion of dependancy injection.
Also check out this page, it dicusses using CasaLib to access the stage from any object. I personally haven't tried it, so that's why it's at the end here ;-)
Are myTA and myTI actually on the stage at author time or are the added dynamically?
In the first case, just add an instance name to each. Then add a variable to each class
var main_mc : Main = root as Main;
You can then access the instances via main_mc.myTA
and main_mc.myTI
(assuming those are the instances names you chose) and everything should be type-safe.
In the dynamic case, just make sure you save off references in the main class to each as you add them.
Another option is to have classes for myTA and myTI send an event in their constructor to announce their existence. The main class can then listen for these and register the references.
To be honest, though, you are mixing up your display with your logic. Read up on MVC and PureMVC in particular. With a good design, everything can be handled by messages, and the instances don't need direct references to each other. IIRC, Moock's AS3 book has a chapter on MVC (but it could be his AS2 book).
I would recommend the Service Locator Pattern for this. The most naive approach would be to create a resource class which contains public static variables. Then in your document class you assign the stage instances to the corresponding static variable in the resource class. Then you can simply access these stage components anywhere.
var someTextArea = Resource.TA; //probably should rename to something more meaningful
For something a little more ingenious you should read the article I linked to.
I think this is better than the dependency injection as constructor injection could lead to huge parameter list as you might add more items to the stage, and I am not so fond on setter injection as it is easy to forget to set them.
EDIT:
Just to make it a bit more clear I thought I would add some code :)
Resource class
package
{
//TODO imports
public class Resource
{
public static var TA:TextArea;
public static var TI:TextInput;
}
}
Document class
//....setup function
Resource.TA = myTA; //myTA is the name of the instance on stage
Resource.TI = myTI;
Foo class
Resource.TA.x = 100;
//or
_myClassMemberVariable = Resource.TA;
_myClassMemberVariable.x = 100;