Форум Flasher.ru

Форум Flasher.ru (http://www.flasher.ru/forum/index.php)
-   ActionScript 3.0 (http://www.flasher.ru/forum/forumdisplay.php?f=83)
-   -   Class, MovieClip, SimpleButton. Не срабатывает обработчик MouseEvent.CLICK (http://www.flasher.ru/forum/showthread.php?t=171727)

AHKHOBA 23.11.2011 00:51

Class, MovieClip, SimpleButton. Не срабатывает обработчик MouseEvent.CLICK
 
Присоединяю к классу клип, в котором 2 кадра. В кадрах - кнопки. В зависимости от значения некой переменной frame, происходит выбор кадра:

Код AS3:

addChild(dialBox);
dialBox.gotoAndStop(frame);

И в первом кадре, и во втором есть кнопка cancel_btn. Разница во внешнем виде только. Но по совершенно непонятной мне причине, кнопка не реагирует на событие нажатия мыши.

Код AS3:

dialBox.cancel_btn.addEventListener(MouseEvent.CLICK, onCancelHandler);

Как будто бы оно не происходит. Спрашиваю обработчик: что такое dialBox.cancel_btn? Отвечает: simpleButton. То есть, кнопка точно видна скрипту.

Уже голова почти разбита об стену - не понимаю, отчего это может быть. Перепробовала все вариации: называла кнопки в разных кадрах по-разному, добавляла стоп-кадры, даже удаляла кнопку из первого кадра, оставив только во втором... Ничто не помогло. Единственное, что понятно: если кадр один, тогда все отлично работает. Итого получается, что проблема в gotoAndStop(). Но какая может быть проблема в этом элементарном действии?..

Еще такой момент: кроме кнопки cancel_btn в этих кадрах есть и ok_btn. С этой кнопкой все в порядке. Разница между ok и cancel кнопками в том, что кнопка ok_btn в обоих кадрах одна и та же. По идее, этот факт должен исключить влияние на проблему метода gotoAndStop(), который сейчас главный подозреваемый... но какая проблема может быть другая?

Кто-нибудь, по возможности, просветите меня в этом вопросе. Буду весьма-весьма признательна.

Ookami 23.11.2011 00:55

может быть событие срабатывает не на этой кнопке, а на другом объекте клипа? Попробуйте
Код AS3:

dialBox.addEventListener(MouseEvent.CLICK, onCancelHandler);

А в onCancelHandler через отладчик посмотрите на event.target

Psycho Tiger 23.11.2011 01:04

Скорее всего тут дело вот в чем: Flash IDE генерирует поля класса, которые ссылаются на объекты дисплей-листа: это сделано для удобства. И вот поменяв кадр у клипа поле класса не затронется никак: и оно будет продолжать ссылаться на клип в первом кадре. Нужно доставать содержимое методами, для доставания контента.
Попробуйте вот так:
Код AS3:

addChild(dialBox);
dialBox.gotoAndStop(2);
(dialBox.getChildByName("cancel_btn") as SimpleButton).addEventListener(MouseEvent.CLICK, onClick);


Ookami 23.11.2011 01:11

Цитата:

Спрашиваю обработчик: что такое dialBox.cancel_btn? Отвечает: simpleButton
Цитата:

Код AS3:

dialBox.getChildByName("cancel_btn") as SimpleButton


Какой смысл?

Psycho Tiger 23.11.2011 01:20

Обращаясь вот так: clip.cancel_btn мы будем ссылаться на некоторое поле cancel_btn, которое будет указывать всегда в одно место. Если мы вызовем gotoAndStop, скорее всего, это поле значения не изменит и будет до сих пор ссылаться в прошлый первый кадр.

fish_r 23.11.2011 01:26

может проще сделать?

поменять
Код AS3:

      dialBox.cancel_btn.addEventListener(MouseEvent.CLICK, onCancelHandler);

на

Код AS3:

      dialBox.addEventListener(MouseEvent.CLICK, onCancelHandler);


Ookami 23.11.2011 01:41

Ну собственно да, я это и предложил - даже если не поможет, то хоть можно будет увидеть на каком объекте срабатывает клик.

Тигра - я имел ввиду зачем надо "as SimpleButton", если ИДЕ итак знает что это кнопка (судя по словам топикстартера)

fish_r 23.11.2011 01:45

и ещё: во втором кадре экземпляр кнопки имеет тоже имя "cancel_bnt" (instance name)? это так - на всякий случай

AHKHOBA 23.11.2011 02:12

Код AS3:

dialBox.addEventListener(MouseEvent.CLICK, onCancelHandler);

Клик срабатывает куда не кликни, event.target возвращает правильный объект.

А логичный и обнадеживающий код:
Код AS3:

(dialBox.getChildByName("cancel_btn") as SimpleButton).addEventListener(MouseEvent.CLICK, onClick);

сообщает об ошибке:
Код:

Error #1009: Cannot access a property or method of a null object reference.
Эта ошибка и раньше иногда вылетала. Мол, вы пытаетесь присвоить метод несуществующему объекту. А иногда не вылетала - объект SimpleButton чудесным образом находился. Но почему-то вот не реагировал на нажатие мыши.

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

Добавлено через 5 минут
Цитата:

и ещё: во втором кадре экземпляр кнопки имеет тоже имя "cancel_bnt"
Да, имя кнопки в обоих кадрах - cancel_btn. Но варианты с разными именами уже испробованы.

Wolsh 23.11.2011 02:28

Цитата:

Это же, кажется, такая элементарщина - передвинуться на заданный кадр!
А у Вас что-то не передвигается?
Мне одному кажется, что программировать в кадрах перестали 6 лет назад?

AHKHOBA 23.11.2011 02:34

Весь код во внешнем as-файле - в классе, собственно. В кадрах у меня кнопки.

Ookami 23.11.2011 02:36

Цитата:

А логичный и обнадеживающий код:
Код AS3:

(dialBox.getChildByName("cancel_btn") as SimpleButton).addEventListener(MouseEvent.CLICK, onClick);

сообщает об ошибке:
Код:

Error #1009: Cannot access a property or method of a null object reference.

Скорее всего getChildByName("cancel_btn") возвращает null, т.е. у dialBox такого чайлда в момент вызова нет.

Цитата:

Клик срабатывает куда не кликни, event.target возвращает правильный объект.
Ну он и должен везде срабатывать ) Суть как-раз в том чтоб поймат таргет при клике по проблемной кнопке. "Правильный объект" - искомая кнопка?

AHKHOBA 23.11.2011 03:06

Цитата:

Скорее всего getChildByName("cancel_btn") возвращает null, т.е. у dialBox такого чайлда в момент вызова нет.
Так и есть. Но по какой причине он null?

Цитата:

Суть как-раз в том чтоб поймат таргет при клике по проблемной кнопке
Обработчик клика правильно называет объекты. Все кнопки - SimpleButto (в т.ч. cancel_btn), сам dialBox - MovieClip. Никаких неожиданностей не обнаружилось.

Wolsh 23.11.2011 04:07

Вы имена протрейсите, а не тип. Тип-то понятно что один. Трейсите target.name и currentTarget.name, авось узнаете что-то для себя интересное.

AHKHOBA 23.11.2011 04:33

ничего нового. Кнопка распознается. Тем не менее, к ней самой нельзя приладить событие.
Но задачу решить надо, поэтому обошлось так:

Код AS3:

dialBox.addEventListener(MouseEvent.CLICK, onClickHandler);
function onClickHandler(event:MouseEvent):void{
  if(event.target.name == "cancel_btn"){
      trace('yes')
  }
}

Довольно странно, но зато работает.

И всё же, интересно было бы всё-таки узнать, откуда это "слепое пятно" взялось. Поэтому, если у кого появится ответ на первоначальный вопрос, тому аплодисменты :)

Всем спасибо!

Wolsh 23.11.2011 05:27

Хм. А какое же тогда имя у кнопки в другом кадре?
Цитата:

Кнопка распознается.

Psycho Tiger 23.11.2011 12:48

Цитата:

Тигра - я имел ввиду зачем надо "as SimpleButton", если ИДЕ итак знает что это кнопка (судя по словам топикстартера)
getChildByName возвращает объект DisplayObject. По идее да, он тоже IEventDispatcher и ему можно кинуть addEventListener, но как-то подписывать его на CLICK не очень, нужно хотя бы привести к InteractiveObject.

@Автор: ну, например Вы можете создать самый минималистичный пример, при котором баг воспроизводится и выложить сюда. Вам сразу скажут, что не так: а то это гадание на картах, что же произошло.

AHKHOBA 23.11.2011 15:01

Вложений: 1
Да, вы правы. Вот пример.
_LANG - переменная, которая принимает значениях "ru" или "eng". В зависимости от _LANG осуществляется переход к кадру diagBox'a.
В этом примере в кадре "ru" как раз и вылетает ошибка, мол, "cancel_btn у вас null".

crazyone 23.11.2011 16:35

Это старый баг 9-го флешплеера. Соберите под 10-й и будет вам счастье.

Чтобы понять, что за баг - добавьте после dailBox.gotoAndStop такой вот код:
Код AS3:

trace(dialBox.numChildren);
                        for(var i:int=0;i<dialBox.numChildren;i++){
                                trace("Child at "+i);
                                trace(dialBox.getChildAt(i));
                                trace(dialBox.getChildAt(i).name);
                        }

И зацените вывод трейса:
Цитата:

5
Child at 0
[object MovieClip]
instance2
Child at 1
[object Shape]
instance4
Child at 2
[object SimpleButton]
ok_btn
Child at 3
null
Ненавижу 9-й плеер. Он отнял у меня столько времени...

Добавлено через 51 секунду
Соответственно при сборке под 10-й трейс будет вот таким:
Цитата:

5
Child at 0
[object MovieClip]
instance2
Child at 1
[object Shape]
instance4
Child at 2
[object SimpleButton]
ok_btn
Child at 3
[object SimpleButton]
cancel_btn
Child at 4
[object TextField]
instance30

thirst 23.11.2011 18:38

По-моему, причина в том, что мувик после вызова gotoandstop/play не имеет доступа к его чилдам (особенность 9флеша, крезиуан прав). Т.е. если есть hero с двумя кадрами "stay" и "staywithgun" и вызывался gotoandstop("staywithgun") из "stay", то флеш не может вызвать символ gun на кадре "staywithgun" внутри hero. Для этого нужно чтобы прошел 1 кадр, только после этого hero уже имеет доступ к чилдам (hero.gun и тд).

AHKHOBA 23.11.2011 23:50

Таки вы правы, crazyone!! В десятом плеере всё отлично.
Спасибо вам, человеческое Большое!


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

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