1

我对 AS3 很陌生,所以如果我的问题看起来很愚蠢,请原谅我。

让我澄清一下我具体想要什么:玩家执行一项任务,当他在途中抓到一些物体时,他将获得积分,例如物体 A 给一分,物体 B 给两分,物体 C 给加分,等等……如果玩家在途中遇到了一些障碍,他就会失败,他必须重新玩游戏,直到他到达目的地(关卡结束)。

所以我想要的是如何存储玩家在撞到障碍物之前获得的积分,并且每次玩家必须重玩游戏时累积获得的积分,直到他达到游戏关卡结束,这样总玩家获得的积分将是所有积分的总和,包括他在实际到达游戏关卡结束之前获得的积分。

My Class Player 是属于框架 WCK 的 Box 类的子类。有没有办法让我正确实现依赖注入以将变量传递给另一个类以便将它们存储在那里?

预先感谢您的帮助!

补充:这是我根据 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;
    }
}
} 
4

2 回答 2

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
          }
      }
    }
}
于 2012-10-09T01:38:20.833 回答
0

我自己解决了我的问题:我使用 SharedObject 方法存储积分,然后将积分值检索回我的类 Player 进行累积。EventDispatcher 确实将点传递给了另一个类,但是一旦 Player 撞到障碍物并且游戏重播,所有的点值都会恢复到初始状态,这使得很难将我传递给另一个类的点取回给 Player 类积累。SharedObject 方法确实帮助我解决了我的案例研究中的这个问题。

于 2012-10-16T15:56:52.360 回答