Создание цепного взрыва (ActionScript 3.0)

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

Информация
Автор/переводчик: 
ProcXel.A
Описание: 

Из этого урока вы научитесь делать цепную реакцию. То есть, например, взрывается одна бочка и...!!!

Ввиду того, что в английской версии урока какие-то унылые кружочки, решил предложить вам что-то более веселое. Нам потребуется:

  • PNG картинка бочки.
  • Звук взрыва.
  • Главный класс.
  • Класс бочки.
  • Класс осколков.

Поехали:

1. Создайте новый документ *.fla с размерами 640х480.

2. Импортируйте на сцену картинку бочки и создайте из этой картинки мувиклип с именем "Bochka", с точкой регистрации снизу посередине и прилинкуйте этот мувиклип к классу Bochka.

3. Внутри мувиклипа Bochka на TimeLine слой с картинкой бочки переименуйте в "bochka".

4. Создайте на TimeLine еще один слой "bochkaHot". Скопируйте в этот слой, в первый кадр картинку бочки и конвертируйте картинку в мувиклип по имени "bochkaHot_mc". В свойствах этого мувиклипа пропишите Инстенс имя "bochkaHot_mc".

5. В свойствах мувиклипа bochkaHot_mc, во вкладке Filters добавьте фильтр Adjust Color и настройте, как на картинке. Мувиклип bochkaHot_mc у нас будет появляться по альфа и имитировать эффект нагревания бочки.

6. Вернемся к нашему мувиклипу Bochka. В TimeLine создадим еще три слоя: explosion, actions, labels.

7. В слое explosion нарисуйте красивую анимацию взрыва :), начиная во второго кадра и до... пока не надоест. :)

8. В слое actions в первом кадре создайте пустой ключевой кадр и пропишите в нем код stop();. Так же создайте еще один пустой ключевой кадр в кадре, следующием после конца анимации взрыва, и так же пропишите в нем код stop();

9. В слое labels в первом ключевом кадре, в свойствах пропишите метку "stay", во втором ключевом кадре пропишите метку "explosion", в последнем ключевом кадре пропишите метку "deleting". Напомню, что пустые ключевые кадры создаются клавишей F7.

Вроде бы все с бочкой. Выйдем на главную сцену и удалим бочку со сцены. Она останется у нас в библиотеке. Теперь создадим мувиклип осколка:

10. Жмем Ctrl+F8 и создаем мувиклип. Называем его "Splinter" (англ.: осколок) и привязываем к классу Splinter.

11. Рисуем что-нибудь похожее на осколок внутри этого мувиклипа и выходим из мувиклипа на главную сцену. Наш осколок сейчас в библиотеке.

Пишем код:

А теперь самое интересное... :) Нам нужно создать три класса: главный, для бочки и для осколка. Жмем Ctrl+N и создаем новый файл *.as. Называем его Main.as и пишем в нем код:

/*
Это главный класс. Его имя должно быть прописано в свойствах *.fla файла.
Класс добавляет на сцену некоторе количество бочек.
По клику по одной из бочек можно запустить цепную реакцию.
Для перезарядки бочек можно нажать пробел.
*/
 
package
{
//Импорт необходимых классов.
import flash.display.MovieClip;
import flash.events.Event;
import flash.events.KeyboardEvent;
import flash.media.Sound;
 
public class Main extends MovieClip
{
//Массив, в котором будут храниться бочки.
private var bochkaArray:Array = [];
//Массив, в котором будут храниться осколки.
private var splintersArray:Array = [];
//Количество выставляемых бочек.
private var numberOfBochka:uint = 15;
//Звук взрыва из библиотеки.
private var explosionSound:Sound = new ExplosionSound();
 
//Конструктор.
public function Main()
 
 
{
//Расставляем несколько бочек на сцене.
CreateFildOfBochka(numberOfBochka);
//Назначаем слушатель события смены кадра.
stage.addEventListener(Event.ENTER_FRAME, Update);
//Назначаем слушатель события на нажатие клавиш.
stage.addEventListener(KeyboardEvent.KEY_DOWN, Reload);
}
 
//Функция проигрывания звука взрыва.
public function PlayExplosionSound():void
{
//Запускаем звук взрыва.
explosionSound.play();
}
 
//Функция создания нескольких бочек на сцене.
private function CreateFildOfBochka(numberOfBochka:uint):void
{
//Цикл.
for (var i:uint = 0; i < numberOfBochka; i++)
{
//Создаем экземпляр бочки.
var bochka:Bochka = new Bochka(stage,this);
//Добавляем в массив бочек.
bochkaArray.push(bochka);
}
}
 
//Функция добавления новых бочек. Функция срабатывает, когда нажимается какая-либо клавиша.
private function Reload(e:KeyboardEvent):void
{
//Узнаем, какая клавиша была нажата.
switch (e.keyCode)
{
//Если нажата клавиша "ПРОБЕЛ".
case 32 :
//Цикл по массиву бочек.
for (var j:uint = 0; j < bochkaArray.length; j++)
{
//Удаляем старые бочки.
stage.removeChild(bochkaArray[j]);
}
 
//Очищаем массив бочек.
bochkaArray = [];
//Создаем новые бочки.
CreateFildOfBochka(numberOfBochka);
//Завершение условия.
break;
}
}
 
//Функция добавления в массив осколков нового осколка.
public function PushNewSplinter(s:Splinter):void
{
//Добавляем в массив новый осколок.
splintersArray.push(s);
}
 
//Проверка попадания осколка в бочку.
private function CheckColisions(s:Splinter):void
{
//Цикл по массиву бочек.
for(var i:uint = 0; i < bochkaArray.length; i++)
{
//Помещаем бочку из массива в локальную переменную для удобства.
var b:Bochka = bochkaArray[i];
//Определяем расстояние от осколка до бочки.
var distance:Number = Math.sqrt(Math.pow((s.x - b.x),2) + Math.pow((s.y - b.y),2));
 
//Если осколок от бочки на расстоянии меньше, чем половина высоты бочки, то рапускаем реакцию нагрева бочки.
if(distance < b.height/2)
{
//Имитируем клик по бочке, так как функция клика у бочки как раз и запускает нагрев.
b.Click();
}
//Если клип бочки доиграл анимацию взрыва, то удаляем бочку.
if(b.currentLabel == "deleting")
{
//Удаляем из списка отображения.
b.Delete();
//Удаляем из массива.
bochkaArray.splice(i,1);
//По идее, ссылок на этот экземпляр класса бочки больше нет, поэтому сборщик мусора очистит память.
}
}
}
 
//Эта функция запускается каждый кадр и обновляет необходимые данные.
private function Update(e:Event):void
{
//Цикл по массиву осколков.
for (var i:uint = 0; i < splintersArray.length; i++)
{
//Помещаем осколок из массива в локальную переменную для удобства.
var s:Splinter = splintersArray[i];
//Обновляем данные осколка (Анимируем его перемещение).
s.Update();
//Проверяем столкновение с бочками.
CheckColisions(s);
//Проверяем вылет за экран. Если осколок улетел за экран, то удаляем его.
if (s.x < 0 || s.x > 640 || s.y < 0 || s.y > 480)
{
//Удаляем осколок из списка отображения.
s.Delete();
//Удаляем осколок из массива осколков.
splintersArray.splice(i, 1);
//По идее, ссылок на этот осколок больше нет. Поэтому сборщик мусора должен очистить память.
}
}
//Выводим на экран количество бочек и осколков в данный момент.
 //trace_txt.text = String(bochkaArray.length +" || "+ splintersArray.length);
}
}
}

Не забудьте прописать Main в свойствах *.fla документа как главный класс.

Теперь создаем файл Bochka.as и пишем код:

/*
Класс бочки.
 
Бочка взрывается и создает осколки.
*/
 
package
{
 //Импорты необходимых классов.
 import flash.display.MovieClip;
 import flash.display.Stage;
 import flash.events.MouseEvent;
 import fl.transitions.Tween;
 import fl.transitions.easing.Strong;
 import fl.transitions.TweenEvent;
 
 public class Bochka extends MovieClip
 {
 /*
 labels:
 1 - "stay"
 2 - "explosion"
 14 - "deleting"
 
 movieclips:
 bochkaHot_mc
 */
 
 //Контейнер для stage.
 private var container:Stage;
 //Контейнер для главного класса.
 private var main:Main;
 //Количество осколков у бочки.
 private var numberOfSplinters:uint = Math.floor(Math.random() * 6) + 10;
 //Переменная для твинанимации нагревания бочки.
 private var heatingTween:Tween;
 //Время нагревания бочки в секундах.
 private var timer:Number = 1;
 //Флаг взрыва бочки.
 private var inBoom:Boolean = false;
 
 //Конструктор.
 public function Bochka(c:Stage, m:Main)
 {
 //Скрываем картинку нагретой бочки, которая будет позже плавно появляться и имитировать нагрев бочки.
 bochkaHot_mc.alpha = 0;
 //Добавляем главный класс в контейнер.
 main = m;
 //Добавляем stage в контейнер.
 container = c;
 //Добавляем бочку в список отображения.
 container.addChild(this);
 //Задаем рандомные бочки координаты на сцене.
 this.x = (Math.random() * 590)+ 25;
 this.y = (Math.random() * 410) + 60;
 //Назначаем слушатель на событие клика по бочке.
 this.addEventListener(MouseEvent.CLICK, Click);
 }
 
 //Функция клика по бочке.
 public function Click(e:MouseEvent = null):void
 {
 //Если бочка еще не взорвалась, то...
 if (! inBoom)
 {
 //Помечаем, что бочка уже взорвана.
 inBoom = true;
 //Анимируем нагрев бочки.
 heatingTween = new Tween(this.bochkaHot_mc,"alpha",Strong.easeOut,0,1,timer,true);
 //Назначаем слушатель на событие завершения анимации нагрева бочки.
 heatingTween.addEventListener(TweenEvent.MOTION_FINISH, Explosion);
 //Удаляем слушатель на клик по бочке - он больше не нужен.
 this.removeEventListener(MouseEvent.CLICK, Click);
 }
 }
 
 //Функция взрыва бочки после полного нагрева.
 private function Explosion(e:TweenEvent):void
 {
 //Запускам звук взрыва.
 main.PlayExplosionSound();
 //Запускаем анимацию взрыва.
 this.gotoAndPlay("explosion");
 //Цикл по количеству осколков.
 for (var i:uint = 0; i < numberOfSplinters; i++)
 {
 //Создаем новый осколок.
 var splinter:Splinter = new Splinter(container,[this.x,this.y + 20]);
 //Помешаем осколок в массив осколков в главном классе.
 main.PushNewSplinter(splinter);
 }
 //Удаляем слушатель завершения анимации нагрева.
 heatingTween.removeEventListener(TweenEvent.MOTION_FINISH, Explosion);
 }
 
 //Функция удаления бочки из списка отображения контейнера stage.
 public function Delete():void
 {
 container.removeChild(this);
 }
 }
}

А теперь быстренько создаем еще один класс Splinter.as:

/*
Класс осколков.
*/
 
package
{
 //Импорт необходимых классов.
 import flash.display.MovieClip;
 import flash.display.Stage;
 
 public class Splinter extends MovieClip
 {
 //Контейнер для stage.
 private var container:Stage;
 //Скорость осколка по х и у.
 private var speedXY:Array = [Math.random()*5 + 0.1,Math.random()*5 + 0.1];
 
 //Конструктор.
 public function Splinter(c:Stage, coords:Array)
 {
 //Помешаем осколок в нужные координаты, которые берутся относительно конкретной бочки.
 this.x = coords[0];
 this.y = coords[1];
 //Добавляем stage в контейнер.
 container = c;
 //Добавляем осколок в список отображения.
 container.addChild(this);
 
 //Рандомно изменяем знак скорости по осям, чтобы осколки летели не только вправо и вниз, но и влево и вверх.
 if(Math.random()*1 < 0.5)
 {
 speedXY[0] = -speedXY[0];
 }
 if(Math.random()*1 < 0.5)
 {
 speedXY[1] = -speedXY[1];
 }
 }
 
 //Функция удаления из списка отображения контейнера.
 public function Delete():void
 {
 container.removeChild(this);
 }
 
 //Функция одновления данных.
 public function Update():void
 {
 //Анимируем перемещение осколка в зависимости от скоростей.
 this.x += speedXY[0];
 this.y += speedXY[1];
 }
 }
}

Сохраняем все классы рядом с *.fla документом. ;)

Готово! Если Я ничего не напутал... И если вы ничего не напутали... То... Должно всё работать. ;) Тестируем ролик: кликаем по первой попавшейся бочке, она бабах! А потом они пыщь! А потом остальные бах бах бах! Ух... Жмем пробел...

Исходник: 

Впервые!

Если у вас было хоть раз желание сделать что-то новое и необычное, то этот видеокурс для вас! Знания ActionScript 3.0 вдохнут в ваши проекты новую жизнь, позволив тем самым поднять их на новый уровень

С помощью этого видеокурса вы пройдёте путь от новичка до Объектно-Ориентированного Программирования, сможете работать со многими популярными библиотеками и научитесь создавать сайты во flash! + Видеокурс по PaperVision3D в подарок!

Видеокурс содержит 119 видеоуроков в 12 главах. На сегодняшний день это единственный видеокурс, таких масштабов

Узнайте о других возможностях ActionScript 3.0

Комментарии

Аватар пользователя ProcXel.A

Цитата: Evgeniy

Не делал, но идея очень нравится, а где ты взял идею? С какого-то англ сайта?

В начале урока указан источник.

Цитата: Михаил

При нажатии клавиши пробел лучше зделать и исчезание "красных сюрикенов".Иначе если постоянно нажимать клавишу пробел то будет каша и крах плагина.

Да.

True Love

Аватар пользователя Константин

Evgeniy,

ну в начале если что есть переменная, описывающая кол-во бочек

 

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

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

у меня ошибка:

1119: Обращение возможного неопределенного свойства alpha через ссылку со статическим типом Class . и Bochka(в 46 и 69 строках Bochka.as)
что это значит? 
Аватар пользователя sponch007

Мёртвая тема

smiles

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

Мёртвая тема

все на форуме :) там вопросы обсуждаются)))

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

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