Статьи

Создание эффектов перехода на экране Flash полностью с помощью кода

Флеш игры — это хлеб и масло инди-поп-культуры. Если рассматривать кусочки хлеба в меню и в самой игре, что осталось? Масло — то самое вещество, которое делает хлеб более вкусным. Что касается флэш-игр, то между меню и играми есть переходы!


Это пример шаблона эффекта перехода, к которому мы будем стремиться:


Как правило, нам нужно создать новый файл Flash (ActionScript 3.0). Установите ширину 400 пикселей, высоту 200 пикселей и частоту кадров 30 кадров в секунду. Цвет фона можно оставить по умолчанию. Сохранить файл; это можно назвать как угодно. Я назвал мой Transitions.fla .

Далее нам нужно создать класс документа . Перейдите в свойства вашего Flash-файла и установите для него класс Transitions . Затем создайте класс документа:

01
02
03
04
05
06
07
08
09
10
11
12
13
package {
    import flash.display.*;
    import flash.events.*;
 
    public class Transitions extends MovieClip {
        static public var val:Number = new Number();
        static public var transitionAttached:Boolean = new Boolean();
        public function Transitions() {
            val = 0;
            transitionAttached = false;
        }
    }
}

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


Наш следующий шаг — создать спрайт, который будет использоваться в качестве каждого квадрата для перехода. Создайте новый класс и сохраните его как Square.as :

01
02
03
04
05
06
07
08
09
10
11
package{
    import flash.display.*;
    import flash.events.*;
     
    public class Square extends Sprite{
        public var squareShape:Shape = new Shape();
        public function Square(){
 
        }
    }
}

Мы используем переменную squareShape чтобы нарисовать нашу форму внутри Sprite. Нарисуйте прямоугольник 40 на 40 пикселей (который является полным размером) и установите его масштаб на 0.1 , десятую часть его размера — это поможет нам в дальнейшем эффекте:

1
2
3
4
5
6
addChild(squareShape);
squareShape.graphics.beginFill(0x000000,1);
squareShape.graphics.drawRect(-20,-20,40,40);
squareShape.graphics.endFill();
this.scaleX = 0.1;
this.scaleY = 0.1;

Создайте еще один новый класс для самого эффекта. Как только мы закончим, добавить эффект на сцену будет очень просто:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
package{
    import flash.display.*;
    import flash.events.*;
    import flash.utils.*;
     
    public class FadeEffect extends Sprite{
        public var currentFadeOut:int = 00;
        public var currentSquares:int = 01;
        public var pauseTime:int = 01;
        public var tempNum:int = 00;
        public var fading:String = «in»;
        public var fadeinTimer:Timer = new Timer(100);
        public var fadeoutTimer:Timer = new Timer(100);
        public var fadeArray:Array = [
                       //top
                       [[01,01,01,01,01,01,01,01,01,01],
                        [02,02,02,02,02,02,02,02,02,02],
                        [03,03,03,03,03,03,03,03,03,03],
                        [04,04,04,04,04,04,04,04,04,04],
                        [05,05,05,05,05,05,05,05,05,05]],
                       //bottom
                       [[05,05,05,05,05,05,05,05,05,05],
                        [04,04,04,04,04,04,04,04,04,04],
                        [03,03,03,03,03,03,03,03,03,03],
                        [02,02,02,02,02,02,02,02,02,02],
                        [01,01,01,01,01,01,01,01,01,01]]];
        public var squaresArray:Array = new Array();
        public function FadeEffect(){
             
        }
    }
}

Вы, вероятно, думаете, «это чертовски много переменных, для чего они все используются?»:

  • currentFadeOut — используется как проверка для tempNum чтобы увидеть, сколько квадратов нужно масштабировать
  • currentSquares — текущее значение, указывающее, какие квадраты должны быть присоединены и / или масштабированы
  • pauseTime — простое целое число, чтобы дать небольшую паузу между переходами и удалением себя
  • tempNum — используется для проверки того, какие числа в массиве нужно масштабировать
  • fading — строка, чтобы проверить, исчезает ли переход
  • fadeinTimer — таймер, который вызывается для начала появления текущего значения currentSquares
  • fadeoutTimer — еще один таймер, который вызывается для начала исчезновения текущего значения currentSquares
  • fadeArray — трехмерный массив, содержащий все шаблоны перехода
  • squaresArray — массив для квадратных спрайтов

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

1
2
3
fadeinTimer.addEventListener(«timer», fadeSquaresInTimer);
fadeinTimer.start();
addEventListener(Event.ENTER_FRAME, enterFrame);

Следующим шагом является создание этих двух слушателей событий. Начнем с более простой из двух, функции enterFrame :

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public function enterFrame(e:Event){
    for each(var s1 in squaresArray){
        tempNum+=1;
        if(fading==»in»){
            if(s1.scaleX<=1){
                s1.scaleX+=0.05;
                s1.scaleY+=0.05;
            }
        }else if(fading==»out»){
            if(tempNum<=currentFadeOut){
                if(s1.scaleX>=0.1){
                s1.scaleX-=0.05;
                s1.scaleY-=0.05;
                }else{
                    if(s1.visible == true){
                        s1.visible = false;
                    }
                }
            }
        }
    }
    tempNum=00;
}

Это может не иметь общего смысла прямо сейчас, но это должно помочь пролить свет.

  • s1 — это имя экземпляра, которое будет дано Квадратам, когда мы создадим их в более поздней функции.
  • Они добавляются в массив с именем squaresArray для отслеживания их количества, и мы выполняем одну и ту же операцию для каждого объекта в массиве.
  • Затем мы увеличиваем tempNum (используемый в tempNum с исчезновением), который используется для масштабирования квадратов в порядке их добавления в массив. Это означает, что он не зависит от шаблона и будет работать с любым шаблоном.

После того…

  • Мы проверяем, правда ли fading или нет.
  • Если true, он масштабирует все квадраты до тех пор, пока они не достигнут своего полного размера (они начинают масштабироваться сразу после увеличения currentSquares).
  • Как только это начинает исчезать, вещи становятся немного более хитрыми; мы только уменьшаем квадраты, которые ниже текущего значения currentFadeOut (это те, которые должны масштабироваться, все остальные должны оставаться в полном масштабе, пока значение не увеличится).
  • Как только они уменьшатся до десятой части размера, мы сделаем эти квадраты невидимыми (они будут удалены со всем эффектом).

Пришло время добавить прослушиватель событий для таймера:

1
2
3
4
public function fadeSquaresInTimer(e:Event){
    fadeSquaresIn(fadeArray[Transitions.val]);
    currentSquares+=1;
}

На первый взгляд это выглядит менее сложным, но вы должны заметить, что мы вызываем функцию с параметром fadeArray . То, какой шаблон выбран из массива, зависит от того, что вы установили val равным в классе Transitions; прямо сейчас он должен использовать первый шаблон, потому что val установлен в 0.

Следующим шагом является создание функции fadeSquaresIn которая вызывается из предыдущего таймера:

1
2
3
4
5
6
7
public function fadeSquaresIn(s:Array){
    for (var row=0; row<s[0].length; row++) {
        for (var col=0; col<s.length; col++) {
             
        }
    }
}

Первое, что мы делаем, это итерация по выбранному шаблону. Мы начинаем со строки 1, колонки 1 и перебираем каждую колонку до тех пор, пока не будет достигнут конец строки. Затем мы переходим на следующий ряд и повторяем процесс.

Следующее, что нужно сделать, это сравнить текущий элемент в массиве со значением currentSquares :

1
2
3
if(int(s[col][row]) == currentSquares){
 
}

Если они эквивалентны, мы добавляем квадрат, squaresArray его соответствующим образом и squaresArray его в squaresArray чтобы его можно было масштабировать:

1
2
3
4
5
var s1:Sprite = new Square();
s1.x = 20+(row*40);
s1.y = 20+(col*40);
addChild(s1);
squaresArray.push(s1);

Мы почти закончили с этой функцией, мы просто должны выполнить проверку, когда количество квадратов равно количеству элементов в шаблоне. Мы делаем это, добавляя следующий оператор if вне обоих циклов for:

1
2
3
4
if(squaresArray.length == (s[0].length * s.length)){
    fadeinTimer.stop();
    addEventListener(Event.ENTER_FRAME, pauseBetween);
}

Самоочевидно — мы остановили таймер и вызвали прослушиватель событий для паузы между появлением и исчезновением Эта функция используется для инициации исчезновения, а также может вызвать изменения в вашей игре:

01
02
03
04
05
06
07
08
09
10
public function pauseBetween(e:Event){
    pauseTime+=1;
    if(pauseTime==60){
        currentSquares=01;
        fading=»out»;
        fadeoutTimer.addEventListener(«timer», fadeSquaresOutTimer);
        fadeoutTimer.start();
        removeEventListener(Event.ENTER_FRAME, pauseBetween);
    }
}

Мы не будем тратить много времени на эту функцию из-за ее простоты. Здесь мы увеличиваем значение pauseTime , и как только оно равняется 60 (то есть прошло две секунды), мы устанавливаем значение currentSquares обратно в 1, устанавливаем fading в "out" чтобы квадраты могли масштабироваться назад, удаляем слушателя для pauseBetween() и добавьте прослушиватель событий для этой новой функции:

1
2
3
4
public function fadeSquaresOutTimer(e:Event){
    fadeSquaresOut(fadeArray[Transitions.val]);
    currentSquares+=1;
}

Это работает так же, как fadeSquaresInTimer() , хотя на этот раз мы вызываем функцию fadeSquaresOut() :

1
2
3
4
5
6
7
8
9
public function fadeSquaresOut(s:Array){
    for (var row=0; row<s[0].length; row++) {
        for (var col=0; col<s.length; col++) {
            if(int(s[col][row]) == currentSquares){
                currentFadeOut+=1;
            }
        }
    }
}

Мы currentFadeOut цикл, но на этот раз, когда мы находим эквивалентный элемент, мы увеличиваем значение currentFadeOut чтобы следующий элемент в squaresArray мог начать squaresArray .

Почти закончено сейчас; осталось только остановить таймер и убрать эффект. Добавьте этот оператор if вне двух циклов for:

1
2
3
4
5
if(currentFadeOut == (s[0].length * s.length)){
    fadeoutTimer.stop();
    pauseTime=01;
    addEventListener(Event.ENTER_FRAME, delayedRemove);
}

Это проверяет, все ли элементы начали исчезать. Если это так, он останавливает таймер, устанавливает pauseTime обратно в 1 и добавляет прослушиватель событий для функции delayedRemove() :

1
2
3
4
5
6
7
8
public function delayedRemove(e:Event){
    pauseTime+=1;
    if(pauseTime==30){
        Transitions.transitionAttached = false;
        removeEventListener(Event.ENTER_FRAME, delayedRemove);
        stage.removeChild(this);
    }
}

Как и прежде, мы увеличиваем значение pauseTime , и когда оно равняется 30 (1 секунда), мы возвращаем логическое значение false чтобы эффект можно было добавить еще раз. Мы удаляем слушателя этого события и удаляем этот эффект со сцены.


Теперь самое простое. Добавьте следующий код в конструктор класса документа, чтобы добавить эффект:

1
2
3
4
5
if(transitionAttached == false){
    transitionAttached = true;
    var f1:Sprite=new FadeEffect;
    stage.addChild(f1);
}

Не стесняйтесь создавать свои собственные шаблоны! Это очень просто, просто создайте новый 2D-массив внутри 3D-массива. Вот массив, который я создал (просто замените ваш 3D-массив на него). Включает 8 разных переходов:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
[//top
[[01,01,01,01,01,01,01,01,01,01],
[02,02,02,02,02,02,02,02,02,02],
[03,03,03,03,03,03,03,03,03,03],
[04,04,04,04,04,04,04,04,04,04],
[05,05,05,05,05,05,05,05,05,05]],
//bottom
[[05,05,05,05,05,05,05,05,05,05],
[04,04,04,04,04,04,04,04,04,04],
[03,03,03,03,03,03,03,03,03,03],
[02,02,02,02,02,02,02,02,02,02],
[01,01,01,01,01,01,01,01,01,01]],
//left
[[01,02,03,04,05,06,07,08,09,10],
[01,02,03,04,05,06,07,08,09,10],
[01,02,03,04,05,06,07,08,09,10],
[01,02,03,04,05,06,07,08,09,10],
[01,02,03,04,05,06,07,08,09,10]],
//right
[[10,09,08,07,06,05,04,03,02,01],
[10,09,08,07,06,05,04,03,02,01],
[10,09,08,07,06,05,04,03,02,01],
[10,09,08,07,06,05,04,03,02,01],
[10,09,08,07,06,05,04,03,02,01]],
//top-left
[[01,02,03,04,05,06,07,08,09,10],
[02,03,04,05,06,07,08,09,10,11],
[03,04,05,06,07,08,09,10,11,12],
[04,05,06,07,08,09,10,11,12,13],
[05,06,07,08,09,10,11,12,13,14]],
//top-right
[[10,09,08,07,06,05,04,03,02,01],
[11,10,09,08,07,06,05,04,03,02],
[12,11,10,09,08,07,06,05,04,03],
[13,12,11,10,09,08,07,06,05,04],
[14,13,12,11,10,09,08,07,06,05]],
//bottom-left
[[05,06,07,08,09,10,11,12,13,14],
[04,05,06,07,08,09,10,11,12,13],
[03,04,05,06,07,08,09,10,11,12],
[02,03,04,05,06,07,08,09,10,11],
[01,02,03,04,05,06,07,08,09,10]],
//bottom-right
[[14,13,12,11,10,09,08,07,06,05],
[13,12,11,10,09,08,07,06,05,04],
[12,11,10,09,08,07,06,05,04,03],
[11,10,09,08,07,06,05,03,03,02],
[10,09,08,07,06,05,04,03,02,01]]];

Вы можете изменить значение Transitions.val чтобы выбрать другой шаблон — например, если val равен 3 , переход будет заметен справа.


Спасибо, что нашли время, чтобы прочитать этот учебник. Если у вас есть какие-либо вопросы, пожалуйста, оставьте комментарий ниже. И если вы хотите испытать трудности, попробуйте сделать эффект плавным с одним паттерном, а с противоположным.