Правильное использование интерфейсов в ActionScript 3 - PullRequest
0 голосов
/ 04 ноября 2011

Я создал интерфейс под названием IHero, который я реализую в своем классе hero.as3.класс hero написан таким образом, что его можно наследовать в классе movieclip для обработки движений и т. д. и т. д. Но почему-то я не могу понять, как кодировать это с хорошей практикой.

Возможно, я не в том направлении.

Я хочу иметь подкласс movieclip, который, например, станет героем.

Должен ли я просто реализовать IHero вкласс героя с помощью следующих методов, или это перебор?- Я думаю, я ищу ответ на то, что должно быть в интерфейсе, а что нет.Вот интерфейс.

package com.interfaces
{
    public interface IHero
    {
        //movement
        function MoveLeft():void;
        function MoveRight():void;
        function MoveUp():void;
        function MoveDown():void;

        //in battle
        function DoDamage(isCasting:Boolean):void;
        function DoHeal():void;
        function Flee():void;
        function TakeDamage():void;
        function IsAlive():Boolean;
        function CheckDeath():void;
        function Die():void;
    }
}

Ответы [ 3 ]

0 голосов
/ 04 ноября 2011

Я думаю, что вы на правильном пути, будь то правильный один или неправильный один, всегда субъективен. Но если вы действительно хотите пойти по этому пути, я предлагаю вам прочитать эту статью Мика Уэста. Его несколько лет, но он все еще очень применим.

Я думаю, у вас действительно есть два различных интерфейса, но, вероятно, больше

public interface IMoveable {
    function moveLeft(obj:DisplayObject):void;
    function moveRight(obj:DisplayObject):void;
    function moveUp(obj:DisplayObject):void;
    function moveDown(obj:DisplayObject):void;
    function Flee(obj:DisplayObject);
}

public interface IFightable {
    function doDamage(withWeapon:IEquipableWeapon);
    function takeDamage(fromWeapon:IEquipableWeapon);
    function get isAlive():Boolean;
    function checkDeath():void;
    function Die():void;
    function doHeal();
    function get health():Number;
}

Тогда ....

public class SimpleMover implements IMoveable {
    // The movement implementation

    // for example:

    public funciton moveLeft(obj:DisplayObject) {
        obj.x = obj.x -= 10;
    } 
}

public class SimpleFighter implements IFightable {
    // The fighting implementation

    private var _health:Number = 100;

    function doDamage(withWeapon:IEquipableWeapon) {
        _health -= withWeapon.damage;
    }
}

Затем добавьте их в свой подкласс MovieClip для своего Hero.

public class Hero extends MovieClip {

    private var _mover:IMoveable;
    private var _fighter:IFightable;

    public function Hero(mover:IMoveable, fighter:IFightable) {
        _mover = move;
        _fighter = fighter;
    }

}

Здесь вы используете класс Hero в качестве компонента Component Manager и Render, что немного противоречит тому, о чем Уэст говорит в этой статье, но я отступаю. Но идея заключается в том, что ваш менеджер (Hero) становится более или менее оркестратором, передавая обратные вызовы, к которым применим любой компонент; вызывая методы на _mover и fighter для выполнения вашей реальной работы.

Есть несколько преимуществ использования подобного подхода и некоторые недостатки. Во-первых, его сложнее настроить; это требует, чтобы вы действительно любили компоненты и то, что собирается делать каждый логический кусок кода. Но, с другой стороны, он отделяет ваши реализации друг от друга, делает его более тестируемым и многократно используемым. Вы также можете поменять компоненты в любое время (во время компиляции или во время выполнения), что обеспечивает гибкость при создании новых сущностей.

Но в любом случае, это всего лишь предположение о несколько иной парадигме, с которой вы, кажется, заигрываете. Может быть, вы получите немного от этого. Но обязательно прочитайте статью, если вы еще этого не сделали.

Также обратите внимание (например, на API) на Unity Engine, который имеет аналогичную модель агрегации и наследования, где интерфейсы являются ключом к абстракции.

0 голосов
/ 04 ноября 2011

Просто чтобы уточнить - интерфейсы реализованы, а не наследуются. Поэтому не имеет значения, какой класс вы создаете, который реализует IHero. Таким образом, чтобы создать тип библиотечного класса, который реализует Ihero, расширьте экранный объект, такой как Sprite или MovieClip, а затем используйте ключевое слово Implements, чтобы указать, что класс реализует Ihero.

Добавьте методы Ihero, и теперь у вас есть класс экранного объекта, который реализует iHero. Это может выглядеть примерно так (обратите внимание, что функция конструктора не указана)

package 
{
    import flash.display.Sprite;
    import com.interfaces.IHero;

    /**
     * ...
     * @author Zachary Foley
     */
    public class MyDisplayObkect extends Sprite implements IHero  
    {

        public function MoveLeft():void
        {
            // Add Implementation here;
        }

        public function MoveRight():void
        {
            // Add Implementation here;
        }

        public function MoveUp():void
        {
            // Add Implementation here;
        }

        public function MoveDown():void
        {
            // Add Implementation here;
        }

        //in battle
        public function DoDamage(isCasting:Boolean):void
        {
            // Add Implementation here;
        }

        public function DoHeal():void
        {
            // Add Implementation here;
        }

        public function Flee():void
        {
            // Add Implementation here;
        }

        public function TakeDamage():void
        {
            // Add Implementation here;
        }
        public function IsAlive():Boolean
        {
            // Add Implementation here;
        }

        public function CheckDeath():void
        {
            // Add Implementation here;
        }

        public function Die():void
        {
            // Add Implementation here;
        }

    }

}
0 голосов
/ 04 ноября 2011

Обычно вам нужно обычное определение класса, которое расширяет мувиклип, а затем настройте мувиклип своего героя, чтобы использовать этот класс в экспорте для параметров ActionScript.Интерфейс, скорее всего, вообще не нужен для вашей игры.

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