Simulate mouse events in ActionScript 3

Given the coordinates of the scene (x, y), I want my flash application to act as if the user clicked on the position (x, y). That is, something like

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

I found a bunch of pages telling about this, and they all give solutions similar to those described above. However, this is not equivalent to user click (x, y). There are two problems:

First, e.stageX and e.stageY are zero. I can not install them directly. The documentation says that they are calculated when installing e.localX and e.localY, but this does not happen when I install e.localX before sending it to the receiver or event listener.

I could rewrite all my event listeners like this:

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

Is this the only option?

The second problem is that my event listeners register with the children of the scene, not the scene itself. Therefore, I need to find out for what purpose to call dispatchEvent. Clearly, Flash is able to determine what the target should be, i.e. Which object belongs to the topmost pixel, visible at (x, y), because it does this when the user actually clicks. Is there an easy way to get this information, or should I just write my own recursive function to do the same? I am using DisplayObjectContainer.getObjectsUnderPoint at the moment, but this is not entirely correct.

I write in FlashDevelop if that matters.

+4
source share
3 answers

e.stageX/Y populated correctly for me ... also getObjectsUnderPoint() works fine. I assume that the x / y values ​​passed to simulateClick are global coordinates?

edit: as indicated in the comments, the mouse event should be dispatched on InteractiveObject instances ... changed the code accordingly.

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

Output:

 target: child 2 localX: 40 localY: 40 stageX: 190 stageY: 190 
+1
source

In question 1: After creating the MouseEvent (assigning it a local x, y), you should be able to directly reference e.stageX and set it for whatever you want before the event is sent. This is simply a property of the MouseEvent instance. For # 2, the currentTarget is always the topmost part of the mouse, while the target is what sends the event - assuming the event is actually sent by mouse interaction. In your case, you can set the target as any object to which you sent an event, and set the currentTarget value arbitrarily. The question is, is this really the most effective way to deal with what's under your arm right now; and the answer is probably no. You would be much better off using the MOUSE_OVER event to make sure the mouse is finished right now, save it as a variable that you can use when you want to name it, and don't try to iterate over the entire display chain all the time (because Flash initially does it is much faster than you can do it in a loop). If you put mouseOver on the scene and just check the currentTarget, you get that the topmost element is under the mouse, in every frame where it changes.

You should be aware that (to prevent some obvious nasty scripts), certain actions cannot be triggered by mouse events that are dynamically generated by ActionScript. These include opening a file link and viewing in full screen.

0
source

I also ran into this problem, was a little sick. In my situation, I was creating an event, performing some complex calculations, but I could not get the global coordinates, although I already set the local coordinates.

In fact, the solution was quite obvious in my case ... Global coordinates are filled only AFTER the event is dispatched , otherwise how can the event know how to translate local to global?

This is another error, on top of not checking the object used to dispatch the event as an InteractiveObject .

I am posting this because someone might run into this problem due to both errors. The quick answer is easy to read.

0
source

Source: https://habr.com/ru/post/1437303/


All Articles