1

私は AS3 にかなり慣れていないので、私の質問がばかげていると思われる場合はご容赦ください。

私が具体的に何を望んでいるのかを明確にしましょう: プレーヤーはミッションに参加します。そのミッションでは、途中でいくつかのオブジェクトをキャッチするとポイントが獲得されます。たとえば、オブジェクト A は 1 ポイント、オブジェクト B は 2 ポイント、オブジェクト C はボーナス ポイントを与えます。など... プレイヤーが途中で障害物にぶつかった場合、ミッションに失敗し、目的地 (レベルの終わり) に到達するまでゲームをやり直さなければなりません。

だから私が欲しいのは、プレイヤーが障害物にぶつかる前に獲得したポイントを保存する方法であり、獲得したポイントは、プレイヤーがゲームレベルの最後に到達するまでゲームをリプレイする必要があるたびに累積され、合計がプレイヤーが獲得したポイントは、実際にゲーム レベルの最後に到達する前に獲得したポイントを含め、すべてのポイントの合計になります。

My Class Player は、フレームワーク WCK に属するクラス Box のサブクラスです。依存性注入を適切に実装して、変数を他のクラスに渡してそこに格納する方法はありますか?

よろしくお願いします。

追加: これは、エイミーの例に基づいて実装したもので、ゲームのセットアップに合わせて調整されています。変数 _totalEarnedPoints の値が、すべてのポイントを蓄積するために Class Player で取得しようとしたときに、EventDispatcher を介して Class PlayerClient の変数 _earnedPoints を更新しなかったため、まだ機能しません。何が間違っていたのか、他に何かを見逃したのかわかりませんか?クラス PlayerClient から変数 _totalEarnedPoints を取得する方法を教えてください。

クラスプレイヤー:

package  
{

public class Player extends Box  
{  
    private var contacts:ContactList;  
    private var myLoader:SWFLoader;  
    private var mcTemp:MovieClip;  
    private var bonusPoints:int = 0;  
    private var onePoint:int = 0;  
    private var twoPoints:int = 0;  
    private var objectACount:int = 0;  
    private var objectBCount:int = 0;  
    private var objectCCount:int = 0;  
    private var replayCount:int = 0;
    protected var _earnedPoints:int; 
    private var myPlayerClient:PlayerClient = new PlayerClient();  
}

public function Player()  
{  
    super();  
}

public override function create():void  
{  
    super.create();  
    listenWhileVisible(this, ContactEvent.BEGIN_CONTACT, handleContact);  
    contacts = new ContactList();  
    contacts.listenTo(this);  
}

public function handleContact(e:ContactEvent):void   
{  
    //Detect collison with other static objects  
    var myObjectA:objectA = e.other.m_userData as objectA;  
    var myObjectB:objectB = e.other.m_userData as objectB;  
    var myObjectC:objectC = e.other.m_userData as objectC;  
    var myObstacle:obstacle = e.other.m_userData as obstacle;       

    if(myObjectC)   
    {
        objectCCount++;  
        myObjectC.remove();  
        if (objectCCount > 0)  
        {  
           bonusPoints = bonusPoints + 5;                   
        }               
    }

    else if(myObjectA) 
    {
        objectACount++;
        myObjectA.remove();
        if (objectACount > 0)
        {
           onePoint = onePoint + 1;                         
        }
    }

    else if(myObjectB) 
    {
        objectBCount++;
        myObjectB.remove();
        if (objectBCount > 0)
        {
          twoPoints = twoPoints + 2;                            
        }
    }       
    else if(myObstacle)
        {               
        var myEarnedPoints:int = myPlayerClient.totalEarnedPoints;
        _earnedPoints = bonusPoints + onePoint + twoPoints + myEarnedPoints;
        dispatchEvent(new Event("EarnedPointChanged"));

        myLoader = new SWFLoader("myMovie.swf",{container:swfHolder,alpha:0,onComplete:completeHandler});
       //adds the loader content to the display list before raw content is loaded.
       addChild(myLoader.content);
       stop();
       myLoader.load();

       function completeHandler(e:LoaderEvent):void
       {
          replayCount++;

          if (replayCount <= 1)
          {
                TweenMax.to(e.target.content, 1, {alpha:1});
                mcTemp = myLoader.rawContent;
                mcTemp.gotoAndPlay(1);
          }
          else if (replayCount >= 1)
          {
                mcTemp = myLoader.rawContent.stop();
                myLoader.unload();
                mcTemp = null;  
          }

       }
       myObstacle.remove();

     }              

}

public function get earnedPoints():int  
{  
     return _earnedPoints;  
}  
}

CLASS PlayerClient

package  
{

public dynamic class PlayerClient extends MovieClip
{
    private var _totalEarnedPoints:int;
    protected var _player:Player;

    public function get player():Player
    {
        return _player;
    }

    public function set player(value:Player):void 
    {
        if (value != _player) 
        {
            if (_player) 
            {
                //[prevent memory leaks][2]
                _player.removeEventListener("EarnedPointChanged", updatePlayerScore);
                //don't need this if we don't have a player
                removeEventListener(Event.REMOVED_FROM_STAGE, cleanUp);
            }
            _player = value;
            if (_player) 
            {
                //listen for changes
                _player.addEventListener("EarnedPointChanged", updatePlayerScore);
                //we added a listener to the new player, need to make sure is removed
                addEventListener(Event.REMOVED_FROM_STAGE, cleanUp);
            }
        }
    }

    protected function cleanUp(e:Event):void 
    {
        _player.removeEventListener("EarnedPointChanged", updatePlayerScore);
    }


    protected function updatePlayerScore(e:Event):void 
    {
        _totalEarnedPoints = _player.earnedPoints;

    }


    public function get totalEarnedPoints():int
    {
        return _totalEarnedPoints;
    }
}
} 
4

2 に答える 2

1

まず、あなたのプロジェクトがバナーや、2 日間作業して二度と見ないという 100% のことを知っているものでない限り、あなたがしていることはあなたを傷つける世界を引き起こします。http://misko.hevery.com/code-reviewers-guide/flaw-brittle-global-state-singletons/を参照してください。

認識する必要があるのは、Points.pointsEarned は、Player の新しいインスタンスを作成した場合にのみ変化するように見えることです。また、複数のプレーヤーがいる場合、新しい各 Player は、最初からより多くのポイントを取得します。一つ前。それはおそらくあなたが望むものではありません。あなたは自分が何を望んでいるのかを実際には語らないので、あなた望む可能性のあるものを 1 つ挙げて、それをどのようにコーディングするかを説明させてください。それが正しくない場合は、そこから行きます。

編集:

これで、獲得したポイントを増やすことができるようにしたいことがわかったので、このクラスははるかに単純になりました (投稿の改訂履歴をチェックして、削除された部分を確認してください)。

package{
  public class Player extends EventDispatcher {
    protected var _earnedPoints:int;
    public function Player() {
       super();//not passing a parameter, so target of events will be this
    }
    public function get earnedPoints():int {
       return _earnedPoints;
    }
    public function set earnedPoints(value:int):void {
       if (value != _earnedPoints) {
          _earnedPoints = value;
          //other Classes can listen for this to see if earnedPoints has changed:
          dispatchEvent(new Event('earnedPointsChanged');
       }
    }
  }
}

この部分については質問されていませんが、理解する必要がある部分だと思います。わかりにくい場合に備えて説明します。「オブジェクト」には、独自のクラスが必要です。

package {
   class TargetObject extends MovieClip {
      public var points:int;
   }
}

これらの値は、各 TargetObject の作成時に設定することも、値がハードコーディングされているいくつかのサブクラスを作成することもできます。

したがって、衝突が発生するたびに、次のようなことができます。

_player.earnedPoints += target.points;

その変数を設定すると、別のクラスから設定されている場合でも、PlayerClient が更新されます。

要約すると、他のインスタンスが自身を更新するためにリッスンできるイベントを生成する必要があります。

package {
   public class PlayerClient extends MovieClip {
      public var playerScoreText:TextField;//assume this is on stage
      protected var _player:Player;
      //assume [dependency injection][1] 
      public function get player():Player {
         return _player;
      }
      public function set player(value:Player):void {
         if (value != _player) {
            if (_player) {
               //[prevent memory leaks][2]
               _player.removeEventListener('earnedPointsChanged', updatePlayerScore);
               //don't need this if we don't have a player
               removeEventListener(Event.REMOVED_FROM_STAGE, cleanUp);
            }
            _player = value;
            if (_player) {
               //listen for changes
               _player.addEventListener('earnedPointsChanged', updatePlayerScore);
               //we added a listener to the new player, need to make sure is removed
               addEventListener(Event.REMOVED_FROM_STAGE, cleanUp);
            }
         }
      }
      protected function cleanUp(e:Event):void {
          _player.removeEventListener('earnedPointsChanged', updatePlayerScore);
      }
      /* This will trigger no matter what changes the value of
         earnedPoints or bonusPoints.
      */
      protected function updatePlayerScore(e:Event):void {
          if (playerScoreText) /*in case it wasn't put on stage */ {
              playerScoreText.text = _player.earnedPoints
          }
      }
    }
}
于 2012-10-09T01:38:20.833 に答える
0

自分で質問を解決しました。SharedObjectメソッドを使用してポイントを保存し、ポイント値をクラスPlayerに取得して蓄積しました。EventDispatcherはポイントを他のクラスに渡しましたが、プレーヤーが障害物にぶつかってゲームがリプレイされると、すべてのポイント値が初期状態に戻ります。そのため、他のクラスに渡したポイントをクラスのプレーヤーに戻すことは困難です。累積。SharedObjectメソッドは、ケーススタディでこの問題を解決するのに役立ちました。

于 2012-10-16T15:56:52.360 に答える