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;
}
每张卡片都是其上方卡片中的容器的子项。我希望能够选择一张卡片并拖动它(和它的孩子们)。问题是,当我点击卡片B时,它会选择卡片E.所以我需要的是选择鼠标事件中最小的孩子,而不是它的父母。有办法控制吗?
我知道我可以做mouseChildren的真假。没关系。必须将所有卡设置为true,以便我可以独立于其父卡选择它们。冒泡我的活动需要做些什么吗?这是我从未理解过的东西。
注意:我发现鼠标功能有问题。修复这将是微不足道的,现在是一种占位符。
答案 0 :(得分:3)
<强> tldr:强>
使用useCapture
设置为true
和stopPropagation
方法的组合。这允许用户单击一个元素并为目标调用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
现在鼠标正在调用目标的函数。令人惊讶的是非直观但允许一些严格的灵活性和控制!