Форум Flasher.ru

Форум Flasher.ru (http://www.flasher.ru/forum/index.php)
-   ActionScript 3.0 (http://www.flasher.ru/forum/forumdisplay.php?f=83)
-   -   импорт мувиклипа из библиотеки по имени массива (http://www.flasher.ru/forum/showthread.php?t=139263)

gashhik 26.04.2010 23:46

импорт мувиклипа из библиотеки по имени массива
 
День добрый. В АС3 я пока не очень и нужна ваша помошь, дорогие знатоки.

Ситуация такая - есть поверхность на которую я подтягиваю из библиотеки своего героя игры (hero) и дублирую для тестирования коллизий с поверхностью.

Код AS3:

        private function init(e:Event=null):void {
                _collisionList=new CollisionList(terrain);
                _CharsArray=[];
                for (var i:uint=0; i<4; i++) {;
                        var chars:hero=new hero  ;
                        _CharsArray.push(chars);
                        addChild(chars);
                        _collisionList.addItem(chars);
                }
        }

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

_namesArray=["myhero","fish","turbo"];
_xArray=["400","800","1100"];

Теперь я хочу перебирая элементы массива ставить на карту персонажей с соответствующими именами из библиотеки. Но у меня не получаеться :(
Делаю так:

Код AS3:

        private function init(e:Event=null):void {
                _collisionList=new CollisionList(terrain);
 
                _CharsArray=[];
                _namesArray=["myhero","fish","turbo"];
                _xArray=["400","800","1100"];
 
                for (var i:uint=0; i<_namesArray.length; i++) {
                        var names=_namesArray[i];
                        var chars:MovieClip=new names  ;                       
                        chars.x=_xArray[i];
                        _CharsArray.push(chars);
                        addChild(chars);
                        _collisionList.addItem(chars);
                }
}

Вообщем я понимаю, что я не прописал что-то, но не знаю, что...

Подскажите, что прописать, что бы элемент массива считался мувиклипом и подтягивался из библиотеки.

udaaff 26.04.2010 23:49

getDefinitionByName()

mickfallout 27.04.2010 00:08

я делаю это так:
Код AS3:

                static private var MovieClipsClassesObject:Object = { };// хранилище всех классов MovieClip'ов использованных в функции newMovieClip
                static public function newMovieClip(imageName:String):MovieClip        //создает MovieClip по имени в ресурсах
                {
                        var movieClipsClass:Class;
                        if (MovieClipsClassesObject[imageName] != null )        //если в хранилище MovieClip'ов под таким именем уже что-то есть
                        {
                                //trace("requested mc "+imageName+", give out from MovieClipsClassesObject")
                                movieClipsClass = MovieClipsClassesObject[imageName];// выдаем класс MovieClip'а из хранилища
                        }else {
                                //trace("requested new mc "+imageName+", give out from resourcesLoader")
                                movieClipsClass = resourcesLoader.content.loaderInfo.applicationDomain.getDefinition(imageName) as Class; //из resourcesLoader берется описание класса нужного MovieClip'а
                                MovieClipsClassesObject[imageName] = movieClipsClass;          //и записывается в хранилище
                        }
                        return new movieClipsClass();
                }


BlooDHounD 27.04.2010 00:47

gashhik, не в коем случаи не делайте так как делает mickfallout.

gashhik 27.04.2010 01:21

фух мозги уже плавлятся.....

Код AS3:

private function init(e:Event=null):void {
      _collisionList=new CollisionList(terrain);
 
        _CharsArray=[];
        _namesArray=["myhero","fish","turbo"];
        _xArray=["400","800","1100"];
 
        for (var i:uint=0; i<_namesArray.length; i++) {
                var names=_namesArray[i];
                      //trace(names+" class: "+getQualifiedClassName(names));       
                      var names:Class=getDefinitionByName("myhero") as Class;
                var chars:MovieClip=new names  ;                       
                chars.x=_xArray[i];
                _CharsArray.push(chars);
                addChild(chars);
                _collisionList.addItem(chars);
                }
}

Ошибка:
Код AS3:

TypeError: Error #1034: Type Coercion failed: cannot convert "myhero" to Class.

Я должен тот класс на который я ссылаюсь как то по особенному обработать?

derhab 27.04.2010 01:36

Код AS3:

private function init(e:Event = null):void {
 
      _collisionList = new CollisionList(terrain);
 
        _CharsArray = [];
        _namesArray = ["myhero","fish","turbo"];
        _xArray = ["400", "800", "1100"];
 
        var len:int = _namesArray.length;
 
        for (var i:int = 0; i < len; i++) {
 
                var charClass:Class = getDefinitionByName(_namesArray[i]) as Class;
                var char:MovieClip = new charClass()  ;                       
                char.x =_xArray[i];
                _CharsArray.push(char);
                addChild(char);
                _collisionList.addItem(char);
 
        }
 
}


gashhik 27.04.2010 01:45

Спасибо тебе добрый человек!!1 РАБОТАЕТ :-*

Wolsh 27.04.2010 02:20

А что мешало хранить в массиве классы, а не строки с их именами?

derhab 27.04.2010 02:41

Цитата:

Сообщение от Wolsh (Сообщение 903921)
А что мешало хранить в массиве классы, а не строки с их именами?

всмысле хранить в массиве уже созданные экземпляры классов?
типа:
Код AS3:

[new myhero(), new fish(), new turbo()];


gashhik 27.04.2010 02:44

Не понимаю...
Как вы это видите в коде?
Код AS3:

_namesArray = ["myhero:MovieClip","fish:MovieClip","turbo:MovieClip"]

типа так?

Wolsh 27.04.2010 02:53

Код AS3:

_namesArray = [myhero, fish, turbo];
...
var mc:MovieClip = new _namesArray[i];


derhab 27.04.2010 02:58

да ниче не мешает:)
если знать заранее имена классов
но может быть ситуация когда имя класса приходит извне в виде строки..

Wolsh 27.04.2010 03:08

Ну об этом ведь речи не было. Для таких случаев и существует getDefinition, но никак не для
Код AS3:

var a:uint = 1;
var b:uint = 2;
var c:uint = 3;
var array:Array = ["a", "b", "c"];
// о боже, как мне узнать значение переменной с именем из массива, под индексом 2?

;)

derhab 27.04.2010 03:10

согласен:)
но был рассмотрен и такой вариант, что тоже может быть полезным

mickfallout 27.04.2010 03:50

Цитата:

Сообщение от BlooDHounD (Сообщение 903892)
gashhik, не в коем случаи не делайте так как делает mickfallout.

А в чём ошибка моего метода?

BlooDHounD 27.04.2010 11:22

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

gashhik 27.04.2010 11:27

Цитата:

Сообщение от Wolsh (Сообщение 903929)
Код AS3:

_namesArray = [myhero, fish, turbo];
...
var mc:MovieClip = new _namesArray[i];


Кстати так я сделал изначально и это не сработало :confused:

mickfallout 27.04.2010 12:25

Цитата:

Сообщение от BlooDHounD (Сообщение 903970)
просто оформлен коряво.

хм, а с оформлением что не так?

Добавлено через 1 минуту
а, вроде нашёл... вместо
//если в хранилище MovieClip'ов под таким именем уже что-то есть
надо было написать
//если в хранилище MovieClip классов под таким именем уже что-то есть

BlooDHounD 27.04.2010 13:16

написать, что типа этого, было бы логичнее:
Код AS3:

                private static const _HASH:Object = new Object();
 
                public static function getClass(name:String):Class {
                        var c:Class = _HASH[ name ];
                        if ( !c ) {
                                c = resourcesLoader.content.loaderInfo.applicationDomain.getDefinition( name ) as Class;
                                _HASH[ name ] = c;
                        }
                        return c;
                }

а у Вас целый букет быдлокода:
1. static до нэймспэйса.
2. название переменной MovieClipsClassesObject с большой буквы.
3. не понятно почему оно является переменной, а не константой.
4. если приватная, то почему без подчёркивания?
5. объект создаёте через литерал { }, а не через new Object(). советую второй вариант.
6. метод называется newMovieClip а параметром передаётся imageName.
7. с названиями в принципе беда: MovieClipsClassesObject, movieClipsClass. непонятно.
8. в качестве результат возвращается экземпляр MovieClip, что само по себе плохо. а что, если вам нужно будет сделать наследника спрайта? или битмапа? или ещё чего угодно? напишите ещё один такой же метод?
9. возвращаете Вы готовый экземпляр, но опираясь на пункт 7, возникает вопрос: а что если надо будет передать параметр в конструктор класса?
10. непонятно откуда берётся resourceLoader, и почему он один. а если подгружаемых библиотек будет много?

на счёт пункта 1 и 4, многие со мной не согласятся. я не очень настаиваю.

Wolsh 27.04.2010 13:55

gashhik, это решение предполагает наличие и доступность данных классов. Если это просто имена объектов в библиотеке, я не смогу помочь - не работаю с ИДЕ.
Да, ассоциативный массив был у меня в мыслях тоже))

mickfallout 27.04.2010 14:10

Цитата:

Сообщение от BlooDHounD (Сообщение 904007)
а у Вас целый букет быдлокода:
1. static до нэймспэйса.
2. название переменной MovieClipsClassesObject с большой буквы.
3. не понятно почему оно является переменной, а не константой.
4. если приватная, то почему без подчёркивания?
5. объект создаёте через литерал { }, а не через new Object(). советую второй вариант.
6. метод называется newMovieClip а параметром передаётся imageName.
7. с названиями в принципе беда: MovieClipsClassesObject, movieClipsClass. непонятно.
8. в качестве результат возвращается экземпляр MovieClip, что само по себе плохо. а что, если вам нужно будет сделать наследника спрайта? или битмапа? или ещё чего угодно? напишите ещё один такой же метод?
9. возвращаете Вы готовый экземпляр, но опираясь на пункт 7, возникает вопрос: а что если надо будет передать параметр в конструктор класса?
10. непонятно откуда берётся resourceLoader, и почему он один. а если подгружаемых библиотек будет много?

на счёт пункта 1 и 4, многие со мной не согласятся. я не очень настаиваю.

5. так было рекомендовано в соглашении Flex SDK coding conventions and best practices читал перевод тут http://racer242.blogspot.com/2008/05/flex_23.html
Цитата:

Object
Используйте вместо new Object() литералы объекта:
можно: {}
нельзя: new Object()
8. Ну во первых тема топика - мувиклипы. Во вторых у меня только три типа - мувиклип, битмап, sound. Мне удобнее использовать отдельные три метода, т.к. в них есть свои особенности, и для строгой типизации. Удобно когда можно писать addChild(newMovieClip("unit")) вместо addChild(MovieClip(newSomething("unit"))).
9.В конструктор класса MovieClip ничего передавать не надо. Там где надо(в битмап например) -там передается, там другая функция...
10. Много библиотек не планируется, откуда берется объясняется выше по коду. Приводить не стал, т.к. это выходит за рамки темы топика (обсуждаем как извлечь из библиотеки, а не как загрузить библиотеку)
1,2,3,4,6,7 - Спасибо, исправлю =)

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

Сообщение от BlooDHounD (Сообщение 904007)
написать, что типа этого, было бы логичнее:
Код AS3:

public static function getClass(name:String):Class


так конечно универсальнее, но у меня например:
Код AS3:

addChild(getBitmap("chest"));
addChild(newMovieClip("unit"));

а у Вас будет что-то типа
Код AS3:

addChild(new Bitmap( BitmapData(new getClass("chest"))));
addChild(MovieClip(new getClass("unit")));


BlooDHounD 27.04.2010 14:44

5. если Вы будите опираться на эту конвенцию то вскоре встретитесь с проблемами. например у литерала {} не так как у всех работает перебор через for .. in
8. тема топика мувиклипы, только потому, что автор, видимо, перешёл к нас с АС2, в котором ничего другого и нету. к тому же даже гуру по привычки называю всю визуалку "мувиками". тупо привычка из старых времён.
9. ваше право. пишете 10 раз один и тот же рас так нравится =)
10. я уже понял, что Вы любите писать одноразовый код.

по поводу того как будет у меня. у меня будет понятно, что происходит, а не создание непонятно чего и не понятно где. к тому же я забыл сказать почему Ваш вариант ещё хуже =)

если у Вас в библиотеке не окажется указанного класса, то у вас произойдёт целый каскад ошибок:
1. new movieClipsClass() - Вы не проверяете существование класса. то есть будет ошибка.
2. даже если Вы поставите проверку в пункте 1 и вернёте null, то у Вас всё упадёт на addChild.

и ещё новый быдлокод:
не используйте для приведение типов конструкции вида MovieClip( object ). это конвертация а не приведение типов. используйте оператор as.

в общем как хотите.

mickfallout 27.04.2010 14:54

Цитата:

Вы не проверяете существование класса. то есть будет ошибка.
Вы тоже не проверяете вроде? =)
Код AS3:

c = resourcesLoader.content.loaderInfo.applicationDomain.getDefinition( name ) as Class;

На данный момент меня устраивает что программа упадёт если нет нужного класса. В дальнейшем естественно воспользуюсь Вашим советом =)
Цитата:

не используйте для приведение типов конструкции вида MovieClip( object ). это конвертация а не приведение типов. используйте оператор as.
В той конвенции написано ровно наоборот.
Цитата:

Оператор "as" используйте только в том случае, если при ошибке приведения к типу, вы хотите получить в результате значение "null", а не генерацию исключения:
можно: IUIComponent(child).document
нельзя: (child as IUIComponent).document
Добавлено через 52 секунды
Цитата:

если Вы будите опираться на эту конвенцию то вскоре встретитесь с проблемами.
Посоветуйте, как какую конвенцию мне опираться? На какую например опираетесь Вы?

BlooDHounD 27.04.2010 16:02

mickfallout, а зачем мне его там проверять? там у меня ошибки не будет. я не создаю экземпляра и уж тем более никуда его не добавляю. просто возвращаю результат.

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

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

Aloran 27.04.2010 17:29

BlooDHounD
Подскажи пожалуйста, а чем конвертация отличается от приведения?
А еще есть моменты когда надо отходить от конвенции?

etc 27.04.2010 18:01

Цитата:

Сообщение от Aloran (Сообщение 904136)
BlooDHounD
Подскажи пожалуйста, а чем конвертация отличается от приведения?

Приведение не делает преобразования из A в B.

Цитата:

Сообщение от Aloran (Сообщение 904136)
А еще есть моменты когда надо отходить от конвенции?

Есть.

BlooDHounD 27.04.2010 18:03

Код AS3:

trace( '5' as Number ); // null
trace( Number( '5' ) ); // 5
 
trace( '<xml>' as XML ); // null
trace( XML( '<xml />' ) ); // <xml />
 
trace( new Sprite() as MovieClip ); // null
trace( MovieClip( new Sprite() ) ); // TypeError #1034

приведение типа всегда возвращает ссылку на тот же объект, что у вас и был, либо null.
конвертация при возвращает ту же ссылку, только если типы совпадают, иначе она пытается создать объект нового типа на базе нового. если и этого не выходит она выбрасывает ошибку.

лично я и не помню, где я в последний раз использовал конвертацию.
для преобразования текста в число я использую parseInt и parseFloat.
для приведения к строке использую метод toString.
для создания XML я всегда пишу new XML().
ну и т.д. то есть убираю посредников.

dimarik 28.04.2010 00:28

Конвертация вроде как шустрее работает.

BlooDHounD 28.04.2010 00:49

Цитата:

Сообщение от dimarik (Сообщение 904323)
Конвертация вроде как шустрее работает.

Код AS3:

public function test() {
        const l:uint = 1e6;
        var i:uint;
        var t:Number;
 
        t = getTimer();
        for ( i=0; i<l; i++ ) {
                this as Sprite;
        }
        trace( getTimer() - t ); // 192
 
        t = getTimer();
        for ( i=0; i<l; i++ ) {
                Sprite( this );
        }
        trace( getTimer() - t ); // 236
}

а если местами поменять, то приведение почти в 2 раза рвёт. лично я уверен, что внутри конвертации сперва происходит приведение, поэтому оно быстрее быть не может. это как конвертацией в String, внутри, которой вызывается toString. так что сомнительно.

p.s.: сегодня прямо день перлов про быстродействие =) записать что ли все ...

gloomyBrain 28.04.2010 00:51

По идее приведение должно быть быстрее - при нем не создается новый объект. Возвращается-то либо сам объект, который конвертируем, либо null (который вообще синглтон).
Код AS3:

var a:MovieClip = new MovieClip();
var b:DisplayObject = a as DisplayObject;
trace(a === b); // true

UPD
А это-то как?
Код AS3:

var a:MovieClip = new MovieClip();
var b:DisplayObject = DisplayObject(a);
trace(a === b); // true


dimarik 28.04.2010 01:05

BlooDHounD, спасибо за тест. А то так влом было писать ).

BlooDHounD 28.04.2010 01:18

gloomyBrain, мдя ... как раз при конвертации новый объект может создаться. а не наоборот. разберитесь с терминами. и перечитайте топик с начала.

p.s.: и с чего Вы взяли, что null это синглтон?

gloomyBrain 28.04.2010 01:29

Да, написал наоборот =)
А про null - а с чего вы взяли, что это не так?

BlooDHounD 28.04.2010 01:39

ну тогда всё просто: null - неведомый жираф. докажите обратное =)
p.s.: сегодня на форуме день голословных утверждений.

gloomyBrain 28.04.2010 01:42

Код AS3:

var a:Sprite = null;
var b:Sprite = null;
trace(a === b); // true


mickfallout 28.04.2010 02:00

Код AS3:

        var i:int = 10;
        var j:int = 10;
        trace(i === j);

хм, любое числовое значение - тоже синглтон?

BlooDHounD 28.04.2010 02:01

mickfallout, мысли читаете =)

gloomyBrain 28.04.2010 12:18

У меня нет разумного объяснения. Может у кого-то оно есть?

BlooDHounD 28.04.2010 13:18

ну рас нету, то остановимся на моём варианте:
Цитата:

Сообщение от BlooDHounD (Сообщение 904350)
null - неведомый жираф.


switcher! 28.04.2010 14:08

Наверное, подливаю масла в огонь. Однако, хочется поставить жирную точку с null.

До сего топика основывался на 4-м посте этой темы.
Полагаю, wvxvw основывался на серьезных документах или тестах. И поможет разъяснить ситуацию.


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

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