2013-02-11 49 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