Статьи

Создание 3D-визитки с Pure AS3

В этом уроке мы создадим 3D-визитку. Мы не будем использовать Away3D , Alternativa , Yogurt3D , Sandy3D , Papervision3D или любой другой 3D-движок, созданный для Flash. Мы будем использовать только 3D-функции Flash Player 10.


Давайте посмотрим на конечный результат, к которому мы будем стремиться:

Нажмите это!


Создайте новый файл ActionScript 3.0.


Перед редактированием, давайте сохраним наш документ как «BusinessCard3D.fla» в любую папку, которую вы хотите.

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


Мы ввели имя класса документа, но еще не создали его.

В разделе «Профиль» щелкните маленький значок пера рядом с «BusinessCard3D».

В этом уроке мы будем использовать Flash Professional. Нажмите кнопку ОК, и перед вами появится новый файл ActionScript. Вы увидите простой класс:

01
02
03
04
05
06
07
08
09
10
11
package {
    
    import flash.display.MovieClip;
  
    public class BusinessCard3D extends MovieClip {
  
        public function BusinessCard3D() {
            // constructor code
        }
    }
}

Удалите строку «// код конструктора» и сохраните ее как «BusinessCard3D.as» в той же папке, которая содержит «BusinessCard3D.fla».


Вам понадобятся две визуальные эффекты для создания визитной карточки. Один из них предназначен для лицевой стороны, а другой — для обратной стороны карты. Я разработал несколько минимальных карт для этого урока:

По сути, скопируйте эти изображения и вставьте их в документ Flash. Они будут добавлены на сцену автоматически. Теперь удалите их и откройте панель «Библиотека»:

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

По умолчанию раздел Связи изображений пуст. Нажмите пробел в разделе Linkage в CardBack.png:

Сделав это, введите «CardBack»:

Сделайте то же самое для изображения CardFront.png. После того, как вы ввели имена ссылок, панель «Библиотека» должна выглядеть следующим образом:

Да. Теперь самое интересное. Теперь мы готовы начать кодирование 🙂


Сначала мы импортируем некоторые другие классы, которые мы будем использовать в следующих шагах:

1
2
3
4
5
import flash.display.Bitmap;
import flash.display.DisplayObject;
import flash.display.Sprite;
import flash.events.Event;
import flash.geom.Point;

Вставьте эти строки между package { и public class BusinessCard3D extends Sprite строки public class BusinessCard3D extends Sprite .


После импорта классов давайте настроим наши переменные. Вставьте эти строки чуть выше строки public function BusinessCard3D() :

01
02
03
04
05
06
07
08
09
10
11
12
13
14
private var businessCard:Sprite
private var frontHolder:Sprite
private var backHolder:Sprite
         
private var frontTexture:Bitmap
private var backTexture:Bitmap
         
private var p1:Point
private var p2:Point
private var p3:Point
         
private var p1_:Point = new Point(0,0)
private var p2_:Point = new Point(100,0)
private var p3_:Point = new Point(0,100)

Как вы можете догадаться, businessCard держит наши две другие карты. Это основной держатель.

frontHolder содержит frontTexture , backHolder — backTexture .

frontTexture и backTexture — это растровые изображения из библиотеки.

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


После настройки переменных напишем нашу первую функцию. Он в основном получает изображения из библиотеки в виде объектов BitmapData, создавая из них растровые изображения frontTexture и backTexture .

1
2
3
4
public function getTextures() {
    frontTexture = new Bitmap(new CardFront(0,0))
    backTexture = new Bitmap(new CardBack(0,0))
}

Сначала мы получаем изображение CardFront, написав: new CardFront(0,0)

Это единственный способ получить BitmapData любого изображения из библиотеки. Мы не можем использовать только BitmapData. Если бы мы использовали 3D-движок, этого, вероятно, было бы достаточно, но в родном Flash 3D нам нужно использовать объект Bitmap, поэтому мы создадим объект Bitmap из BitmapData.

new CardFront(0,0) возвращает нам BitmapData, и этот BitmapData используется в Bitmap для создания frontTexture . Мы делаем то же самое для backTexture и наши текстуры готовы.


Теперь мы напишем нашу вторую функцию. Эта функция строит наши держатели и добавляет наши текстуры в держатели:

01
02
03
04
05
06
07
08
09
10
11
12
public function addIntoHolders() {
    businessCard = new Sprite()
    frontHolder = new Sprite()
    backHolder = new Sprite()
  
    frontHolder.addChild(frontTexture)
    backHolder.addChild(backTexture)
  
    businessCard.addChild(frontHolder)
    businessCard.addChild(backHolder)
    addChild(businessCard)
}

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

Наконец, мы добавляем основной держатель на сцену, на сцену. Мы будем использовать основной держатель в качестве визитной карточки.


Нам нужно изменить поворот и координаты х, у карт.

1
2
3
4
5
6
7
8
9
public function initCards() {
    backHolder.rotationY = 180
                 
    frontTexture.x = -frontTexture.width/2
    frontTexture.y = -frontTexture.height/2
                 
    backTexture.x = -backTexture.width/2
    backTexture.y = -backTexture.height/2
}

Сначала мы поворачиваем обратную сторону карты на 180 градусов. Затем мы устанавливаем позиции обеих карт. На самом деле это простой трюк; мы фактически установили точку регистрации держателя карт в ее центре. Это из-за перспективы 3D-сцены по умолчанию в нашем документе.


Это, пожалуй, самый сложный шаг в нашем уроке. Мы строим визитную карточку, и когда мы смотрим на лицевую сторону карты, обратная сторона карты не должна быть видна. Как мы можем это сделать? Мы можем написать некоторые условия, используя повороты основного держателя … но есть более простой способ.

Представьте, что у нас есть две красные точки и одна синяя точка на поверхности. Теперь представьте, что у нас есть бесконечная линия, которая проходит через две красные точки. Эта линия делит поверхности на две стороны. Проверьте изображение ниже:

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


Теперь поговорим о 3D.

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

Вы видите бесконечную линию? Проверьте изображение ниже:

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

Этот метод используется в Away3D, PaperVision, Yogurt3D, Alternativa и других движках и в основном улучшает производительность.

Для этого метода мы будем использовать функцию:

1
2
3
4
5
6
7
public function isFrontFacing(displayObject:DisplayObject):Boolean {
    
    p1 = displayObject.localToGlobal(p1_);
    p2 = displayObject.localToGlobal(p2_);
    p3 = displayObject.localToGlobal(p3_);
    return Boolean((p2.x-p1.x)*(p3.y-p1.y) — (p2.y-p1.y)*(p3.x-p1.x) > 0);
}

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


Теперь мы наконец-то напишем нашу последнюю функцию. Эта функция в основном вращает нашу визитную карточку и проверяет видимость лиц.

01
02
03
04
05
06
07
08
09
10
public function render(e:Event) {
    businessCard.x = stage.stageWidth/2
    businessCard.y = stage.stageHeight/2
    
    businessCard.rotationY += (mouseX — businessCard.rotationY)*0.2
    businessCard.rotationX += (mouseY — businessCard.rotationX)*0.2
 
    frontHolder.visible = isFrontFacing(frontHolder);
    backHolder.visible = isFrontFacing(backHolder);
}

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


Мы готовы. Давайте назовем наши функции по порядку:

1
2
3
4
5
6
public function BusinessCard3D() {
   getTextures()
   addIntoHolders()
   initCards()
   addEventListener(Event.ENTER_FRAME, render)
}

Мы также добавляем событие ENTER_FRAME для запуска функции рендеринга каждый кадр.


Наконец-то мы готовы протестировать наш фильм.

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

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


Во-первых, для нашей анимации мы будем использовать Tweener. Это действительно просто.

Итак, загрузите последнюю версию Tweener с code.google.com . Я использую версию 1.33.74, ActionScript 3 (Flash 9+).

Извлеките ZIP-файл и переместите папку «caurina» в папку, содержащую наш Flash-документ.


Наши первые строки были об импорте классов. Мы импортируем Tweener, а также MouseEvent.

1
2
3
4
5
6
7
8
import flash.display.Bitmap;
import flash.display.DisplayObject;
import flash.display.Sprite;
import flash.events.Event;
import flash.geom.Point;
     
import caurina.transitions.Tweener
import flash.events.MouseEvent

В нашей функции render() вращение карты было напрямую связано с координатами мыши. Но мы не хотим этого сейчас. Мы в основном нажмем на карту, и она перевернется.

Итак, удалите выделенные строки:

01
02
03
04
05
06
07
08
09
10
public function render(e:Event) {
    businessCard.x = stage.stageWidth/2
    businessCard.y = stage.stageHeight/2
    
    businessCard.rotationY += (mouseX — businessCard.rotationY)*0.2
    businessCard.rotationX += (mouseY — businessCard.rotationX)*0.2
 
    frontHolder.visible = isFrontFacing(frontHolder);
    backHolder.visible = isFrontFacing(backHolder);
}

Мы добавим новую переменную, frontFace . Его тип является логическим. Когда пользователь нажимает на карту, мы поворачиваем нашу карту на 180 или на 0 в зависимости от значения frontFace .

1
private var frontFace:Boolean = true

Теперь мы пишем нашу последнюю функцию. Когда мы нажимаем на карту, эта функция будет запущена.

1
2
3
4
5
6
7
8
9
public function onDown(e:MouseEvent) {
    if(frontFace) {
        Tweener.addTween(businessCard,{rotationY:180,time:1})
        frontFace = false
    }else{
        Tweener.addTween(businessCard,{rotationY:0,time:1})
        frontFace = true
    }
}

Сначала мы посмотрим на переменную frontFace . Если это true то это означает, что мы сейчас смотрим на лицевую сторону карты. Если это false значит, мы смотрим на обратную сторону карты.

Когда мы смотрим на лицевую сторону карты, в основном мы говорим «поверните ее на 180 градусов», чтобы мы могли видеть обратную сторону карты. Мы используем ту же идею, когда смотрим на обратную сторону карты (в этом случае мы поворачиваем ее на 0 градусов).


Наша последняя строка — добавить прослушиватель MouseEvent для запуска функции onDown() мы только что написали. Мы добавляем его в нашу визитную карточку. Вы даже можете добавить его на сцену.

1
businessCard.addEventListener(MouseEvent.MOUSE_DOWN, onDown)

Проверьте свой фильм и нажмите на карту. Может быть, вы можете написать забавное предложение «Нажмите, чтобы вращать мою визитную карточку;)» на ваших изображениях 🙂


На этом уроке мы узнали, как построить трехмерную двухстороннюю плоскость, используя собственный Flash Player 10 3D API и ActionScript 3.0. Сначала мы контролировали его с помощью координат мыши. Затем мы переключились на управление на основе кликов, чтобы не запутывать пользователей.

Как вы видите, возможности 3D-функции в Flash Player не идеальны, но мы всегда можем сформулировать решения и можем создавать простые трехмерные динамические анимации без какого-либо стороннего движка.