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

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

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

Регистрация: Jan 2010
Сообщений: 26
По умолчанию hitTestPoint глючит

Не могу понять в чем дело, подскажите кто знает.

Есть 2 объекта ss1 и ss2.
Хочу узнать находится ли мышка над ними.

Но не непрямую, а через объект higlight, который выравнивается сначала с ss1 и проверяется на пересечение с мышкой, а потом выравнивается с ss2 и тоже проверяется на мышку.

Глюк в том что первая проверка на мышку не срабатывает. Точнее срабатывает только тогда, когда мышь находится на пересечении фигур

Код AS3:
import flash.geom.ColorTransform;
var color:ColorTransform = new ColorTransform();;
 
//Выравнивание с ss1
higlight.x = ss1.x;
higlight.y = ss1.y;
//Проверка на мышку и подсветка
	if (higlight.hitTestPoint(mouseX,mouseY,true)) {
		color.redOffset   = 50;
		ss1.transform.colorTransform = color;
	} else {
		color.redOffset   = 0;
		ss1.transform.colorTransform = color;
	}
 
//Выравнивание с ss2
higlight.x = ss2.x;
higlight.y = ss2.y;
//Проверка на мышку и подсветка
	if (higlight.hitTestPoint(mouseX,mouseY,true)) {
		color.redOffset   = 50;
		ss2.transform.colorTransform = color;
	} else {
		color.redOffset   = 0;
		ss2.transform.colorTransform = color;
	}

Этот код может работать так как нужно, только если в hitTestPoint свойство shapeFlag поставить в false, но мне нужно именно true для большей точности.
Вложения
Тип файла: zip hitTest_src.zip (8.6 Кб, 65 просмотров)

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

Регистрация: Mar 2010
Адрес: Электросталь
Сообщений: 38
Проблема в том, что скрипт выполняется ВЕСЬ и сразу, то есть фактически

Код AS3:
higlight.x = ss1.x;
higlight.y = ss1.y;
эта часть пропускается (точнее она выполняется, но тут же идёт переопределение):

Код AS3:
higlight.x = ss2.x;
higlight.y = ss2.y;
поэтому код выполняется лишь в том случае, когда мышка над объектом ss2

Предлагаю вам ввести слушатели событий, типа MOUSE_OVER

Добавлено через 5 минут
И кстати, наверняка у вас возникнут проблемы с индексами, ибо рамка выделения всегда будет сверху, посоветую использовать swapChildren и свойство mouseEnabled = false - тем самым оно будет игнорировать объекты на "мышкабельность" и щелчок и наведение мыши будут проходить насквозь


Последний раз редактировалось NBVestal; 22.03.2010 в 11:21.
Старый 22.03.2010, 16:55
sltt вне форума Посмотреть профиль Отправить личное сообщение для sltt Найти все сообщения от sltt
  № 3  
Ответить с цитированием
sltt

Регистрация: Jan 2010
Сообщений: 26
Цитата:
Сообщение от NBVestal Посмотреть сообщение
Проблема в том, что скрипт выполняется ВЕСЬ и сразу
Но если вместо
higlight.hitTestPoint(mouseX,mouseY,true)
написать
higlight.hitTestPoint(mouseX,mouseY,false)
то оно работает

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

Регистрация: Mar 2010
Адрес: Электросталь
Сообщений: 38
ну это логично - ваша флешка состоит из двух кадров - одного ключевого и одного простого, и так как она постоянно проигрывается, следовательно, флешка обновляется и тем самым происходит это наложение...но с точки зрение программирования это не верно - раньше сам такую ошибку делал - всё должно умещаться в пределах одного ключевого кадра и обрабатываться с помощью слушателей событий...сейчас попробую написать правильный код с пояснением

Добавлено через 24 минуты
Только просмотрите код ВНИМАТЕЛЬНО, вообще по логике вам не нужен hitTestPoint

Код AS3:
import flash.geom.ColorTransform;
var color:ColorTransform = new ColorTransform();
 
 
function ss1_nad(event:MouseEvent):void {
        //Выравнивание с ss1
        higlight.x = ss1.x;
        higlight.y = ss1.y;
 
	color.redOffset = 50;
	ss1.transform.colorTransform = color; 
}
 
function ss1_nad_out(event:MouseEvent):void	{
	color.redOffset = 0;
	ss1.transform.colorTransform = color;
}
 
 
function ss2_nad(event:MouseEvent):void {
        //Выравнивание с ss2
        higlight.x = ss2.x;
        higlight.y = ss2.y;
 
	color.redOffset = 50;
	ss2.transform.colorTransform = color;
}	
 
function ss2_nad_out(event:MouseEvent):void {
	color.redOffset = 0;
	ss2.transform.colorTransform = color;
}
 
 
ss1.addEventListener(MouseEvent.MOUSE_OVER, ss1_nad);
ss2.addEventListener(MouseEvent.MOUSE_OVER, ss2_nad);
//добавляем двум объектам слушателей события "мышь над объектом"
 
ss1.addEventListener(MouseEvent.MOUSE_OUT, ss1_nad_out);
ss2.addEventListener(MouseEvent.MOUSE_OUT, ss2_nad_out);
//добавляем двум объектам слушателей события "мышь за пределами объекта"
//соответствующие функции см выше
 
higlight.mouseEnabled = false;
//это ОЧЕНЬ важный пункт - это свойство позволяет мыши как бы пройти НАСКВОЗЬ
//объекта higlight, для того, чтобы мышка взаимодействовала только с ss1 и ss2
если есть вопросы по коду, задавайте...

и ещё одно...все три объекта, естественно, имеют три разных индекса отображения (я про передний и задний план), чтобы подсветка правильно выполнялась, надо постоянно менять местами индексы объектов. Поэкспериментируйте с функцией swapChildren

Добавлено через 34 минуты
И да, не забудьте оставить в своём ролике только ОДИН кадр - первый ключевой

Старый 22.03.2010, 20:00
sltt вне форума Посмотреть профиль Отправить личное сообщение для sltt Найти все сообщения от sltt
  № 5  
Ответить с цитированием
sltt

Регистрация: Jan 2010
Сообщений: 26
Да, этот код работает, но не в ту сторону.

Как я уже писал, мне нужно определить не момент MOUSE_OVER, MOUSE_OUT на ss1 и ss2, а узнать, находится ли в данный момент мышка над объектом higlight, который выровнян с ss1,ss2.

Поясню для чего это вообще нужно.
Есть куча полупрозрачных png. Все они двигаются.
Мне нужно узнать над какими находится мышка, не учитывая область полупрозрачности.
Я знаю что есть библиотеки для таких случаев, но при размере каждого рисунка 100:100px и их количестве в 50 штук, мувик начинает заметно грузить процессор даже на хорошей машине.

Поэтому изобретаю велосипед.
Есть куча PNG, и одна векторная маска, которая по очереди выравнивается с каждым из рисунков и проверяется на мышку.

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

Регистрация: Mar 2010
Адрес: Электросталь
Сообщений: 38
Так в чём проблема? Если нужно узнать, находится ли в данный момент мышка над объектом higlight, то просто добавить слушатель события этому объекту, и сделать тогда проверку на равенство координат с помощью if

а чтобы процессор не грузился, нужно весь код распределить по классам, да к тому же пользоваться addChild() и removeChild() с удалением всех ссылок, чтобы работал сборщик мусора, к тому же можно удалять слушатели события в случае ненадобности (removeEventListener), а то при многократном прохождении кода процессор начинает грузиться, и чем меньше в нём лишнего, и чем динамичней все объекты, тем лучше

а этот способ "векторная маска, которая по очереди выравнивается с каждым из рисунков и проверяется на мышку" это очень нерентабельно с точки зрения программирования, и, естественно, при такой прогонке процессор нереально загружен, поэтому данная проверка должна вызываться, когда мышка находится над экземпляром желаемого объекта, то есть MOUSE_OVER. А прогонять проверку по всем элементам с помощью постоянного обновления кадров или слушателя ENTER_FRAME - это огромная и абсолютно лишняя затрата памяти


Последний раз редактировалось NBVestal; 22.03.2010 в 20:49.
Старый 22.03.2010, 21:15
sltt вне форума Посмотреть профиль Отправить личное сообщение для sltt Найти все сообщения от sltt
  № 7  
Ответить с цитированием
sltt

Регистрация: Jan 2010
Сообщений: 26
Цитата:
Сообщение от NBVestal Посмотреть сообщение
а этот способ "векторная маска, которая по очереди выравнивается с каждым из рисунков и проверяется на мышку" это очень нерентабельно с точки зрения программирования, и, естественно, при такой прогонке процессор нереально загружен
Вы знаете менее затратный способ проверки полупрозрачных PNG на пересечение, нежели перемещение 1-го Sprite и его проверка HitTestPoint?

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

Регистрация: Mar 2010
Адрес: Электросталь
Сообщений: 38
я не понимаю смысл использования HitTestPoint, если вы всё равно накладываете спрайт на объект с точно такими же координатами. гораздо удобнее, по-моему, использовать hitTestObject в этом случае, всё равно тут нет явной проверки на точку. И от прозрачности это не зависит, они всё равно пересекаются границей прямоугольного контейнера, а не фактической графикой...

Или взглянем на этот вопрос по другому...то есть, вам нужно, чтобы объект higlight прошёлся по всем графическим объектам, и в каждом случае выполнялась проверка? Только вот зачем это? Тогда надо задавать какой то интервал, а то все эти перемещения будут мгновенными и незримыми. Ведь можно же просто поставить событие на наведение мышки, которое будет проверять, пересекается ли higlight с объектом, или нет...

Можно, например, задать в конструкторе объекта флаг, который будет меняться, если higlight равен данному объекту, и мышка находится над ним

Старый 22.03.2010, 22:08
sltt вне форума Посмотреть профиль Отправить личное сообщение для sltt Найти все сообщения от sltt
  № 9  
Ответить с цитированием
sltt

Регистрация: Jan 2010
Сообщений: 26
Цитата:
Сообщение от NBVestal Посмотреть сообщение
я не понимаю смысл использования HitTestPoint, если вы всё равно накладываете спрайт на объект с точно такими же координатами. гораздо удобнее, по-моему, использовать hitTestObject в этом случае, всё равно тут нет явной проверки на точку. И от прозрачности это не зависит, они всё равно пересекаются границей прямоугольного контейнера, а не фактической графикой...
public function hitTestPoint(x:Number, y:Number, shapeFlag:Boolean = false):Boolean
shapeFlag:Boolean (default = false) — Указывает, следует ли выполнять тестирование по фактическим пикселам объекта (true) или по рамке (false).

Цитата:
Сообщение от NBVestal Посмотреть сообщение
то есть, вам нужно, чтобы объект higlight прошёлся по всем графическим объектам, и в каждом случае выполнялась проверка? Только вот зачем это? Тогда надо задавать какой то интервал, а то все эти перемещения будут мгновенными и незримыми.
Дело в том что проходится по всем объектам придется в любом случае. Какой бы алгоритм здесь не использовался. А интервал, только добавит пропущенных пересечений.


Короче я так подумал, что самым оптимальным будет при создании Sprite с рисунком, запихивать туда-же "маску". Потом каждый шаг времени проверять пересечения спрайта и мышки методом hitTestPoint(x,y,false) и если они пересекаются, проверять маску методом hitTestPoint(x,y,true).
Изображения
 


Последний раз редактировалось sltt; 22.03.2010 в 22:15.
Старый 22.03.2010, 22:22
NBVestal вне форума Посмотреть профиль Отправить личное сообщение для NBVestal Найти все сообщения от NBVestal
  № 10  
Ответить с цитированием
NBVestal
 
Аватар для NBVestal

Регистрация: Mar 2010
Адрес: Электросталь
Сообщений: 38
Цитата:
Сообщение от sltt Посмотреть сообщение
public function hitTestPoint(x:Number, y:Number, shapeFlag:Boolean = false):Boolean
shapeFlag:Boolean (default = false) — Указывает, следует ли выполнять тестирование по фактическим пикселам объекта (true) или по рамке (false).
Знаю, но вы же проверяете не пересечение точки с объектом, а объекта с объектом...

К тому же, маску можно задать с помощью кода, параметр mask, если я не ошибаюсь

Я просто не понимаю, зачем проходиться по всем объектам, если можно добавить в конструкторе класса этого слушатель, и если уж какая то особо узкая специфика, создать своё событие, или отправлять конкретное событие с помощью dispatchEvent();

и чего я уж тем более не понимаю, ЗАЧЕМ проверять пересечение спрайта и мышки методом пересечения точки и спрайта, когда в том же классе можно добавить проверку на нахождение курсора над мышкой...это и проще, и понятнее, и быстрее работает, и не требует ежесекундной проверки, и маска - это не точка, поэтому лучше проверять hitTestObject'ом

Добавлено через 26 минут
просто, возможно, вам нужно взглянуть на вашу задачу с другой стороны, найти альтернативный подход к решению?

Создать новую тему Ответ Часовой пояс GMT +4, время: 23:39.
Быстрый переход
  « Предыдущая тема | Следующая тема »  

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

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


 


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


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