选择"最年轻的" AS3中鼠标下的子(仅限目标)

时间:2016-10-19 21:49:52

标签: actionscript-3

tldr: 如何告诉鼠标事件只针对鼠标下最小的孩子,其父母?

我正在制作纸牌游戏,试图更好地学习OOP。我有一个Card类和一个CardHome类。每张卡都包含一张可以存放卡的CardHome,等等。因此,移动卡片将移动其中包含的所有卡片。问题是我的鼠标事件正在检测所有卡的父级。所以我认为我需要的是一种说法"只为目标最年轻的孩子运行这个鼠标事件"。有办法吗?

private function pressCard(me:MouseEvent):void{
        var c:Object = me.target as Card;
        // place card in center of container x wise
        c.x = 0;
        // and down 5
        c.y = 5;

        // bring drag container up to front z order
        addChild(c as Card);

        // begin dragging drag container
        c.startDrag(true);

        // hide mouse
        Mouse.hide();

        // add listener to this card for mouse up
        c.addEventListener(MouseEvent.MOUSE_UP,dropCard);
    }

    private function dropCard(me:MouseEvent):void{
        var c:Object = me.target as Card;

        // release drag container
        c.stopDrag();

        // remove mouse up listener from card
        c.removeEventListener(MouseEvent.MOUSE_UP,dropCard);
        Mouse.show();


        // check for colision with a card that has a matching holder
        for (var i:int = 0; i < deckArray.length; i++){
            if (c.hitTestObject(deckArray[i]) && c != deckArray[i]){
                trace("hit",deckArray[i]._containerOwned._occupied,deckArray[i]._flippable);
                if (deckArray[i]._number == c._number + 1 && deckArray[i]._flippable == false && deckArray[i]._suit != c._suit && deckArray[i]._containerOwned._occupied == false){ 
                    c._containedIn.parent._containerOwned._occupied = false;
                    makeFlippable(c._containedIn.parent);
                    deckArray[i]._containerOwned.addChild(c as Card);
                    c._containedIn = c.parent;                      
                    c.x = 0;
                    c.y = 0;
                    break;
                } 
            }
        }

        // add selected card back to home spot
        c._containedIn.addChild(c);
        c.x = 0;
        c.y = 0;
    }

    private function mOver(me:MouseEvent):void{
        trace(me.target._number);
        trace(getHighestZ());
    }

    private function getHighestZ():Card{
        var highestZ:int = 0;
        var c:Card;
        for (var i:int = 0; i < deckArray.length; i++){
            if (deckArray[i].hitTestPoint(stage.mouseX,stage.mouseY) && deckArray[i].getChildIndex() > highestZ){
                c = deckArray[i];
                highestZ = deckArray[i].getChildIndex();
            }
        }
        return c;
    }

enter image description here

每张卡片都是其上方卡片中的容器的子项。我希望能够选择一张卡片并拖动它(和它的孩子们)。问题是,当我点击卡片B时,它会选择卡片E.所以我需要的是选择鼠标事件中最小的孩子,而不是它的父母。有办法控制吗?

我知道我可以做mouseChildren的真假。没关系。必须将所有卡设置为true,以便我可以独立于其父卡选择它们。冒泡我的活动需要做些什么吗?这是我从未理解过的东西。

注意:我发现鼠标功能有问题。修复这将是微不足道的,现在是一种占位符。

1 个答案:

答案 0 :(得分:3)

<强> tldr:

使用useCapture设置为truestopPropagation方法的组合。这允许用户单击一个元素并为目标调用eventHandler ,而不是目标和舞台之间的任何元素!

所以这里的关键是访问as3事件流。当触发鼠标事件时,它会从阶段向上传播到可以接收该类型鼠标事件的所有对象。在这种情况下,卡父母。然后气泡回到舞台上。所以我需要的是将捕获设置设置为true,将使用事件处理程序的阶段切换到冒泡阶段(这会导致第一个元素实际上将函数调用为实际目标)然后,而不是让事件传播回到舞台,调用stopPropagation方法。看起来像这样:

c.addEventListener(MouseEvent.MOUSE_OVER, mOver, true);

这里的true表示在到目标的回程的路上触发每个元素上的函数。然后在mOver函数中执行:

stopPropagation();
trace(c._Number);
// and any other code to do on this target

这可以防止事件通过鼠标下的其他卡流回。

现在取代像

这样的输出
5
3
9

当鼠标在9张牌上时(超过3张牌,超过5张)我现在就可以了

9

然后当我鼠标悬停在3上时我得到了

3

现在鼠标正在调用目标的函数。令人惊讶的是非直观但允许一些严格的灵活性和控制!

from Adobe on Event Flow

enter image description here

enter image description here