2

私はフラッシュアプ​​リケーションの外部タッチ入力に使用しています。as3のTUIOライブラリを介して受信するタッチパネルからの信号(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 の 1 つになります。トレースでは、次のような階層が表示されます。

worldMap
    MovieClip
        ....
           MovieClip

はい、mouseEnabled = falseの子のすべてのプロパティを再帰的に設定できworldMapます。この問題のみを修正できますが、よりグローバルなケースでの間違ったオブジェクト選択の問題は修正できません。

この関数を変更しようとして、2 つのヘルパー関数を作成しました。

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

しかし、新しい修正の後、新しいバグがあります:(フレックスドラッグドロップを使用するとバグが表示されます。ドラッグドロップ中にフレックスはドラッグされた画像を表示し、tuioは間違ったドロップターゲットを検出します。トレース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 が必要です。

ユーザー入力に対して有効なオブジェクトを見つける方法は?

PS Linux および Windows フラッシュ プレーヤーでテスト済み。

アップデート 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回でゆっくり効きます。そして、短時間に何度も何度も触れた後、クラッシュしました。

4

1 に答える 1

0

あなたのやり方は正しいように見えます。私が修正する唯一のことは、isMouseChildrenEnabled では、最初のmouseChildren = falseで停止して falseを返すことができるということです。

Flex がドラッグされたオブジェクトの画像を追加すると、常にトップ ターゲットとして取得されます。そのための特別なケースをコーディングする必要があります。

于 2012-11-09T23:22:59.033 に答える