リスナーは関与しません。問題は、 MOUSE_OVERおよびMOUSE_OUTリスナーを使用できることですが、マウスを MovieClip の上にすばやくドラッグすると、これらのリスナーのいずれかがアクティブにならない場合があります。何度か試しました。
4 に答える
mouseOverとmouseOutで問題が発生したことはありません。
ただし、hitTestPointを使用できます。
function detectMouseOver(d:DisplayObject):Boolean
{
var mousePoint:Point = d.localToGlobal(new Point(d.mouseX,d.mouseY));
return d.hitTestPoint(mousePoint.x,mousePoint.y,true);
}
そのプロパティが使用可能であり、呼び出し元から設定されていることが確実な場合は、stage.mouseXおよびstage.mouseY(localToGlobalではなく)を使用することもできます。
私はコードをテストしていませんが、動作するはずだと思います。
(編集)
ただし、マウスがオブジェクトの上を通過したことを絶対に確認したい場合は、オブジェクトを完全にスキップするほど速く移動した場合でも、2フレームのマウスポイント間のポイントを確認する必要があります。
たとえば、次のようになります。
d.addEventListener(Event.ENTER_FRAME, checkMouseOver);
var lastPoint:Point;
const MAX_DIST:Number = 10;
function checkMouseOver(e:Event):void
{
var isOver:Boolean = false;
var d:DisplayObject = e.currentTarget as DisplayObject;
var thisPoint:Point = d.localToGlobal(new Point(d.mouseX,d.mouseY))
if (lastPoint)
while (Point.distance(thisPoint,lastPoint) > MAX_DIST)
{
var diff:Point = thisPoint.subtract(lastPoint);
diff.normalize(MAX_DIST);
lastPoint = lastPoint.add(diff);
if (d.hitTestPoint(lastPoint.x,lastPoint.y,true))
{
isOver = true;
break;
}
}
if (d.hitTestPoint(thisPoint.x,thisPoint.y,true))
isOver = true;
lastPoint = thisPoint;
//do whatever you want with isOver here
}
最後の状態が終了したかどうかを思い出し、isOver!=wasOverのときにカスタムイベントをディスパッチできます。whileループ内でこれを行うと、非常に正確なマウスオーバー検出が得られます。
しかし、shapeFlag = trueのhitTestPointは、特に1つのフレームで大量に使用される場合、CPUにかなりの負荷がかかると思います。したがって、この場合、このMAX_DISTをできるだけ高く設定することをお勧めします。
次に数学を使用します。
if(mouseX>mc.x-(mc.width/2) && mouseX<mc.x+(mc.width/2) && mouseY>mc.y-(mc.height/2) && mouseY<mc.y+(mc.height/2)){
hovered = true;
//do stuff..
}else{
if(hovered){
hovered=false;
//do rollout stuff..
}
}
ムービークリップの登録ポイントに依存することに注意してください...この場合、登録ポイントはムービークリップの中央にあります。
別の方法はhitTestObject()
、関数に組み込まれていますshapeFlag = true;
。
マウスが「十分に迅速に」通過した場合、OSは、そもそも画面のその部分のマウスイベントをFlashに送信しなかった可能性があります。解像度が発火する(またはOSが処理できる)よりもはるかに速くマウスを動かすと、目撃している効果があります(実際、画面のその部分ではマウスイベントが処理されませんでした)。そうでない場合、MOUSE_OVERは確実に発火します(マウスが実際にムービークリップ上に少なくとも1つの移動イベントを生成する場合)。
ただし、さまざまなOSまたはブラウザのセキュリティ制限のため、マウスがステージ領域を離れる(Flashを離れる)場合、MOUSE_OUTイベントは発生しない可能性があります。
これを修正するには、stage::flash.events.Event.DEACTIVATEとstage:: flash.events.Event.MOUSE_LEAVEのリスナーを登録します。これは、MOUSE_OUTをリッスンしているすべてのスプライト/ムービークリップ内で、同じハンドラー関数を再利用します。
mouseLeaveイベント(ステージによって発生)は、特に問題のために作成されます。「ポインターがステージ領域から移動すると、Stageオブジェクトによってディスパッチされます。マウスボタンが押された場合、イベントはディスパッチされません。」起動した場合は、MOUSE_OVER「状態」(おそらくそのような状態)のムービークリップのMOUSE_OUTのように処理する必要があります。ステージ領域を離れるときにマウスボタンが押された場合、ユーザーはある時点でマウスボタンを離す可能性が高く、代わりにDEACTIVATEがステージ上で起動します。
ステージ マウスの動きをリッスンして、マウスの下にあるクリップを確認することもできます。
stage.addEventListener(MouseEvent.MOUSE_MOVE , onMouseMove);
function onMouseMove(e:MouseEvent):void {
trace(stage.getObjectsUnderPoint(new Point(e.stageX , e.stageY)));
}
あなたのムービークリップが配列内にあるかどうかを確認してください。