Форум Flasher.ru

Форум Flasher.ru (http://www.flasher.ru/forum/index.php)
-   API приложений и сред (http://www.flasher.ru/forum/forumdisplay.php?f=61)
-   -   [Nape] Обращение к родительскому классу (http://www.flasher.ru/forum/showthread.php?t=212602)

neonoviiwolf 23.03.2016 19:28

Обращение к родительскому классу
 
Доброго!
Ранее никогда не пробовал писать код с обращением к родителю

Что хочу: диспатчить событие в определённый мувик из тела body в Nape.

тут происходит столкновение, я хочу отправить событие в родительский класс,в котором был создан body
Код AS3:

                private function defoltCollision(cb:PreCallback):PreFlag
                {
                        if ((cb.int1.castBody.velocity.y > 0) && (Math.abs(cb.int1.castBody.position.y - cb.int2.castBody.position.y) > 30))
                        {
                                stage.dispatchEvent(new UserEvent(UserEvent.COLLISION_GROUND_UNIT, true, false));
                                cb.int1.castBody.velocity.y *= -1;
                                cb.int2.castBody.parent.dispatchEvent(new UserEvent(UserEvent.KILL_UNIT, true, false));
 
                        }
                        return PreFlag.IGNORE_ONCE;
                }

тут его принимаю.
unit - это экземпляр класса, в котором создан экземпляр Body

Код AS3:

                public function KillGroundUnit(_unit:MovieClip)
                {
                        unit = _unit;
                }
 
                override public function init(e:Event):void
                {
                        super.init(e);
                        this.addEventListener(Event.ENTER_FRAME, updateClip);
                        unit.addEventListener(UserEvent.KILL_UNIT, killUnit);
                        unit.addEventListener(UserEvent.REVIVAL_UNIT, revivalUnit);
                }

ну разумеется не заработал, вот и думаю, как этакое реализовать

Добавлено через 1 час 34 минуты
Код AS3:

cb.int2.castBody.parent.dispatchEvent(new UserEvent(UserEvent.KILL_UNIT, true, false));

ошибка вылезает тут, т.к. нету parent у Body, вариантов вижу несколько, но всё костыли, которые на выходе выдают, что в несколько классов могут менять один и тотже параметр, что совсем не хорошо, вот хотел через события, дабы избежать зависимостей, но увы

Добавлено через 1 час 36 минут
Код AS3:

public class GroundUnits extends ParentCommon
        {
                private var body:Body;
                private var timer:Timer = new Timer(Math.random() * 4000);
                public function GroundUnits()
                {
                        body = new Body(BodyType.KINEMATIC);
                        body.shapes.add(new Polygon(Polygon.box(35, -35)));
                        body.align();
                        body.userData.tempSpeed = 0;
                        timer.addEventListener(TimerEvent.TIMER, timerUpdateTempSpeed);
                        timer.start();
                }

я, наивно, предполагал, что раз экземпляр Body создаётся в каком либо классе, то он и будет его родителем.

Wolsh 23.03.2016 21:15

root, parent, child — это термины DisplayList
parent — не тот, кто создал (такого свойства вообще нет), а тот, кто добавил в свой Список Отображения.

neonoviiwolf 23.03.2016 21:20

Цитата:

Сообщение от Wolsh (Сообщение 1192896)
root, parent, child — это термины DisplayList
parent — не тот, кто создал (такого свойства вообще нет), а тот, кто добавил в свой Список Отображения.

это я уже выяснил, есть возможность красиво сделать без использования body.userData.***?

Wolsh 23.03.2016 21:21

То, что Вы считали парентом — не может подписаться на событие от Body и передиспатчить его?

Добавлено через 3 минуты
Тут два очевидных пути:
1) передиспатчивать событие. То есть генерить его в Body, ловить в его создателе и диспатчить от создателя. Тогда вторая часть (с подпиской) не меняется.
2) Подписываться на событие от Body а не от его "парента"-создателя. Возможно, для этого у создателя надо завести публичную ссылку на экземпляр Body

neonoviiwolf 23.03.2016 21:25

Цитата:

Сообщение от Wolsh (Сообщение 1192898)
То, что Вы считали парентом — не может подписаться на событие от Body и передиспатчить его?

нету у Body такого свойства, такую ошибку выдает.

Добавлено через 6 минут
Цитата:

Сообщение от Wolsh (Сообщение 1192898)
То, что Вы считали парентом — не может подписаться на событие от Body и передиспатчить его?

Добавлено через 3 минуты
Тут два очевидных пути:
1) передиспатчивать событие. То есть генерить его в Body, ловить в его создателе и диспатчить от создателя. Тогда вторая часть (с подпиской) не меняется.
2) Подписываться на событие от Body а не от его "парента"-создателя. Возможно, для этого у создателя надо завести публичную ссылку на экземпляр Body

всё красиво, но как это реализовать я пока не понимаю.

Wolsh 23.03.2016 22:09

Код AS3:

private var body:Body;

(сразу хочется сказать, что Вы вывернули наизнанку конвенции: приватные члены именуются с андерскора: _body, а публичные и локальные — без.
Сделайте этому свойству геттер
Код AS3:

public function get body():Body { return _body; }

Диспатчите событие из body:
Код AS3:

cb.int2.castBody.dispatchEvent(new UserEvent(UserEvent.KILL_UNIT, true, false));

Подписываетесь тоже на событие от body:
Код AS3:

_unit.body.addEventListener(UserEvent.KILL_UNIT, killUnit);


neonoviiwolf 23.03.2016 22:58

Wolsh невозможно повесить событие на Body

Добавлено через 6 минут
в общем сделал так, но мне не нравится

Код AS3:

                private function defoltCollision(cb:PreCallback):PreFlag
                {
                        if (cb.int2.castBody.userData.killUnits == false)
                                if ((cb.int1.castBody.velocity.y > 0) && (Math.abs(cb.int1.castBody.position.y - cb.int2.castBody.position.y) > 30))
                                {
                                        stage.dispatchEvent(new UserEvent(UserEvent.COLLISION_GROUND_UNIT, true, false));
                                        cb.int1.castBody.velocity.y *= -1;
                                        cb.int2.castBody.userData.killUnits = true;
                                }
                        return PreFlag.IGNORE_ONCE;
                }

в классе Unit
Код AS3:

this.addChild(new KillGroundUnit(sprite, body));

Код AS3:

ackage classesGame.killUnits
{
        import classesGame.parentsCommon.ParentCommon;
        import classesGame.userEvent.UserEvent;
        import flash.display.MovieClip;
        import flash.events.Event;
        import nape.phys.Body;
 
        public class KillGroundUnit extends ParentCommon
        {
                private var _sprite:MovieClip;
                private var _body:Body;
 
                public function KillGroundUnit(sprite:MovieClip, body:Body)
                {
                        _sprite = sprite;
                        _body = body;
                }
 
                override public function init(e:Event):void
                {
                        super.init(e);
                        this.addEventListener(Event.ENTER_FRAME, updateClip);
                }
 
                private function updateClip(e:Event):void
                {
                        if (_sprite.currentFrame == 11)
                                if (_body.userData.killUnits == false)
                                        _sprite.gotoAndPlay(1);
                                else _sprite.gotoAndStop(11);
                }
 
                override public function removeInit(e:Event):void
                {
                        super.removeInit(e);
                        this.removeEventListener(Event.ENTER_FRAME, updateClip);
                }
        }
}


caseyryan 24.03.2016 06:27

У тебя вообще какая-то каша в коде. Я думал ты уже давно понял, что нейп - это чисто математика, он к дисплей листу вообще никакого отношения не имеет, и глупо искать у него каких-то родителей. У нейпа есть только пространство Space, в котором и происходят все вычисления.
Мне не понятны у тебя две вещи:
1) У тебя тело создается не в том объекте, к которому оно принадлежит что ли?
2) Почему ты не используешь для этого стандартные события нейпа? То, что у тебя сделано с событиями - это такой дикий костыль, что просто жесть)

Я делаю просто. У меня физическое тело персонажа создается в самом классе персонажа, которому оно принадлежит. А подписывается оно на события примерно так:
Вот метод из рабочей игры:

Код AS3:

protected function createPhysBody():void {
 
        var bodyWidth:        int                                        = dip(70) * p_totalCharScale;
        var bodyHeight:        int                                        = dip(25) * p_totalCharScale;
        _physBody                                                        = new Body(BodyType.DYNAMIC);
        _physBody.allowRotation                                = false;
        _mainShape                                                        = new Polygon(
                Polygon.regular(bodyWidth, bodyHeight, 4)
        );       
        _mainShape.userData.object                        = this;
        _mainShape.cbTypes.add(CallbackTypes.playerPhysCbType);
        _physBody.shapes.add(_mainShape);
        _physBody.mass                                                = 30;
 
        var shapeWidth:Number                                = bodyWidth * p_totalCharScale;
        _feelerShape        = new Polygon(
                Polygon.rect( -p_hitZoneWidth * .5,
                -p_hitZoneHeight * 2,
                p_hitZoneWidth, p_hitZoneHeight)
        );
        _feelerShape.userData.object                = this;
        _feelerShape.sensorEnabled                        = true;
        _feelerShape.cbTypes.add(CallbackTypes.heroSensorCbType);
        _physBody.shapes.add(_feelerShape);
        var enemyWeaponLis:InteractionListener        = new InteractionListener(
                CbEvent.BEGIN,
                InteractionType.SENSOR,
                CallbackTypes.heroSensorCbType,
                CallbackTypes.enemyWeaponCbType,
                onEnemyWeaponCollision
        );
        var inclineBeginLis:InteractionListener        = new InteractionListener(
                CbEvent.BEGIN,
                InteractionType.SENSOR,
                CallbackTypes.playerPhysCbType,
                CallbackTypes.inclineCbType,
                onInclineCollision
        );
        var inclineEndLis:InteractionListener                = new InteractionListener(
                CbEvent.END,
                InteractionType.SENSOR,
                CallbackTypes.playerPhysCbType,
                CallbackTypes.inclineCbType,
                onInclineCollision
        );
        // обработка лестниц
        var ladderBeginLis:InteractionListener        = new InteractionListener(
                CbEvent.BEGIN,
                InteractionType.SENSOR,
                CallbackTypes.playerPhysCbType,
                CallbackTypes.ladderCbType,
                onLadderCollision
        );
        var ladderEndLis:InteractionListener                = new InteractionListener(
                CbEvent.END,
                InteractionType.SENSOR,
                CallbackTypes.playerPhysCbType,
                CallbackTypes.ladderCbType,
                onLadderCollision
        );
 
 
        var explosionListener:InteractionListener        = new InteractionListener(
                CbEvent.BEGIN,
                InteractionType.SENSOR,
                CallbackTypes.heroSensorCbType,
                CallbackTypes.effectCbType,
                onEffectCollision
        );
        //  чтобы потом было проще удалять все слушатели циклом, или добавлять их в Space
        _listeners.push(
                enemyWeaponLis,
                inclineBeginLis,
                inclineEndLis,
                explosionListener,
                ladderBeginLis,
                ladderEndLis
        );
 
}

Все типы колбэков нейпа занесены в статические константы, и доступны по все игре
Код AS3:

package  {
        import nape.callbacks.CbType;
 
        public class CallbackTypes {
 
                public static const enemyCbType:                CbType        = new CbType();
                public static const enemyPhysCbType:        CbType        = new CbType();
                public static const npcCbType:                        CbType        = new CbType();
                public static const obstacleCbType:                CbType        = new CbType();
                public static const playerSensorCbType:        CbType        = new CbType();
                // это для проверок типа вижу / не вижу
                public static const playerPhysCbType:        CbType        = new CbType();
                public static const bulletCbType:                CbType        = new CbType();
                public static const effectCbType:                CbType        = new CbType();
                public static const feelerCbType:                CbType        = new CbType();
                public static const inclineCbType:                CbType        = new CbType();
                public static const ladderCbType:                CbType        = new CbType();
                public static const roomKeyCbType:                CbType        = new CbType();
 
                public static const enemyWeaponCbType:        CbType        = new CbType();
                public static const wallCbType:                        CbType        = new CbType();
 
 
 
                public function CallbackTypes() {
 
                }
 
        }
 
}

То есть если создается тело оружия врага, то ему добавляется колбэк enemyWeaponCbType,
и, свой персонаж уже сможет определить, что он столкнулся с оружием врага, к примеру.

Ну и наконец обработчик столкновения с оружием врага
Код AS3:

private function onEnemyWeaponCollision(collision:InteractionCallback):void {
        if (_dead || _immortal || _isFalling || _isJumping) return;
        var shape1:        Shape                = collision.int1.castShape;
        if (shape1.userData.object == this) {
                var hitterBody:        Body                = collision.int2.castBody;
                if (hitterBody.userData.object is ColdWeaponPhysicsBase) {
                        var coldWeapon:ColdWeaponPhysicsBase = hitterBody.userData.object as ColdWeaponPhysicsBase;
                        if (coldWeapon.backsOff) {
                                // нужно ли отбрасывать ударом?
                                //backOff(dip(70));
                        }
                        if (coldWeapon.falls) {
                                var direction:int  = hitterBody.position.x > physX ? -1 : 1;
                                scaleX = -direction;
                                quickFallAnimation();
                        }
                        health -= coldWeapon.power;
                }
        }
}

Как видишь, при столкновении с оружием врага, у персонада сразу отнимается соответствующий процент здоровья, и не нужно ничего никуда диспатчить

neonoviiwolf 24.03.2016 11:00

Цитата:

1) У тебя тело создается не в том объекте, к которому оно принадлежит что ли?
в том, sprite это просто мувик с анимацией, он ток двигается вместе с Body, из-за этого и тему создал, так как не хочу их хоть как-то связывать более
caseyryan идею я понял, но пока не дорос, сложновато, чтобы с ходу переписать код


Часовой пояс GMT +4, время: 20:33.

Copyright © 1999-2008 Flasher.ru. All rights reserved.
Работает на vBulletin®. Copyright ©2000 - 2026, Jelsoft Enterprises Ltd. Перевод: zCarot
Администрация сайта не несёт ответственности за любую предоставленную посетителями информацию. Подробнее см. Правила.