2013-02-11 50 views
0

我有一個小型項目,我正在嘗試幫助學習as3。這是一個從基礎遊戲設計與ActionScript 3.0的變化。我只使用fla來創建文檔類。所有藝術品都被加載爲文件。在這本書中,他只是把所有的代碼都放在了文檔類中,隨後我就按照預期工作。我試圖將代碼分解成單獨的類來獲得OOP的句柄。一個類創建背景 - Background.as,一個創建角色 - Character.as,另一個創建一個按鈕,我爲6個不同的按鈕實例化了6次 - GameButton.as。當然還有GameWorld.as,它是文檔類。一切都按預期加載並顯示。但是,當我嘗試添加按鈕的eventListener時,我沒有得到任何迴應。我曾嘗試在GameButton.as中放置eventListener,並且在GameWorld.as中嘗試了它,但都沒有成功。另外,我在實例化各個類時傳遞了對舞臺的引用,因爲當我嘗試在GameWorld.as中添加addChild時,什麼也不會顯示出來。我搜索了這個網站,發現了類似的東西,但似乎沒有幫助。提前感謝您提供我的任何建議。下面是代碼:在主文檔類中爲外部類添加eventlisteners

GameWorld.as

package 
{ 
    import flash.net.URLRequest; 
    import flash.display.Loader; 
    import flash.display.Sprite; 
    import flash.display.DisplayObject 
    import flash.events.MouseEvent; 
    import GameButton; 
    import Character; 
    import Background; 

    [SWR(width = "550", height = "400", backgroundColor = "#FFFFFF", frameRate = "60")] 

    public class GameWorld extends Sprite 
    { 
     //public variables 
     //Background 
     public var gameBackground:Background; 

     //Character 
     public var catCharacter:Character; 

     //Buttons 
     public var upButton:GameButton; 
     public var downButton:GameButton; 
     public var growButton:GameButton; 
     public var shrinkButton:GameButton; 
     public var vanishButton:GameButton; 
     public var spinButton:GameButton; 

     public function GameWorld() 
     { 
      //Add the background to the stage 
      gameBackground = new Background("../images/background.png", stage); 

      //Add the character(s) to the stage 
      catCharacter = new Character("../images/character.png", stage); 

      //Set initial character position 
      catCharacter.CharacterPos(225, 150); 

      //Add the buttons to the stage 
      upButton = new GameButton("../images/up.png", stage, 25, 25); 
      downButton = new GameButton("../images/down.png", stage, 25, 85); 
      growButton = new GameButton("../images/grow.png", stage, 25, 145); 
      shrinkButton = new GameButton("../images/shrink.png", stage, 425, 25); 
      vanishButton = new GameButton("../images/vanish.png", stage, 425, 85); 
      spinButton = new GameButton("../images/spin.png", stage, 425, 145); 

      //Button event handlers 
      upButton.addEventListener(MouseEvent.CLICK, upButtonHandler); 

     } 


     public function upButtonHandler(event:MouseEvent) 
     { 
      trace("You clicked the up button!"); 
      catCharacter.CharacterMove(15); 
     } 

    } 

} 

GameButton.as

package 
{ 
    import flash.net.URLRequest; 
    import flash.display.Loader; 
    import flash.display.Sprite; 
    import flash.display.Stage; 
    import flash.events.MouseEvent; 

    public class GameButton extends Sprite 
    { 
     //public variables 
     public var stageRef:Stage; 
     public var urlRequest:URLRequest; 
     public var gameButtonLoader:Loader; 
     public var gameButtonSprite:Sprite; 

     //Constructor 
     public function GameButton (urlRequest:String, stageRef:Stage, xPos:Number, yPos:Number) 
     { 
      this.stageRef = stageRef 

      this.urlRequest = new URLRequest(); 
      gameButtonLoader = new Loader(); 
      gameButtonSprite = new Sprite(); 

      this.urlRequest.url = urlRequest; 
      gameButtonLoader.load(this.urlRequest); 
      gameButtonSprite.addChild(gameButtonLoader); 
      this.stageRef.addChild(gameButtonSprite); 

      gameButtonSprite.buttonMode = true; 

      gameButtonSprite.x = xPos; 
      gameButtonSprite.y = yPos; 
     } 

    } 

} 

Character.as

package 
{ 
    import flash.net.URLRequest; 
    import flash.display.Loader; 
    import flash.display.Sprite; 
    import flash.display.Stage; 

    public class Character 
    { 
     //private variables 
     private var stageRef:Stage; 
     private var urlRequest:URLRequest; 
     private var characterLoader:Loader; 
     private var characterSprite:Sprite; 

     //public variables 
     public var character_x_pos:Number; 
     public var character_y_pos:Number; 

     //Constructor 
     public function Character (urlRequest:String, stageRef:Stage) 
     { 
      this.stageRef = stageRef; 
      this.urlRequest = new URLRequest(); 
      characterLoader = new Loader(); 
      characterSprite = new Sprite(); 

      this.urlRequest.url = urlRequest; 
      characterLoader.load (this.urlRequest); 
      characterSprite.addChild (characterLoader); 
      this.stageRef.addChild (characterSprite); 
      characterSprite.mouseEnabled = false; 
     } 

     //Set the position of the character 
     public function CharacterPos(xPos:Number, yPos:Number):void 
     { 
      characterSprite.x = xPos; 
      characterSprite.y = yPos; 
     } 

     //Move the position of the character 
     public function CharacterMove(yPos:Number):void 
     { 
      characterSprite.y -= yPos; 
     } 

    } 

} 

Background.as

package 
{ 
    import flash.net.URLRequest; 
    import flash.display.Loader; 
    import flash.display.Sprite; 
    import flash.display.Stage; 

    public class Background 
    { 
     //Private variables 
     private var stageRef:Stage; 
     private var urlRequest:URLRequest; 
     private var backgroundLoader:Loader; 
     private var backgroundSprite:Sprite; 

     //Constructor 
     public function Background (urlRequest:String, stageRef:Stage) 
     { 
      this.stageRef = stageRef; 
      this.urlRequest = new URLRequest(); 
      backgroundLoader = new Loader(); 
      backgroundSprite = new Sprite(); 

      this.urlRequest.url = urlRequest; 
      backgroundLoader.load (this.urlRequest); 
      backgroundSprite.addChild (backgroundLoader); 
      this.stageRef.addChild (backgroundSprite); 
      backgroundSprite.mouseEnabled = false; 
     } 

    } 

} 

回答

0

所有本領域是內裝入作爲文件。

這不是我推薦的方法。上帝給我們的Flash IDE有一個原因 - 它不是寫代碼!任何時候你花費在佈局和代碼中的個體都只是浪費了,除非你有實際的需求來改變運行時的視覺效果。你的路徑都是硬編碼的事實表明你沒有這個要求。

讓我們回過頭來想象一下,您有一個符號,其中包含6個已創建爲符號類型的Button(當您選擇Button作爲符號類型時)。這些將是SimpleButtons,但在下面的Class中,我們只是將它們鍵入爲DisplayObject。該類不關心它們是什麼,但使用Simplebutton放棄它們,結束,關閉並擊中不需要代碼的狀態。

請注意,下面假設您已經「自動聲明階段實例」關閉,這是IMO做事的最佳方式。

package view { 
    public class NavBar extends Sprite { 
     //because you put these on stage in the Symbol, they will be available in the constructor 
     public var upButton:DisplayObject; 
     public var downButton:DisplayObject; 
     public var growButton:DisplayObject; 
     public var shrinkButton:DisplayObject; 
     public var rotateButton:DisplayObject; 
     public var vanishButton:DisplayObject; 
     //makes it easier to do the same setup on all buttons 
     protected var allButtons:Vector.<DisplayObject> = <DisplayObject>([upButton, downButton, growButton, shrinkButton, rotateButton, vanishButton]); 
     public function NavBar() { 
     super(); 
     for each (var btn:DisplayObject in allButtons) { 
      btn.buttonMode = true; 
      btn.mouseChildren = false; 
      btn.addEventListener(MouseEvent.CLICK, onButtonClick); 
     } 
     } 
     protected function onButtonClick(e:MouseEvent):void { 
      switch (e.target) { 
      case upButton: 
       dispatchEvent(new CharacterEvent(CharacterEvent.UP)); 
       break; 
      case downButton: 
       dispatchEvent(new CharacterEvent(CharacterEvent.DOWN)); 
       break; 
      case growButton: 
       dispatchEvent(new CharacterEvent(CharacterEvent.GROW)); 
       break; 
      case shrinkButton: 
       dispatchEvent(new CharacterEvent(CharacterEvent.SHRINK)); 
       break; 
      case rotateButton: 
       dispatchEvent(new CharacterEvent(CharacterEvent.ROTATE)); 
       break; 
      case vanishButton: 
       dispatchEvent(new CharacterEvent(CharacterEvent.VANISH)); 
       break; 
      default: 
       break; 
      } 
     } 

    } 
} 

請注意,零布局代碼。此代碼依賴於自定義事件類。我要寫這個事件類,以便它始終冒泡。這樣一來,就可以在任何地方顯示列表上發出的,在頂層收到:

package control { 
    class CharacterEvent extends Event { 
     public static var UP:String = 'characterUp'; 
     public static var DOWN:String = 'characterDown'; 
     public static var GROW:String = 'characterGrow'; 
     public static var SHRINK:String = 'characterShrink'; 
     public static var ROTATE:String = 'characterRotate'; 
     public static var VANISH:String = 'characterVanish'; 
     public function CharacterEvent(type:String) { 
      super(type, true, true);//always bubbles 
     } 
     public function clone():Event { 
      return new CharacterEvent(type); 
     } 
    } 
} 

現在,如果你想手動處理有鑑於符號的實例。的NavBar作爲它的基類,它看起來就像這樣:

package { 
    public var navBar:NavBar; 
    class GameWorld { 
     public function GameWorld() { 
     try { 
      var navClass:Class = getDefinitionByName('NavBarSymbol') as Class; 
     } catch (e:Error) { 
      trace('You need to have a Library symbol called NavBarSymbol'); 
     } 
     if (navClass) { 
      navBar = new navClass() as NavBar; 
      //unnecessary layout code here 
      //Note that this is NOT the responsibility of the child Class! 
      addChild(navBar); 
     } 
     //instantiate character 
      ... 
     //by listening to the whole Document, you can add other things that 
     //dispatch Character events on the display list, like a keyboard listener 
     addEventListener(CharacterEvent.UP, moveCharacterUp); 
     //listeners for the rest of the character events... 
     } 
     public function moveCharacterUp(e:CharacterEvent):void { 
      //character move logic 
     } 
     //other handlers 
    } 
} 

就個人而言,我只是導航欄添加到舞臺,那麼就沒有必要在所有管理它(甚至不是一個變量引用它),只需爲各種角色事件添加事件偵聽器即可。

問題的根源似乎不是字符代碼。但是,我會給你一些關於它的「最佳實踐」指針。

  • AS3中的約定是用於類成員(屬性和方法)爲以小寫字母開頭的駱駝大小寫。所以,characterPos()characterMove()
  • 你的類已經包含名字中的字符,所以真的這些應該只是pos()move()(儘管現在不需要縮短position())。
  • 你的孩子類正在做的與他們對父母的引用做的唯一事情就是自己添加。爲此,他們不需要也不應該提及父母。這是父母的負責添加子項(或者如果您使用舞臺,則爲Flash Player的責任)。也就是說,你可以給你的角色一個父類的引用,這個類的類型是IEventDispatcher,並允許角色傾聽這個頻道。這個概念被稱爲event bus

請注意,許多人做你在做什麼的原因是Adobe未能記錄如何properly use OOP with the timeline。不幸的是,到了2009年底/ 2010年初我們幾個人的時候,損失已經完成,每個人都假設如果你想寫出好的代碼,你不得不假裝時間軸和舞臺不存在。

我知道我已經涵蓋了很多理由,可能大部分我所說的直接抵觸你認爲你知道的東西,所以請不要猶豫,問你可能有什麼問題。

+0

謝謝艾米,這很有道理。我只是盲目地遵循不使用Flash IDE的書。你的方法非常有幫助。 – user2063030 2013-02-12 16:12:29

+0

不客氣:) – 2013-02-12 16:23:18