Форум Flasher.ru
Ближайшие курсы в Школе RealTime
Список интенсивных курсов: [см.]  
  
Специальные предложения: [см.]  
  
 
Блоги Правила Справка Пользователи Календарь Поиск рулит! Сообщения за день Все разделы прочитаны
 

Вернуться   Форум Flasher.ru > Flash > ActionScript 3.0

Версия для печати  Отправить по электронной почте    « Предыдущая тема | Следующая тема »  
Опции темы Опции просмотра
 
Создать новую тему Ответ
Старый 18.12.2015, 14:55
Bred45 вне форума Посмотреть профиль Отправить личное сообщение для Bred45 Найти все сообщения от Bred45
  № 1  
Ответить с цитированием
Bred45

Регистрация: Dec 2008
Сообщений: 87
Question Как это - MOUSE_OUT сработал, а hitTestPoint возвращает true

Вот упрощенный вариант.
На сцене клип mc с двумя кадрами.
По MOUSE_OVER и MOUSE_OUT - прыгает с кадра на кадр.
При перетаскивании - мышь слетает с клипа и он "моргает".
Чтобы этого избежать - отключаю слушатели на время таскания.
При MOUSE_UP возвращаю их на место, но нужно перевести клип в нужный кадр.
И тут использую hitTestPoint, чтобы проверить, над клипом мышь или нет.
Если нет - прыгаю на первый кадр.

Так вот: если резко потащить клип и бросить его - можно отловить ситуацию, когда hitTestPoint вернет true и клип не сбросится в деактивированное состояние. По идее, если MOUSE_UP сработало над клипом, должен был включиться обработчик MOUSE_OUT и сбросить клип, но trace показывает, что событие уже произошло ДО этого.

Минималистический пример:
Код AS3:
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);
	}
}

Старый 18.12.2015, 16:31
samana вне форума Посмотреть профиль Отправить личное сообщение для samana Найти все сообщения от samana
  № 2  
Ответить с цитированием
samana
 
Аватар для samana

блогер
Регистрация: Mar 2008
Адрес: Днепропетровск
Сообщений: 1,783
Записей в блоге: 3
Думаю не нужен здесь hitPoint. Просто контролируйте момент драга. Что-то вроде этого:
Код AS3:
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);
}

Старый 18.12.2015, 17:04
Bred45 вне форума Посмотреть профиль Отправить личное сообщение для Bred45 Найти все сообщения от Bred45
  № 3  
Ответить с цитированием
Bred45

Регистрация: Dec 2008
Сообщений: 87
Спасибо. Ваш пример вообще не сбрасывает клип на 1-ый кадр при отпускании мыши в случае привязки клипа не по центру. А если по центру - то все равно глюк отлавливает при резком переносе.

Не знаю, как сюда ссылку на видео добавить... видимо, нельзя.

Рискну. Там всего 300 килобайт.
https://yadi . sk/i/S3tqcPe3mKSX9

Старый 18.12.2015, 23:07
faraday вне форума Посмотреть профиль Отправить личное сообщение для faraday Найти все сообщения от faraday
  № 4  
Ответить с цитированием
faraday
 
Аватар для faraday

Регистрация: Apr 2009
Сообщений: 409
флеш так же слушает мув, и так же выполняет hitTest для того чтобы диспатчить over и out. и делает он это раньше вашего слушателя move. то есть если мышка переместилась за такт больше чем размер объекта и вышла за его пределы. флеш диспатчит аут, перед тем как ваш мув должен его сдвинуть. но пример все равно не понятный, если использовать startDrag проблемы нет? еще попробуйте в move смотреть координаты передаваемые с событием. может оно не успевает всплыть и обновить mouseX стейджа

Старый 19.12.2015, 17:19
Bred45 вне форума Посмотреть профиль Отправить личное сообщение для Bred45 Найти все сообщения от Bred45
  № 5  
Ответить с цитированием
Bred45

Регистрация: Dec 2008
Сообщений: 87
Про startDrag не скажу, мне он не подходит.
Ну, вот давайте упростим до минимума:

Код AS3:
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)
	}
}
Все тот две двухкадровый клип с привязкой по центру размером 100х100 лежит в точке (200,200);
Вопрос - будет ли выполняться traсe?
Ответ - да, при медленном движении мыши.
Вот вывод при движении мыши вниз.
Код:
mcRollOut 209 250
внутри 209 250
А вот при движении вверх:
Код:
mcRollOut 194 149
mcRollOut 191 147
mcRollOut 185 148
149 - это максимальная величина (и для меня это ожидаемо).
По координате х - ситуация похожая.

Почему срабатывает mcRollOut в точке 228 250, если эта точка все еще принадлежит прямоугольнику?

Старый 19.12.2015, 23:33
Wolsh вне форума Посмотреть профиль Отправить личное сообщение для Wolsh Найти все сообщения от Wolsh
  № 6  
Ответить с цитированием
Wolsh
Нуб нубам
 
Аватар для Wolsh

модератор форума
Регистрация: Jan 2006
Адрес: Бердск, НСО
Сообщений: 6,445
Как 250 принадлежит прямоугольнику, если он размером 100 с привязкой по центру в координате 200?
Первый пиксель то это не "1", а "0". Соответственно 100-й пиксель прямоугольника имеет stage-координату 249.
Подумайте об этом так: если бы Вы захотели прямо вплотную к этому прямоугольнику расположить второй прямоугольник - какую координату Вы ему зададите, 250 или 251?
Ответ - 250. И это уже НЕ принадлежит первому.
__________________
Reality.getBounds(this);

Старый 20.12.2015, 20:44
Bred45 вне форума Посмотреть профиль Отправить личное сообщение для Bred45 Найти все сообщения от Bred45
  № 7  
Ответить с цитированием
Bred45

Регистрация: Dec 2008
Сообщений: 87
Wolsh, спасибо, я предполагал это. Но почему тогда срабатывает hitTestPoint?

Мне hitTestPoint нужен, потому что у меня движение ограничено, скажем, по y, как в моем первом примере.
Т.е. мышь при отпускании кнопки слетит с клипа с большой долей вероятности. Можно событие CLICK подключить (и по нему активировать кнопку принудительно), но это не решает проблему полностью. Как вообще избежать этого глюка? Дайте идею, пожалуйста.

Старый 21.12.2015, 00:27
Wolsh вне форума Посмотреть профиль Отправить личное сообщение для Wolsh Найти все сообщения от Wolsh
  № 8  
Ответить с цитированием
Wolsh
Нуб нубам
 
Аватар для Wolsh

модератор форума
Регистрация: Jan 2006
Адрес: Бердск, НСО
Сообщений: 6,445
Ну, вообще, первое что приходит в голову это использовать MOUSE_UP от клипа, а не от стейджа.
А чтобы ловить отпускание мыши вне клипа, подписаться на RELEASE_OUTSIDE опять же от клипа.
Но я не гарантирую, что это защитит "от шумахера", надо протестировать.

Добавлено через 8 минут
Использование хиттеста вообще не должно приходить в голову, особенно при быстром движении, так как код исполняется ДО отрисовки и будет глючить по определению. Попросту говоря, хиттест проверяет совпадение с объектом, отрисованным в прошлом кадре.

Добавлено через 15 минут
Еще один вариант - разобраться с последовательностью событий. Например, при ROLL_OUT можно проверять свойство MouseEvent#button - нажата ли кнопка, или отпущена.
__________________
Reality.getBounds(this);

Старый 21.12.2015, 10:37
Bred45 вне форума Посмотреть профиль Отправить личное сообщение для Bred45 Найти все сообщения от Bred45
  № 9  
Ответить с цитированием
Bred45

Регистрация: 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.
Быстрый переход
  « Предыдущая тема | Следующая тема »  
Опции темы
Опции просмотра

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.


 


Часовой пояс GMT +4, время: 13:18.


Copyright © 1999-2008 Flasher.ru. All rights reserved.
Работает на vBulletin®. Copyright ©2000 - 2024, Jelsoft Enterprises Ltd. Перевод: zCarot
Администрация сайта не несёт ответственности за любую предоставленную посетителями информацию. Подробнее см. Правила.