PDA

Просмотр полной версии : MOUSE_OVER с учетом прозрачности


Korchy
13.12.2013, 18:16
Как правильно сделать контроль за наведением/уходом курсора на спрайт с учетом прозрачности перекрывающих спрайтов?
Например нужно подкрашивать линии при наведении курсора и возвращать цвет при уходе курсора с линии. Перекрывающие спрайты (красный круг) могут быть чайлдами линии, а могут и не быть.

Пока сделал так: в контейнере сцены, проверяю MOUSE_MOVE, определяю спрайт с учетом прозрачности всех остальных и ему адресно перенаравляю MOUSE_OVER, вроде бы работает, но решение кажется топорным:


protected function OnMouseMove(e:MouseEvent):void {
// Учесть прозрачность спрайтов для наведения мышки
if(lOnMouseOverFlag==false) {
// Первый проход - обработка (проверка по какому объекту было наведение с учетом прозрачности)
var OverObject:EventDispatcher = EventDispatcher(GetObjectUnderPoint(e.stageX, e.stageY));
if (lMouseOverObject != OverObject && lMouseOverObject != null) {
lMouseOverObject.dispatchEvent(new MouseEvent(MouseEvent.MOUSE_OUT));
lMouseOverObject = null;
}
if (OverObject != null && e.target != OverObject) {
lOnMouseOverFlag = true;
e.stopImmediatePropagation();
OverObject.dispatchEvent(new MouseEvent(MouseEvent.MOUSE_OVER));
lMouseOverObject = OverObject;
}
}
else {
// Второй проход - по правильному объекту с учетом прозрачности вышестоящих - сбросить флаг
lOnMouseOverFlag = false;
}

silin
13.12.2013, 23:07
не оч. понятно, что значит 'с учетом прозрачности перекрывающих спрайтов'
почему нельзя в MOUSE_OVER просто проверить, на что наехали: на линию или нет (e.target is Line) ?

Korchy
14.12.2013, 10:30
не оч. понятно, что значит 'с учетом прозрачности перекрывающих спрайтов'
почему нельзя в MOUSE_OVER просто проверить, на что наехали: на линию или нет (e.target is Line) ?


Я же картинку приложил: линию закрывает спрайт с дыркой. Нужно, чтобы при наведении на часть линии, которая видна в дырке от красного круга, она тоже реагировала на наведение/уход курсора.

caseyryan
14.12.2013, 11:37
http://www.flasher.ru/forum/showthread.php?t=202844

silin
14.12.2013, 20:59
сори, меня смутило, что речь о спрайте, если это не битмап, то в дырку и так будет "все видно"
package
{
import flash.display.Sprite;
import flash.events.MouseEvent;

public class Main extends Sprite
{

public function Main()
{
super();
var circle:Circle = new Circle();
var circle1:Circle = new Circle();
var line:Line = new Line();
var line1:Line = new Line();
line.x = line.y = 200;
line1.x = line1.y = 200;
circle1.x = circle1.y = 150;
line1.rotation = 45;

addChild(line1);
addChild(line);
line.addChild(circle); // могут быть чайлдами линии
addChild(circle1) // а могут и не быть

addEventListener(MouseEvent.MOUSE_OVER, mouseOver);
addEventListener(MouseEvent.MOUSE_OUT, mouseOut);

}

private function mouseOut(e:MouseEvent):void
{
var line:Line = e.target as Line;
if (line)
{
line.uncolorize();
}
}

private function mouseOver(e:MouseEvent):void
{
var line:Line = e.target as Line;
if (line)
{
line.colorize();
}
}

}

}
import flash.display.Sprite;

class Line extends Sprite
{
public function Line()
{
graphics.beginFill(0xC0C0C0);
graphics.drawRect(-100, -5, 200, 10);

}

public function colorize():void
{
graphics.clear();
graphics.beginFill(0xFF8000);
graphics.drawRect(-100, -5, 200, 10);
}

public function uncolorize():void
{
graphics.clear();
graphics.beginFill(0xC0C0C0);
graphics.drawRect(-100, -5, 200, 10);
}

}

class Circle extends Sprite
{
public function Circle()
{
graphics.beginFill(0x0000FF);
graphics.drawCircle(0, 0, 60);
graphics.drawCircle(0, 0, 40);

}
}

Korchy
15.12.2013, 11:09
2 caseyryan

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

2 silin

сори, меня смутило, что речь о спрайте, если это не битмап, то в дырку и так будет "все видно"

Нет, именно битмап. Сорри с моей стороны, видимо плохо изложил проблему. Красный круг с дыркой, это просто для примера, на самом деле будет битмапа сложной формы. Для спрайта с битмапдатой события не возникает, если он перекрыт вышележащим.