Статьи

Создание активной флеш-игры: отскок

Первые впечатления очень важны на портале Flash-игр; если ваша игра не захватывает игрока в первые несколько секунд, у них есть множество других игр на выбор. Поскольку меню является первым пунктом интерфейса, все, что вы можете сделать, чтобы сделать его менее скучным, поможет. В этом уроке мы создадим меню, которое включает в себя глубину переключения, эффекты плавного пролонгации и два различных дизайна перехода.


Вот два проекта, над которыми мы будем работать:

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

Второй дизайн переводит все экраны снизу: более гибкий выбор, если у вас более четырех вариантов.


Есть две основные вещи, которые делают это меню «активным». Первый — это эффекты прокрутки на кнопках: независимо от того, насколько они масштабируются при развертывании, они уменьшаются от этого определенного размера (в отличие от анимации, созданной на временной шкале). Во-вторых, код второго стиля разработан так, чтобы быть гибким и легко расширяемым для ваших собственных нужд.


Первое, что нам нужно создать, это новый файл Flash (ActionScript 3.0). Установите ширину 600 пикселей, высоту 300 пикселей, а количество кадров в секунду — 30. Цвет фона можно оставить белым.

Теперь сохраните файл; Вы можете назвать его как угодно, но я назвал мой menuBounce.fla .

В следующем разделе мы создадим восемь мувиклипов, используемых в меню. Для справки, вот список всех цветов, используемых на протяжении всего урока:

  • Белый — #FFFFFF ( 0xffffff )
  • Золото — # E8A317 ( 0xe8a317 )
  • Светло-золотой — # FBB917 ( 0xfbb917 )
  • Синий — # 1569C7 ( 0x1569c7 )
  • Голубой — # 1389FF ( 0x1389ff )
  • Зеленый — # 347235 ( 0x347235 )
  • Светло-зеленый — # 3E8F1B ( 0x3e8f1b )
  • Красный — # 990000 ( 0x990000 )
  • Светло-красный — # C10202 ( 0xc10202 )
  • Матовый серый — # 222222 ( 0x222222 )

Для начала мы создадим «спины» (видеоклипы, которые будут заменять настоящие экраны), но прежде чем мы начнем, давайте включим некоторые очень полезные функции Flash.

Щелкните правой кнопкой мыши по сцене и выберите «Сетка»> «Показать сетку». По умолчанию он создает сетку 10 на 10 пикселей на сцене. Затем снова щелкните правой кнопкой мыши по сцене и на этот раз выберите Snapping> Snap to Grid.

Теперь мы можем начать рисовать! Выберите инструмент «Прямоугольник» и нарисуйте светлый золотой прямоугольник размером 600×300 пикселей. Затем выберите эту заливку, щелкните правой кнопкой мыши и выберите «Преобразовать в символ». Назовите MovieClip goldBack , установите тип MovieClip и регистрацию вверху слева.

Затем щелкните правой кнопкой мыши MovieClip и выберите Duplicate три раза, чтобы сделать еще три его копии. Теперь перекрасьте их в светло-голубой, светло-зеленый и светло-красный. Затем назовите их blueBack , greenBack и redBack соответственно.

Чтобы завершить спины, мы должны добавить какой-то текст внутри каждого мувиклипа: на goldBack напишите «PLAY», на blueBack напишите «INSTRUCTIONS», на greenBack напишите «OPTIONS», а на redBack напишите «CREDITS». После того, как вы написали текст, я бы порекомендовал разбивать его на части, пока он не станет заливкой (это устраняет необходимость вложения шрифтов и делает переход более плавным). Ваши спины должны выглядеть примерно так:

пример blueBack

Теперь давайте начнем с интерактивных квадратов! Выберите инструмент «Прямоугольник» и нарисуйте светло-золотой квадрат размером 100×100 пикселей. Выберите заливку, щелкните правой кнопкой мыши и «Преобразовать в символ». Назовите MovieClip goldSquare , установите тип MovieClip и регистрацию вверху слева. Сейчас самое время написать текст на квадрате, но на этот раз вместо того, чтобы разбивать текст на части, оставьте это сейчас. Вставьте ключевой кадр и измените цвет заливки на золотой. Теперь разбейте текст на две части, пока они не станут заполнителями.

Теперь щелкните правой кнопкой мыши MovieClip и выберите Duplicate Symbol три раза. Затем повторите ту же процедуру, что и ранее, для остальных трех цветов, назвав MovieClips blueSquare , greenSquare и redSquare соответственно. Ваши квадраты должны выглядеть примерно так:

greenSquare пример 2-кадровый вид

Начните с удаления всего со сцены. Затем перейдите в «Вставка»> «Новый символ». Назовите его menuBounceMC , установите тип MovieClip, регистрацию вверху слева и экспортируйте его как MenuBounceMC .

Теперь перетащите в нее все спинки из библиотеки и расположите их следующим образом:

  • GoldBack: (-600,0)
  • BlueBack: (0, -300)
  • greenBack: (0,300)
  • RedBack: (600, 0)

Если вы собираетесь использовать дизайн в одном направлении, тогда расположите все четыре спины в одном из этих положений. Я использовал (0, 300).

Теперь перетащите все квадраты из библиотеки в мувиклип и разместите их следующим образом:

  • goldSquare: (120 150)
  • blueSquare: (240 150)
  • greenSquare: (360,150)
  • redSquare: (480, 150)

Последнее, что мы должны сделать перед тем, как начать кодирование, — это присвоить имена экземпляров. Установите имена экземпляров для квадратов как square0 , square1 , square2 , square3 , начиная слева. Затем установите имена экземпляров для спины в соответствии с квадратом того же цвета. Поэтому goldBack получит имя экземпляра back0 потому что у goldSquare есть имя экземпляра square0 .


Теперь, когда мы закончили создание и размещение мувиклипов, мы можем приступить к настройке двух классов, которые мы будем использовать.

Сначала зайдите в Свойства вашего Flash-файла и установите его класс на MenuBounce; Затем создайте новый файл ActionScript 3.0 и сохраните его как MenuBounce.as .

Теперь скопируйте в него следующий код; Я объясню это после:

01
02
03
04
05
06
07
08
09
10
11
package{
    import flash.display.MovieClip;
    import flash.events.Event;
     
    public class MenuBounce extends MovieClip{
        public var menuBounceMC:MenuBounceMC = new MenuBounceMC();
        public function MenuBounce(){
            addChild(menuBounceMC);
        }
    }
}

Это базовый класс документа, в который мы добавили немного дополнительного кода, который создает экземпляр MenuBounceMC и добавляет его на сцену.

Теперь создайте новый файл ActionScript 3.0 и сохраните его как MenuBounceMC.as . Теперь скопируйте в него следующий код, чтобы мы могли его настроить.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
package{
    import flash.display.MovieClip;
    import flash.display.Sprite;
    import flash.events.Event;
    import flash.events.MouseEvent;
     
    public class MenuBounceMC extends MovieClip{
        public var activeSquare:MovieClip;
        public var activeBack:MovieClip;
        public var squaresArray:Array = new Array();
        public var backsArray:Array = new Array();
        public var speed:Number = 20;
         
        public function MenuBounceMC(){
             
        }
    }
}

Каждая переменная имеет определенное назначение:

  • activeSquare : какой квадрат переворачивается
  • activeBack : какая спина была выбрана для перемещения
  • squaresArray : массив, содержащий все квадратные squaresArray
  • backsArray : массив, содержащий все backsArray
  • speed : сколько пикселей спины перемещаются на каждый кадр

Все эти переменные были установлены, за исключением topSquare (который устанавливается в других функциях) и массивов. Таким образом, мы должны поместить все мувиклипы в массив. Добавьте следующие строки внутри конструктора:

1
2
squaresArray = [square0, square1, square2, square3];
backsArray = [back0, back1, back2, back3];

Однако этот метод может быть немного утомительным, если вы собираетесь использовать большое количество MovieClips в меню — скажем, 50. Альтернативой может быть создание MovieClips полностью с помощью кода и добавление их при добавлении в меню. Но для нашей цели использования только восьми мувиклипов это прекрасно работает.

Последний набор вещей, которые нам нужно добавить для завершения настройки, это наши прослушиватели событий, которые будут запускать все переходы и эффекты пролонгации. Добавьте эти строки ниже строк push() .

1
2
3
4
addEventListener(MouseEvent.MOUSE_OVER, bounceOver);
addEventListener(MouseEvent.MOUSE_OUT, bounceOut);
addEventListener(MouseEvent.CLICK, bounceClick);
addEventListener(Event.ENTER_FRAME, bounceUpdate);

Давайте начнем с создания трех простых функций:

1
2
3
4
5
6
7
8
9
public function bounceOver(event:MouseEvent):void {
             
}
public function bounceOut(event:MouseEvent):void {
             
}
public function bounceClick(event:MouseEvent):void {
                 
}

Внутри функции bounceOver() начните с добавления оператора if, чтобы удостовериться, что спина в данный момент не «активна», то есть переход, переход или выход сверху:

1
2
3
if(activeBack == null){
 
}

Остальная часть кода в функции bounceOver() будет записана внутри этого оператора if. Теперь мы выясняем, является ли объект, на который перевернут ( event.target ), квадрат, проверяя, находится ли он в squaresArray[] :

1
2
3
if(squaresArray.indexOf(event.target) != -1){
 
}

Предполагая, что это так, мы выполняем настоящую функцию функции:

1
2
3
activeSquare = event.target as MovieClip;
activeSquare.gotoAndStop(2);
setChildIndex(activeSquare, numChildren — 1);

Сначала мы устанавливаем переменную activeSquare чтобы указывать на рассматриваемый квадрат. После этого мы приостанавливаем анимацию этого квадрата на втором кадре, который отображает его изображение «ролловера». Наконец, мы перемещаем спрайт, чтобы быть на вершине всего остального, используя setChildIndex () .

Теперь перейдем к функции bounceOut() . На этот раз мы начнем с проверки, является ли объект, из которого выкатывается мышь, текущим активным квадратом :

1
2
3
if(event.target == activeSquare){
 
}

Внутри блока if добавьте следующий код; он снова приостанавливает анимацию квадрата в первом кадре, а затем устанавливает activeSquare обратно в ноль, чтобы мы могли перевернуть другой:

1
2
activeSquare.gotoAndStop(1);
activeSquare = null;

Затем перейдите к функции bounceClick() . Эта функция будет использоваться для инициации всех переходов. Начните с проверки, есть ли уже активная спина:

1
2
3
if(activeBack == null){
 
}

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

1
2
3
4
5
if(activeBack == null){
 
}else{
    activeBack = null;
}

Предполагая, что в данный момент нет активного возврата, еще раз добавьте блок if, чтобы проверить, был ли объект, по которому щелкнули, квадратом:

1
2
3
4
5
6
7
if(activeBack == null){
    if(squaresArray.indexOf(event.target) != -1){
         
    }
}else{
    activeBack = null;
}

Если пользователь щелкнул квадрат, мы должны установить соответствующую спину как «активную» спину. Поскольку индекс каждого элемента в backsArray[] совпадает с индексом каждого элемента в squaresArray , это просто:

1
2
3
4
5
6
7
8
if(activeBack == null){
    if(squaresArray.indexOf(event.target) != -1){
        activeBack = backsArray[squaresArray.indexOf(event.target)] as MovieClip;
         
    }
}else{
    activeBack = null;
}

Теперь нам просто нужно переместить активный в данный момент назад, чтобы он был поверх всего остального:

1
2
3
4
5
6
7
8
if(activeBack == null){
    if(squaresArray.indexOf(event.target) != -1){
        activeBack = backsArray[squaresArray.indexOf(event.target)] as MovieClip;
        setChildIndex(activeBack, numChildren — 1);
    }
}else{
    activeBack = null;
}

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

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
public function bounceUpdate(event:Event):void {
    for each (var square in squaresArray) {
        if(square == activeSquare){
            if(square.scaleX <= 1.5){
                square.scaleX +=0.05;
                square.scaleY +=0.05;
            }
        }else{
            if(square.scaleX >= 1){
                square.scaleX -=0.05;
                square.scaleY -=0.05;
            }
        }
    }
}

Здесь мы создали цикл for-each, чтобы циклически проходить через каждый квадрат в массиве и проверять, является ли он активным в данный момент квадратом. Если это так, мы увеличиваем масштаб до тех пор, пока он не станет больше или равен в 1,5 раза его обычному размеру; если это не так, мы уменьшаем его, пока он не вернется к своему обычному размеру. (Технически этот код может позволить ему быть немного меньше обычного размера, но на практике это незаметно.)

Вот где некоторые из вас пойдут разными путями; если вы создаете дизайн 1, переходите к шагу 7а, а если вы создаете дизайн 2, переходите к шагу 7b.


Поздравляем, вы выбрали дизайн 1! Эта конструкция проста и понятна — при условии, что у вас ровно четыре квадрата и спины. Больше, и это становится беспорядком, чтобы поддержать.

Мы собираемся использовать длинную серию вложенных выражений if-else — очень грязно, я знаю. Но позвольте мне рассказать вам причину этого! Каждая спинка имеет различную стартовую позицию и направление перехода. В двух словах, вы не можете использовать один цикл for для перемещения всех мувиклипов, если у вас нет одного оператора if для проверки того, какая спина движется, другого для установки оси движения (x или y) и третьего для установки скорость (положительная или отрицательная). Хорошо, мы могли бы хранить всю эту информацию в свойствах квадратов или что-то в этом роде, но я думаю, что это один из подходов, где применяется «Keep It Simple, Stupid».

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
if(activeBack == back0){
    if(back0.x < 0){
        back0.x += speed;
    }
}else{
    if(back0.x > -600){
        back0.x -= speed;
    }
}
if(activeBack == back1){
    if(back1.y < 0){
        back1.y += speed;
    }
}else{
    if(back1.y > -300){
        back1.y -= speed;
    }
}
if(activeBack == back2){
    if(back2.y > 0){
        back2.y -= speed;
    }
}else{
    if(back2.y < 300){
        back2.y += speed;
    }
}
if(activeBack == back3){
    if(back3.x > 0){
        back3.x -= speed;
    }
}else{
    if(back3.x < 600){
        back3.x += speed;
    }
}

Код легко понять; он смотрит на каждую спину и перемещает ее на сцену или за сцену в правильном направлении, в зависимости от того, активен он или нет.


Поздравляем, вы выбрали Дизайн 2! Эта конструкция гораздо более гибкая и значительно упрощает добавление бэкбэков и использование меньшего количества кода. Для этого дизайна мы будем использовать еще один цикл for-each для проверки каждого обратно в backsArray :

01
02
03
04
05
06
07
08
09
10
11
for each (var back in backsArray){
    if(back == activeBack){
        if(back.y > 0){
            back.y -= speed;
        }
    }else{
        if(back.y < 300){
            back.y += speed;
        }
    }
}

Теперь это должно быть довольно легко понять. Он перебирает спины и проверяет каждый, активен ли он. Если это так, код перемещает его вверх на сцену и прекращает перемещать его, когда он полностью включен (то есть, когда он равен y=0 или выше). Если задняя часть не активна, код перемещает ее назад, пока не достигнет своей начальной позиции.


Вот проблема: при 16 квадратах (и 16 спинах) вы можете сделать так, чтобы квадраты 1, 5, 9 и 13 делали соответствующие спины переходами слева, квадраты 2, 6, 10 и 14 — переходами сверху и так далее? Вам нужно будет объединить два подхода, а также проверить положение активного квадрата / назад в его массиве.

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