2012-01-03 58 views
0

這個讓我瘋狂了幾個小時。我嘗試調用kill();(函數takeDamage()),該函數在同一個類中,但它不會找到它。AS3 - 錯誤#1180:調用可能未定義的方法kill。

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;

在此先感謝。

回答

2

kill()是一個實例方法,但takeDamage是一個靜態類方法。您不能從靜態類方法調用實例方法。當你有一個實例引用來調用它時,你只能調用實例方法。

+0

我現在覺得很愚蠢,但我該如何做一個方法的實例?這可能很容易,但我找不到它。 – 2012-01-03 21:38:52

+1

@RobbeVanWinckel你不能創建一個方法的實例。問題是takeDamage()是屬於類Ship的一種方法(不是Ship類型的對象)。從其他代碼判斷,你可能只想從takeDamage()和health變量中刪除「static」關鍵字 - 它們似乎屬於一個玩家(實例)。 – weltraumpirat 2012-01-03 21:45:08

+0

@weltraumpirat問題是我在另一個類中使用該方法,如果我刪除單詞static,則會給出錯誤#1119:通過靜態類型Class的引用訪問可能未定義的屬性maxHealth。那我該如何解決呢? – 2012-01-03 21:54:10

0

不錯,簡單的一個在今年年初!

您已將函數'takeDamage'聲明爲靜態方法 - 這意味着它不屬於類Ship的特定實例,而是它屬於類本身。靜態方法和屬性可以是一個有點混亂,如果你是新的面向對象,而是通過一個簡單的例子是很容易解釋:

類成員屬性

在這個例子中,我們聲明一個新的類定義爲船舶我們可以通過setSpeed()來定義船舶實例的速度。

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 

正如你可以從上面看到,船舶,我們創建的每個實例可以擁有自己的速度 - 這是面向對象編程的基礎(船舶是對象,速度就是數據)。

靜態屬性

現在,我們將創建另一個類,這段時間稱爲StaticShip它採用了靜態的屬性,而不是,請注意使用靜態關鍵字:

public class StaticShip { 
    private static var speed : Number; 

    public function setSpeed(value : Number) : void { 
     this.speed = value; 
    } 

    public function getSpeed() : Number { 
     return this.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 

注意如何既StaticShips 10移動 - 這是因爲我們設置了「cargoShip」比如去年的速度 - 在StaticShip的「速度」屬性聲明靜態它跨越共享該類的所有實例。

現在,就像您可以在類中具有靜態屬性一樣,您也可以具有靜態函數。通常,當你調用一個類的方法(例如: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秒等等);但他們也共同使用的設計模式,如Static Factory Method

現在,你看到你的錯誤的原因 - 成員級別方法能夠調用靜態方法,即:

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()); 
    } 
} 

這是因爲靜態方法沒有範圍(即:他們不知道是哪個插件因爲它們只能引用其他靜態成員),因此無法訪問類成員(方法和屬性)。

爲了解決您的問題,您可以向船舶引入一個名爲'STAGE'的靜態屬性(通常靜態屬性用全部大寫寫入,以區分它們與成員屬性),然後使您的方法保持靜態。

希望這會有所幫助,祝你好運! 喬尼。

+0

這樣做,擺脫了錯誤。現在是它不會執行代碼的問題。任何想法如何解決? – 2012-01-03 22:36:16

相關問題