AS3-错误#1180:调用可能未定义的方法kill



这个让我疯狂了几个小时。我试图调用同一类中的方法kill();(在函数takeDamage()中),但它找不到

package classes.ship
{   
imports ...
public class Ship extends MovieClip
{
    var speed:Number;
    var shootLimiter:Number;
    public static var health:Number;
    public static var maxHealth:Number;
    public function initialize()
    {
        var stageReff:Stage = this.stage as Stage;
        stage.addEventListener(KeyboardEvent.KEY_DOWN, reportKeyDown);
        stage.addEventListener(KeyboardEvent.KEY_UP, reportKeyUp);
        stage.addEventListener("enterFrame", move);
    }
    //code
    public static function takeDamage(d):void
    {
        health -= d;
        if(health <= 0)
        {
            health = 0;
            kill();
        }
        Main.healthMeter.bar.scaleX = health/maxHealth;
    }
    public function kill():void
    {
        var boom = new Explosion();
        stage.addChild(boom);
        boom.x = this.x;
        boom.y = this.y;
        this.visible = false;
        //Main.gameOver();
    }
    //code
}   
}

var stageReff:Stage = this.stage as Stage;有关吗?

提前谢谢。

kill()是一个实例方法,但takeDamage是一个静态类方法。不能从静态类方法调用实例方法。只有当有实例引用可调用时,才能调用实例方法。

这是一款适用于年初的简单款!

您已经将函数"takeDamage"声明为静态方法,这意味着它不属于类Ship的特定实例,而是属于类本身。如果你是OOP的新手,静态方法和属性可能会有点令人困惑,但很容易通过一个快速的例子来解释:

类成员属性

在这个例子中,我们为Ship声明了一个新的Class定义,我们可以通过setSpeed()定义Ship实例的速度。

public class Ship {
    private var speed : Number;
    public function setSpeed(value : Number) : void {
        this.speed = value;
    }
    public function getSpeed() : Number {
        return this.speed;
    }
}

现在我们将创建几艘船并设置它们的速度:

var scoutShip : Ship = new Ship();
scoutShip.setSpeed(500);   // Scout's are fast!
var cargoShip : Ship = new Ship();
cargoShip.setSpeed(10);    // Cargo ships are sloooow.
trace("Scout Ship Speed: " + scoutShip.getSpeed());  // 500
trace("Cargo Ship Speed: " + cargoShip.getSpeed());  // 10

正如你从上面看到的,我们创建的每个新的Ship实例都可以有自己的速度-这是面向对象编程的基础(其中Ship是对象,它的速度是数据)。

静态特性

现在我们将创建另一个类,这次名为StaticShip,它使用静态属性,请注意static关键字的使用:

public class StaticShip {
    private static var speed : Number;
    public function setSpeed(value : Number) : void {
        this.speed = value;
    }
    public function getSpeed() : Number {
        return this.speed;
    }
}

由于speed属性是静态的,它在StaticShip的所有实例中共享;例如:

var scoutShip : StaticShip = new StaticShip();
scoutShip.setSpeed(500);   // So the scout should move at 500
var cargoShip : StaticShip = new StaticShip();
cargoShip.setSpeed(10);    // ... and the Cargo move at 10, as before
trace("Scout Ship Speed: " + scoutShip.getSpeed());  // 10
trace("Cargo Ship Speed: " + cargoShip.getSpeed());  // 10

请注意两个StaticShip是如何以10移动的——这是因为我们最后设置了"cargoShip"实例的速度——因为StaticShips中的"Speed"属性被声明为静态,它在该类的所有实例中共享。

现在,正如您可以在类中拥有静态属性一样,您也可以拥有静态函数。通常,当您调用Class的方法(即:setSpeed())时,您需要在实例(即:scoutShip.setSpeed(500);)上调用该方法,然而,静态方法允许您与给定类的其他静态成员交互,下面是另一个示例:

静态方法示例

public class StaticMethodShip {
    private static var speed : Number;
    // Note that setSpeed is now declared as static
    public static function setSpeed(value : Number) : void {
        this.speed = value;
    }
    public function getSpeed() : Number {
        return this.speed;
    }
}

现在,我们仍然可以像以前一样创建StaticMethodShip的新实例,但因为我们现在已经将"setSpeed"声明为静态,所以我们不能在实例上调用setSpeed:

var scoutShip : StaticMethodShip = new StaticMethodShip();
// This call will trigger Error #1180 - Call to a possibly undefined Method because
// setSpeed was declared as static.
scoutShip.setSpeed(500);

相反,我们现在只能调用StaticMethodShip类上的setSpeed()方法,即:

// Set the speed of all StaticMethodShip instances.
StaticMethodShip.setSpeed(250);    // all StaticMethodShips travel at 250.
// Proof!
var shipOne : StaticMethodShip = new StaticMethodShip();
var shipTwo : StaticMethodShip = new StaticMethodShip();
trace("ShipOne Speed: " + shipOne.getSpeed());  // 250
trace("ShipTwo Speed: " + shipTwo.getSpeed());  // 250

当你想定义给定类的所有实例的行为时,静态方法很有用(即:所有StaticMethodShips以指定的速度移动,所有淡出Tweens持续0.25秒,等等);但它们也用于常见的设计模式,如静态工厂方法

现在,由于您看到错误成员级别的方法能够调用静态方法,即:

public class StaticExampleOne {
    public static function getName() : String {
        return "Robbe";
    }
    public function traceName() : void {
        // traces 'Robbe'.
        trace(getName());
    }
}

在使用中(new StaticExampleOne().traceName())这很好——成员方法可以毫无问题地访问静态方法,但这不起作用:

public class StaticExampleTwo {
    private var name : String = "Robbe";
    public function getName() : void {
        return this.name;
    }
    public static function traceName() : void { 
        // Throws Error #1180.
        trace(getName());
    }
}

这是因为静态方法没有作用域(即:它们也不知道自己引用的是类的哪个实例,因为它们只能引用其他静态成员),因此无法访问类级成员(方法和属性)。

为了解决您的问题,您可以向Ship引入一个名为"STAGE"的新静态属性(通常静态属性是用ALL CAPS编写的,以将其与成员属性区分开来),然后使kill()方法成为静态的。

希望这能有所帮助,祝你好运!乔尼。

最新更新