Старлинг определяет кнопку как изображение

У меня есть класс, который представляет собой экран, когда я перемещаю курсор, я хотел бы определить, какой объект находится под ним. Я добавил настраиваемую кнопку класса TalentBtn, который происходит от класса Button от starling, но когда я его отслеживаю, это экземпляр класса Image. Я не могу преобразовать его в talenTbtn, когда я пытаюсь, он ссылается на null. Я обнаруживаю объекты с помощью метода hitTest (point), который возвращает DisplayObject. Как вы думаете, я могу как-нибудь решить эту проблему? Вот метод обнаружения

private function onOverTalent(e:TouchEvent):void {
        var point:Point = new Point(e.getTouch(stage).globalX, e.getTouch(stage).globalY);
        
        displayObject = hitTest(point);
        if (displayObject == null) {
            return;
        }
        
        if (displayObject is Image) {
            talentFound = displayObject as TalentBtn;

            trace(displayObject);
            trace(talentFound);
        }
        
    }

Результаты трассировки:

    [object Image]
    null

person Ferenc Dajka    schedule 06.10.2012    source источник


Ответы (1)


Кнопка является подклассом DisplayObjectContainer, и при его создании добавляет к себе изображение для фона и текстовое поле для метки (если есть). Оба они содержатся в спрайте внутри кнопки.

Чтобы конкретно указать на то, что вы пытаетесь сделать, попробуйте следующее:

private function onOverTalent(e:TouchEvent):void
{
    var point:Point = new Point(e.getTouch(stage).globalX, e.getTouch(stage).globalY);

    var hit:DisplayObject = hitTest(point);
    if (!hit)
    {
        return;
    }

    // Probably not a good idea, in case the interior structure of Button ever changes.
    var button:Button = hit.parent.parent as Button;
    trace(button);
    }
}

Однако у этого подхода есть проблема: если код внутри Button когда-либо изменится, он может сломаться. Итак, вот более общий подход:

private function onOverTalent(e:TouchEvent):void
{
    var point:Point = new Point(e.getTouch(stage).globalX, e.getTouch(stage).globalY);

    var hit:DisplayObject = hitTest(point);
    if (!hit)
    {
        return;
    }

    var button:Button;
    if (hit is Image || hit is TextField)
    {
        // Should be the containing Sprite now
        hit = hit.parent;
        while (hit)
        {
            button = hit as Button;

            if (button)
            {
                break;
            }

            // Go up one in the display hierarchy
            hit = hit.parent;
        }

        // None of it was a button.
        if (!button)
        {
            return;
        }

        // button will be the Button object at this point.
        trace(button);
    }
}

Однако есть ли у вас причина не просто слушать событие touch на самой кнопке?

http://doc.starling-framework.org/core/starling/display/DisplayObject.html#event:touch

person Scott A    schedule 18.10.2012
comment
Прежде всего, спасибо за хороший ответ. Во-вторых, я не хотел добавлять к каждой кнопке нового слушателя, я был уверен, что это бесполезно тратит много памяти. Теперь я знаю, что это не так, но кого это волнует;) - person Ferenc Dajka; 26.10.2012
comment
@FerencDajka В частности, в Starling события объединены и не могут сильно увеличивать использование памяти, если вообще. - person Scott A; 27.10.2012