在AS3中更新变量

时间:2014-05-18 21:49:15

标签: actionscript-3 flash flashdevelop

我正在关注一个avoider游戏教程,似乎无法在我班级的所有部分获得更新值。

package  
{
import flash.display.Sprite;    
import flash.text.TextField
import flash.text.TextFormat


public class Score extends Sprite
{
    public var scoreDisplay:String;
    public var currentValue:int;

    public function Score() 
    {
        updateDisplay()
    }

    public function updateDisplay():void
    {

        scoreDisplay = currentValue.toString();

        var format:TextFormat = new TextFormat();
            format.size = 25;
            format.font = "Verdana"

        var myText:TextField = new TextField();
            myText.defaultTextFormat = format;
            myText.text = scoreDisplay;
            myText.background = true;
            myText.autoSize
            myText.width = 50;
            myText.height = 35;

        addChild(myText)
            myText.x = 340
            myText.y = 10
            myText.mouseEnabled = false
    }

    public function addToValue( amountToAdd:Number ):void
    {
        currentValue = currentValue + amountToAdd;
    }
}
}

每当我在'addToValue'中运行'currentValue'的跟踪时,它会以10的增量进行更新,但'updateDisplay'中'currentValue'的跟踪始终具有值0.我绝对无法弄清楚为什么一个'currentValue'没有更新另一个。

编辑1:

package  
{
import flash.display.Sprite;

public class Start extends Sprite
{
    public var game:Game;
    public var gameover:GameOver;
    public var background:Sprite;


    public function Start() 
    {
        background = new Sprite
        background.graphics.beginFill(0xC0C0C0)
        background.graphics.drawRect(0, 0, 400, 300)
        background.graphics.endFill();
        addChild(background)


        var score:Score = new Score()
        addChild(score)

        game = new Game();
        game.addEventListener(AvatarEvent.DEAD, startOver);
        addChild(game);
    }

    public function startOver(avatarEvent:AvatarEvent):void
    {
        game.removeEventListener(AvatarEvent.DEAD, startOver);
        gameover = new GameOver();
        gameover.addEventListener(NavigationEvent.RESTART, requestRestart);
        removeChild(game)
        addChild(gameover);
    }

    private function requestRestart(e:NavigationEvent):void 
    {
        restartGame();
    }

    public function restartGame():void
    {
        gameover.removeEventListener(NavigationEvent.RESTART, requestRestart);
        game = new Game();
        game.addEventListener(AvatarEvent.DEAD, startOver);
        addChild(game);

        removeChild(gameover);
    }
}

}

编辑2

package  
{
import flash.display.Sprite;
import flash.events.Event;
import flash.events.TimerEvent;
import flash.text.TextField;
import flash.text.TextFormat;
import flash.utils.Timer;

import Score;

public class Game extends Sprite
{
    public var army:Array;
    public var gameTimer:Timer;
    public var player:Player;
    public var background:Sprite;
    private var instanceScore:Score

    public function Game() 
    {           
        army = new Array();
        var newenemy:Enemy = new Enemy(100, -15);
        army.push(newenemy);
        addChild(newenemy);

        player = new Player();
        addChild(player);
        player.x = mouseX;
        player.y = mouseY;

        gameTimer = new Timer(20);
        gameTimer.addEventListener(TimerEvent.TIMER, move);
        gameTimer.addEventListener(TimerEvent.TIMER, onTick);
        gameTimer.start();

        instanceScore = new Score();
    }

    private function move(timerEvent:TimerEvent):void
    {

        player.x = mouseX;
        player.y = mouseY;

        for each (var enemy:Enemy in army)
        {
            enemy.moveDownABit();

            if (player.hitTestObject(enemy))
            {
                gameTimer.stop();

                dispatchEvent( new AvatarEvent( AvatarEvent.DEAD));

            }
        }
    }

    public function onTick(e:Event):void
    {
        if (Math.random() < .1)
        {
            var randomX:Number = Math.random() * 400;
            var newEnemy:Enemy = new Enemy(randomX, -15);
            army.push(newEnemy);
            addChild(newEnemy);

            instanceScore.addToValue(10)

            var score:Score = new Score()
            addChild(score)

        }
    }


}

}

1 个答案:

答案 0 :(得分:1)

addToValue调用updateDisplay中,还要将TextFields提取到实例变量,并将其添加到init方法中。必须明确设置值。您期望隐式数据流...在ActionScript 3中没有给出。另一种方式是事件......但这也只是使用方法。

首先,我会创建一个专门的通知事件。只要您更熟悉ActionScript中的架构概念,这就派上用场了。这可能是偏离一般的,但出于访问者(get score)和mutators(set score)的演示目的,这可能是一个好主意。

package {

  import flash.events.Event;

  public class ScoreChangeEvent extends Event {

    public static const SCORE_CHANGED:String = 'scoreChanged';

    private var _score:int;

    public function get score():int {
      return _score;
    }

    public function ScoreChangeEvent(score:int) {
      super(SCORE_CHANGED, true, false);
      this._score = score;
    }

    override public function clone():Event {
      return new ScoreChangeEvent(_score);
    }
  }
}

然后我重构了代码的某些部分,使可访问的内容成为可访问的,可扩展的,可扩展的和不可访问的内容,以及外部世界无法访问的内容。

package {

  import flash.display.Sprite;
  import flash.text.TextField;
  import flash.text.TextFormat;

  [Event(name="scoreChanged", type="ScoreChangeEvent")]

  public class ScoreDisplay extends Sprite {

    /** The text field displaying the score. */
    protected var _scoreTextField:TextField;

    /** The internal storage variable for score to display. */
    private var _score:int;

    /**
     * The score to be displayed. When the score changes,
     * a ScoreChangeEvent will be dispatched.
     *
     * @see ScoreChangeEvent#SCORE_CHANGED
     */
    public function get score():int {
      return _score;
    }

    public function set score(value:int):void {
      if (_score == value) {
        return;
      }
      _score = value;
      updateDisplayList();
      this.dispatchEvent(new ScoreChangeEvent(_score));
    }

    public function ScoreDisplay() {
      init();
    }

    /** Creation of children and initial rendering. */
    private function init():void {
      this.createChildren();
      this.updateDisplayList();
    }

    /**
     * DisplayObjects, which are one created once should be
     * created in a dedicated method.
     */
    protected function createChildren():void {

      if (!_scoreTextField) {
        const format:TextFormat = new TextFormat();
        format.size = 25;
        format.font = "Verdana";

        _scoreTextField = new TextField();
        _scoreTextField.defaultTextFormat = format;
        _scoreTextField.background = true;
        _scoreTextField.autoSize;
        _scoreTextField.width = 50;
        _scoreTextField.height = 35;
        _scoreTextField.x = 340;
        _scoreTextField.y = 10;
        _scoreTextField.mouseEnabled = false;

        addChild(_scoreTextField);
      }
    }

    /** Reset the display. */
    public function reset():void {
      this.score = 0;
    }

    /**
     * Adds a certain value to the current score.
     * @param value The calue to be added.
     */
    public function addToScore(value:int):void {
      score += value;
    }

    /**
     * Update the display when ever needed.
     * 
     * This method should never be triggered by an
     * different class, only be the instance itself
     * when a value changed.
     */
    protected function updateDisplayList() {
      this._scoreTextField.text = this.score.toString();
    }
  }
}
  • 只有通过get / set方法才能访问score,这样可以很容易地了解日志记录或调试器更改值的时间。
  • _scoreTextField受到保护,这意味着可以通过扩展子类来修改它。
  • addToScore将修改score属性,作为回报更新显示。
  • 仅在updateDisplayList更改时才会调用
  • score。这样可以很容易地理解发生了什么。

我的代码是Flex组件生命周期的廉价副本,只是为了说明某些模式在Flash中98%的用户界面相关编程中可能变得非常方便。

相反,您的class也可以简单地重构为

package {

  import flash.display.Sprite;
  import flash.text.TextField;
  import flash.text.TextFormat;

  public class ScoreDisplay extends Sprite {

    protected var scoreTextField:TextField;

    private var _score:int;

    public function get score():int {
      return _score;
    }

    public function set score(value:int):void {
      if (_score == value) {
        return;
      }
      _score = value;
      scoreTextField.text = _score.toString();
    }

    public function ScoreDisplay() {
      const format:TextFormat = new TextFormat();
      format.size = 25;
      format.font = "Verdana";

      scoreTextField = new TextField();
      scoreTextField.defaultTextFormat = format;
      scoreTextField.background = true;
      scoreTextField.autoSize;
      scoreTextField.width = 50;
      scoreTextField.height = 35;
      scoreTextField.x = 340;
      scoreTextField.y = 10;
      scoreTextField.mouseEnabled = false;

      addChild(scoreTextField);
    }

    public function addToScore(value:int):void {
      score += value;
    }
  }
}

但是,当游戏变得更加复杂并且更重要时,该代码不是真正可扩展的并且需要更多更改,这将需要您在扩展组件时进行更多思考。

我希望这有点帮助。