imageflashbuttonactionscriptstarling-framework

Starling detects button as Image


I have a class which is a screen, when I move the cursor, I'd like to detect what object is under it. I added a custom button of a the class TalentBtn which extends from starling's Button class, but when I trace it out it is an instance of the Image class. I can't cast it to a talenTbtn, when I try, it refers to null. I detect the objects with hitTest(point) method, which returns a DisplayObject. Do you guys think I can solve this problem somehow? Here's the detecting method

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

The results of the traces are:

    [object Image]
    null

Solution

  • Button is a subclass of DisplayObjectContainer, and when it is created it adds to itself an Image for the background and a TextField for the label (if any). Both of these are contained within a Sprite that is within the Button.

    To specifically address what you're trying to do, try this:

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

    However, this approach has a problem: if the code inside of Button ever changes, it might break. So here's a more general approach:

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

    However, do you have a reason for not just listening for the touch event on the button itself?

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