2012-10-09 19 views
1

我相當新的AS3,所以請原諒我,如果我的問題看起來很愚蠢。如何在類中設置其值時更新類中的變量?

讓我澄清一下我特別想要的:玩家繼續執行任務,當他在途中捕捉到一些物體時,他可以獲得積分,例如物體A給出一個點,物體B給出兩個點,物體C給予獎勵積分等......如果玩家在途中遇到一些障礙,他就無法完成任務,他必須重放比賽直到他到達目的地(關卡結束)。

所以我想要的是如何在玩家遇到障礙物之前存儲玩家獲得的積分,並且每次玩家必須重放遊戲直到達到遊戲級別結束時積累的積分所以玩家獲得的總積分將是所有積分的總和,包括他在實際達到遊戲結束前獲得的積分。

My Class Player是屬於框架WCK的類Box的子類。有沒有辦法讓我正確地實施依賴注入以將變量傳遞給另一個類來存儲它們?

非常感謝您的幫助!

ADDED:下面是我基於Amy的例子實施的一些調整,以適應我的遊戲設置。它仍然不起作用,因爲當我嘗試在Class Player中檢索它時,變量_totalEarnedPoints的值未通過EventDispatcher更新Class PlayerClient中的變量_earnedPoints以累積所有點。我不確定我做錯了什麼或錯過了其他什麼?任何人都可以請指出並告訴我如何從Class 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; 
    } 
} 
} 

回答

0

我得到了我的問題由自己解決的:我用共享對象的方法來存儲點,然後檢索點值返回到我的班級玩家進行積累。 EventDispatcher並沒有將這些分數傳遞給另一個分類,但是一旦玩家擊中了障礙物並且重玩了遊戲,所有的分數值都會回到初始狀態,這使得很難將我傳遞給其他分類的分數返回到類Player積累。 SharedObject方法確實幫助我解決了我的案例研究中的這個問題。

1

首先,你在做什麼事情給你造成傷害的世界,除非你的項目,你知道橫幅或東西100%,你將工作2天,永遠不會再看。請參閱http://misko.hevery.com/code-reviewers-guide/flaw-brittle-global-state-singletons/

您需要認識到的是,您的Points.pointsEarned看起來只會在您創建Player的新實例時發生改變,並且如果您有多個玩家,則每個新玩家的點數都會更高開始比以前。這可能不是你想要的。你並沒有真正說出你想要的是什麼,所以讓我拋出一件你可能想要的東西,並告訴你如何編碼它。如果這不對,我們會從那裏開始。

編輯:

好了,現在我們知道,你希望能夠只遞增獲得的積分,所以現在這個類變得簡單多了(檢查後的修訂歷史記錄查看部分被移除的內容, ):

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 
      } 
     } 
    } 
} 
+0

我知道我的代碼出了問題,因爲我是新的AS3,所以請耐心等待......我對您的代碼有疑問,我不知道是否可以在我的案例中應用:由於我基於[WCK](http://www.sideroller.com/wck/)的框架構建了我的遊戲,類Player是類Box的子類,它是如何在框架WCK中構建的。我真的不知道如何使類Player成爲EventDispatcher的子類,就像您在代碼中執行的一樣,以分派事件。我可以導入flash.Event。*而不是實現你的代碼?非常感激! – Teresa

+0

我修改了上面的問題,以便您可以清楚地看到我想要的內容。我確實想像你那樣實施依賴注入來以一種乾淨的方式正確地工作。所以我非常感謝你幫助我解決問題。 – Teresa

+0

如果您走過依賴關係樹,則Box最終是MovieClip的一個子類,它是一個EventDispatcher。 –

相關問題