PDA

Просмотр полной версии : Как из класса "увидеть" объекты сцены?


nail84
30.07.2007, 13:45
Здравствуйте... Проблема вот в чем... Я создаю класс, и мне из него надо написать что-нибудь в текстовое поле расположенное на сцене.
В AS2 это выглядело бы так:
_root.textVar='Test';
В AS3 пишу следующее:
main_report.text='Test';
не прокатывает :( ....
Пытался узнать полный путь текстового поля main_report с помощью 'parent.name' показало root1, но
root1.main_report.text='Test';
тоже не прокатывает :( ....
PS ковыряю хелп уже 1.5 часа....

etc
30.07.2007, 13:46
Собственно, Document class есть рутовый класс, он и содержит в себе все текстовые поля и прочее.

Код в кадрах в AS3 не пишут.

Usnul
30.07.2007, 14:42
грузить основной класс в тот из которого ты хочешь им пользоваться, например так:

public class my_class extends Sprite
{
public var _root:root_classClass;
public function my_class(root_class:root_classClass){
_root = root_class;
trace(_root.myTextField);
}
}

nail84
30.07.2007, 15:01
to __etc: спасибо, но код в кадрах я не пишу.... Эт я уже усвоил Ж)
to Usnul: понял, спасибо.... а как это выглядит с точки зрения производительности?
---------------------
думаю изменю логику.... буду обращаться к объектам на сцене только Document class'ом (все объекты все равно в нем создаются)....

Usnul
30.07.2007, 15:03
очень даже хорошо выглядет, обьект всеравно грузится при запуске программы, так что это всего-лишь ссылка по сути.

miramax
30.07.2007, 15:06
Код в кадрах в AS3 не пишут.Я пишу :rolleyes:

Кстати текстовые поля объявленые в кадрах инициализируются не сразу =(
Ну например нарисовал клип, назвал классом MyClip, а в нём в первом кадре текстовое поле textField.
Так вот конструкция

var clip:* = new MyClip()
trace(clip.textField)
Будет выдывать undefined, т.к. текстфилды будут доступны только в следующем кадре. Так что нужен таймаут или ентерфрейм.
Очень жаль...
ведь визуально текстфилды расставлять удобнее....

Usnul
30.07.2007, 15:09
кадры - это ваше воображение, их не существует на самом деле, а раз нету кадров, то и писать в них что-либо является ересью и ловушками сатаны. Эрго: АС3 в кадрах, добропорядочные хрестиане, не пишут.

nail84
30.07.2007, 15:09
ясно.... а с точки зрения стиля что правильней манипулировать объектами только из Document class'а, а из остальных классов только инфу получать, или каждым классом править объекты на сцене?

miramax
30.07.2007, 15:16
кадры - это ваше воображение, их не существует на самом деле, а раз нету кадров, то и писать в них что-либо является ересью и ловушками сатаны. Эрго: АС3 в кадрах, добропорядочные хрестиане, не пишут.
Да не, всё нормально. Надо совмещать клипы с кодом в кадрах и классовую структуру.
Есть такие задачи которые "без кадров" решать очень долго...

miramax
30.07.2007, 15:24
ясно.... а с точки зрения стиля что правильней манипулировать объектами только из Document class'а, а из остальных классов только инфу получать, или каждым классом править объекты на сцене?
Document class это типа точки входа... Обычно в Document class'e кроме инициализации других объектов ничего нет.
Надо стараться поменьше оставлять "на сцене" и побольше юзать коснтрукторы. Это с опытом придёт =)

Основную структуру программы надо держать в классах.
А в кадрах удобно держать код для маленьких кирпичиков гуя находящихся "на нижнем этаже" (типа красивых кнопок, переходов и форм с тексфилдами)

nail84
30.07.2007, 15:25
Спасибо.... направление понял)

vapes
30.07.2007, 15:46
Я тоже иногда пишу код в кадре типа stop(); или когда по окончанию проигрывания мувика нужно вызвать метод.

ALiEN_
31.07.2007, 16:04
Надо писать так - как позволяет писать редактор. Хочешь писать в кадрах пиши, хочешь цеплять внешние классы - цепляй, хочешь юзай автосоздание классов =) Но это моё мнение. 8)

А вот для того что бы видеть объекты сцены:

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

2. Воспользоваться кодом выше - отдавать ссылку на саму сцену.

3. Использовать статический класс, с линками на объекты сцены (получается гораздо удобнее, т.к. не надо ничего никому передавать, как первых двух случаях)

4. Использовать stage, parent - прямо внутри класса.

5. ??? Есть еще варианты?

nail84
31.07.2007, 17:18
1. Проще всего создать массив ссылок на эти объекты, и отдавать этот массив нужным классам.
4. Использовать stage, parent - прямо внутри класса.

Вот именно это у меня и не получилось.... При попытке обратиться к объекту, расположенному на сцене, непосредственно из класса через stage и parent, флеш ругался на недопустимые методы....
Буду признателен если напишешь как это правильно делать.

mushtra
06.08.2007, 16:26
В твоём случае:
var p = root;
p.textVar='Test';

etc
06.08.2007, 16:30
mushtra, а что мешает написать сразу root.textVar = …?

mushtra
06.08.2007, 16:47
Не берусь с Вами спорить: очень слаб в AS3, но кажется сталкивался с ситуацией, что для обращения к свойствам одного объекта из другого, необходимо регистрировать первый объект в последнем. Впрочем, думаю, если и тот и другой вариант верны, то автору топика ситуация должна проясниться. Вообще, считаю, что стереотип областей видимости в ОП AS2, вполне применим и к AS3, только синтаксис другой.

ALiEN_
06.08.2007, 21:58
Вот именно это у меня и не получилось.... При попытке обратиться к объекту, расположенному на сцене, непосредственно из класса через stage и parent, флеш ругался на недопустимые методы....
Буду признателен если напишешь как это правильно делать.

Например так:

Основной код в КАДРЕ =)

var arrayLinks:Array = new Array();

var o1 = new Sprite();
o1.name = "myObjectName1";
arrayLinks.push(o1);

var o2 = new Shape();
o2.name = "myObjectName2";
arrayLinks[1] = o2;

var o3 = new MovieClip();
o3.name = "myObjectName3";
addChild(o3);
arrayLinks.unshift(o3);

for each (var i in arrayLinks) trace(i.name);

trace("----");

var myClass = new MyClass();

myClass.setMyArrayLinks(arrayLinks);
myClass.getNameObjects();


и код класса "MyClass" в библиотеке


var arrayLinks:Array;

function setMyArrayLinks(n:Array){

arrayLinks = n;

}

function getNameObjects(){

for each (var i in arrayLinks) trace(i.name);

}


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

Например тогда при создании нашего MyClass, нам не пришлось бы сетить setMyArrayLinks(n:Array) - наш массив с линками.
Мы засетили бы наш массив один раз в статичский класс GlobalLinks, например, тогда код класса MyClass сильно упрощается. И можно создавать хоть 10 объектов типа MyClass, сетить массивы в каждый объект не пришлось бы.

Вот пример нашего нового MyClass:


function getNameObjects(){

for each (var i in GlobalLinks.arrayLinks) trace(i.name);

}


Удобнее? на все 100% =)

P.S. Как видно из примера линки могут содержать как добавленные на сцену объекты, так и еще не добавленные.

etc
06.08.2007, 22:33
Не понимаю, зачем все эти извращения с массивами, когда есть numChildren и getChildAt…

ALiEN_
08.08.2007, 22:14
Хм... попробуй взять мой код выше, и прилепить в метод getNameObjects numChildren и getChildAt ....

В основном коде, ведь есть объекты не являющиеся чилдами для stage. Как раз для таких вещей и нужны массивы линков =)

etc
08.08.2007, 22:49
private function get objectNames():Array {
var count:uint = this.numChildren;
var out:Array = [];

while (count--) {
out.push(this.getChildAt(count).name);
}

return out.reverse();
}

:bye:

ALiEN_
09.08.2007, 17:13
Этот пример работатать не будет =) Я конечно не гуру, но в хелпе вот написано:

numChildren property

numChildren:int [read-only]

Language version: ActionScript 3.0
Player version: Flash Player 9

Returns the number of children of this object.


Что это свойство возвращает нам колличество чилдов объекта. А как я писал раньше массив ссылок дает нам возможность получать доступ к объектам не являющимися ничьими чилдами.

Кстати, даже если мы просто захотим получить массив чилдов со stage, то даже в этом случае, твой ппример работать не будет. Потому что если твой метод вставить в MyClass, то мы никак не увидим чилдов stage. А судя повсему получим лишь чилдов нашего MyClass.

:away:

etc
09.08.2007, 17:17
Переделать геттер в метод и передавать ссылку на DisplayObject, тот же Stage. Все будет работать, не надо ла-ла :bye:

ALiEN_
09.08.2007, 17:27
Не будет работать =) как там в анекдоте? Нет глазок нет мультиков =)...

Берем предыдущий код:



var arrayLinks:Array = new Array();

var o1 = new Sprite();
o1.name = "myObjectName1";
arrayLinks.push(o1);

var o2 = new Shape();
o2.name = "myObjectName2";
arrayLinks[1] = o2;

var o3 = new MovieClip();
o3.name = "myObjectName3";
addChild(o3);
arrayLinks.unshift(o3);

trace(stage.numChildren);



Посмотри сколько чилдов ты увидишь =)))

:bye:

etc
09.08.2007, 17:32
Ну безусловно один. А что вы мне пытаетесь доказать? Я никак не пойму.
Что такое массив я и без вас знаю. Вот применять его нужно только там, где он действительно требуется и осмысленно, а не везде и всюду. В противном случае утечки памяти и прочие радости жизни возникнут очень быстро.

И вы тему читали? Просят найти все объкты на сцене. Живущие в памяти никого не интересуют.

ALiEN_
09.08.2007, 17:36
Гхм .... резко Вы поменяли тему =) ладно, думаю все уже и так все поняли. А объяснить я пытаюсь следущее, что объекты не являющиеся чилдами, кроме как через ссылки - и описанные выше способы никак увидеть нельзя. Особенно через getChildAt и т.д. ... А утечки памяти выходят лишь при неумелом обращении с сылками. Ну и при использовании ликерских классов. Если не удаляем евенты, соответственно, и т.д.

etc
09.08.2007, 17:40
ALiEN_, прочтите внимательно тему и что хотел автор. Ваши ссылки в массивах ему нахрен не нужны. Ибо у него просто нет никаких ссылок.

ALiEN_
09.08.2007, 17:50
Я конечно извиняюсь, очевидно это все оффтопик =) но с поста номер 20, я задал достаточно простой вопрос, и в посте 21, видимо получил не совсем тот ответ =))

А как по Вашему - под объектами сцены здесь очевидно понимаются все объекты или только избранные?? 8)

Объекты addChild() или вообще все объекты?? Ведь НЕ чилдовые объекты сцены, все равно являются объектами, и ссылки на них находятся на сцене =)



Так что действительно надо бы еще раз просмотреть всю ветку ответов, а так же то что хотел автор "Как из класса "увидеть" объекты сцены?" =)))

etc
09.08.2007, 18:12
Объектами сцены являются те объекты, которые на ней находятся. Под объектом подразумевается любой интерактивный визуальный элемент, а не любой объект ActionScript. Интерактивные объекты, не лежащие на сцене лишь существуют в пределах видимости конструктора/метода или лежат в массиве. Про них речь не идет вообще.

ALiEN_
09.08.2007, 18:13
Объекты типа Array - тоже находятся на сцене, если они там созданы =)) и объекты типа Object... или это не так?

etc
09.08.2007, 18:16
Интересно услышать, как у вас массив на сцене находится. Сцена — визуальный объект. Никакие массивы на нем лежать не могут.

ALiEN_
09.08.2007, 18:19
Хм, а разве stage не является классом? И объекты в нем лежать не могут? это как?

Вас послушать, так получается, что созданный но не добавленный addChild() объект - уже и не объект вовсе =)

etc
09.08.2007, 18:25
По-моему у вас свое понятие «сцена». «Лежать» на сцене могут лишь визуальные объекты, типа Sprite, MovieClip и т.п.
Все остальные объекты являются либо локальными переменными метода/конструктора, либо свойством класса. Свойства и переменные на сцене «лежать» не могут.
Если вы хотите перечислять свойства (неважно, какие) класса (неважно, какого) и хранить их в массиве, то так и пишите, а не применяйте понятие «лежит» к тому, чего быть не может.

Кстати, про писанину в кадре:

var test:Sprite = new Sprite();
trace(this.test);

ALiEN_
09.08.2007, 18:31
Именно так =)

Вы привели пример со ссылкой на объект =)))

а теперь попробуйте его своим numChildren или getChildAt


var test:Sprite = new Sprite();

trace(test);
trace(this.test);


test в данном случае Ваш "визуальный" объект как раз и "лежит" в stage, но не добавлен для отображения, и недоступен для получения его методами getChild, и другими. 8)

Кстати не совсем согласен с "локальными переменными" или "свойствами", т.к. каждое свойство, либо локальная, или не локальная переменная - все равно не перестает быть объектом так уж сделано во флеше =)

etc
09.08.2007, 18:41
Нет, проблема как раз в том, что вы пишете код в кадре и не понимаете результирующей структуры создаваемого класса. Не лежит ничего на сцене, test преобразовывается публичное свойство класса MainTimeline.
Ничего подобного не будет происходить, если писать код не в кадре. Именно поэтому, как я уже говорил, код в кадрах писать не стоит.
Если бы вы создали Document class и написали бы подобный код в конструкторе, то получили бы ошибку.

ALiEN_
09.08.2007, 18:52
Свойство не перестанет быть объектом, ведь так?

Теперь копнем глубже, если мы не говорим addChild, для объекта, он остается локальным "свойством", либо "переменной", а другими словами объектом класса stage.

Если весь код выкинуть в main.as ... это ничего особо не изменит. т.е. Ваш test, так и будет объектом типа Sprite(); хоть и будет являться локальной "переменной", либо "свойством".

etc
09.08.2007, 18:56
Ещё раз, про термины, определяемые в данной теме:
«лежит на сцене» — визуальный элемент, находящийся на сцене. Например, красный кружочек.
«сцена» — рабочая область приложения, по умолчанию белого цвета.

Все остальное не лежит на сцене. Так яснее?

ALiEN_
09.08.2007, 19:15
Эх .... кружочек ....

Вот хелп:

Class Stage

Package flash.display
Class public class Stage

Language version: ActionScript 3.0
Player version: Flash Player 9

The Stage class represents the main drawing area. The Stage represents the entire area where Flash® content is shown.

Вы наверно это имели ввиду когда говорили про рабочую область приложения?

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

основной код:

var test:Sprite = new Sprite();
test.name = "Это объект 'test'";


var test2 = new Sprite();
test2.name = "А это объект 'test2'";
addChild(test2);


var z = new MyClass();
addChild(z);

var tmp = this;

trace("Что это у нас? : " + tmp);
trace("----");

z.setStage(tmp);
z.getObjects();



код класса MyClass

var st;

function setStage(s){

st = s;

}

function getObjects(){


trace("А это что? : " + st);

trace(parent.getChildByName("А это объект 'test2'").name);

trace(st.test.name);

}


:quiet:

etc
09.08.2007, 19:18
Вы наверно это имели ввиду когда говорили про рабочую область приложения?
Нет, Stage — свойство stage у DisplayObject. И tmp в вашем коде вовсе не является Stage.

var sp:Sprite = new Sprite();
sp.name = 'test';
addChild(sp);
trace(stage.getChildByName('test')); // null

Вы оперируете терминами, которые в рамках данной темы означают совершенно иное. Что именно — я уже рассказал.
В вашем случае «сцена» — Document class, «лежит» = «принадлежит» или является локальной переменной. В рамках данной темы требуется иное.

ALiEN_
09.08.2007, 19:24
Раз Вы поленились посмотреть код, могу кинуть исходник, либо просто дать трейс:

trace


Что это у нас? : [object MainTimeline]
----
А это что? : [object MainTimeline]
А это объект 'test2'
Это объект 'test'

etc
09.08.2007, 19:27
Какой-то беспредметный спор. Ещё раз говорю: «лежит» — это лежит визуально. Сцена — это сцена, Document class, а не Stage. Stage — класс Stage. ТОЧКА. Ваш код ничего никому не объясняет и что им требовалось сказать или доказать — неясно.
Засим тема закрыта, я запарился втолковывать тривиальные термины.