2014-05-18 5 views
0

나는 avoider 게임 자습서를 따르고 있으며 클래스의 모든 부분에서 업데이트 할 가치가없는 것처럼 보입니다. 나는 그것이 10 씩 증가하지만, 'updateDisplay'의 'CurrentValue에'내부의 추적에 의해 업데이트하고 'addToValue'의 'CurrentValue에'내부에 대한 추적을 실행 할 때마다AS3에서 변수 업데이트

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; 
    } 
} 
} 

는 항상 내가 절대적으로 할 수있는 0의 값을 갖는다 'currentValue'가 다른 것을 업데이트하지 않는 이유를 파악하지 못합니다.

EDIT 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); 
    } 
} 

} 

addToValueupdateDisplay 편집 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) 

     } 
    } 


} 

} 
+0

이 '점수'클래스를 사용하는 코드를 게시하십시오. –

+0

업데이트 됨.코드가 실행되고 오른쪽 상단에 "0"이 표시됩니다. – windigo

+0

게시 한 코드에서 'score.addToValue'가 호출되지 않습니다. –

답변

1

아니라 인스턴스 변수에 TextFields 추출하고 init 방법에 추가. 값은 명시 적으로 설정되어야합니다. ActionScript 3에서는 제공되지 않는 암시적인 데이터 흐름을 기대하고 있습니다. 다른 방법으로는 이벤트가 될 것입니다.하지만 이는 메서드를 사용하는 것뿐입니다.

처음에는 알림 전용 이벤트를 만듭니다. ActionScript의 아키텍처 아이디어에 익숙해지면 바로 사용할 수 있습니다. 이것은 물론 일반화 될 수는 없지만 접근 자 (get score)와 변형 자 (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); 
    } 
    } 
} 

는 그럼, 액세스 할 외부 세계에 접근 할 수없는 수 있어야 무엇을 확장하고 액세스 할 수 있어야 무엇을 확장해야하는지 액세스 할 수 있도록, 코드의 일부를 리팩토링. 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(); 
    } 
    } 
} 
  • 접근이 값이 로깅 또는 디버거에 의해 변경 될 때 쉽게 이해할 수 있습니다, 가져 오기/설정 방법으로 만 가능합니다.
  • _scoreTextField은 보호되어 있으므로 하위 클래스를 확장하여 수정할 수 있습니다.
  • addToScore은 표시를 업데이트하는 score 속성을 수정합니다.
  • updateDisplayListscore이 변경된 경우에만 호출됩니다. 이렇게하면 무슨 일이 일어나는지 쉽게 알 수 있습니다.

내 코드는 Flash의 모든 사용자 인터페이스 관련 프로그래밍의 98 %에서 매우 유용 할 수있는 특정 패턴이 있음을 보여주기 위해 Flex 구성 요소 라이프 사이클의 저렴한 복사본입니다. 반대로

, 당신의 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; 
    } 
    } 
} 

에 리팩토링 할 수 그러나 그 코드는 정말 확장하지 않고 게임이 더 중요한 무엇을 더 복잡 얻을 때 당신을 필요로 더 많은 변화를 요구한다 구성 요소를 확장 할 때 훨씬 더 생각하십시오.

조금 도움이 되었기를 바랍니다.

+0

textfileds를 추출하고 명시 적으로 설정하는 것에 대해 더 자세히 설명 하시겠습니까? 죄송합니다, AS3에 새로 온 것입니다 – windigo

+0

너무 좋지 않았 으면 좋겠습니다. :) –

+0

아니, 이거 놀랍다. 두 가지 예가 위에 있습니다. 정말 고맙습니다. – windigo