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

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

Версия для печати  Отправить по электронной почте    « Предыдущая тема | Следующая тема »  
Опции темы Опции просмотра
 
Создать новую тему Ответ
Старый 05.07.2007, 21:27
xintrea вне форума Посмотреть профиль Отправить личное сообщение для xintrea Посетить домашнюю страницу xintrea Найти все сообщения от xintrea
  № 1  
Ответить с цитированием
xintrea
 
Аватар для xintrea

Регистрация: Mar 2002
Адрес: https://webhamster.ru
Сообщений: 107
По умолчанию AS2: Получить (рекурсивный?) список мувиклипов с полным путем.

Здравствуйте!

Инструменты - mtasc, FDT.

В целях облегчения отладки, хочу сделать себе такую функцию, которая бы выводила в trace информацию о всех существующих в данный момент клипах, начиная с _root, с полным путем.

Пока что найденные решения (типа такого http://www.flasher.ru/forum/showthread.php?t=91727) не радуют, потому что

- не показывают полного пути (чтобы виден был _root или там _level0)
- показывают мувиклипы только текущего уровня. Если в мувиклипе содержится еще один мувиклип, внутри которого еще мувиклипы, то их не видно. (возможно я тут не прав, возможно я не вижу "внутреннего" мувиклипа потому что неправильно загружаю, но проверить не могу потому что нет функции отладки, о которой я как раз и говорю)

В общем, нужен аналог списка мувиков (или даже всех объектов), который можно получить в Flash IDE через менюшку List Objects.

Есть уже готовые наработки?
__________________
Со всяческими пожеланиями, Xintrea.
https://webhamster.ru

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

Регистрация: Oct 2006
Адрес: spb.ru
Сообщений: 3,221
такое сгодится?
Код:
function giperTrace(o){
	if(typeof(o)!='movieclip' || o.checked ) return;
	trace(o);
	o.checked = true;
	for( var p in o )giperTrace ( o[p]);
}
giperTrace(this);
немного портит клипы.. добавляет свойство, чтобы по перекрестным ссылкам не бегать. Можно и без этого обойтись, создав объект:
Код:
var _checked_:Object = {};
function giperTrace(o){
	if(typeof(o)!='movieclip' || _checked_[o._target] ) return;
	trace(o);
	_checked_[o._target] = true;
	for( var p in o )giperTrace ( o[p]);
}
giperTrace(this);


Последний раз редактировалось Kikasso; 05.07.2007 в 22:12.
Старый 06.07.2007, 01:57
xintrea вне форума Посмотреть профиль Отправить личное сообщение для xintrea Посетить домашнюю страницу xintrea Найти все сообщения от xintrea
  № 3  
Ответить с цитированием
xintrea
 
Аватар для xintrea

Регистрация: Mar 2002
Адрес: https://webhamster.ru
Сообщений: 107
Нет, не работает оно как надо.

Вот код который у меня получился. Я подгружаю swf-файл, в котором есть три мувиклипа (для каждого мувиклипа прописаны LinkageID и заданы InstanceName).

Код:
class Application 
{
  var _checked_:Object = {};
  private var scopeRef:MovieClip;
         
  function Application(scope:MovieClip) 
   {
    Flashout.info("Application constructor start.");

    scopeRef = scope;

    // Загрузка ресурсов
    var dpt=10;
    scopeRef.createEmptyMovieClip("resource", dpt++);
    scopeRef.resource._x=200;
    scopeRef.resource.loadMovie("resource.swf");
    
    // Пробуем сделать список что имеем в ресурсах в данный момент
    // но ничего внутри ресурсов не видно
    trace("List of resource start");
    for(var prop in scopeRef.resource)
     trace("Prop "+scopeRef.resource[prop]);
    trace("List of resource end");
      
    // Программно создаем текстовое поле
    scopeRef.createTextField("tf", 0, 100, 100, 800, 600);
    scopeRef.tf.text = "Hello flasher!";
   }

  // Функция рекурсивной печати имеющихся мувиклипов
  public function giperTrace(o)
   {
    if(typeof(o)!='movieclip' || _checked_[o._target] ) return;
    trace(o);
    _checked_[o._target] = true;
    for( var p in o )
     giperTrace ( o[p]);
   }
         
  // --- Main Entry Point
  static function main() 
   {                
    trace("Run main function");

    // Запускаем инициализацию приложеня
    var appinst:Application = new Application(_root);

    // Печатаем список всех мувиклипов
    appinst.giperTrace(_root);
   }
}
В результате выполнения имеем лог такой

Код:
Run main function
Application constructor start.
List of resource start
List of resource end
_level0
_level0.resource
То есть виден только мувик "resource". Внутри него ничего не видим. А если скомпилированный swf-файл запустить в Flash IDE и посмотреть Object List, то увидим такое

Код:
Level #0: Frame=1
  Edit Text: Target="_level0.tf" Variable= Visible=true Text = Hello flasher!"
  Movie Clip: Frame=1 Target="_level0.resource"
    Movie Clip: Frame=1 Target="_level0.resource.mcCellCommandPlayer"
      Shape:
    Movie Clip: Frame=1 Target="_level0.resource.mcCellEnemyPlayer"
      Shape:
    Movie Clip: Frame=1 Target="_level0.resource.mcCellBall"
      Shape:
      Shape:
    Edit Text: Target="_level0.resource.instance1" Variable= Visible=true Text = CellCommandPlayer"
    Edit Text: Target="_level0.resource.instance2" Variable= Visible=true Text = CellEnemyPlayer"
    Edit Text: Target="_level0.resource.instance3" Variable= Visible=true Text = CellBall"
то есть на самом деле внутри мувика "resource" есть три мувиклипа, но они почему-то недоступны. Кстати, внутри конструктора Application я тоже пытаюсь распечатать содержимое приаттаченого swf-файла. Но даже с прямым указанием мувика, который нужно обработать, мувики внутри него не видятся. Мувик подгружается нормально, и его, и мувики внутри него из которых он состоит, я вижу в окне флешплейера при запуске. Но мувики внутри подруженного как мувик swf-файла - недоступны программно, хотя для них в serource-фале указаны (как писал выше) LinkageID и InstanceName.


Поэтому вопрос - почему Flash при печати Object List видит мувики внутри swf-файла, а программно они недоступны? И как сделать чтоб они стали доступными, например, для копирования? Чтобы можно было копировать эти встроенные мувики через attachMovie() или там duplicateMovieClip()? Или это принципиально в AS2 невозможно? И единственный выход - помещать каждый мувик в отдельный SWF-файл?
__________________
Со всяческими пожеланиями, Xintrea.
https://webhamster.ru


Последний раз редактировалось xintrea; 06.07.2007 в 02:01.
Старый 06.07.2007, 02:25
lowka вне форума Посмотреть профиль Отправить личное сообщение для lowka Найти все сообщения от lowka
  № 4  
Ответить с цитированием
lowka

Регистрация: Sep 2006
Сообщений: 256
Функция рабочая (только добавьте проверку на нужные типы). Вы бы загрузки-то дождались, а потом и посмотрели, что у вас там.

Старый 06.07.2007, 04:18
xintrea вне форума Посмотреть профиль Отправить личное сообщение для xintrea Посетить домашнюю страницу xintrea Найти все сообщения от xintrea
  № 5  
Ответить с цитированием
xintrea
 
Аватар для xintrea

Регистрация: Mar 2002
Адрес: https://webhamster.ru
Сообщений: 107
Мда.. Еще бы еще ктонить рассказал, как делать проверку на загруженность в AS2 средствами mtasc онли. Или это есть зло?

В данный момент добавил пару методов

Код:
  public function checkLoaded(target_mc:MovieClip) 
   {
    var pctLoaded:Number = target_mc.getBytesLoaded()/target_mc.getBytesTotal()*100;
    trace("target_mc "+target_mc);
    trace("target_mc.getBytesLoaded() "+target_mc.getBytesLoaded());
    trace("target_mc.getBytesTotal() "+target_mc.getBytesTotal());
    trace("pctLoaded "+pctLoaded);
    
    if (!isNaN(pctLoaded) && (pctLoaded==100)) 
     {
      trace("clearing interval");
      clearInterval(myInterval);
      target_mc.onLoad = doOnLoad;
     }
   }
   
  public function doOnLoad() 
   {
    trace("Movie load full");
   }
Вызов загрузки делаю так

Код:
    scopeRef.createEmptyMovieClip("resource", dpt++);
    scopeRef.resource.loadMovie("resource.swf");
    myInterval = setInterval(checkLoaded, 100, scopeRef.resource);
Получаю такой лог

Код:
Run main function
Application constructor start.
List of resource start
List of resource end
_level0
_level0.resource
target_mc _level0.resource
target_mc.getBytesLoaded() 1440
target_mc.getBytesTotal() 1440
pctLoaded 100
clearing interval
Как видно, назначить мувику метод onLoad() не получается. Лог доходит до строчки "clearing interval", дальше по идее должа появиться строчка "Movie load full". Но ее в логе нет.

Подозреваю, что назначить метод мувику нельзя потому, что функция onLoad() в моем коде является методом класса Application, который не является мувиклипом вообще. Но как по-другому назначить мувику onLoad-метод, сообразить не могу.

PS: Размер загружаемого swf в байтах - 1087. А в логе пишется что загружается 1440 байт. Запуск swf обычный, локальный. Откуда берутся лишние байты в размере загружаемого файла?
__________________
Со всяческими пожеланиями, Xintrea.
https://webhamster.ru

Старый 06.07.2007, 08:47
etc вне форума Посмотреть профиль Найти все сообщения от etc
  № 6  
Ответить с цитированием
etc
Et cetera
 
Аватар для etc

Регистрация: Sep 2002
Сообщений: 30,787
MovieClipLoader в помощь, без извращений и интервалами.

з.Ы. onLoad так не используется и работать не будет.

з.Ы.Ы. Байты берутся из расжатого swf.

Старый 06.07.2007, 17:18
xintrea вне форума Посмотреть профиль Отправить личное сообщение для xintrea Посетить домашнюю страницу xintrea Найти все сообщения от xintrea
  № 7  
Ответить с цитированием
xintrea
 
Аватар для xintrea

Регистрация: Mar 2002
Адрес: https://webhamster.ru
Сообщений: 107
Сделал через MovieClipLoader, но не хватает последнего штриха. А именно - не могу из onLoadInit() вызвать метод нужного мне объекта.

У меня есть инстанс объекта, который именуется appinst. У этого объекта есть метод onLoadResourceMovie(). Но когда я пытаюсь его вызвать из onLoadInit() моего листенера через команду

appinst.onLoadResourceMovie(target_mc);

то компиляция не проходит, и на этой строке мне выдается ошибка

type error Unknown variable appinst

Вот код двух моих классов, из которых и состоит проект.

Код:
class Application 
{
  var _checked_:Object={};
  private var scopeRef:MovieClip;
         
  function Application(scope:MovieClip) 
   {
    Flashout.info("Application constructor start.");
    scopeRef = scope;
   } 

  function addTextLabel()
   {
    // Программно создаем текстовое поле
    scopeRef.createTextField("tf", 0, 100, 100, 800, 600);
    scopeRef.tf.text = "Hello flasher!";
   }

  function initLoadResouceMovie()
   {
    // Загрузка ресурсов
    var dpt=10;
    
    // Инитим загружающие мувик листенеры
    var my_mcl:MovieClipLoader = new MovieClipLoader();
    var listenerinst:LoadListener = new LoadListener(my_mcl);
    my_mcl.addListener(listenerinst);
    
    // Запускаем процесс загрузки ресурсов
    scopeRef.createEmptyMovieClip("resource", dpt++);
    my_mcl.loadClip("resource.swf", scopeRef.resource);
   }

  public function giperTrace(o)
   {
    if(typeof(o)!='movieclip' || _checked_[o._target] ) return;
    trace(o);
    _checked_[o._target] = true;
    for( var p in o )
     giperTrace ( o[p]);
   }
        
  public function onLoadResourceMovie(target_mc:MovieClip)
   {
   	trace("Movieclip load complete "+target_mc);
    giperTrace(_root);
   }
 
  // --- Main Entry Point
  static function main() 
   {                
    trace("Run main function");
    var appinst:Application = new Application(_root);
    
    appinst.addTextLabel();
    appinst.initLoadResouceMovie();
   }
}
Код:
class LoadListener {
 
 var mcl:Object;
 
 public function LoadListener(target_mcl:Object)
  {
   mcl=target_mcl;
  }
 
 public function onLoadStart(target_mc:MovieClip) 
  {
   trace("********* LoadListener Start *********");
   trace("Your begin load movie clip = "+target_mc);
   var loadProgress:Object = mcl.getProgress(target_mc);
   trace(loadProgress.bytesLoaded+" = bytes loaded at start");
   trace(loadProgress.bytesTotal+" = bytes total at start");
  }

 public function onLoadProgress(target_mc:MovieClip, loadedBytes:Number, totalBytes:Number) 
  {
   trace("********* LoadListener Progress *********");
   trace("onLoadProgress() called back on movie clip "+target_mc);
   trace(loadedBytes+" = bytes loaded at progress callback");
   trace(totalBytes+" = bytes total at progress callback");
  }
  
 public function onLoadComplete(target_mc:MovieClip) 
  {
   trace("********* LoadListener Complete *********");
   trace("Your load is done on movie clip = "+target_mc);
   var loadProgress:Object = mcl.getProgress(target_mc);
   trace(loadProgress.bytesLoaded+" = bytes loaded at end");
   trace(loadProgress.bytesTotal+" = bytes total at end");
  }
  
 public function onLoadInit(target_mc:MovieClip) 
  {
   trace("********* LoadListener Init *********");
   trace("Movie clip = "+target_mc+" is now initialized");
   
   // теперь можно применять любые установки
   appinst.onLoadResourceMovie(target_mc); // <-- Эта строка не компилится
  }

 public function onLoadError(target_mc:MovieClip, errorCode:String) 
  {
   trace("********* LoadListener Error *********");
   trace("ERROR CODE = "+errorCode);
   trace("Your load failed on movie clip = "+target_mc+"\n");
  }
}
Вооот. Я честнагря в объектном программировании не силен, поэтому понять не могу, почему инстанс appinst объекта Application неизвестен в методе onLoadInit().

Посему тупой вопрос - как правильно вызвать метод одного объекта из другого?
__________________
Со всяческими пожеланиями, Xintrea.
https://webhamster.ru

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

Регистрация: Oct 2006
Адрес: spb.ru
Сообщений: 3,221
Я могу ошибаться, но
Код:
_checked_ = new Object();
надо писать внутри конструктора, а в шапке только объявить его тип:
Код:
var _checked_:Object;
appinst в вашем втором классе не значится. Передавайте параметр при иннициации, вы же scoope передаете в конструктор первому классу.
Я честно говоря не понимаю, нафига вам вообще этот LoadListener отдельным классом. Дописать onLoadInit в базовый класс, добавить слушателем себя, добиться нормальной работы, а потом уже мудрить.


Последний раз редактировалось Kikasso; 06.07.2007 в 18:04.
Старый 07.07.2007, 03:33
xintrea вне форума Посмотреть профиль Отправить личное сообщение для xintrea Посетить домашнюю страницу xintrea Найти все сообщения от xintrea
  № 9  
Ответить с цитированием
xintrea
 
Аватар для xintrea

Регистрация: Mar 2002
Адрес: https://webhamster.ru
Сообщений: 107
Цитата:
Сообщение от Kikasso
Я могу ошибаться, но

_checked_ = new Object();

надо писать внутри конструктора, а в шапке класса только объявить его тип:

var _checked_:Object;
Да, вы совершенно правы. Кроме того, метод giperTrace() пришлось доработать, так как воспользоваться им можно было только один раз. При следующем вызове этого метода, в объекте _checked_ уже отмечено, что данный мувик был обработан, и его имя повторно не выводится в лог. Я внес те исправления что выше написаны и сделал из одного метода giperTrace() два вот таких

Код:
  public function giperTrace(o)
   {
    delete _checked_;
    _checked_ = new Object();
    giperTraceRecurse(o);
   }
        
  public function giperTraceRecurse(o)
   {
    if(typeof(o)!='movieclip' || _checked_[o._target] ) return;
    trace(o);
    _checked_[o._target] = true;
    for( var p in o )
     giperTrace ( o[p]);
   }
Теперь вызов giperTrace() всегда работает как надо. Не знаю, красивое ли решение (может можно как-то очищать объекты, а не удалять и заводить новые), но оно работает.


Цитата:
Сообщение от Kikasso
appinst в вашем втором классе не значится. Передавайте параметр при иннициации, вы же scoope передаете в конструктор первому классу.
Да, спасибо за подсказку. Почему-то думал, что флеш хранит список инстансов, и к ним можно просто обращаться. А оказывается ООП во флеше почти такое же низкоуровневое как в сиплюсплюсе. Сделал с передачей параметра appinst, и вызов appinst.onLoadResourceMovie() заработал.

Теперь метод giperTrace(), вызваный из onLoadResourceMovie(), показывает все мувиклипы.

Код:
_level0
_level0.resource
_level0.resource.mcCellBall
_level0.resource.mcCellEnemyPlayer
_level0.resource.mcCellCommandPlayer

Цитата:
Сообщение от Kikasso
Я честно говоря не понимаю, нафига вам вообще этот LoadListener отдельным классом. Дописать onLoadInit в базовый класс, добавить слушателем себя, добиться нормальной работы, а потом уже мудрить.
Отдельным классом - это задел на будущее. Да и по логике вещей, листенеры - это вещь в себе, т.е. это такие объекты, которые не входят в состав других объектов. А значит это отдельный класс.
__________________
Со всяческими пожеланиями, Xintrea.
https://webhamster.ru

Старый 07.07.2007, 04:02
lowka вне форума Посмотреть профиль Отправить личное сообщение для lowka Найти все сообщения от lowka
  № 10  
Ответить с цитированием
lowka

Регистрация: Sep 2006
Сообщений: 256
Цитата:
Сообщение от xintrea
Да, спасибо за подсказку. Почему-то думал, что флеш хранит список инстансов, и к ним можно просто обращаться. А оказывается ООП во флеше почти такое же низкоуровневое как в сиплюсплюсе.
А чем выше уровень ООП, то тем меньше в нем места для инкапсуляции?

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

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

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


 


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


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