|
|
|||||
Регистрация: Sep 2012
Сообщений: 1
|
Эмуляция движения мыши
Доброго времени суток.
Возникла задача загружать на сцену сторонний swf и там эмулировать движения мыши. С AS не слишком дружу, поэтому прошу посильной помощи. С загрузкой стороннего swf проблем вроде как нет, а вот с эмуляцией справиться не получилось. Буду благодарен за любую информацию. Есть неизвестная сторонняя флешка, в ней на событие "движение мыши" срабатывает анимация задача сделать некую оболочку, которая сможет загрузить такую стороннюю флешку и вызвать в ней событие "движение мыши" (анимацию) по определенным координатам, то есть как-то эмулировать без непосредственного движения мыши |
|
|||||
Регистрация: Jun 2006
Адрес: Москва
Сообщений: 461
|
Не получится, в AS3 нет возможности управлять курсором мыши. Экранные же объекты получаются события мыши только при реальном ее использовании, поэтому даже отправка своих мышиных событий не возимеет эффект (безопасность, все дела).
Хотя термин "отправка" тут используется в контексте отношения "ребенок к родителю", а не наоборот. |
|
|||||
getObjectsUnderPoint по координатам фейкового указателя.
Проходитесь по массиву и диспетчите-баблите вручную нужный набор событий из подходящего InteractiveObject (верхний из тех, кто mouseEnabled) Вот на коленке наваял пример: package { import flash.display.DisplayObjectContainer; import flash.display.Sprite; import flash.events.Event; [SWF(width="900", height="900")] public class fakeMouseTestContent extends Sprite { private static const NUM_IN_LAYER : Number = 3; private static const DEEP : Number = 3; private var _circles : Vector.<Vector.<Sprite>> = new Vector.<Vector.<Sprite>>(DEEP); public function fakeMouseTestContent() { //Security.allowDomain('*'); if(stage) { init(); } else { addEventListener(Event.ADDED_TO_STAGE, onAddedToStage); } } //*** private ***// private function init():void { drawBg(); createCircles(this); } private function drawBg():void { graphics.beginFill(0x0, 0); graphics.drawRect(0, 0, stage.stageWidth, stage.stageHeight); } private function createCircles(host : DisplayObjectContainer):void { for(var deepCount : int = 0; deepCount < DEEP; deepCount++) { _circles[deepCount] = new Vector.<Sprite>(NUM_IN_LAYER); for(var circleCount : int = 0; circleCount < NUM_IN_LAYER; circleCount++) { var circle : InteractiveCircle = new InteractiveCircle(InteractiveCircle.MAX_SIZE/(1 + deepCount)); _circles[deepCount][circleCount] = circle; circle.name = 'deep : ' + deepCount + ' , num : ' + circleCount; if(deepCount > 0) { var parentLayer : Vector.<Sprite> = _circles[deepCount-1]; var parentCircle : Sprite = parentLayer[int(Math.random() * parentLayer.length)]; parentCircle.addChild(circle); } else { host.addChild(circle); } var circleParent : DisplayObjectContainer = circle.parent; circle.x = Math.random()*(circleParent.width - circle.width); circle.y = Math.random()*(circleParent.height - circle.height); } } } //*** handlers ***/// private function onAddedToStage(event : Event):void { init(); } } } import flash.display.Sprite; import flash.events.MouseEvent; internal class InteractiveCircle extends Sprite { public static const MAX_SIZE : Number = 400; private static const COLOR : uint = 0x0; private static const FILL_ALPHA : Number = 0.5; private static const OUT_ALPHA : Number = 0.5; private static const OVER_ALPHA : Number = 1; public function InteractiveCircle(size : Number = MAX_SIZE) { initListeners(); draw(size); toOutState(); } //*** private ***// private function draw(size : Number):void { graphics.clear(); graphics.beginFill(COLOR, FILL_ALPHA); graphics.drawCircle(size/2, size/2, size/2); } private function initListeners():void { addEventListener(MouseEvent.MOUSE_OVER, onMouseOver); addEventListener(MouseEvent.MOUSE_OUT, onMouseOut); } private function toOverState():void { alpha = OVER_ALPHA; } private function toOutState():void { alpha = OUT_ALPHA; } //*** handlers ***// private function onMouseOver(event : MouseEvent):void { trace('over. name : ' + event.currentTarget.name); toOverState(); } private function onMouseOut(event : MouseEvent):void { trace('out. name : ' + event.currentTarget.name); toOutState(); } } package { import flash.display.Loader; import flash.display.Sprite; import flash.events.Event; import flash.net.URLRequest; import flash.system.LoaderContext; [SWF(width="900", height="900")] public class fakeMouseTestContainer extends Sprite { private static const URL : String = 'fakeMouseTestContent.swf'; private static const REQUEST : URLRequest = new URLRequest(URL); private var _loader : Loader; private var _fakeCursor : FakeCursor; public function fakeMouseTestContainer() { init(); loadContent(); } //*** private ***// private function init():void { _loader = new Loader(); _loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onLoadComplete); addChild(_loader); _fakeCursor = new FakeCursor(); addChild(_fakeCursor); _fakeCursor.x = stage.stageWidth/2; _fakeCursor.y = stage.stageHeight/2; KeyboardManager.init(stage); } private function loadContent():void { var context : LoaderContext = new LoaderContext(false); _loader.load(REQUEST, context); } //*** handlers ***// private function onLoadComplete(event : Event):void { _fakeCursor.reset(); } } } package { import flash.display.InteractiveObject; import flash.display.Sprite; import flash.events.Event; import flash.events.MouseEvent; import flash.geom.Point; import flash.ui.Keyboard; import flash.utils.Dictionary; public class FakeCursor extends Sprite { private static const SIZE : Number = 10; private static const COLOR : uint = 0xAA00AA; private static const ALPHA : Number = 0.5; private static const SPEED : Number = 10; private static const DIRECTIONS : Object = initDirections(); // private var _currObjectsUnderPoint : Dictionary; private var _currentTopObject : InteractiveObject; private var _currentPoint : Point; public function FakeCursor() { draw(); addEventListener(Event.ADDED_TO_STAGE, onAddedToStage); addEventListener(Event.REMOVED_FROM_STAGE, onRemovedFromStage); } //*** public ***// public function reset():void { _currObjectsUnderPoint = new Dictionary(true); _currentTopObject = null; _currentPoint = null; onEnterFrame(null); } //*** private ***// private function draw():void { graphics.beginFill(COLOR, ALPHA); graphics.drawCircle(0, 0, SIZE/2); } //*** handlers ***// private function onEnterFrame(event : Event):void { move(); findInteractObject(); } private function move():void { var pressedKeys : Array = KeyboardManager.getPressedKeys(); var direction : Point = new Point(); for each(var keyCode : int in pressedKeys) { var currDirection : Point = DIRECTIONS[keyCode] as Point; if(currDirection) { direction = direction.add(currDirection); } } x += direction.x * SPEED; y += direction.y * SPEED; } private function findInteractObject():void { var globalPoint : Point = this.localToGlobal(new Point()); var objects : Array; var numObjects : uint; var objectsHash : Dictionary; var topObject : InteractiveObject; if(_currentPoint && _currentPoint.equals(globalPoint)) { return; } _currentPoint = globalPoint; objects = stage.getObjectsUnderPoint(globalPoint); objectsHash = new Dictionary(); numObjects = objects.length; for(var i : int = 0; i < numObjects; i++) { var object : InteractiveObject = objects[i] as InteractiveObject; if(object) { if(!topObject) { topObject = object; } objectsHash[object] = object; } } handleUnderObjects(objectsHash, topObject); } private function handleUnderObjects(newObjects : Dictionary, topObject : InteractiveObject):void { for each(var oldObject : InteractiveObject in _currObjectsUnderPoint) { if((oldObject in newObjects) == false) { disptatchMouseEvent(oldObject, MouseEvent.MOUSE_OUT, topObject); } } for each(var newObject : InteractiveObject in newObjects) { if((newObject in _currObjectsUnderPoint) == false) { disptatchMouseEvent(newObject, MouseEvent.MOUSE_OVER, _currentTopObject); } } _currObjectsUnderPoint = newObjects; if(_currentTopObject != topObject) { if(_currentTopObject) { disptatchMouseEvent(_currentTopObject, MouseEvent.MOUSE_OUT, topObject); } if(topObject) { disptatchMouseEvent(topObject, MouseEvent.MOUSE_OVER, _currentTopObject); } _currentTopObject = topObject; } } private function disptatchMouseEvent(object : InteractiveObject, type : String, relatedObject : InteractiveObject):void { var globalPoint : Point = new Point(this.x, this.y); var localPoint : Point = object.globalToLocal(globalPoint); var localX : Number = localPoint.x; var localY : Number = localPoint.y; var event : MouseEvent = new MouseEvent(type, true, false, localX, localY, relatedObject) object.dispatchEvent(event); } //*** handles ***// private function onAddedToStage(event : Event):void { reset(); addEventListener(Event.ENTER_FRAME, onEnterFrame); } private function onRemovedFromStage(event : Event):void { removeEventListener(Event.ENTER_FRAME, onEnterFrame); } //*** private static ***// private static function initDirections():Object { var directions : Object = {}; directions[Keyboard.UP] = new Point(0, -1); directions[Keyboard.DOWN] = new Point(0, 1); directions[Keyboard.LEFT] = new Point(-1, 0); directions[Keyboard.RIGHT] = new Point(1, 0); return directions; } } }
__________________
9 из 10 голосов в моей голове сказали наркотикам "НЕТ" Мои ачивки: художник-паразит. Последний раз редактировалось ChuwY; 07.09.2012 в 18:12. |
|
|||||
Регистрация: Jun 2006
Адрес: Москва
Сообщений: 461
|
Баблить событие это конечно хорошо, но такой трюк пройдет, если у нас обе флешки в руках. Если же флешка сторонняя, как я понял у автора, то каким макаром мы отправим события через стадии захвата и таргета?
|
|
|||||
Цитата:
Флешка-контент это просто пример интерактивного приложения, реагирующего на различные мышесобытия. Вся эмуляция производится в загрузчике. 1. Вы ХОТЬ РАЗ пользовались фазой захвата? 2. Тем не менее фаза захвата вполне себе эмулируется таким образом. 3. Диспатч с баблингом проводит событие по фазе цели и фазе восходящей маршрутизации.
__________________
9 из 10 голосов в моей голове сказали наркотикам "НЕТ" Мои ачивки: художник-паразит. |
|
|||||
Регистрация: Jun 2006
Адрес: Москва
Сообщений: 461
|
Цитата:
var event : MouseEvent = new MouseEvent(type, true, false, localX, localY, relatedObject) object.dispatchEvent(event); Вы диспатчите событие своим курсором и обходитесь своими обработчиками, а обработчики целевой флешки никак не могут быть задействованы. Кто же будет диспатчить вам мышиное события из сторонней флешки, которую мы будем таким образом слушать, если реального взаимодействия с мышью нет. Да, мы используем прослойку, и ловим интерактивные элементы, мы знаем, что в флешке что-то может реагировать на мышь... Но мы не знаем, что именно происходит в целевой флешке в обработчиках этих мышиных событий, а автору нужно именно это, как я понял (т.е. должен отработать внутренний хэндлер при прохождении фейково мышки по дисплей обжекту, а не фейковая мышка отрапортовать, что тут вот типа мышь задействована может быть). Если это play() всей флешки, хорошо, я если что-то посложней? Т.е. вашим методом мы можем отследить где и когда может возникнуть мышиный эвент, но вот что должно произойти во флешке по ним - не узнаем до использования настоящей мыши. Вопрос немного в сторону: по идее ваш метод не будет работать в контексте безопасности, когда действие должно быть обязательно произведено на физическом уровне (реальный клик мышью, например, для для перехода в фуллскрин), а не программным диспатчем мышиных событий. Только этот момент меня и смутил, а как вариант способа определения интерактивности частей загруженной флешки - вполне элегантное решение Прошу прощения, если сумбурно объяснил этот момент. Последний раз редактировалось Hidest; 07.09.2012 в 17:48. |
|
|||||
Цитата:
Событие рассылает именно тот самый объект, который рассылал бы его в том случае, если бы вместо фейкового указателя был настоящий. При этом срабатывают самые настоящие хендлеры целевой флешки. p.s. Извиняюсь, архив с исходниками отлепился от сообщения. Прикрепляю заново.
__________________
9 из 10 голосов в моей голове сказали наркотикам "НЕТ" Мои ачивки: художник-паразит. |
|
|||||
Регистрация: Jun 2006
Адрес: Москва
Сообщений: 461
|
Тьфу, минус мне за невнимательность, не заметил, что реально объект диспатчит событие, а не фейковые курсор и его хендлеры как раз и должны сработать. Вопрос снят
|
Часовой пояс GMT +4, время: 07:28. |
|
« Предыдущая тема | Следующая тема » |
|
|