我用于我的flash应用程序外部触摸输入。我通过TUIO库收到来自触摸屏的信号as3(https://code.google.com/p/tuio-as3/)
我有时遇到问题,然后TuioManager错误检测到必须接收触摸输入的对象。
private function getTopDisplayObjectUnderPoint(point:Point):DisplayObject {
var targets:Array = stage.getObjectsUnderPoint(point);
var item:DisplayObject = (targets.length > 0) ? targets[targets.length - 1] : stage;
if (this.touchTargetDiscoveryMode == TOUCH_TARGET_DISCOVERY_MOUSE_ENABLED) {
while (targets.length > 0) {
item = targets.pop() as DisplayObject;
//ignore debug cursor/object/blob and send object under debug cursor/object/blob
if ((item is ITuioDebugCursor || item is ITuioDebugBlob || item is ITuioDebugObject || item is ITuioDebugTextSprite) && targets.length > 0) {
continue;
}
if (item.parent != null && !(item is InteractiveObject)) item = item.parent;
if (item is InteractiveObject) {
if ((item as InteractiveObject).mouseEnabled) return item;
}
}
item = stage;
}
else if (this.touchTargetDiscoveryMode == TOUCH_TARGET_DISCOVERY_IGNORELIST) {
while (targets.length > 0) {
item = targets.pop();
//ignore debug cursor/object/blob and send object under debug cursor/object/blob
if ((item is ITuioDebugCursor || item is ITuioDebugBlob || item is ITuioDebugObject || item is ITuioDebugTextSprite) && targets.length > 0) {
continue;
}
if (!bubbleListCheck(item)) return item;
}
item = stage;
}
return item;
}
我使用了this.touchTargetDiscoveryMode == TOUCH_TARGET_DISCOVERY_MOUSE_ENABLED
。
此函数不使用mouseChildren
属性。
例如,我在fxg图形中使用世界地图,我想要禁用其所有子项:worldMap.mouseChildren = false;
但如果我使用系统鼠标输入,它可以工作,但不适用于TUIO。函数getTopDisplayObjectUnderPoint
的结果将是子MovieClip之一。在跟踪中,我看到层次结构如:
worldMap
MovieClip
....
MovieClip
是的,我可以递归地为mouseEnabled = false
的孩子设置所有属性worldMap
。它可以解决这个问题,但在更全局的情况下,错误的对象选择不会出现问题。
我试图修改这个函数并编写了两个辅助函数:
private function isMouseChildrenEnabled(obj:DisplayObject):Boolean {
if (obj.parent == null) {
return true;
}
return obj.parent.mouseChildren && isMouseChildrenEnabled(obj.parent);
}
private function findMouseEnabledObject(obj:InteractiveObject):InteractiveObject
{
if (obj.mouseEnabled && isMouseChildrenEnabled(obj))
return obj;
return obj.parent ? findMouseEnabledObject(obj.parent) : null;
}
private function getTopDisplayObjectUnderPoint(point:Point):DisplayObject {
var targets:Array = stage.getObjectsUnderPoint(point);
var item:DisplayObject = (targets.length > 0) ? targets[targets.length - 1] : stage;
if(this.touchTargetDiscoveryMode == TOUCH_TARGET_DISCOVERY_MOUSE_ENABLED){
while(targets.length > 0) {
item = targets.pop() as DisplayObject;
//ignore debug cursor/object/blob and send object under debug cursor/object/blob
if((item is ITuioDebugCursor || item is ITuioDebugBlob || item is ITuioDebugObject || item is ITuioDebugTextSprite) && targets.length > 0){
continue;
}
if (item.parent != null && !(item is InteractiveObject)) item = item.parent;
if (item is InteractiveObject) {
var io:InteractiveObject = findMouseEnabledObject(item as InteractiveObject);
if (io) return io;
}
}
item = stage;
} else if (this.touchTargetDiscoveryMode == TOUCH_TARGET_DISCOVERY_IGNORELIST) {
while(targets.length > 0) {
item = targets.pop();
//ignore debug cursor/object/blob and send object under debug cursor/object/blob
if((item is ITuioDebugCursor || item is ITuioDebugBlob || item is ITuioDebugObject || item is ITuioDebugTextSprite) && targets.length > 0){
continue;
}
if (!bubbleListCheck(item)) return item;
}
item = stage;
}
return item;
}
但是经过新的修复我们有新的错误:( 如果我使用flex拖放,我会看到bug。在拖拽期间,flex显示拖动的图像和tuio检测到错误的放下目标。在trace stage.getObjectsUnderPoint()中,我看到如下内容:
[n] - image (mouseEnabled=true, mouseChildren=true)
parent: embed_swf_drag_cursor... (mouseEnabled=false, mouseChildren=false)
parent: application_systemManager... (mouseEnabled=true, mouseChildren=true)
parent: stage
[n-1] - borderContainer (mouseEnabled=true, mouseChildren=true) - it is my drop target
结果我将systemManager作为目标,但我需要BorderContainer。
如何正确查找用户输入的启用对象?
P.S。在Linux和Windows Flash播放器上测试过。
更新13.11
我尝试编写获得启用对象的函数:
private function getTopEnabledObject(object:DisplayObjectContainer, hitPoint:Point):InteractiveObject
{
if (!object.mouseChildren)
return null;
var child:DisplayObject;
for (var i:int = object.numChildren - 1; i >= 0; i--)
{
child = object.getChildAt(i);
if (child.visible && child is InteractiveObject && child.hitTestPoint(hitPoint.x, hitPoint.y, true))
{
if (child is DisplayObjectContainer)
{
var target:InteractiveObject = getTopEnabledObject(child as DisplayObjectContainer, hitPoint);
if (target)
return target;
}
if ((child as InteractiveObject).mouseEnabled)
return child as InteractiveObject;
}
}
return null;
}
它在5-10次缓慢运作。在短时间内经过多次触摸后我崩溃了。
答案 0 :(得分:0)
你做的方式看起来是正确的。我唯一要纠正的是,在isMouseChildrenEnabled中,您可以在第一个 mouseChildren = false 处停止并返回false。
如果Flex添加拖动对象的图像,您将始终将其作为顶级目标。你必须为它编写特殊情况。