|
|
« Предыдущая тема | Следующая тема » |
Опции темы | Опции просмотра |
|
|
|||||
Регистрация: Dec 2008
Сообщений: 87
|
Как это - MOUSE_OUT сработал, а hitTestPoint возвращает true
Вот упрощенный вариант.
На сцене клип mc с двумя кадрами. По MOUSE_OVER и MOUSE_OUT - прыгает с кадра на кадр. При перетаскивании - мышь слетает с клипа и он "моргает". Чтобы этого избежать - отключаю слушатели на время таскания. При MOUSE_UP возвращаю их на место, но нужно перевести клип в нужный кадр. И тут использую hitTestPoint, чтобы проверить, над клипом мышь или нет. Если нет - прыгаю на первый кадр. Так вот: если резко потащить клип и бросить его - можно отловить ситуацию, когда hitTestPoint вернет true и клип не сбросится в деактивированное состояние. По идее, если MOUSE_UP сработало над клипом, должен был включиться обработчик MOUSE_OUT и сбросить клип, но trace показывает, что событие уже произошло ДО этого. Минималистический пример: import flash.events.MouseEvent; import flash.geom.Point; var dltY:Number; mc.buttonMode = true; mc.addEventListener(MouseEvent.MOUSE_OVER, mOver); mc.addEventListener(MouseEvent.MOUSE_OUT, mOut); mc.addEventListener(MouseEvent.MOUSE_DOWN, mDown); function mOver(e:MouseEvent){ mc.gotoAndStop(2); } function mOut(e:MouseEvent){ mc.gotoAndStop(1); } function mDown(e:MouseEvent){ mc.removeEventListener(MouseEvent.MOUSE_OVER, mOver); mc.removeEventListener(MouseEvent.MOUSE_OUT, mOut); stage.addEventListener(MouseEvent.MOUSE_MOVE, mMove); stage.addEventListener(MouseEvent.MOUSE_UP, mUp); dltY = mouseY - mc.y; } function mMove(e:MouseEvent){ mc.y = mouseY - dltY; e.updateAfterEvent(); } function mUp(e:MouseEvent){ mc.addEventListener(MouseEvent.MOUSE_OVER, mOver); mc.addEventListener(MouseEvent.MOUSE_OUT, mOut); stage.removeEventListener(MouseEvent.MOUSE_MOVE, mMove); stage.removeEventListener(MouseEvent.MOUSE_UP, mUp); checkHit(); } function checkHit(){ if(!mc.hitTestPoint(stage.mouseX, stage.mouseY)){ mc.gotoAndStop(1); } } |
|
|||||
Думаю не нужен здесь hitPoint. Просто контролируйте момент драга. Что-то вроде этого:
import flash.events.MouseEvent; mc.stop(); var _isDrag=false; // DRAG mc.addEventListener(MouseEvent.MOUSE_DOWN, mcMouseDown) function mcMouseDown(e:MouseEvent):void { stage.addEventListener(MouseEvent.MOUSE_MOVE, stageMouseMove); stage.addEventListener(MouseEvent.MOUSE_UP, stageMouseUp); _isDrag=true; } function stageMouseUp(e:MouseEvent):void { stage.removeEventListener(MouseEvent.MOUSE_MOVE, stageMouseMove); stage.removeEventListener(MouseEvent.MOUSE_UP, stageMouseUp); _isDrag=false; } function stageMouseMove(e:MouseEvent):void { mc.x=stage.mouseX; mc.y=stage.mouseY; } //OVER OUT mc.addEventListener(MouseEvent.ROLL_OVER, mcRollOver); mc.addEventListener(MouseEvent.ROLL_OUT, mcRollOut); function mcRollOver(e:MouseEvent):void { mc.gotoAndStop(2); } function mcRollOut(e:MouseEvent):void { if(!_isDrag) mc.gotoAndStop(1); } |
|
|||||
Регистрация: Dec 2008
Сообщений: 87
|
Спасибо. Ваш пример вообще не сбрасывает клип на 1-ый кадр при отпускании мыши в случае привязки клипа не по центру. А если по центру - то все равно глюк отлавливает при резком переносе.
Не знаю, как сюда ссылку на видео добавить... видимо, нельзя. Рискну. Там всего 300 килобайт. https://yadi . sk/i/S3tqcPe3mKSX9 |
|
|||||
Регистрация: Apr 2009
Сообщений: 409
|
флеш так же слушает мув, и так же выполняет hitTest для того чтобы диспатчить over и out. и делает он это раньше вашего слушателя move. то есть если мышка переместилась за такт больше чем размер объекта и вышла за его пределы. флеш диспатчит аут, перед тем как ваш мув должен его сдвинуть. но пример все равно не понятный, если использовать startDrag проблемы нет? еще попробуйте в move смотреть координаты передаваемые с событием. может оно не успевает всплыть и обновить mouseX стейджа
|
|
|||||
Регистрация: Dec 2008
Сообщений: 87
|
Про startDrag не скажу, мне он не подходит.
Ну, вот давайте упростим до минимума: import flash.events.MouseEvent; mc.stop(); mc.addEventListener(MouseEvent.ROLL_OUT, mcRollOut); function mcRollOut(e:MouseEvent):void { trace("mcRollOut", e.stageX, e.stageY) if(mc.hitTestPoint(e.stageX, e.stageY)){ trace("внутри", e.stageX, e.stageY) } } Вопрос - будет ли выполняться traсe? Ответ - да, при медленном движении мыши. Вот вывод при движении мыши вниз. А вот при движении вверх: 149 - это максимальная величина (и для меня это ожидаемо). По координате х - ситуация похожая. Почему срабатывает mcRollOut в точке 228 250, если эта точка все еще принадлежит прямоугольнику? |
|
|||||
Нуб нубам
модератор форума
Регистрация: Jan 2006
Адрес: Бердск, НСО
Сообщений: 6,445
|
Как 250 принадлежит прямоугольнику, если он размером 100 с привязкой по центру в координате 200?
Первый пиксель то это не "1", а "0". Соответственно 100-й пиксель прямоугольника имеет stage-координату 249. Подумайте об этом так: если бы Вы захотели прямо вплотную к этому прямоугольнику расположить второй прямоугольник - какую координату Вы ему зададите, 250 или 251? Ответ - 250. И это уже НЕ принадлежит первому.
__________________
Reality.getBounds(this); |
|
|||||
Регистрация: Dec 2008
Сообщений: 87
|
Wolsh, спасибо, я предполагал это. Но почему тогда срабатывает hitTestPoint?
Мне hitTestPoint нужен, потому что у меня движение ограничено, скажем, по y, как в моем первом примере. Т.е. мышь при отпускании кнопки слетит с клипа с большой долей вероятности. Можно событие CLICK подключить (и по нему активировать кнопку принудительно), но это не решает проблему полностью. Как вообще избежать этого глюка? Дайте идею, пожалуйста. |
|
|||||
Нуб нубам
модератор форума
Регистрация: Jan 2006
Адрес: Бердск, НСО
Сообщений: 6,445
|
Ну, вообще, первое что приходит в голову это использовать MOUSE_UP от клипа, а не от стейджа.
А чтобы ловить отпускание мыши вне клипа, подписаться на RELEASE_OUTSIDE опять же от клипа. Но я не гарантирую, что это защитит "от шумахера", надо протестировать. Добавлено через 8 минут Использование хиттеста вообще не должно приходить в голову, особенно при быстром движении, так как код исполняется ДО отрисовки и будет глючить по определению. Попросту говоря, хиттест проверяет совпадение с объектом, отрисованным в прошлом кадре. Добавлено через 15 минут Еще один вариант - разобраться с последовательностью событий. Например, при ROLL_OUT можно проверять свойство MouseEvent#button - нажата ли кнопка, или отпущена.
__________________
Reality.getBounds(this); |
|
|||||
Регистрация: Dec 2008
Сообщений: 87
|
Wolsh, большое спасибо за идеи, буду пробовать.
RELEASE_OUTSIDE спас ситуацию. Я тестировал в CS6, где плеер ограничивается версией 11.2 и это событие было недоступно. Во FD со свежей версией плеера все работает. Wolsh, спасибо и за подсказку по хиттесту. Не знал, что он работает с отрисовкой. Добавлено через 2 часа 4 минуты Кажется, я поторопился радоваться. В проекте глюк повторился. Трейсы показывают, что MOUSE_UP, сработал после ROLL_OUT, хотя оба события привязаны к клипу, что я понять уже никак не могу. Попробую Ваш второй вариант... Добавлено через 2 часа 39 минут Второй вариант с событием e.buttonDown, кажется, сработал! По крайней мере, отловить не удается. Последний раз редактировалось Bred45; 21.12.2015 в 11:47. |
Часовой пояс GMT +4, время: 13:18. |
|
« Предыдущая тема | Следующая тема » |
Опции темы | |
Опции просмотра | |
|
|