3D пространство с помощью ActionScript 3.0 (Часть 2)

Content on this page requires a newer version of Adobe Flash Player.

Это - вторая часть урока "3D пространство с помощью ActionScript 3.0". В этом уроке мы заставим наши квадраты двигаться в 3D пространстве синусоидальной волной. При этом будем иметь возможность управлять некоторыми параметрами движения квадратов.

Настройка объектов:
Откройте *.fla файл предыдущего урока. Создайте на сцене три ползунка (слайдера) на верхнем левом углу. Задайте им такие имена в свойствах (Instance name): angleSpeedSlider, zSpeedSlider, radiusSlider. (Для тех, кто не в курсе: слайдер - это компонент. Все компоненты лежат в библиотеке компонентов, которая вызывается клавишами Ctrl+F7 или через меню Window -> Components)

Написание кода:

Перейдем в первый кадр TimeLine. Из прошлого урока у нас в этом кадре должен был остаться код. Сотрите его и вставьте на его место следующий код:

//Начальная настройка слайдеров.
angleSpeedSlider.value = 10;
angleSpeedSlider.minimum = 1;
angleSpeedSlider.maximum = 30;
 
zSpeedSlider.value = 7;
zSpeedSlider.minimum = 1;
zSpeedSlider.maximum = 20;
 
radiusSlider.value = 7;
radiusSlider.minimum = 1;
radiusSlider.maximum = 20;
 
//Максимальная глубина квадратов.
const MAXIMUM_Z:Number = 450;
 
//Количество квадратов.
const NUMBER_OF_BOXES:Number = 14;
 
//Создаем массив, который будет содержать квадраты.
var boxes:Array = new Array();
 
//Задаем фокусное расстояние.
var focalLength:Number = 300;
 
//Задаем точку появления квадратов.
var vanishingPointX:Number = stage.stageWidth / 2;
var vanishingPointY:Number = 20;
 
//Задаем 3Д пол для квадратов.
var floor:Number = 80;
 
//Задаем начальную глубину.
var startingDepth:Number = MAXIMUM_Z;
 
//Задаем расстояние по оси Z между соседними квадратами.
var zDistance:Number = 50;
 
//Задаем скорость движения квадратов по оси Z.
var zSpeed:Number = -(zSpeedSlider.value);
 
//Мы назначаем различный стартовый угол для каждого квадрата (мы увеличиваем его позже).
var angle:Number = 0;
 
//Угловое различие между квадратами
var angleDifference:Number = 0.3;
 
//Скорость изменения угла между квадратами.
var angleSpeed:Number = angleSpeedSlider.value * 0.01;
 
//Радиус траектории движения квадратов.
var radius:Number = radiusSlider.value * 10;
 
//Этот цикл создает и размещает квадраты (первый квадрат находится дальше всех).
for (var i=0; i < NUMBER_OF_BOXES; i++) {
 
 //Создается новый квадрат.
 var box:MyBox = new MyBox();
 
 //Расчитываем 3Д положение по оси Х (мы сделаем волну синуса).
 box.xpos3D = Math.sin(angle) * radius;
 
 //Сохраняем информацию о значении угла квадрата.
 box.currentAngle = angle;
 
 //Увеличиваем стартовый угол следующего квадрата.
 angle += angleDifference;
 
 //3Д позиция по оси У у всех квадратов одинаковая.
 box.ypos3D=floor;
 
 //Задаем положение квадрата по оси Z. Чем больше Z, тем дальше квадрат от нас.
 box.zpos3D=startingDepth;
 
 //Обновляем начальную глубину для следующего квадрата.
 startingDepth-=zDistance;
 
 //Расчитываем размер квадрата относительно его положения по оси Z.
 var scaleRatio = focalLength/(focalLength + box.zpos3D);
 
 //Задаем размеры квадрата
 box.scaleX=box.scaleY=scaleRatio;
 
 //Размещаем квадрат на сцене. Переводим 3Д координаты в 2Д.
 box.x=vanishingPointX+box.xpos3D*scaleRatio;
 box.y=vanishingPointY+box.ypos3D*scaleRatio;
 
 //Помещаем квадрат в массив.
 boxes.push(box);
 
 //Добавляем квадрат в список отображения.
 addChild(box);
}
 
//Используем событие ENTER_FRAME для анимации.
addEventListener(Event.ENTER_FRAME, enterFrameHandler);
 
//Эта функция вызывается каждый кадр.
function enterFrameHandler(e:Event):void {
 
 //Получаем динамические скорости от наших ползунков.
 angleSpeed=angleSpeedSlider.value*0.01;
 zSpeed = -(zSpeedSlider.value);
 radius = radiusSlider.value * 10;
 
 //Цикл перебивает квадраты.
 for (var i=0; i < NUMBER_OF_BOXES; i++) {
 
 //Сохраняем квадрат в локальной переменной.
 var box:MyBox = (MyBox)(boxes[i]);
 
 //Обновляем позицию по оси Z.
 box.zpos3D+=zSpeed;
 
 //Обновляем угол квадрата.
 box.currentAngle+=angleSpeed;
 
 //Если zpos3D <= -focalLength, то помещаем квадрат в самое начало, позади всех других.
 if (box.zpos3D<=- focalLength) {
 
 //Сохраняем последний квадрат в локальной переменной.
 //Последный квадрат всегда первый в массиве - это результат действия функции сортировки sortZ().
 var lastBox:MyBox = (MyBox)(boxes[0]);
 
 //Размещаем квадрат позади последнего.
 box.zpos3D=lastBox.zpos3D+zDistance;
 
 //Получаем новый угол для квадрата (Угол такой же, как у последнего квадрата, минут угловое отличие angleDifference).
 box.currentAngle=lastBox.currentAngle-angleDifference;
 }
 
 //Расчитываем новую позицию по оси Х.
 box.xpos3D=Math.sin(box.currentAngle)*radius;
 
 //Расчитываем размер квадрата.
 var scaleRatio = focalLength/(focalLength + box.zpos3D);
 
 //Задаем размер квадрата.
 box.scaleX=box.scaleY=scaleRatio;
 
 //Задаем прозрачность квадрата по альфа каналу в зависимости от размера квадрата.
 box.alpha=scaleRatio-0.5;
 
 //Размещаем квадрат на сцене. Переводим 3Д координаты в 2Д.
 box.x=vanishingPointX+box.xpos3D*scaleRatio;
 box.y=vanishingPointY+box.ypos3D*scaleRatio;
 }
 
 //Сортируем квадраты по глубине.
 sortZ();
}
 
//Функция сортировки квадратов, чтобы они отображались корректно.
function sortZ():void {
 
 //Сортировка квадратов таким образом, что квадрат в наибольшим значением Z всегда был вначале массива.
 boxes.sortOn("zpos3D", Array.NUMERIC | Array.DESCENDING);
 
 //Задается новый индекс квадрата в списке отображения квадратов.
 for (var i:uint = 0; i < NUMBER_OF_BOXES; i++) {
 setChildIndex(boxes[i], i);
 }
}

Протестируйте ролик. Теперь можете наслаждаться своим собственным 3D пространством. :) И Я, и автор урока уверены, что коментарии к коду довольно хорошо описывают суть происходящего, поэтому на этом урок окончен. :) Как видите, это совершенно просто. Мы помещаем объекты в воображаемое 3D пространство и преобразуем их координаты в 2D. Если у вас возникли какие-либо вопросы, то задавайте их на форуме.

Исходник: 

Похожие записи

Комментарии

Аватар пользователя NecroS

молодец....спасибо вещь стоящая....хотя если подумать флеш нам дает теперь возможность действительно размещать объекты в 3D пространстве без доп преобразования координат......но урок очень хороший еще раз спасибо

Аватар пользователя Rell

Вот это умельцы!

Аватар пользователя NecroS

Слушай а вот пожелание-просьба......а ты можешь сделать урок создание собственного скрола.....вот кнопки прокрутки я делаю без проблем а вот сам ползунок чтобы он подстраивался под размер текста ну никак.....стандартный компонент не устраивает в силу не подходящего по стилю =)))) буду очень благодарен

Аватар пользователя NOX

не забудьте определить в классе MyBox переменную currentAngle

Аватар пользователя komar

 NecroS я к тебе присоединюсь авторы сделайте пожалуйста отдельный видео или текстовый урок по созданию скрола заранее спасибо)

Аватар пользователя Fly
Цитата: komar

NecroS я к тебе присоединюсь авторы сделайте пожалуйста отдельный видео или текстовый урок по созданию скрола заранее спасибо)

Все заявки на форум

1) Админ всегда прав
2) Если админ не прав, смотри пункт 1

Мы в контакте - https://vkontakte.ru/club9573247
Не отвечаю на вопросы в личку касаемо Flash, у нас для этого есть форум

Аватар пользователя NecroS

Fly,
я там как то оставлял заявку но как видно она так и не реализовалась....вот решил конкретно к человеку обратится!

Аватар пользователя Fly

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

1) Админ всегда прав
2) Если админ не прав, смотри пункт 1

Мы в контакте - https://vkontakte.ru/club9573247
Не отвечаю на вопросы в личку касаемо Flash, у нас для этого есть форум

Аватар пользователя NecroS

Запрещается создаавть темы аналогичные ранее созданным. Воспользуйтесь поиском, как на главном сайте, так и на форуме.

отредактируйте первое правило на форуме......в слове создавать буква А не на своем месте =))