4

ステージ座標 (x,y) を指定して、ユーザーが位置 (x,y) をクリックしたかのように Flash アプリを動作させたいと考えています。つまり、次のようなものです

function simulateClick(x:Number, y:Number):void{
    var e:MouseEvent = new MouseEvent(MouseEvent.CLICK, true, false, x, y)
    stage.dispatchEvent(e);
}

この種のことについて話しているページをたくさん見つけましたが、それらはすべて上記のような解決策を提供しています。ただし、これはユーザーが (x,y) をクリックすることと同じではありません。2 つの問題があります。

1 つ目は、e.stageX と e.stageY が両方とも 0 であることです。これらを直接設定することはできません。ドキュメントには、e.localXとe.localYが設定されているときに計算されると書かれていますが、e.localXをdispatchEventの前に設定した場合や、イベントリスナーで設定した場合は発生しません。

すべてのイベント リスナーを次のように書き換えることができます。

var p:Point = e.target.localToGlobal(new Point(e.localX, e.localY));

これが唯一のオプションですか?

2 番目の問題は、イベント リスナーがステージ自体ではなく、ステージの子に登録されていることです。したがって、dispatchEvent を呼び出すターゲットを見つける必要があります。明らかに、Flash はターゲットが何であるかを判断できます。つまり、ユーザーが実際にクリックしたときに、位置 (x,y) で表示される最上部のピクセルを所有するオブジェクトを特定できます。この情報を取得する簡単な方法はありますか、それとも同じことを行うために独自の再帰関数を作成する必要がありますか? 現在、DisplayObjectContainer.getObjectsUnderPoint を使用していますが、正しくありません。

それが違いを生むなら、私はFlashDevelopで書いています。

4

3 に答える 3

1

e.stageX/Y私にとっては正しく入力されています...また、正常に動作しているgetObjectsUnderPoint()ようです。渡された x/y 値simulateClickはグローバル座標であると想定していますか?

編集:コメントで指摘されているように、マウスイベントは InteractiveObject インスタンスでディスパッチする必要があります...それに応じてコードを変更しました。

import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.DisplayObject;
import flash.display.InteractiveObject;
import flash.display.Sprite;
import flash.events.MouseEvent;
import flash.geom.Point;

public function simulateClick(x:Number, y:Number):void
{
    var objects:Array = stage.getObjectsUnderPoint(new Point(x, y));

    var target:DisplayObject;
    while(target = objects.pop())
    {
        if(target is InteractiveObject)
        {
            break;
        }
    }

    if(target !== null)
    {
        var local:Point = target.globalToLocal(new Point(x, y));

        var e:MouseEvent = new MouseEvent(MouseEvent.CLICK, true, false, local.x, local.y);
        target.dispatchEvent(e);
    }
}

public function addedToStage():void
{
    var parent:Sprite = new Sprite();
    stage.addChild(parent);

    var child:Sprite = new Sprite();
    child.name = 'child 1';
    child.graphics.beginFill(0xff0000, 1);
    child.graphics.drawRect(0, 0, 200, 200);
    child.graphics.endFill();

    var child2:Sprite = new Sprite();
    child2.name = 'child 2';
    child2.graphics.beginFill(0xff00ff, 1);
    child2.graphics.drawRect(0, 0, 100, 100);
    child2.graphics.endFill();
    child2.x = 150;
    child2.y = 150;

    var bmpData:BitmapData = new BitmapData(80, 80, false, 0x00ff00);
    var bmp:Bitmap = new Bitmap(bmpData);
    bmp.name = 'bitmap';

    child2.addChild(bmp);

    parent.addChild(child);
    parent.addChild(child2);

    child2.addEventListener(MouseEvent.CLICK, function(e:MouseEvent):void
    {
        trace('target: ' + e.target.name);
        trace('localX: ' + e.localX);
        trace('localY: ' + e.localY);
        trace('stageX: ' + e.stageX);
        trace('stageY: ' + e.stageY);
    });

    simulateClick(190, 190);
}

出力:

target: child 2
localX: 40
localY: 40
stageX: 190
stageY: 190
于 2012-10-02T00:18:30.677 に答える
0

私もこの問題に直面しており、少し頭が痛くなりました。私の状況では、少し複雑な計算を実行してイベントを作成していましたが、既にローカル座標を設定していたにもかかわらず、グローバル座標を取得できませんでした。

実際、私の場合、解決策は非常に明白でした... グローバル座標は、イベントがディスパッチされた後にのみ入力されます。そうでない場合、イベントはローカルからグローバルへの変換方法をどのように知ることができますか?

これは、イベントのディスパッチに使用されるオブジェクトが InteractiveObject であることを確認しないことに加えて、もう 1 つの落とし穴です。

両方の落とし穴のために他の誰かがこの問題に直面する可能性があるため、これを投稿します。読みやすい素早い回答。

于 2015-10-30T18:54:33.107 に答える
0

質問 1 について: MouseEvent を作成した後 (ローカルの x、y を割り当て)、e.stageX を直接参照して、イベントをディスパッチする前に必要なものに設定できるはずです。これは、MouseEvent インスタンスの単なるプロパティです。#2 では、currentTarget は常にマウスの下の一番上にあるものであり、target はイベントをディスパッチしているものです (イベントが実際にマウス操作によってディスパッチされていると仮定します)。あなたの場合、ターゲットをイベントをディスパッチするオブジェクトに設定し、 currentTarget を任意に設定できます。問題は、これが現在マウスの下にあるものを処理する最も効率的な方法であるかどうかです。答えは、おそらくそうではありません。MOUSE_OVER イベントを使用して、マウスが現在上にあるものを監視する方がずっと良いでしょう。これを呼び出したいときに使用できる変数として保存し、ディスプレイ チェーン全体を常に反復しようとしないでください (Flash は、ループで実行できるよりもはるかに高速にネイティブに実行するため)。ステージに mouseOver を配置し、currentTarget を確認するだけで、マウスが変化するすべてのフレームで、マウスの下にある一番上のアイテムを取得できます。

(明らかな厄介なスクリプトを防ぐために) 特定のアクションは、actionscript によって動的に生成されるマウス イベントによってトリガーできないことに注意してください。これらには、ファイル参照を開くことと全画面表示にすることが含まれます。

于 2012-10-02T00:16:01.077 に答える