Форум Flasher.ru

Форум Flasher.ru (http://www.flasher.ru/forum/index.php)
-   ActionScript 3.0 (http://www.flasher.ru/forum/forumdisplay.php?f=83)
-   -   AS3, как самоудаляться и запускать при этом метод из основного класса (http://www.flasher.ru/forum/showthread.php?t=133488)

Sergko 07.12.2009 00:28

AS3, как самоудаляться и запускать при этом метод из основного класса
 
Подскажите пожалуйста!

У меня основной класс создает две кнопки - экземпляры одного класса button(пользовательский). При нажатии одной из них, обе удаляются с экрана и запускается анимация. Как сделать так, чтобы по окончанию анимации она самоудалялась, а также снова создавала эти две кнопки???

Очень прошу!

Jewelz 07.12.2009 10:10

при окончании анимации диспатчите Event, ловите его в основном классе и делайте дальше что душе угодно :)

например можно в последнем кадре анимации прописать
Код AS3:

dispatchEvent(new Event("end"));

чтобы в каждом кадре не проверять окончание

Juice_Green 07.12.2009 10:54

to Jewelz:
пользовательские классы и и куски кода на кадры вешать - плохая практика

Котяра 07.12.2009 11:06

можно использовать в основном классе
Код AS3:

animation.play();
animation.addFrameScript(animation.totalFrame-1, endPlaying);


Jewelz 07.12.2009 13:00

Цитата:

Сообщение от Juice_Green (Сообщение 870692)
to Jewelz:
пользовательские классы и и куски кода на кадры вешать - плохая практика

к примеру у меня есть библиотека с MovieClip в котором нарисована анимация персонажа: поворот, прыжок, удар

соответственно я запускаю ту или иную анимацию по какому-то действию пользователя, как мне тогда лучше узнать что анимация остановилась и можно делать следущее действие?

gloomyBrain 07.12.2009 13:47

Читайте про свойства currentFrame, currentFrameLabel в help'е

Juice_Green 07.12.2009 14:15

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

Jewelz 07.12.2009 15:47

Цитата:

Сообщение от Juice_Green (Сообщение 870757)
Jewelz, не увидел убедительных аргументов, просто потом разбираться в вашем коде будет очень сложно другому человеку, да и сами запутаетесь, когда забудете где делаете диспетчирезацию события

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

как бы вы сделали? мне очень интересно, потому что я знаю что писать код в кадрах не есть хорошо (сам использую только stop(); и dispatchEvent()), если есть более удобный способ, я с радостью приму его во внимание

Котяра 07.12.2009 17:35

я писал выше - уточняю:
Код AS3:

public function playAnimation():void
{
animation.play();
animation.addFrameScript(animation.totalFrame-1, endPlaying);
}
public function endPlaying():void
{
animation.stop();
// если надо то диспатчим событие, хотя мы уже в хэндлере события
}


Jewelz 07.12.2009 17:46

Котяра, с вашим кодом я абсолютно согласен, только он не удобен если на одной таймлайн находится несколько анимаций, и не известен точный кадр их окончания, + анимация может быть перерисована и длительность увеличится => изменится номер последнего кадра

gloomyBrain 07.12.2009 18:19

Цитата:

не известен точный кадр их окончания
Цитата:

+ анимация может быть перерисована и длительность увеличится => изменится номер последнего кадра
Ответ:
Код AS3:

animation.totalFrames-1

Цитата:

не удобен если на одной таймлайн находится несколько анимаций
Чем? Тем, что каждой надо добавить листенер для события ENTER_FRAME? Этого можно не делать, если воспользоваться функцией
Код AS3:

addFrameScript(номер кадра, имя функции)

Но по сути это то же самое, что написать код в кадре =)

Jewelz 07.12.2009 18:50

Код AS3:

animation.totalFrames-1

это если одна анимация, я писал про несколько: у одной конец в 23 кадре, у другой в 101, у третьей в 115

Цитата:

Сообщение от gloomyBrain (Сообщение 870849)
Чем? Тем, что каждой надо добавить листенер для события ENTER_FRAME?

да, этим

Цитата:

Сообщение от gloomyBrain (Сообщение 870849)
Этого можно не делать, если воспользоваться функцией
Код AS3:

addFrameScript(номер кадра, имя функции)


и когда я изменяю одну из 10 анимаций в IDE - я должен поменять константу с концом анимации в коде, по-идее правильный способ, но он мне не нравится тем, что мне нужно следить за всеми этими изменениями, + если графику делаю не я, то мне нужно при каждом изменении проверять "концы", ИМХО проще в конце отсылать событие и я точно буду уверен что какая бы анимация не была я всегда узнаю об ее окончании

Код AS3:

Но по сути это то же самое, что написать код в кадре =)

по сути да, но на деле - нет, так как весь код все-таки хранится в одном месте и при разработке к примеру во FD, ты видишь что и где написано, но опять в моем случае я считаю лучше в кадрах ;)

gloomyBrain 07.12.2009 19:15

Цитата:

это если одна анимация, я писал про несколько: у одной конец в 23 кадре, у другой в 101, у третьей в 115
Хорошо, Jewelz, ответьте на вопрос, что такое totalFrames?

etc 07.12.2009 21:19

gloomyBrain, имеются ввиду вложенные анимации.

gloomyBrain 07.12.2009 22:08

А разве это что-нибудь поменяет?

etc 08.12.2009 09:56

Цитата:

Сообщение от gloomyBrain (Сообщение 870902)
А разве это что-нибудь поменяет?

Кардинально.

dimarik 08.12.2009 11:50

А если пробежаться по дереву и навесить addFrameScript каждому ребенку, имеющему totalFrames > 1 или еще по каким-нибудь признакам? Все это дело завернуть в класс, который укажете в качестве base-класса в linkage, можно даже jsfl'ом, и скомпилить им сразу.

__ant 08.12.2009 12:03

Цитата:

и когда я изменяю одну из 10 анимаций в IDE - я должен поменять константу с концом анимации в коде, по-идее правильный способ, но он мне не нравится тем, что мне нужно следить за всеми этими изменениями, + если графику делаю не я, то мне нужно при каждом изменении проверять "концы", ИМХО проще в конце отсылать событие и я точно буду уверен что какая бы анимация не была я всегда узнаю об ее окончании
Я бы расставил метки в кадрах, использовал бы currentLabels и addFrameScript.

Код в кадрах это плохо.

dimarik 08.12.2009 12:07

Храните каждую логически законченную анимацию в отдельном библиотечном символе символе.

Котяра 08.12.2009 13:04

Цитата:

Сообщение от Jewelz (Сообщение 870864)
Код AS3:

animation.totalFrames-1

это если одна анимация, я писал про несколько: у одной конец в 23 кадре, у другой в 101, у третьей в 115
и когда я изменяю одну из 10 анимаций в IDE - я должен поменять константу с концом анимации в коде,

когда поменяешь длину анимации, её totalFrame изменится.
для 10 анимаций делаешь массив анимаций, можно сделать именованный хэш список
Код AS3:

// массив анимаций
public var animationArray:Array =[] /*of MovieClip*/
private var _currentAnimation:MovieClip;
 
// здесь по логике запускаем необходимую анимацию
public function game():void
{
//.........
// запускаем нужный клип
playAnimation(animationArray[8]);
 
//........
}
 
public function playAnimation(animation:MovieClip):void
{
_currentAnimation = animation;
animation.addFrameScript(animation.totalFrame-1, endPlaying);
animation.play();
}
 
public function endPlaying():void
{
_currentAnimation.stop();
// если надо то диспатчим событие, хотя мы уже в хэндлере события
}

плюс в том что существует одна единственная ф-ция для конца анимации и не надо код писать в кадрах вообще.
минус в том что неизвестен currentTarget и анимации запускаются строго по одной

ЗЫ: смотрим тонкости
Код AS3:

package
{
 
public class Delegate
{
  public static function create(handler:Function,...args):Function
  {
    return function(...innerArgs):void
    {
      handler.apply(this,innerArgs.concat(args));
    }
  }
 }
}


//Теперь мы можем вызывать нашу функцию с параметрами:

Код AS3:

package {
 
 import flash.display.*;
 
 public class main extends Sprite {
 
 
  public function main() {
//...
  }
 
// массив анимаций  - заполняется отдельным методом - здесь не указан..
public var animationArray:Array =[] /*of MovieClip*/
 
// здесь по логике запускаем необходимую анимацию
public function game():void
{
//.........
// запускаем нужный клип
playAnimation(8);
 
//........
}
 
public function playAnimation(ind:int):void
{
var animation:MovieClip = animationArray[ind] as MovieClip;
animation.addFrameScript(animation.totalFrame-1, Delegate.create(endPlaying,ind));
animation.play();
}
 
public function endPlaying(ind:int):void
{
var animation:MovieClip = animationArray[ind] as MovieClip;
animation.stop();
trace(ind);
// если надо то диспатчим событие, хотя мы уже в хэндлере события
}
}


Jewelz 08.12.2009 13:56

звучит убедительно, будем пробовать применять, благодарю

Цитата:

Сообщение от dimarik (Сообщение 871028)
Храните каждую логически законченную анимацию в отдельном библиотечном символе символе.

да, такой вариант тоже рассматривался, вполне пригодно

Sergko 09.12.2009 00:56

Спасибо, все попробовал, но видимо я чего-то не понимаю. Недавно осваивать начал.
Привожу код, помогите пожалуйста
Код AS3:

package Dial{
        import flash.display.*;
        import flash.events.*;
        import Dial.*;
        public class Dial extends MovieClip{
                var _sifri:Array = new Array();
                var _first:Array = new Array();
                var _second:Array = new Array();
                var _third:Array = new Array();
                var btn1:button;
                var btn2:button;
                var btn3:button;
                public function Dial() {
                        sifri();
                        repeat();
                }
                public function FclickListener(e:MouseEvent):void{
                        removeChild(btn1);
                        removeChild(btn2);
                        removeChild(btn3);
                        e.updateAfterEvent();
                }
                public function sifri() {
                        var textt1:text1 = new text1();
                        var textt2:text2 = new text2();
                        var textt3:text3 = new text3();
                        var contt1:cont1 = new cont1();
                        var moviet1:movie1 = new movie1();
                        _first.unshift(textt1,contt1,moviet1);
                        _second.unshift(textt2,contt1,moviet1);
                        _third.unshift(textt3,contt1,moviet1);
                        _sifri.unshift(_first,_second,_third);
                }
                public function repeat() {
                        sifri();
                        addChild(btn1 = new button(_sifri[0][0],_sifri[0][1],_sifri[0][2]));
                        btn1.x = 300;
                        btn1.y = 300;
                        addChild(btn2 = new button(_sifri[1][0],_sifri[1][1],_sifri[1][2]));
                        btn2.x = 300;
                        btn2.y = 250;
                        addChild(btn3 = new button(_sifri[2][0],_sifri[2][1],_sifri[2][2]));
                        btn3.x = 300;
                        btn3.y = 200;
                        btn1.addEventListener(MouseEvent.CLICK,FclickListener)
                        btn2.addEventListener(MouseEvent.CLICK,FclickListener)
                        btn3.addEventListener(MouseEvent.CLICK,FclickListener)
                }
        }
}

Это код главного класса, вот код собственно кнопки
Код AS3:

package Dial{
        import flash.display.*;
        import flash.events.*;
        import Dial.*;
        public class button extends MovieClip{
                var textII:MovieClip;
                var contII:MovieClip;
                var movieII:MovieClip;
                public function button(textI:MovieClip,contI:MovieClip,movieI:MovieClip) {
                        addEventListener(MouseEvent.ROLL_OVER,overListener);
                        addEventListener(MouseEvent.ROLL_OUT,outListener);
                        addEventListener(MouseEvent.CLICK,clickListener);
                        settextII(textI);
                        setcontII(contI);
                        setmovieII(movieI);
                        addChild(textII);
                        textII.x = 50;
                        textII.y = 9;
                }
                public function overListener(e:MouseEvent):void{
                        stage.addChild(contII);
                        contII.play();
                        contII.x = 100;
                        contII.y = 100;
                }
                public function outListener(e:MouseEvent):void{
                        stage.removeChild(contII);
                }
                public function clickListener(e:MouseEvent):void{
                        stage.removeChild(contII);
                        stage.addChild(movieII);
                        movieII.play();
                        movieII.x = 300;
                        movieII.y = 0;
                }public function gettextII():MovieClip{
                        return textII;
                }
                public function settextII(newtext:MovieClip):void{
                        textII=newtext;
                }
                public function getcontII():MovieClip{
                        return contII;
                }
                public function setcontII(newcont:MovieClip):void{
                        contII=newcont;
                }
                public function getmovieII():MovieClip{
                        return movieII;
                }
                public function setmovieII(newmovie:MovieClip):void{
                        movieII=newmovie;
                }
 
        }
}

Я уверен, что код громоздкий, и если кто подскажет, как улучшить буду благодарен. Но мой основной вопрос: как видно из кода при нажатии на любую кнопку происходит запуск мувика movie1, как мне сделать так, что конкретно написать, чтобы при окончании мувика снова вызывалась функция repeat в главном классе, а соответственно кнопки опять появлялись.

Мечтатель 09.12.2009 10:07

Код AS3:

public function clickListener(e:MouseEvent):void
{
                        stage.removeChild(contII);
                        stage.addChild(movieII);
                        movieII.play();
                                movieII.addEventListener(Event.ENTER_FRAME, enterFrameListener);
                        movieII.x = 300;
                        movieII.y = 0;
 
function enterFrameListener(e:Event):void
{
if(movieII.currentFrame==movieII.totalFrames)
{
  movieII.removeEventListener(Event.ENTER_FRAME, enterFrameListener);
  Dial.repeat();
 
}
}


Метод экземпляра класса Dial repeat() должен быть определен, как статический, либо в классе Dial должно быть определено открытое статическое св-во, со ссылкой на экземпляр класса Dial, в противном случае невозможно будет вызвать метод repeat() экз.класса Dial из кода в классе button (имена классов задают с большой буквы) без создания самого экземпляра.

Добавлено через 23 минуты
Хотя можно получить ссылку из класса Button на экземпляр класса Dial, следующим образом (так как Вы добавляете экземпляры классов Button в список отображения класса Dial)

this.parent
Код AS3:

public function clickListener(e:MouseEvent):void
{
                        stage.removeChild(contII);
                        stage.addChild(movieII);
                        movieII.play();
                                movieII.addEventListener(Event.ENTER_FRAME, enterFrameListener);
                        movieII.x = 300;
                        movieII.y = 0;
 
function enterFrameListener(e:Event):void
{
if(movieII.currentFrame==movieII.totalFrames)
{
  movieII.removeEventListener(Event.ENTER_FRAME, enterFrameListener);
  parent.repeat();
 
}
}
}



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

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