Форум Flasher.ru

Форум Flasher.ru (http://www.flasher.ru/forum/index.php)
-   ActionScript 3.0 (http://www.flasher.ru/forum/forumdisplay.php?f=83)
-   -   error 1061 (http://www.flasher.ru/forum/showthread.php?t=138231)

elcard 02.04.2010 12:23

error 1061
 
Пару дней назад начал изучать as3. Постепенно врубаюсь. Начал делать игру по примеру MerlinTwi http://flasher.ru/forum/showthread.php?t=83431 и встрял в начале на 2 странице на прелоадере.
Цитата:

Ошибка 1061: Call to a possibly undefined method play through a reference with static type flash.display:DisplayObjectContainer.
при компиляции. Сижу два часа сравниваю его исходник со своим и вроде все так же, но не могу понять в чем ошибка.
Даже в мане опечатку нашел пока искал
Цитата:

progress - мувик состоящий из 100 кадров
Имеется ввиду progressbar, а не progress, так?

wvxvw 02.04.2010 16:05

Номера ошибок никто не знает наизусть. Если вы хотите получить ответ - не называйте темы так никогда.
И читайте, что говорится в ошибке - вы вызываете методо play() у переменной типизированой как DisplayObjectContainer - возможно у нее есть такой метод, но вы должны компилятору это явно объяснить = кастовать к объекту, у которого такой метод есть.

sub_putnik 03.09.2010 15:59

Вставь в прелоадаре вместо parent.play();

Код AS3:

if (parent is MovieClip) {
( parent as MovieClip ).play();
}


in4core 04.09.2010 00:55

Код AS3:

if (parent is MovieClip) {
( parent as MovieClip ).play();
}

Что за бред ??? Сам понимаешь что написал? Если объект есть мувиклип, то превратить объект в мувиклип и проиграть. зачем делать абсурдное приведение типов?

dimarik 04.09.2010 01:39

Штобы компилятор не ругался, не?

in4core 04.09.2010 02:13

еще один весельчак)) даж я с минимальными знаниями ас3 и то понимаю, что если объект уже мувиклип, то компилятор не будет ругаться на объект.методКлипа().

Добавлено через 41 секунду
хотя если ошибаюсь мне будет оч стыдно за свои слова :)

-De- 04.09.2010 02:23

чувак...
Код AS3:

var tehMovie:DisplayObjectContainer = new MovieClip();//parent есть DisplayObjectContainer
//tehMovie.play();//не покатит, у DisplayObjectContainer нет метода play
(tehMovie as MovieClip).play();//всё ок

ну и проверочка, что там MovieClip а не спрайт какой.

Obi 04.09.2010 02:40

Цитата:

Сообщение от in4core (Сообщение 933412)
Что за бред ??? Сам понимаешь что написал? Если объект есть мувиклип, то превратить объект в мувиклип и проиграть. зачем делать абсурдное приведение типов?

Никто никого превращать не будет. У нас тут не сеансы черной магии, а компилятор – не Воланд. Мы просто явно указываем компилятору, с объектом какого типа имеем дело.

Элементарный пример:

Код AS3:

public static function closeUIWindow(value:Object):UIWindow {
  if(value is String) {
      return closeWindowByName(value as String);
  }else if(value is UIWindow) {
      return closeWindow(value as UIWindow);
  }else {
      trace('unknown type');
      return null;
  }
}

Хотя звездочка тут бы лучше смотрелась.

in4core 04.09.2010 17:38

Ну да если объект диспейконтейнер просто тогда да. Согласен. Но тогда и надо писать так:

Код AS3:

if (parent is DisplayObjectContainer) {
( parent as MovieClip ).play();
}

разницу видим?

i.o. 04.09.2010 18:07

Цитата:

Сообщение от in4core (Сообщение 933517)
Ну да если объект диспейконтейнер просто тогда да. Согласен. Но тогда и надо писать так:

Код AS3:

if (parent is DisplayObjectContainer) {
( parent as MovieClip ).play();
}

разницу видим?

Видим. Это называется небезопасное приведение типов :)
Вот здесь вы проверяете: parent является ли DisplayObjectContainer - так он и так им является, иначе что это за parent. Единственная ситуация, когда это условие не проканает - parent == null.
Ладно проверили, убедились, что parent не null. Далее вы ему, сразу так не церемонясь, заявляете, что он MovieClip. Откуда такая уверенность? А что если он Sprite? Так вот если он будет Sprite, то (parent as MovieClip) в рантайме у вас превратиться в null. А у null вы попытаетесь вызвать метод play();, за что получите рантайм-ошибку.

Так что человек здесь все правильно делал:
Код AS3:

if( parent is MovieClip )
        (parent as MovieClip).play();

Вы какую мысль пытались донести?

derhab 04.09.2010 18:19

Цитата:

Сообщение от in4core
...Что за бред ??? Сам понимаешь что написал?...

Цитата:

Сообщение от in4core
...даж я с минимальными знаниями ас3 и то понимаю...

Цитата:

Сообщение от in4core
хотя если ошибаюсь мне будет оч стыдно за свои слова

уже стыдно?)

in4core 05.09.2010 02:01

стыдно конечно) ну не суть. зато много полезного

gloomyBrain 05.09.2010 21:02

А мне не нравится кастовать по 2 раза. Достаточно вспомнить, что
Код AS3:

someObject as MovieClip

вернет null, если кастинг не прошел. Поэтому, чаще всего делаю так:
Код AS3:

var someClip:MovieClip = someObject as MovieClip
if(someClip != null) {
someClip.gotoAndStop("куда-то там");
}


etc 06.09.2010 17:17

gloomyBrain, достаточно if (someClip)

i.o. 06.09.2010 17:41

Цитата:

А мне не нравится кастовать по 2 раза. Поэтому, чаще всего делаю так:
Когда кастуется два раза, то не создается лишняя переменная. Если нужно откастовать экземпляр и вызвать у него один метод, то нет смысла создавть дополнительную переменную.
Если же необходимо вызвать много методов / свойств - то ваш вариант безусловно лучше.

gloomyBrain 06.09.2010 17:44

etc, спасибо =) но я в курсе. Привык так просто, вот и пишу

@i.o.
Кастинг несколько медленнее создания переменной.

etc 06.09.2010 18:01

gloomyBrain, гм, по моему быстрее или медленнее — это сущая мелочь.

goldlider 22.11.2011 20:17

Читал предыдущие посты, но не догнал такую вещь. В Flash IDE на основной шкале имеются мувики с вложенными кадрами. Класс WeaponDemo - это Document Class.

Код AS3:

package
{
        import flash.display.*;
 
        public class WeaponsDemo extends MovieClip
        {
                public function WeaponsDemo()
                {       
                        for (var i:int = 0; i < numChildren; i++)
                        {
                                if (getChildAt(i) is MovieClip)
                                {
                                        (getChildAt(i) as MovieClip).stop(); // Если не сделать кастинг, то в строгом режиме компилятор выдает ошибку "1061: Call to a possibly undefined method stop through a reference with static type flash.display:DisplayObject".
                                }
                        }
                }
        }
}

Ведь метод stop() яв-ся родным методом класса MovieClip. Почему же тогда приходится выполнять кастинг?

Stitch512 22.11.2011 20:25

Метод getChildAt возвращает DisplayObject, не обязательно MovitClip, это уже выше обсудили.

goldlider 22.11.2011 20:29

Цитата:

Сообщение от Stitch512 (Сообщение 1047597)
Метод getChildAt возвращает DisplayObject, не обязательно MovitClip, это уже выше обсудили.

Код AS3:

trace(getChildAt(i)) выводит [object MovieClip]


gloomyBrain 22.11.2011 20:38

goldlider, а что делает функция trace?

КорДум 22.11.2011 20:39

Код AS3:

trace(getChildAt(i))

Здесь неявно вызывается метод toString(), который есть у всех экземпляров вообще всех классов. В MovieClip он переопределен, вот и показывает, что это не Object (DisplayObject), а MovieClip.

goldlider 22.11.2011 20:43

Цитата:

Сообщение от КорДум (Сообщение 1047603)
Код AS3:

trace(getChildAt(i))

Здесь неявно вызывается метод toString(), который есть у всех экземпляров вообще всех классов. В MovieClip он переопределен, вот и показывает, что это не Object (DisplayObject), а MovieClip.

че то я не понял. Как это выз-ся toString без моего ведома?

КорДум 22.11.2011 20:45

Неявно.
Как тут:
Код AS3:

if (someObject)

происходит неявное сравнение с true.

artcraft 22.11.2011 20:45

метод трейс умеет выводить только строки, если ему скормить что-то что отличается от строки, он сперва конвертнёт это в строку

КорДум 22.11.2011 20:46

Тут еще подумал, получается, у всех классов этот метод сам переопределяется компилятором.

gloomyBrain 22.11.2011 20:48

Цитата:

происходит неявное сравнение с true.
Происходит приведение типа к Boolean.

Цитата:

у всех классов этот метод сам переопределяется компилятором.
метод toString определен либо у прототипа, либо у класса. Компилятор сам ничего не переопределяет

КорДум 22.11.2011 20:49

gloomyBrain, да. Это и имел в виду. В обоих случаях.

goldlider 22.11.2011 20:50

Цитата:

Сообщение от artcraft (Сообщение 1047607)
метод трейс умеет выводить только строки, если ему скормить что-то что отличается от строки, он сперва конвертнёт это в строку

как я понял, получается, что это trace вызывает toString() неявно.

artcraft 22.11.2011 20:55

да, втихаря

goldlider 22.11.2011 22:32

Объясните пожалуйста такую вещь. В приведенном мной выше коде, над объектом какого класса выз-ся метод getChildAt()?
Если этот метод вызывается над объектом класса WeaponsDemo, который яв-ся наследником DisplayObjectContainer. Так зачем приведение метода getChildAt() к типу MovieClip, если этот метод итак передается по наследству.

Получается что запись getChildAt(i).stop аналогична записи this.getChildAt(i).stop. Что из этого выходит, что объекту WeaponsDemo из метода getChildAt(i) возвращается объект DisplayObjectContainer и затем вызывается метод stop().

У меня какая-то каша ничего понять не могу.

Bgg 22.11.2011 23:02

Цитата:

Сообщение от goldlider (Сообщение 1047633)
getChildAt(i) возвращается объект DisplayObjectContainer и затем вызывается метод stop().

С чего вы взяли что возвращается DisplayObjectContainer? Не нужно ничего придумывать или предполагать. Метод getChildAt возвращает DisplayObject, о чем пишется в документации.

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

Читайте книги и документацию, и каша пропадет.

goldlider 22.11.2011 23:29

Цитата:

Сообщение от Bgg (Сообщение 1047637)
С чего вы взяли что возвращается DisplayObjectContainer? Не нужно ничего придумывать или предполагать. Метод getChildAt возвращает DisplayObject, о чем пишется в документации.

Тогда, как это может быть true

Код AS3:

(getChildIndex(i) is MovieClip)

Согласно вашим словам getChildIndex возвращает DisplayObject. Тогда получается

Код AS3:

(DisplayObject is MovieClip) // isn't true

что не может быть на самом деле.

Bgg 22.11.2011 23:44

Цитата:

Сообщение от goldlider (Сообщение 1047641)
Тогда получается
Код AS3:

(DisplayObject is MovieClip) // isn't true

что не может быть на самом деле.

По вашему мувиклип не визуальный объект что ли? Проверили пропихнув это в трейс и трейс выдал странный вариант? Читайте про проверку типов.

Код AS3:

var m:MovieClip = new MovieClip();
var s:String = new String("s");
 
trace(m is DisplayObject);//true
trace(s is DisplayObject);//false
trace(MovieClip is Class);//true

Документация опять бежит вам на помощь и показывает цепочку наследования: MovieClip > Sprite > DisplayObjectContainer > InteractiveObject > DisplayObject > EventDispatcher > Object

goldlider 22.11.2011 23:51

bgg, вы о чем? Я знаю, что в каком порядке идет в дисплей листе. Вы сказали, что getChildIndex возвращает объект класса DisplayObject. Как тогда DisplayObject может приводится к классу MovieClip, который находится ниже в иерархии?

Bgg 22.11.2011 23:58

Причем тут дисплей лист? Мда, вам ещё оказывается все объяснили на второй странице, если бы заметил раньше, то не распинался бы.

Все, ушел из темы, тут я бессилен.

Psycho Tiger 23.11.2011 00:43

Человек просто совсем начинает, что вы так сразу на него то? )
Смотри.
Есть такая штука: наследование. Создали класс А, и унаследовали от него класс Б. Класс Б является наследником класса А, т.е. он унаследовал его поведения и свойства, но при этом он его расширил, добавив что-то своё новое. И фишка в том, что мы можем в переменную с типом А записать ссылку на экземпляр с типом Б:
Код AS3:

var obj:A=new B();

потому что всякое Б - это А, только дополненное и расширенное. Однако, обратное утверждение не верно: не всякое А это Б.
Манипуляции происходят со ссылками. Мы не изменили сущность экземпляра класса Б, записав ссылку на него в переменную с типом А. Однако компилятор то этого не знает ) Ему побоку что там записано: А или Б. Он точно знает, что там А и поступать он будет как с А. К чему я клоню?
К тому что если в Б создать метод hello, то мы не сможем его вызвать через переменную с типом А: потому что компилятор не знает, что там записано на самом деле. Это остается на откуп программисту. И надо подсказать ему:
Код AS3:

(obj as B).hello();

И это подводит нас к ещё одной штуковине. Как уже было сказано ранее сущность не меняется. Поэтому если в классе А есть метод method, то в классе Б его можно перекрыть. Для примера, пусть в классе А метод method делает trace(1), а в классе Б этот метод переопределен, и он делает trace(2).
Код AS3:

var obj:A=new B(); //тип переменной A, но лежит там B
obj.method();//хоть тип переменной и A, но лежит то там B! И видим мы 2

Это кстати называется полиморфизмом.

Вот этот method в твоём примере это toString. (на самом деле, насколько я знаю это неправда, но для понимания считай так: не нужно тебе в прототипы лезть). А метод hello в это stop.
Цепочка вообще такая:
MovieClip->Sprite->DisplayObjectContainer->InteractiveObject->DisplayObject->EventDispatcher.
В переменную с типом EventDispatcher ты можешь записать любой MovieClip. Или любой DisplayObject. А в переменную с типом DisplayObjectContainer ты можешь записать Sprite. Но ты не можешь записать в переменную с типом DisplayObjectContainer, скажем, EventDispatcher.

Ookami 23.11.2011 01:05

Тигра красавец =) Тебе бы маны писать =) Плюс в карму


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

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