关于这个问题有很多问题,所以想知道我是否真的无法访问其他对象 所以我要说我有一个导弹类。
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不被视为对象,因为它只是一个文件?
或者有办法解决这个问题吗?
答案 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
类。
也许你在询问时并不知道正确的术语。但理解对象和类之间的区别实际上很重要。
如果有的话,你试图访问Ship
类的对象,而不是类本身。但问题仍然存在,为什么它不起作用。答案就是范围。使用实例名称ship
自动声明的变量在主时间轴(Main
类)上声明。这与Missile
课程分开。
看看您使用missiles
数组做了什么:
您在Ship
类声明它:
public class Ship extends MovieClip {
public var missiles:Array;
然后您尝试在该类的对象上访问它:
ship.missiles
现在为什么你认为ship
本身有所不同?您也不希望直接访问missiles
!就像你missiles
在某个对象中而你需要该对象才能到达missiles
一样,ship
本身也是如此:你需要它所居住的对象才能访问它。
你基本上都在问&#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这有帮助!