PDA

Просмотр полной версии : attachMovie и onPress, почему не хотят жить вместе?


gfdrf
06.06.2006, 10:27
Снова вопросы к гуру, и наверно снова дурацкие :umnik2:
Ситуация следующая.
В фильме есть пустой клип, в который из библиотеки, с помощью attachMovie подгружается мувик. После загрузки мне нужно, чтобы его можно было мышкой перемещать. Вот тут затык. Не работает!
Причем если поместить его вручную из библиотеки в тот же клип, то естественно всё работает. Правда при ручном помещении его в клип, мы задаем ему instance name, и onPress замечательно работает. А при аттаче, я так понимаю instance name остается пустым, поэтому и не работает onPress. Хотя в параметрах attachMovie задается имя клипа.
Подскажите плиз, где косяк, и как его объехать!
Извините, если вопрос дурацкий.

kayama
06.06.2006, 11:17
А что мешает при аттаче задавать название экземпляра, а потом при событии указать его же?

Ты вообще как аттач пишешь?

orangeline
06.06.2006, 11:18
yourClip.attachMovie("anyClip", "anyClip_1", getNextHighestDepth());

теперь instance name приаттаченного клипа - anyClip_1, помещенного на временную диаграмму клипа yourClip

а перемещать тебе нужно не yourClip, на который ты аттачиш, а anyClip_1 (не забудь что координаты будут отсчитываться от начала координат клипа yourClip в этом случае)

kayama
06.06.2006, 11:27
А координаты в данном случае будут не причем, он то в пустоймувиклип его вставляет....

gfdrf
06.06.2006, 13:05
Я аттачил так
attachMovie("ac","ac",1)
Может надо второе имя сделать типа "ас_1", т е отличным от первого?
Может как раз в этом косяк?
И я понимаю, что мне нужно перемещать не клип в который аттачу, а сам объект.
но clip.ac.onPress....... не работает.

iNils
06.06.2006, 13:09
Первое - это имя в библиотеки, второе имя на сцене. Они между собой ни как не пересекаются, хоть ты трижды в квадрате назовешь их одинаково.

kayama
06.06.2006, 13:19
Я аттачил так
attachMovie("ac","ac",1)
Может надо второе имя сделать типа "ас_1", т е отличным от первого?
Может как раз в этом косяк?
И я понимаю, что мне нужно перемещать не клип в который аттачу, а сам объект.
но clip.ac.onPress....... не работает.
Именно! А дальше если не хочешь изучать синтаксис вложенности, просто протрейсь присоединяемый клип, а потом пропиши его адрес напрямую:
Будет что-то типа _root.ac1.onPress = function ()
{тра-та-та};

gfdrf
06.06.2006, 13:19
Вот и я подумал что они могут быть одинаковыми.
Ведь если я вручную помещаю в клип, я его тоже обзываю "ас", и имя в библиотеке у него "ас", и тем не менее всё работает...
Вечером ещё подумаю, хотя свежих мыслей нет...

PS пока писал появилось ещё одно сообщение...
Я и аттачил соответственно clip.attachMovie("ac","ac",1)
и потом _root.clip.ac.onPress= function ()
{тра-та-та}

и с рутом не работает, и без рута не работает...

iNils
06.06.2006, 13:25
this.attachMovie ("ac", "ac", 1);
this.ac.onPress = function () {
// код
}

этот код должен находится в том клипе в который аттачишь иначе надо путь вместо this указать

kayama
06.06.2006, 13:27
Я ж написал примерно, он-то у тебя может и по другому называться..
Если он у тебя клип-в-клипе-в-клипе, то ессессно и строка будет начинатся по другому....
Либо как iNils написал...

gfdrf
06.06.2006, 23:35
Да так всё, так, и всё это я знаю и понимаю. И делал перетаскивание в клипах разной степени вложенности, и из рута, и из промежуточных клипов.
Блин, решил выложить пример, может он поможет.
В примере, уже есть клип "ас", помещенный вручную в клип "clip" (он в центре). Ему ручками присвоено instance name "ас".Его можно без проблем таскать мышкой.
При нажатии на волшебную кнопку, этот же клип из библиотки аттачится в клип "clip", т.е. точно туда же. И его нельзя таскать!
Однако волшебная кнопка, при повторном нажатии удаляет клип "ас". При этом удаляются ОБА клипа! Значит они оба "ас"! Но почему один можно таскать, а другой нет?
Не подумайте обо мне полохого, пожалуйста, пиво я не пил уже 2 дня...
Но вот такой клин... или засада...

iNils
06.06.2006, 23:58
Когда ты пытаешь сделать аттач программно, ты назначаешь на него действия до появляения клипа. А это бесполезно.
Сначала аттач, потом вешаешь обработчик событий.

gfdrf
07.06.2006, 00:09
Почти понял, но если можно, поподробней
Я же вроде сначала аттачу, потом уже пытаюсь пеоремещать?
Или я все же что то не понимаю? Истина где то рядом?

iNils
07.06.2006, 00:22
aa.onPress = function () {
if (i == 0 || i == undefined) {
var mc = clip.attachMovie ("ac", "ac", 1);
i = 1;
mc.onPress = function () {
this.startDrag ();
};
mc.onRelease = function () {
this.stopDrag ();
};
} else {
clip.unloadMovie ("ac");
i = 0;
}
};

gfdrf
07.06.2006, 00:30
Опа, работает!
Огроменнейшее спасибо!
Коментов не требую, попытаюсь разобраться сам.
В очередной раз прошу пардону, просто для меня Flash хобби, а не способ зарабатывания денег, поэтому времени ему уделяется далеко не столько, сколько хотелось бы :-(

PS Уже всё понял.

Madasan
07.06.2006, 00:48
И лучше не называть мувики одинаково, иначе можно получить подобный глюк, когда кажется что мувик удалился, а на самом деле трейс показывает что этот мувик существует.!(То есть это только на мониторе удалилось два мува, а на самом деле - один) Для удаления приаттаченого мувика cуществует removeMovieClip,(кстати если его применить подобной ситуации то с монитора не удалиться не один мувмув, пока не назовешь их по разному) а unloadMovie это применяется для выгрузки мува загруженного методом loadMovie.

iNils
07.06.2006, 00:59
То есть это только на мониторе удалилось два мува, а на самом деле - один

Вставь внутрь "ac" и проверь :)

if (!_global.flag){
_global.flag = 0
}
this.flag = _global.flag++
this.onEnterFrame = function () {
trace (flag)
}

Madasan
07.06.2006, 01:43
Вставь внутрь "ac" и проверь :)

Да чего проверять, если мувы помещенные на таймлайн вручную, находятся на отрицательной глубине, и их хрен удалишь, если глубину на положительную не поменять, а unload... хэ...

iNils
07.06.2006, 01:46
Я знаю про открицательные глубины, но ты все же вставь и посмотри.

Madasan
07.06.2006, 02:27
Посмотрел, но не понял что должен был там увидеть :( Я вот еще дебаггер запустил, так там этот клип, что вручную помещен и находиться на отрицательной глубине в _root! - после unload - ВИСИТ,(вложенный в него удаляется, а тот что в _root - нет) и все свойства у него имеются, но при этом то что внутри типа код действительно не выполняется и на сцене его нет. :confused:

iNils
07.06.2006, 02:39
Лог
------------
Запускаем
0
0
0
0
0
0
Жмем на копку - Делаем аттач
0
1
0
1
0
1
Жмем на кнопку - удаление
[и нечего тут нет]
[и нечего тут нет]
[и нечего тут нет]
устал ждать :)

Удалался бы один, то второй onEnterFrame работал

iNils
07.06.2006, 02:56
Слепой я :) Только сейчас заметил, что удаляем с помощью unloadMovie, поэтому:
1. По сколько в данном случаи это не глобальный метод, а метод мувиклипа, то у него нет аргуметов.
2. unloadMovie удаляет содержимое экземпляра, а не сам экземпляр.

Madasan
07.06.2006, 11:43
Тут такая петрушка получается. Если записать так: clip.ac.unloadMovie() то удаляется ac, clip при этом естесственно остается. А если записать так clip.unloadMovie(), то ac также удаляется а clip типа исчезает со сцены, что естесственно потому что содержимое удалено, но в дебагере видно, что он есть! При этом trace(clip.ac.getDepth()) в обоих случаях выводит: -16..(с копейками), а trace(clip.ac) выводит _level0.clip.ac Очевидное невероятное из цикла "секреты реализации" :)

iNils
07.06.2006, 13:49
Листинг 3-х кодов, которые потребуется при чтении
1. Используем заместо оригинала
aa.onPress = function () {
if (i == 0 || i == undefined) {
clip.attachMovie ("ac", "ac1", 1);
i = 1;
} else {
clip.ac.unloadMovie ();
i = 0;
trace (clip.ac.getDepth ());
}
};
//***************перемещение************************
_root.clip.ac.onPress = function () {
_root.clip.ac.startDrag ();
};
_root.clip.ac.onRelease = function () {
_root.clip.ac.stopDrag ();
};
_root.onEnterFrame = function () {
for (arg in clip) {
trace (clip[arg] + " " + clip[arg].getDepth());
}
trace ("--------");
};

2. Используем заместо оригинала
aa.onPress = function () {
if (i == 0 || i == undefined) {
//clip.ac.swapDepths (100)
clip.attachMovie ("ac", "ac", 1);
i = 1;
} else {
clip.ac.unloadMovie ();
i = 0;
trace (clip.ac.getDepth ());
}
};
//***************перемещение************************
_root.clip.ac.onPress = function () {
//this.startDrag ();
_root.clip.ac.startDrag ();
};
_root.clip.ac.onRelease = function () {
//this.stopDrag ();
_root.clip.ac.stopDrag ();
};
_root.onEnterFrame = function () {
for (arg in clip) {
trace (clip[arg] + " " + clip[arg].getDepth());
}
trace ("--------");
};

3. Это для нового пустого файла
this.createEmptyMovieClip ("mcA", 0);
this.mcA.createEmptyMovieClip ("mcB", 0);
this.mcA.createEmptyMovieClip ("mcC", 1);
this.cx = 0;
this.onEnterFrame = function () {
this.cx++;
if (this.cx == 5) {
trace ("unload");
this.mcA.unloadMovie ();
}
trace (this.mcA.mcB);
trace (this.mcA.mcC);
trace (this.mcA);
trace ("---------------");
};


Тут такая петрушка получается. Если записать так: clip.ac.unloadMovie() то удаляется ac, clip при этом естесственно остается.
Уще раз повторю, unloadMovie() выгружает содержимое клипа к которому он прикручен, но не сам клип. Поставь при аттаче имя нового клипа ac1, вместо ac и ты с помощью кода 1 увидишь что все осталось на месте.
А если записать так clip.unloadMovie(), то ac также удаляется а clip типа исчезает со сцены, что естесственно потому что содержимое удалено, но в дебагере видно, что он есть! При этом trace(clip.ac.getDepth()) в обоих случаях выводит: -16..(с копейками)Клип clip :) остается на месте, поэтому он и весит в дебагере.

а trace(clip.ac) выводит _level0.clip.ac Очевидное невероятное из цикла "секреты реализации" :)
Смотри код 3. На момент unload мы видим в трейсе все три клипа
unload
_level0.mcA.mcB
_level0.mcA.mcC
_level0.mcA
но уже в следующем кадре только один
undefined
undefined
_level0.mcA
потому что выгруз происходит на следующий кадр

Единственный "глюк" виден в коде 2. Трейс нам постоянно показывает отрицательную глубину для клипа ac. Жмем кнопку и создаем еще один ac, трейс нам теперь показывает наличие двух ac в clip, но с одинаковой глубиной. Это объясняется тем, что при наличии двух клипов с одинаковым именем, при обращении по этому имени мы получаем доступ к тому клипу, чья глубина меньше (видимо по этому нам дебагер врет, и мы видим в нем только один клип, а не два). Это легко проверить расскоментировав строчку во втором коде со сменой глубины, теперь в трейсе глубина будут от того клипа который мы приаттачили.
А собственно клюк заключается в том, что clip.ac.unloadMovie () умудряется удалить первоначальный клип. Но еще более странный глюк получается если расскомментировать строку в со сменой глубины в коде 2.
Запускаем и оттаскиваем первоначальный клип ac в сторону, жмем кнопку и добавляем новый клип ac. А теперь наведите на первоначальный, нам нем курсор принимает форму руки, нажимаем и пытаемся его оттащить его...у меня оттаскивается приаттаченный :) А теперь в том же коде 2 смените часть кода отвечающая за нажатие и отжатие мыши для клипа ac на этот
_root.clip.ac.onPress = function () {
this.startDrag ();
//_root.clip.ac.startDrag ();
};
_root.clip.ac.onRelease = function () {
this.stopDrag ();
//_root.clip.ac.stopDrag ();
};

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

gfdrf
07.06.2006, 14:01
Ёлки-палки!
Вот уж не думал, что мой ламерский вопрос вызовет такую бурную дискуссию! Сколько инфы!
Вечером засяду за углубленное изучение :p

Madasan
07.06.2006, 14:10
Есть еще интересный момент. Если есть клип помещенный в ручную на сцену (clip), а в нем еще один клип (ac), то у нас имеется:
_level0.clip.ac.instance1
Если мы вызовем clip.attachMovie("ac","ac",0) то получим:
_level0.clip.ac.instance1
_level0.clip.ac.instance2
если мы удалим вложенный клип и оставим:
_level0.clip
то при вызове clip.attachMovie("ac","ac",0) получаем:
_level0.clip.ac
Собственно клипы с одинаковыми именами отличаются друг от друга кроме глубины этим самым instanceN

iNils
07.06.2006, 14:21
Как мне кажется это происходит потому что:
1. В момент запуска флеш в ac находит клип без имени и называет его instance1 (так как других там нет)
2. При аттаче происходипотчи тоже самое что и в 1, но при поиске внутренных клипов, флеш начинает искать через имя ac и соответсвенно попадает на тот что у нас были находит там уже названный instance1, и в новом ac (считая что у нас он один) называет клип без имени уже instance2.
Смени строку аттача на clip.attachMovie ("mc", "mc", 1, {_name: "h"});
И смотри дебаггер :) У меня получилось так:
clip.ac.instance1
clip.ac.instance2
clip.h
:)

Madasan
07.06.2006, 15:08
Как мне кажется это происходит потому что:
1. В момент запуска флеш в ac находит клип без имени и называет его instance1 (так как других там нет)Флэш прилепляет instanceN всем клипам, помещенным на сцену не программно а в среде редактирования, вне зависимости от того, задано ли ему имя в панели свойств или нет.

iNils
07.06.2006, 15:24
Флэш прилепляет instanceN всем клипам, помещенным на сцену не программно а в среде редактирования, вне зависимости от того, задано ли ему имя в панели свойств или нет.
С чего ты взял?

Madasan
07.06.2006, 15:58
Не знаю, видимо совсем эти клипы запарили...
На самом деле действительно instancе имеется у клипов с одинаковыми именами, ну и при отсутсвии имени соответсвенно, ведь можно сделать и так:
attachMovie('clip','',0)

iNils
07.06.2006, 16:14
Да нет, instance1 и тд это название текстового поля было :)