0

这是我的问题。在我的文档类 TowerDefenseGame.as 中,我定义了一个变量 Turrent1Flag:

package 
{
import flash.display.MovieClip;
import flash.events.*;
import flash.display.Sprite;
import flash.display.Shape;
import flash.text.TextField;
import flash.text.TextFormat;
import flash.text.TextFieldType;

public class TowerDefenseGame extends MovieClip
{
       public var Turrent1Flag==0;
}

public function TowerDefenseGame()
{
  ......
}

现在,在另一个类 Turrent1Button.as 中,我需要创建一个鼠标单击事件,通过该事件将 Turrent1Flag 设置为 1:

package 
{
import flash.display.MovieClip;
import flash.events.*;
import flash.display.Sprite;
import TowerDefenseGame;

public class TurretButton1 extends MovieClip
{
    public var ButtonBase:Sprite=new Sprite();
    public var TurretBase:Sprite=new Sprite();
    public var Gun:Sprite=new Sprite();

    public function TurretButton1()
    {
               ......
       this.addEventListener(MouseEvent.CLICK, MouseClick);
    }

    public function MouseClick(event:MouseEvent):void
    {
        MovieClip(root).Turret1Flag = 1;
    }

好吧,这行不通。我正在使用 Adob​​e flash cs6,它说无法访问该值。有人知道怎么做吗?

4

3 回答 3

1

因此,首先,AS3 让您在 AS2 中习惯做的事情变得困难,以允许更好的面向对象实践。当您在班级之间保持高而紧密的墙壁时,更改A班变得更容易,而不会对B班产生任何影响。B班只知道门窗是进入A班房屋的“官方”通道,所以移动沙发没关系。您还可以非常轻松地将具有相似门窗的 C 类替换为 A 类。

当你通过引入全局状态来穿墙时,你不能在不改变 A 类的情况下用 C 类替换 B 类,因为 A 类直接引用 B 类并且知道沙发在哪里。

处理此问题的一种方法是通过控制反转(IoC)。因此,对于我们的房子,沙发可能是从外部提供的,并且提供的任何组件都可能保留对它的引用,因此无论它在房子的哪个位置,它都可以访问沙发。因此,您可以选择创建您的TurretButton并将其传递给拥有它的任何人,同时您TowerDefenseGame保留对它的引用并直接收听它,并更改其自己的标志以响应点击。

查看您的代码,您可能不需要走那么远,因为我没有看到任何迹象表明您TurretButton实际上是嵌套的。在这种情况下,您可以直接收听它,无论您是在舞台上创建它还是通过代码创建它(我不喜欢)。如果您在 IDE 中使用舞台并且它存在于舞台上,那么只需创建一个类型的公共变量TurretButton(或者您可能可以使用SimpleButton,因为您不再需要基于您显示的代码的特殊类)。该实例将在您的构造函数中可用TowerDefenseGame. 只需将您的事件侦听器添加到其中,然后侦听器和您要更改的变量在同一范围内。因此,你试图解决的问题从来不存在——你只是从一个过于复杂的角度看待问题。

实际上,如果您的代码以一种未显示的方式嵌套,您可以使用 ActionScript 3 的事件系统(非常棒)来处理该问题,而无需引入直接耦合,也无需通过代码创建按钮并将其下推到它在哪里使用。一种方法是只监听任何鼠标点击(因为这是一个冒泡事件)并查看点击了什么。另一种解决方案是从按钮生成自定义事件,然后您可以从顶层监听该事件以更改标志。这看起来像:

包视图.按钮 {
   公共类 TurretButton 扩展 MovieClip {
      公共功能炮塔按钮(){
         极好的();
         mouseChildren = 假;
         addEventListener(MouseEvent.CLICK, broadcastTurretEvent);
      }
      受保护的函数broadcastTurretEvent(e:Event):void {
         dispatchEvent(new Event('turretClicked', true));//true参数让它冒泡
      }
   }
}

然后你的塔类看起来像

包裹 {
   公共类 TowerDefenseGame 扩展 MovieClip {
      //您将其称为 Turret1Flag 的事实表明您将拥有超过 1 个
      protected var turretFlags:Array /*of Boolean*/ = [false, false];
      //你的炮塔按钮实例  
      //不显示嵌套,这只是为了表明
      //这些是命名实例,因此您知道它们的名称
      //它们可以嵌套在任何级别    
      public var turret1:TurretButton;
      public var turret2:TurretButton;
      //...ETC。
      公共功能塔防游戏(){
         极好的();
         addEventListener('turretClicked', onTurretClicked);
      }
      受保护的功能 onTurretClicked(e:Event):void {
         //你也可以只提取数字并做数学运算
         //获取正确的数组索引
         开关(e.target.name){
            案例“炮塔1”:
               turretFlags[0] = !turretFlags[0];
               休息;
            案例“炮塔2”:
               turretFlags[1] = !turretFlags[1];
               休息;
         }
      }
   }
}

请注意这是如何扩展的。您不必为每个按钮设置不同的类来更改每个单独的标志。无需大量代码更改即可添加更多按钮。您可以进一步采用此解决方案并创建一个自定义事件,该事件具有一个属性,说明单击了哪个按钮,并且您可以通过依赖注入等提供用于该按钮的值。

我还在我的代码中假设标志应该是布尔值,并且它们在第一次单击时打开,在第二次单击时关闭,等等。您可以采用相同的想法并将其更改为,例如,每增加一次点击。我怀疑您实际上并不想执行您的代码显示的操作,只需单击一下就将其打开,然后永远保持打开状态。

另一个注意事项是,如果您认为您可能希望长期使用 AS3 进行编码,您可能应该学习 AS3 中使用的编码约定。其中之一是类名以大写字母开头,而属性和方法则不是。

于 2013-03-03T16:10:51.110 回答
1

尝试这个:

private static var _instance:TowerDefenseGame;
public static function get instance():TowerDefenseGame { return _instance; }

public function TowerDefenseGame() 
{
    _instance = this;
}

public function MouseClick(event:MouseEvent):void
{
       TowerDefenseGame.instance.Turret1Flag = 1;
}
于 2013-03-02T23:30:29.753 回答
0

对所有事情都习惯性可能不是一个好习惯,但是静态变量看起来可以在这里工作。

public class TowerDefenseGame extends MovieClip
{
    public static var Turrent1Flag = 0;
}

在 Turrent1Button.as 中:

public function MouseClick(event:MouseEvent):void
{
    TowerDefenseGame.Turret1Flag = 1;
}
于 2013-03-03T00:13:40.193 回答