Как в Animate CC2017 остановить работу скрипта снегопада при нажатии на кнопку?

vladas1983

Участник
Топикстартер
Сообщения
33
Реакции
0
Здравствуйте!

Делаю открытку со снегопадом. Скрипт снегопада нашел в интернете. Скрипт находится на основной сцене, запускается в середине открытки - там, где поставлен кадр со скриптом. На другом слое находится сам шарик с именем экземпляра "SnowFlake". На открытке в конце ролика есть кнопка "Повторить просмотр", при нажатии на которую происходит возврат к первому кадру и анимация начинается снова, но снегопад все равно продолжается. А нужно, чтобы он также останавливался и начался в середине открытки. Я так пониманию, если он был запущен программно, то и выключать его нужно программно. Перепробовал различные варианты со шкалой времени, но на снег реакции никакой. Хоть и совсем плохо разбираюсь в actionscript попробовал разные варианты кода, вроде:

Код:
snowflakes.stop();
или
Код:
snowflakes.stop(1);
или
Код:
SnowFlake.stop();
возможно, пробовал другие коды

Пробовал эти строки вставлять в функцию, созданную автоматически через окно "Фрагменты кода":
Код:
function fl_ClickToGoToAndPlayFromFrame(event:MouseEvent):void
Но, все мои предположительные строки кода не работали. Либо ошибка выдавалась сразу после запуска ролика, либо у же после нажатия на кнопку "Повторить просмотр".

Скрипт при нажатии на кнопку "Повторить просмотр":
Код:
button_1.addEventListener(MouseEvent.CLICK, fl_ClickToGoToAndPlayFromFrame);

 
function fl_ClickToGoToAndPlayFromFrame(event:MouseEvent):void
{
    gotoAndPlay(1);
}
 
button_1.addEventListener(MouseEvent.CLICK, fl_ClickToStopAllSounds);
 
function fl_ClickToStopAllSounds(event:MouseEvent):void
{
    SoundMixer.stopAll();
}

Скрипт снегопада:
Код:
var snowflakes:Array = new Array();

var snowflakeProps:Dictionary= new Dictionary(true);

var max_snowsize:Number = 0.04;

// Количество снежинок

var snowflakesCnt:Number = 40;

var oheight:Number;

var owidth:Number;

init();

function init():void {




       // Задаем ширину и высоту области, где будет идти снег, она будет равна размерам нашей флэшки

   owidth = 549;

   oheight = 547;




   for (var i:int=0; i<snowflakesCnt; i++) {




       var t:MovieClip = new SnowFlake();//

       t.name = "snowflake"+i;




       t.alpha = .2+Math.random()*.9;

       t.x = -(owidth/2)+Math.random()*(1.5*owidth);

       t.y = -(oheight/2)+Math.random()*(1.5*oheight);

       t.scaleX = t.scaleY=.5+Math.random()*(max_snowsize*5);

       var o:Object = new Object();

       //Скорость и горизонтальное перемещение снежинок

       o.k = 1+Math.random()*4;

       o.wind = -1.5+Math.random()*(1.2*2);




       snowflakeProps[t] = o;




       addChild(t);

       snowflakes.push(t);

   }

   addEventListener(Event.ENTER_FRAME, snowFlakeMover);

}

function shakeUp():void{

   for (var i:int=0; i<snowflakes.length; i++) {

       var t:MovieClip = snowflakes[i] as MovieClip;

       t.x = -(owidth/2)+Math.random()*(1.5*owidth);

       t.y = -(oheight/2)+Math.random()*(1.5*oheight);

   }

}

function snowFlakeMover(evt:Event):void {

   var dO:MovieClip;

   var o :Object;

   if(visible && parent.visible){

   for (var i:int = 0; i < snowflakes.length; i++) {

       dO = snowflakes[i] as MovieClip;

       o = snowflakeProps[dO];

       dO.y += o.k;

       dO.x += o.wind;

       if (dO.y>oheight+10) {




           dO.y = -20;




       }

       if (dO.x>owidth+20) {




           dO.x = -(owidth/2)+Math.random()*(1.5*owidth);

           dO.y = -20;




       } else if (dO.x<-20) {




           dO.x= -(owidth/2)+Math.random()*(1.5*owidth);

           dO.y = -20;

       }




   }

   }

}
 
Последнее редактирование модератором:
Снег всё время идёт, потому что нет ни одной функции убивающей вот это событие:
addEventListener(Event.ENTER_FRAME, snowFlakeMover);

Событие ENTER_FRAME происходит независимо от того, остановлен ли мувик, добавлен ли он на сцену или нет, visible или нет, поэтому вот это:
не будет работать.

А вообще, думаю, у вас там так намешано, что что-либо посоветовать нереально.
 
Намешено, где? В скрипте снегопада? Что-то не так с ним? В каком из скриптов должны быть строки убивающие это событие? Скрипт кнопки также можно отредактировать. Нужно, чтобы все возвращалось обратно к первому кадру анимация, снег и звук.
 
Намешано не в коде, а вообще в проекте. И не видя его, достаточно сложно что-либо советовать.
 
Я выложил открытку в исходнике по это ссылке, оставив в ней фон, снег и кнопку DropMeFiles – бесплатный файлообменник без регистрации
Там есть еще одна проблема, что после возврата на первый кадр и промотки до момента, когда начинается снег, снег останавливается, но не исчезает, а новый начинает падать прямо на этот и после возврата снова на первый кадр появляется еще один застывший снег и так далее, с каждым возвратом нарастает снег на открытке.
 
Снег нарастает, потому что как я писал выше. Я позже постараюсь посмотреть что там можно сделать (если у самого ума хватит, конечно), сейчас немного пьяно и тяжко втыкать. А вообще, как я и говорил, весь проект сделан не по правилам AS3. Всё должно быть в одном кадре, и управляться программным способом. А так как у Вас сделано - это времена AS2, то есть Flash CS6. Ну, что есть, то есть, позже посмотрю, если никто не опередит. И всех с 1 декабря!
 
Я, конечно, совершенно не в теме Animate и его скриптовой модели, но как Явакэпу, мне кажется, что снег убирается примерно такой последовательностью:
Код:
for (var i=0;i<snowflakes.length;i++) snowflakes[0].remove();
 
Нет. Так ты просто тупо убираешь каждую снежинку, но событие "ENTER_FRAME происходит независимо от того, остановлен ли мувик, добавлен ли он на сцену или нет, visible или нет"... Снежинки ты убъёшь, а событие все равно будет отарабанивать и далее, в результате будет тормоза из-за этого, имхо.
В данном случае вообще неправильно используется ENTER_FRAME. Потому что весь ролик - это не один кадр, как нужно было бы, а последовательность кадров. А движение во времени по кадрам, это и есть ENTER_FRAME... Короче масло масленное...
Тут не снежинки нужно гасить, хотя, это правильно, в смысле, создал объект - не забудь убить объект, тут нужно немного переделать сам проект и гасить этот ENTER_FRAME
 
А вообще прикольно выглядит скриптинг для Animate.
 
к примеру. Если добавить на линейку времени после кадра (в любом месте), где снег запускается, кадр с таким кодом
Код:
removeEventListener(Event.ENTER_FRAME, snowFlakeMover);
то снег остановится, но остановится вообще, а это не то. А все потому, что сам проект неправилен. Тут нужно посидеть продумать структуру изначально, а я сейчас уже 0,5 выпил, извините.
Вопрос к автору сего. Что должно вообще происходить? Должен начинаться падать снег, и через какое-то время падение заканчивается, и появляется кнопка повторить, так?
 
Последнее редактирование:
  • Спасибо
Реакции: Flame
А вообще прикольно выглядит скриптинг для Animate.
Нет. Скриптинг, такой же как в js. Неприкольно то, что всё это завязано на время выполнения, на кадры, на, хрен знает что ещё (адобе, такой адобе), но в данном случае неправилен не код, а сам проект. Тут нужно понимать, что в AS3 такое правило. Весь проект - в одном кадре. И код, и анимация. Анимация рисуется в Animate(Flash), а код... Код AS3. Практически, что js. Гы-гы, а что в нашем мире сейчас не js? Господи, если бы я в 90-х знал, что моё тупое скриптингование на js - это божественное направление... =) Ребзя! Хороших Вам выходных, и привет из Питера, мои маленькие депрессивные друзья. =)
 

Не по теме:
Так как я из Питера, то депрессия, это моя жизнь =). Тут, главное, грамотно распределять её по частям тела =)
 
Читать более нету сил, други мои, но я бы делал так:
Один кадр в нём:
слой со снегом
слой с фоном
слой с кнопкой
слой с as

В слое as примерно такой алгоритм:
Стоп вообще всего.
Запускаем плавное появление фона. Стоп. Пауза.
Затем запускаем таймер, в котором выполняется снегопад и!!! через какое-то время, снегопад заканчивается (а это значит, удаляются все объекты, события и сам таймер)
Появляется кнопочка для повтора и всё висит и ждёт нажатие
Как-то так.

А для этого весь проект надлежит красиво распять =). Хотя, может я протрезвею, и будет не все так плачевно, ну, или кто-нибудь, всё-таки мощнее в этом, чему я был бы несказанно ради, ибо, одно удовольствие общаться с людьми, которые круче тебя. Это развитие.
 
Вообщем, как же это неинтересно копаться в чужом коде...
Ничего не менял, разве что немного увеличил продолжительность анимации на главной линейки времени + убрал лишний слой со снегом.

В коде:
немного видоизменил код снегопада + код нажатия на кнопку "повторить просмотр".
+
добавил переменную wait, которая по-умолчанию = false. Как только она станет =true (а это происходит принудительно в 166 кадре), то снегопад мы прекращаем, и тупо гасим снежинки, меняя их прозрачность к нулю. Но!!! Нужно понимать, что снежинки на самом деле все равно падают, только теперь они прозрачны и не видны. А потому, при нажатии на кнопку "повторить просмотр" мы удаляем событие "Event.ENTER_FRAME, snowFlakeMover", дабы совсем не грузить систему лишним. По-хорошему, нужно удалять и все снежинки, типа removeChild() делать, и вообще всё переделывать так, чтобы проект состоял из одного кадра с кодом, как я уже писал выше, но мне лень =).

Файлы
Если файл fla у вас не откроется, значит у вас древний Animate CC =))
Ну, и вот сам код:

Код:
var snowflakes:Array = new Array();
var snowflakeProps:Dictionary= new Dictionary(true);
var max_snowsize:Number = 0.04;
// Количество снежинок
var snowflakesCnt:Number = 40;
var oheight:Number;
var owidth:Number;
var wait:Boolean = false;
// как только будет true снег прекращаем падать (а для этого в любом кадре, после кадра с этим кодом, просто пишем wait=true)

init();
// событие вытащил из функции, чтобы потом, при нажатии на кнопку "повторить", это событие можно было грохнуть без особых заморок, и чтобы оно не висело в памяти.
addEventListener(Event.ENTER_FRAME, snowFlakeMover);

function init():void {
 
        // Задаем ширину и высоту области, где будет идти снег, она будет равна размерам нашей флэшки
    owidth = 549;
    oheight = 547;
  
    for (var i:int=0; i<snowflakesCnt; i++) {
 
        var t:MovieClip = new SnowFlake();//
        t.name = "snowflake"+i;
 
        t.alpha = .2+Math.random()*.9;
        t.x = -(owidth/2)+Math.random()*(1.5*owidth);
        t.y = -(oheight/2)+Math.random()*(1.5*oheight);
        t.scaleX = t.scaleY=.5+Math.random()*(max_snowsize*5);
        var o:Object = new Object();
        //Скорость и горизонтальное перемещение снежинок
        o.k = 1+Math.random()*4;
        o.wind = -1.5+Math.random()*(1.2*2);
 
        snowflakeProps[t] = o;
 
        addChild(t);
        snowflakes.push(t);
    }
}


function snowFlakeMover(evt:Event):void {
    var dO:MovieClip;
    var o :Object;
  
// сделано по тупому, но это для того, чтобы было понятно, что происходит.
// А происходит следующее: Мы просто прекращаем сбрасывать координаты
// снежинок в начальное положение и, таким образом, не даём им появляться снова,
//+ меняем их прозрачность к нулю.
    if (wait)
    {
        for (var j:int = 0; j < snowflakes.length; j++)
        {
        dO = snowflakes[j] as MovieClip;
        o = snowflakeProps[dO];
        dO.y += o.k;
        dO.x += o.wind;
        dO.alpha = dO.alpha - .03;
        }     
    }
    else
    {
    if(visible && parent.visible){
    for (var i:int = 0; i < snowflakes.length; i++) {
        dO = snowflakes[i] as MovieClip;
        o = snowflakeProps[dO];
        dO.y += o.k;
        dO.x += o.wind;
        if (dO.y>oheight+10) {
 
            dO.y = -20;
 
        }
        if (dO.x>owidth+20) {
 
            dO.x = -(owidth/2)+Math.random()*(1.5*owidth);
            dO.y = -20;
 
        } else if (dO.x<-20) {
 
            dO.x= -(owidth/2)+Math.random()*(1.5*owidth);
            dO.y = -20;
        }
 
    }
    }
} // else
}
Код:
button_1.addEventListener(MouseEvent.CLICK, fl_ClickToGoToAndPlayFromFrame);

 
function fl_ClickToGoToAndPlayFromFrame(event:MouseEvent):void
{
// удаляем событие
    removeEventListener(Event.ENTER_FRAME, snowFlakeMover);
    gotoAndPlay(1);
}
 
Последнее редактирование: