PDA

Просмотр полной версии : [AS2]метод "не видит" свойство класса


genius
28.06.2005, 18:15
есть следующий класс:

class game.MusicFile extends game.MusicObject {
private var mp3file:Sound

public function MusicFile () {
}
/*
* загружаем файл (не закончено)
*/
public function load(mp3fileLocation:String):Void {
TRACE(Flashout.INFO + "mp3 started loading");
var z = scopeRef.createEmptyMovieClip("mp3fileContainer", scopeRef.getNextHighestDepth());
mp3file = new Sound(scopeRef.mp3fileContainer);
TRACE(Flashout.DEBUG + "setting onLoad");
mp3file.onLoad = this.onLoad;
TRACE(Flashout.DEBUG + "onLoad set");
mp3file.loadSound("music.mp3", false);
}
public function startPlay():Void {
TRACE(Flashout.DEBUG + "this is mp3file="+mp3file);
mp3file.start();
TRACE(Flashout.DEBUG + "mp3 playing");
}
private function onLoad(success:Boolean):Void {
var suc = success ? "successfully" : "not successfully";
TRACE(Flashout.DEBUG + "onLoad called. loaded "+suc);
TRACE(Flashout.DEBUG + scopeRef);
if (success) {
TRACE(Flashout.DEBUG + this);
TRACE(Flashout.INFO + "mp3file=" + mp3file);
this.startPlay();
} else {
TRACE(Flashout.ERROR + "mp3 not loaded");
}
}
}

на выходе трейсит следующее:

[22:29:180] info: game.MusicFile.load()
mp3 started loading
[22:29:180] debug: game.MusicFile.load()
setting onLoad
[22:29:190] debug: game.MusicFile.load()
onLoad set
[22:29:350] debug: game.MusicFile.onLoad()
onLoad called. loaded successfully
[22:29:350] debug: game.MusicFile.onLoad()
_level0
[22:29:350] debug: game.MusicFile.onLoad()
[object Object]
[22:29:350] info: game.MusicFile.onLoad()
mp3file=undefined // фак!!! почему???

объясните дураку, почему мне говорят, что свойства mp3file не существует? ведь методом выше оно было, а методом ниже его уже нет.

что я делаю не так? заранее спасибо за помощь.

Nirth
28.06.2005, 18:30
потому что ты теперь находишься в другой области видимости, используй класс mx.utils.Delegate

mp3file.onLoad = mx.utils.Delegate(this,this.onLoad)

genius
28.06.2005, 18:33
а какой области видимости я нахожусь? и почему в другой, а не в своём объекте?

спасибо за помощь :)

Nirth
28.06.2005, 18:35
ты находишься в области видимости объекта Sound. поэтому и не видит.

genius
28.06.2005, 18:46
ты находишься в области видимости объекта Sound. поэтому и не видит.

ага. у меня была такая мысль. только вот MTASC ругался, не хотел

то есть использование Delegate - это обычный метод, который используют в таких случаях?

Nirth
28.06.2005, 18:52
Да это стандарт, в старших языках(Java, C#) есть даже специальные поля в классе, делегаторы,во флэше пока такого нету зато есть класс кое как эмулирующий данную фиговину=)

7thsky™
28.06.2005, 19:12
у функций описанных в классах, всего три звена в цепочке видимости:

локальные данные
объект вызвавший функцию
и глобал

вот пример:
class test extends Object {
var a;
var type = 5;
function test () {
var a = {};
a.type = 100;
a.test = method;
a.test ();
}
function method () {
trace ('>> ' + type);
}
}

в файле
a = new test (); // в трайс выдаст 100

genius
29.06.2005, 02:45
спасибо, друзья, вы мне здорово помогли :)

genius
29.06.2005, 17:02
чтобы всё заработало в FAME пришлось поправить класс Delegate: в 27 и 29 строчках заменить func на func2.

2Nirth: вызывается он, конечно, Delegate.create() :) и спасибо за замечательный туториал по FAME!

Nirth
29.06.2005, 17:04
писал не я, я просто перевел=)

genius
29.06.2005, 17:32
а что делать с watch? какой у него scope?

есть следующий код (при успешной загрузке у класса MusicFile устанавливается атрибут loaded=true, что работает 100%):


musicFile = new MusicFile(scopeRef);
musicFile.watch("loaded", ifLoaded);
musicFile.load("music.mp3");
musicFile.loaded = true;

и метод класса:

private function ifLoaded ():Void{
if (musicFile.loaded == true) {
recordBeat();
} else if (musicFile.loaded == false) {
} else {
TRACE(Flashout.FATAL + "loading terminated without error and success");
}
}

как не сложно догадаться, дважды выдает "loading teminated". при том, что я точно знаю, что загрузка завершилась успешно. ну и контрольная установка свойства "loaded" тоже приводит к ошибке, чего быть по определению не должно.

как решить эту проблему? какая область видимости у watch? заранее спасибо за помощь :)

Nirth
29.06.2005, 17:41
так получилось, что за свою короткую жизнь не юзал watch? но если я понимаю правильно думаю делегейт опять должен придти на помощь

musicFile.watch("loaded",Delegate.create(this,this.ifLoaded));

silin
29.06.2005, 19:31
как решить эту проблему? какая область видимости у watch?имхо текущая линейка и _global,
т.е.давать ей нада ссылку , которую видно с этой линейки
иными словами вот так работает
musicFile ={ifLoaded:function(o){trace(o)}};
musicFile.watch("loaded",musicFile.ifLoaded );
musicFile.loaded = true;а так уже нет
musicFile ={ifLoaded:function(o){trace(o)}};
musicFile.watch("loaded",ifLoaded );
musicFile.loaded = true;

genius
29.06.2005, 19:37
2 silin: текущая линейка - это какая?

по поводу вашего примера - работает, да. но меня интересует такой способ решения задачи, чтобы при загрузке вызывался метод родительского класса. то есть в данном случае не метод класса MusicFile, а метод класса, в котором содержится этот самый экземпляр класса MusicFile (в моем случае "главный" класс Game).

silin
29.06.2005, 19:55
>>текущая линейка - это какая?

та, где этот код
>>не метод класса MusicFile, а метод класса, в котором содержится этот самый экземпляр класса MusicFile

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

genius
29.06.2005, 20:13
есть класс Game. экземпляр его один, но делать через глобал не хочется по политическим мотивам - пригодится на будущее.

в экземпляре game класса Game содержатся экземпляры других классов (например экземпляр musicFile класса MusicFile). хочется, чтобы game сказал musicFile загружаться, а когда тот загрузится - чтобы не в самом musicFile что-то сработало (как это сделать понятно), а чтобы musicFile сказал своему "папе" game (в котором он находится), что он загрузился и можно делать что-то дальше.

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

watch, кстати, ведет себя как-то очень странно. у класса Game есть метод ifLoaded (собственно его код привожу только чтобы проиллюстрировать, что со свойством "loaded2" кроме чтения ничего не происходит):

private function ifLoaded ():Void{
TRACE(Flashout.DEBUG + "musicFile.loaded2=" + musicFile.loaded2);

if (musicFile.loaded2 == true) {
recordBeat();
} else if (musicFile.loaded2 == false) {
} else {
TRACE(Flashout.FATAL + "loading finished without error and success");
}
}

дальше начинается мистика (в моём понимании).

musicFile = new MusicFile();
//musicFile.watch("loaded2", Delegate.create(this, this.ifLoaded));
musicFile.loaded2 = true;
TRACE(Flashout.DEBUG + "musicFile.loaded2=" + musicFile.loaded2);

дает на выходе:

[09:59:386] debug: game.Game.Game()
musicFile.loaded2=true //всё как должно быть

musicFile = new MusicFile();
musicFile.watch("loaded2", Delegate.create(this, this.ifLoaded));
musicFile.loaded2 = true;
TRACE(Flashout.DEBUG + "musicFile.loaded2=" + musicFile.loaded2);

дает на выходе:

[09:29:033] debug: game.Game.ifLoaded()
musicFile.loaded2=undefined

[09:29:033] fatal: game.Game.ifLoaded()
loading finished without error and success

[09:29:033] debug: game.Game.Game()
musicFile.loaded2=undefined // почему блин?!!

что происходит с переменной? куда девается её значение? почему она становится undefined?

Nirth
29.06.2005, 20:25
в экземпляре game класса Game содержатся экземпляры других классов (например экземпляр musicFile класса MusicFile). хочется, чтобы game сказал musicFile загружаться, а когда тот загрузится - чтобы не в самом musicFile что-то сработало (как это сделать понятно), а чтобы musicFile сказал своему "папе" game (в котором он находится), что он загрузился и можно делать что-то дальше.

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

silin
29.06.2005, 21:02
да вроде ты передаешь ссылку на несуществующий метод, причем тут мистика
import mx.utils.Delegate
musicFile ={ifLoaded:function(){trace('метод musicFile')}};
this.ifLoaded=function(){trace('метод '+this)}//попробуй закомментровать эту строчку

musicFile.watch("loaded",this.ifLoaded);
musicFile.loaded = true;//метод [object Object]

musicFile.watch("loaded",Delegate.create(this, this.ifLoaded));
musicFile.loaded = true;//метод _level0

musicFile.watch("loaded",musicFile.ifLoaded);
musicFile.loaded = false;//метод musicFile