AS3 - Ошибка № 1180: вызов возможно неопределенного метода kill. - PullRequest
0 голосов
/ 04 января 2012

Этот сводит меня с ума на пару часов.Я пытаюсь вызвать метод 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;?

Заранее спасибо.

Ответы [ 2 ]

2 голосов
/ 04 января 2012

kill () - метод экземпляра, но takeDamage - метод статического класса. Вы не можете вызывать методы экземпляра из статического метода класса. Вы можете вызывать методы экземпляра только тогда, когда у вас есть ссылка на экземпляр для его вызова.

0 голосов
/ 04 января 2012

хороший простой в начале года!

Вы объявили функцию 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, который вместо этого использует статическое свойство, обратите внимание на использование 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

Обратите внимание, как оба StaticShips перемещаются на 10 - это потому, что мы устанавливаем скорость экземпляра cargoShip последней - поскольку свойство speed в StaticShip объявляется static оно является общим для всех экземпляров этого класса.

Теперь, как вы можете иметь статические свойства в классах, вы также можете иметь статические функции.Обычно, когда вы вызываете метод класса (то есть: 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);

Вместо этого теперь мы можем вызывать только метод setSpeed ​​() класса StaticMethodShip, то есть:

// 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 движутся с указанной скоростью, все переходы с затуханием длятся в течение 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» (обычно статические свойства записываются во ВСЕХ CAPS, чтобы отличать их от свойств члена), а затем сделать ваш метод kill() статическим.

Надеюсь, это поможет и удачи!Jonny.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...