2010-12-02 12 views
0

私は、ステージ上に常に少なくともいくつかのコンポーネント(ユーザー入力のための説明とテキスト入力用のテキスト領域)を持つテキストアドベンチャーゲームに取り組んでいます。したがって、私はFlashのWYSIWYG設計環境を通してこれらのコンポーネントを静的に作成しました。私はそれぞれインスタンス名 "myTA"と "myTI"を与えました。メインクラス(ステージのドキュメントクラス)がそれらとやり取りすることができました(実行時にタイプライターのように一度に1文字ずつテキストを動的に追加します)が、同じパッケージ内の他のクラスは認識できないようですステージコンポーネント。すべてがメインクラス内で発生した非ドキュメントクラスのクラスをFlash AS3のステージコンポーネントに「認識」させるにはどうすればよいですか?

ケースA、::メインはタイプライター印刷を処理するために、第2のクラスのタイプライター "を呼び出し

package { 
    public class Main extends MovieClip { 
     public var myTA:TextArea; 
     var displayedChar:String = new String(); 
     var textToWrite:String = new String(); 
     var i:int = 0; var intervalId:uint; 
     var done:int = 0; 

     public function Main { 
     setUpTA(); 
     } 

     public function setUpTA(){ 
     myTA.text = "" + playAtInterval("Hello Player!"); 
     }   

     public function writeCharsSlowly(){  
     textToWrite = arguments[0];  
     displayedChar=textToWrite.substring(i,i+1); 
     myTA.appendText(displayedChar);        
     i++;  
     if (i == textToWrite.length) {   
      done = 1;   
      clearInterval(intervalId);  
     }    
     }     

     public function playAtInterval(theText:String) {     
     i = 0;    
     intervalId = setInterval(writeCharsSlowly, 100, theText);   
     } 
    } 
} 

ケースB:

以下は、関連するコードです

メイン:

package { 
    public class Main extends MovieClip { 
     public var myTA:TextArea; 
     public var myTI:TextInput; 
     var str:String = new String(); 

     public function Main{ 
     testTypeWriter(); 
     } 

     public function testTypeWriter(){ 
     typeW.playAtInterval("Hello Player"); 
     typeW.addEventListener(MouseEvent.CLICK,testTypeWriter2); 
     typeW.addEventListener(KeyboardEvent.KEY_DOWN,inputEngine2) 
     addChild(typeW); 
     } 

     public function testTypeWriter2(event:MouseEvent){ 
     if (myTI.text == "a") { 
      typeW.playAtInterval("yo"); 
     } else { 
      typeW.playAtInterval("Greetings, I am a test..."); 
     }    
     addChild(typeW); 
     } 

     public function inputEngine2(event:KeyboardEvent){ 
     str = String.fromCharCode(event.charCode); 
     myTI.appendText(str); 
     } 

タイプライター:

package { 
    public class TypeWriter extends MovieClip { 
     public var myTI:TextInput; 
     public var myTA:TextArea; 
     var i:int = 0; 
     var done:int = 0; 
     var intervalId:uint; 
     var displayedChar:String = new String(); 
     var textToWrite:String = new String(); 

     public function TypeWriter(){ 
     ///nothing here 
     } 

     public function writeCharsSlowly(){  
     textToWrite = arguments[0];  
     displayedChar = textToWrite.substring(i,i+1); 
     myTA.appendText(displayedChar);        
     i++;  
     if (i == textToWrite.length) {   
      done = 1;   
      clearInterval(intervalId);  
     }    
     }     

     public function playAtInterval(theText:String) {     
     i = 0;    
     intervalId = setInterval(writeCharsSlowly, 100, theText);   
     } 
    } 
} 

ケースAが動作しますが、B Flashが "エラー#1009:nullオブジェクト参照のプロパティまたはメソッドにアクセスできません"というエラーが表示され、myTAで操作しようとしているTypeWriterの最初の行に注意します問題。

既存のステージコンポーネントを「認識」しているドキュメントクラス以外に他のクラスを作成するにはどうすればよいですか?

おかげで、

CCJ

答えて

0

私はいくつかの依存性の注入は、この問題を解決すると思います。 Typewriterクラスをインスタンス化するときは、myTAmyTIに参照を渡します。例:

public function Main{ 
    testTypeWriter(this.myTA, this.myTI); 
} 

次に、あなたのTypewriterコンストラクタは次のようになります。

public function TypeWriter(ta:TextArea, ti:TextArea){ 
    this.myTA = ta; 
    this.myTI = ti; 
    } 

また、これは、アプリケーションがあまり密結合することの利点を持っているので、たとえば、あなたが異なるとあなたのTypewriterクラスを再利用することができますテキストエリアとテキスト入力。

編集

将来的にあなたを助けるかもしれないいくつかの余分な情報:ルート・オブジェクトを介して、ステージ要素にアクセスすることができます。ただし、これは表示リストに追加されたオブジェクトでのみ機能します。さんはTypewriterは、表示リスト内のオブジェクトを表していると言ってみましょう、あなたは、このようmyTAにアクセスできます。

MovieClip(root).myTA 

(変更MovieClipSpriteにそれがあなたのドキュメントクラスを拡張何場合)。

しかし、Typewriterが表示リストに追加されていないようだから、私は依存性注入の最初の提案を使うことをお勧めします。

さらにthis pageをチェックし、CasaLibを使用して任意のオブジェクトからステージにアクセスします。私は個人的にそれを試していないので、それはここに終わりです;-)

0

myTAとmyTIは実際に作成時にステージ上にあるのですか、それとも動的に追加されますか?

最初のケースでは、それぞれにインスタンス名を追加するだけです。次に、各クラスに変数を追加します。

var main_mc : Main = root as Main;

You can then access the instances via main_mc.myTAおよびmain_mc.myTI(選択したインスタンス名であることが前提です)すべてが型保護されている必要があります。

動的なケースでは、メインクラスの参照を追加するときに、その参照をそれぞれ保存するようにしてください。

もう1つの方法は、myTAとmyTIのクラスを作成して、その存在をアナウンスするイベントをコンストラクタで送信することです。メインクラスはこれを聞いて参照を登録できます。

しかし、正直言ってディスプレイを自分のロジックに混ぜています。 MVCとPureMVCを特に読んでください。優れた設計では、すべてがメッセージによって処理され、インスタンスはお互いに直接参照する必要はありません。 IIRCでは、MoockのAS3の本はMVCに関する章を持っています(ただし、彼のAS2の本かもしれません)。

0

彼らが常に舞台に立つという事実は、あなたがそれらのために特定のクラスを作るのを止めてはいけません。

ゲームの構造によっては、TextFieldを使用してMovieClipを作成し、それをTypewriterクラスにリンクするか、TextFieldのクラスを作成してイベントを使用してテキストコンテンツを変更することができます。

外部クラスを使用しているため、Flash CS内にロジックを保持する理由はありません。

1

これにはService Locator Patternをお勧めします。最も単純なアプローチは、パブリック静的変数を含むリソースクラスを作成することです。ドキュメントクラスで、ステージインスタンスをリソースクラスの対応する静的変数に割り当てます。次に、これらのステージコンポーネントに簡単にアクセスできます。

var someTextArea = Resource.TA; //probably should rename to something more meaningful 

少し独創的なものについては、私がリンクしている記事を読むべきです。

コンストラクタインジェクションがステージに多くのアイテムを追加する可能性があるので、コンストラクタインジェクションが巨大なパラメータリストになる可能性があるので、これは依存性インジェクションより優れていると思うし、セッタインジェクションを好きではない。

EDIT:

ちょうど私が、私はいくつかのコードを追加するだろうと思ったことは、もう少し明確にする:)

リソースクラス

package 
{ 
    //TODO imports 
    public class Resource 
    { 
     public static var TA:TextArea; 
     public static var TI:TextInput; 
    } 
} 

Documentクラス

//....setup function 
Resource.TA = myTA; //myTA is the name of the instance on stage 
Resource.TI = myTI; 

のFooクラス

Resource.TA.x = 100; 
//or 
_myClassMemberVariable = Resource.TA; 
_myClassMemberVariable.x = 100; 
0

だけ明確にすること。ステージを書くときは、実際にあなたのフラッシュドキュメントのドキュメントクラスを意味します。ステージは、表示リストに追加されたすべてのインスタンスがアクセスできるクラスです。

テキストフィールドを更新する必要があるクラスに渡します。

var tw : Typewriter = new Typewriter(); 
    tw.inputField = myTI; 
    tw.textArea = myTA; 

それとも

var tw : Typewriter = new Typewriter(myTI, myTA); 
関連する問題