无法从另一个对象访问对象属性

时间:2015-09-07 17:10:44

标签: actionscript-3 flash object

关于这个问题有很多问题,所以想知道我是否真的无法访问其他对象 所以我要说我有一个导弹类。

public class Missile extends MovieClip {

...

public function update(e:Event) {
    x += speed;

    if (notInScreen()) this.remove();

    for (var i in Main.instance.enemies) {
        if (hitTestObject(Main.instance.enemies[i])) {
            Main.instance.enemies[i].explode();
            this.remove();
        }
    }
}

public function remove() {
    this.parent.removeChild(this);
    ship.missiles.splice(0,1);      // <--- error
}

}

当它调用remove()函数时,它会尝试访问Ship类,我已将Ship放在舞台上并命名其实例ship。但我仍然得到错误1120:访问未定义的属性船 船只包含导弹阵列

public class Ship extends MovieClip {
    public var missiles:Array;

和Main包含敌人阵列

public class Main extends MovieClip {
    public var enemies:Array;

但是Main.instance.enemies有效,这是否意味着Main不被视为对象,因为它只是一个文件? 或者有办法解决这个问题吗?

3 个答案:

答案 0 :(得分:0)

当然你会得到那个错误,因为在你的Missile类中你不能像这样访问舞台中的对象。

要使用ship对象,您可以执行以下操作:

MovieClip(root).ship.missiles.splice(0, 1);

或者,如果你的Missile被添加到舞台上,你可以写下来:

MovieClip(this.parent).ship.missiles.splice(0, 1);

希望可以提供帮助。

答案 1 :(得分:0)

简而言之,你所做的是不好的做法。它不是Missile对象关注的问题,而是将它自身从它存储的某些数据结构中移除,然后再将其自身销毁。我将在下面解释如何进一步说明,但首先回答你的问题:

为什么一件事不起作用

  

当它调用remove()函数时,它会尝试访问Ship类,我已将Ship放在舞台上并命名其实例ship

不,它没有访问Ship类。

  1. 在舞台上放置船只会创建该类的对象
  2. 为其指定实例名称会在幕后创建变量 对象的引用
  3. 也许你在询问时并不知道正确的术语。但理解对象和类之间的区别实际上很重要。

    如果有的话,你试图访问Ship类的对象,而不是类本身。但问题仍然存在,为什么它不起作用。答案就是范围。使用实例名称ship自动声明的变量在主时间轴(Main类)上声明。这与Missile课程分开。

    看看您使用missiles数组做了什么:

    1. 您在Ship类声明它:

      public class Ship extends MovieClip {
          public var missiles:Array;
      
    2. 然后您尝试在该类的对象上访问它:

      ship.missiles
      
    3. 现在为什么你认为ship本身有所不同?您也不希望直接访问missiles!就像你missiles在某个对象中而你需要该对象才能到达missiles一样,ship本身也是如此:你需要它所居住的对象才能访问它。

    4. 你基本上都在问&#34;嘿,我给了我这艘船的导弹!&#34;答案是&#34;什么船?&#34;,因为你不清楚你的意思是什么。您从未在ship类中声明变量Missile正在制作快捷方式,它应该以某种方式访问​​主时间轴上的ship变量,但它们完全是分开的。在项目中使用相同的名称可以诱骗你进入这样的谬误。您也可以尝试访问bananas课程中的Missile,该课程也不会发挥作用,但更明显的是它是其他内容。

      为什么其他的东西有效

        

      但是Main.instance.enemies有效,这是否意味着Main不被视为对象,因为它只是一个文档?

      没有&#34;只是一个文件&#34;。 Main只是另一个类。当它被用作文档类时有一些特性,但这些在这里并不重要。

      Main.instance.enemies的工作原理如下。 正如我在上面解释的那样,变量存在于对象中(反过来又可以被生活在对象中的变量引用)

      因此,您需要对对象的引用才能访问其中的变量。 Missile类,因此从它派生的对象都没有这个引用。 (是的,这正是错误所说的)。

      问题是:你如何以某种方式将ship对象引用到Missile对象中?

      一种不错的方法是将引用传递给Missile构造函数:

      public class Missile extends MovieClip 
      {
          private var ship:Ship;
      
          public function Missile(ship:Ship)
          {
              // error handling when ship is null is omitted here
      
              this.ship = ship;
          }
      

      当您创建Missile类的实例时,您将ship的实例传递给它:

      var missile:Missile = new Missile(ship);
      
        

      免责声明以下是解释您的代码中发生了什么。需要明确的是:这是非常糟糕的编码实践。你应该从不这样做。重要的是要了解它的工作原理。重要的是要理解为什么它不好。

      static个关键字。在整个答案中,必须通过从该类创建的对象访问类定义的所有变量。

      如果变量是static,则它与对象无关,而与类本身无关。如果某些东西真的可以与单个对象相关联,那就非常有趣,例如常量:

      • Math.PI
      • MouseEvent.MOUSE_DOWN

      每个对象不必存在一次。由于类的static变量与类而不是其对象相关联,因此可以通过类名访问此static变量。

      这就是其他界限发挥作用的地方:

        

      Main.instance

      通过类名访问

      instance,这意味着它是static变量。这意味着Main类有一个静态变量(或者也可能是一个函数),它保存对其中一个对象的引用。

      通过static机制,对象的引用变得全局可用,因为类名在任何地方都可用。 这就是如何偷偷地将一个对象引用到一个它不应该实际进入的地方。 这是此解决方案的不良部分。全局可用的东西没有很好地封装。每个人都可以访问和修改它,这会导致滥用。

      怎么做

      同样,问题是您需要引用某个对象才能使用它来执行操作,例如执行一些碰撞检测。

      最好的办法是先了解属于哪里。虽然可以理解Ship类有一个包含所有missiles的数组,但在Main中使用该数组要容易得多。这是因为导弹对象本身独立于船只,无论如何它们都被添加到主时间线上。

      public class Main extends MovieClip {
          private var missiles:Array;
          private var enemies:Array;
      

      如果你考虑一下,船与导弹之间唯一真正的联系就是船是它们产生的地方。

      现在,您可以轻松地从Missile类生成新的Main对象,并将这些对象提供给数组。

      最重要的是,您现在可以将两个阵列放在一个位置,并且可以Main 中执行碰撞检测。对于什么代码应该去哪里(如果敌人测试导弹或导弹测试敌人?)这一切都发生在所有对象的所有引用都可用的地方。没有滥用static

答案 2 :(得分:-1)

我不知道为什么你可以做'Main.instance.enemies'但是,你需要进入舞台。
你能用以下几种方式做到这一点:

第一种方式:从显示对象访问时:

this.parent;

第二种方式:从类的实例访问时:

this.root.stage

第三种方式:推动阶段作为类实例的参数:

var class:Class1=new Class1(stage);

在班上:

public class class1{
    var mainStage:object;
    public function class1(stage:Object){
    mianStage=stage;
}

IH☺PE这有帮助!