Вход

Просмотр полной версии : "Война" событий :)


Barss07
13.01.2006, 13:39
Друзья, подскажите, пожалуйста, как победить конфликт между событиями?

Вот есть clip1. Внутри него есть clip2.
====================================
clip1.clip2.onPress = function() {
trace("Зеленый");
};
====================================
При клике на втнутренний клип событие срабатывает.
Но стоит добавить обработчик для "внешнего" клипа -

====================================
clip1.onRollOver = function() {
trace("Над черным");
};
====================================
событие внутреннего клипа не происходит.

Весьма неудобно, приходится изголяться, сильно усложняя код.
Наверяка есть грамотное решение, а?

KPaul
13.01.2006, 13:52
Можно например юзать hitTest.
Или если я правильно помню, можно вместо клипов использовать Button-ы
и в основных пропертях сменить "Track as Button" на "Track as menu item".
Хотя могу и ошибаться...

antonyrec
13.01.2006, 13:54
Наверяка есть грамотное решение, а?

Есть. Поиск. Тема много раз обсуждалась. Поищи.

antonyrec
13.01.2006, 14:00
movie1.onRelease = function() {
trace("Событие для movie1");
if (this.movie2.hitTest(_xmouse, _ymouse, true)) {
this.movie2.onRelease();
}
};
movie1.movie2.onRelease = function() {
trace("Событие для movie2");
};

Barss07
13.01.2006, 14:25
Спасибо за ответы! Не попадалось мне обсуждение этого вопроса раньше, простите.

silin
13.01.2006, 15:07
>>Наверяка есть грамотное решение, а?
решений может быть много, но в каждом конкретном случае свое..
если любопытно вот решение,претендующее на некую универсальность:
на прототип мувиклипа вешаем просмотр хиттестов всех мувиков,
опредляем на какие пришелся клик,
если их несколько, вычисляем кто верхний,
вещаем событие с таргетом=этому мувику:
import mx.events.EventDispatcher;
EventDispatcher.initialize(MovieClip.prototype);

MovieClip.prototype.onRelease=function(){
if(!_root.hitTest(_xmouse,_ymouse,true))return;
var mc_array=[];
getMC=function(mc){
for(var i in mc)if(typeof mc[i] == 'movieclip' && mc[i].hitTest(_xmouse,_ymouse,true)){
mc_array.push(mc[i]);
getMC(mc[i]);
}
}
getMC(_root);//находим все мувики с которыми есть хиттест,
//хорошо если он один, если много нужно знать какой сверху
////////функции для сортировка пересекающихся мувиков////////////
var isParent=function (a,b){//является ли a потомком b ?
while((a=a._parent)!=_root) if(a==b) return true;
return false;
}
var getParentDepth=function(a,p){//глубина контейнера a в предке p
while(a._parent!=p) a=a._parent;
return a.getDepth();
}
var getGeneric=function(a,b){//ближайший общий родитель
while (!isParent(a,b) && b!=_root)b=b._parent;
return b
}
var order=function(a,b){//функция для сортировки
//если родство по прямой, то дети всегда выше родителей
if(isParent(a,b))return -1;
if(isParent(b,a))return 1;
//для двоюродных меряемся предками
var p=getGeneric(a,b);//ближайший общий родитель
return getParentDepth(a,p) > getParentDepth(b,p);//глубины контейнеров в ближайшем общем родителе
}
///////////////////////////////////////
switch(mc_array.length){
case 0:return;//нет ничего, выходим
case 1:var mc=mc_array[0];break;//только один
default :var mc=mc_array.sort(order)[0];//много: сортируем
}
this.dispatchEvent({type:'realRelease',target:mc});
}

MovieClip.prototype.addEventListener('realRelease',onRealRelease);
//теперь просто слушаем событие 'realRelease', чтобы знать по кому кликнули
function onRealRelease(e){
trace(e.target);
//target=e.target;
}

Barss07
13.01.2006, 15:31
silin, спасибо, интересно! Попробую разобраться.

Есть один момнет, который я не понимаю. Когда речь идет о, скажем, событии onPress - то проблема со вложенным клипом понятна. Возникает некая двойственность.
Но если для "внешнего" клипа определено событие onRollOver, то что мешает событию onPress для внутреннего? Ведь ролловер уже произошло и, скажем так, можно о нем и забыть? Почему оно блокирует клик по внутреннему?
Ну, я готов принять это как факт, но мне непонятен смысл :))

silin
13.01.2006, 15:37
придется принять это как факт
(или смотреть в сторону AS3: там этого гемора уже нет..)

Homo Sapiens
14.01.2006, 00:42
Всё достаточно просто, если подписываешь клип на одно из кнопочных событий (onRollOver к ним тоже относится), клип начинает вести себя как кнопка, глуша при этом все события внутренних клипов.
На мой взгляд, наиболее эффективное решение - внешний клип использовать только как контейнер, не вешая на него событий, а для всей реакции на действия пользователей выделять смысловуе зоны.
Метод с использованием hitTest мне не особо нравится из-за замедления производительности и из-за корявости самого hitTest. Ради интереса можно попробовать потестить им клип в форме полумесяца :)

silin
14.01.2006, 02:50
>>из-за корявости самого hitTest.
про какую корявость речь ?
>>Ради интереса можно попробовать потестить им клип в форме полумесяца
да хоть в форме звезды Давида: mc.hitTest(x,y,true)

Barss07
14.01.2006, 11:46
>>про какую корявость речь ?
Наверно, речь о "корявости" при вычислении коллизии клипов.
А насчет принадлежности конкретной точки клипу, метод, насколько я в курсе, работает корректно.

Antares
14.01.2006, 12:34
При чем здесь коллизии клипов?

silin
14.01.2006, 12:38
дада: "корявость при вычислении коллизии клипов" это корявость рук, а не hitTest

Barss07
14.01.2006, 14:31
Ну, раз речь зашла о "корявости рук", тему пора закрывать. Еще раз спасибо всем ответившим.

Homo Sapiens
17.01.2006, 02:30
Ну как сказать, например создаешь клип в форме полумесяца, halfmoon, создаёшь клип в форме круга, sphere, совмещаешь клипы, так чтобы круг находился внутри полумесяца, но не касался его, пишешь
trace(halfmoon.hitTest(sphere))
Угадай, что он выведет?

Antares
17.01.2006, 04:19
Угадай, насколько сложно с этим справиться :)

Ни разу не замечал за хиттестом какой-то необычности в поведении