Особенность этого ролика в том, что фильмы, которые показываются по разным каналам это внешние ролики, находящиеся в других SWF-файлах. Таким образом, на сцене могут находиться одновременно несколько разных фильмов, которые загружаются при проигрывании.
Каждый фильм находится на отдельном уровне, который имеет свой номер. Уровень 0 это главный монтажный стол данного ролика, остальные уровни имеют номера 1, 2 и т.д. Уровни с большим номером находятся над уровнями с меньшим номером и перекрывают их. Стрелка на рисунке показывает направление взгляда.
Для обращения к уровню с номером N используют условное имя _levelN (level уровень). Адрес _level0 совпадает с адресом _root данного фильма. Однако каждый загруженный фильм имеет свой главный монтажный стол _root, не зависящий от основного.
Загружаемые ролики могут иметь разную частоту смены кадров, но при проигрывании всегда используется частота, установленная для главного монтажного стола _level0.
loadMovieNum ( имя файла, номер уровня );
Например код:
loadMovieNum ( "vesti.swf", 1 );загружает ролик vesti.swf в уровень 1. Для обращения к нему (например, для перемещения) нужно использовать адрес _level1. Однако это можно делать только в следующем кадре, иначе фильм не успеет загрузиться.
Если в этом уровне уже был фильм, он удаляется из памяти. Таким же образом можно заменить и основной ролик, загрузив новый фильм в уровень 0.
Откройте файл PRACTICE\11\tv.fla, создайте слой Программа и добавьте в первый кадр код
chNames = ["vesti.swf", "sport.swf", "ctc.swf"]; MAX = chNames.length; loadChannels(); function loadChannels() { for ( i = 1; i <= MAX; i++ ) loadMovieNum ( chNames[i-1], i ); } |
Далее для удобства записываем длину массива (число каналов) в переменную MAX и вызываем функцию loadChannels, которая загружает ролики в память на уровни 1, 2 и 3. Обратите внимание, что в цикле при обращении к массиву использован индекс i-1, поскольку номера элементов массивов начинаются с нуля.
Если запустить и просмотреть ролик, мы ничего не увидим, потому что в первом кадре каждого из внешних фильмов стоит команда
_visible = false;
Это сделано специально, иначе все ролики сразу после загрузки
появятся в левом верхнем углу экрана.
Работать с уровнями _level1, _level2 и _level3 пока нельзя, поскольку они будут полностью загружены только к началу следующего кадра.
function A() { var qq; var x: Number, s: String; ... }Тип переменной qq не определен, в нее можно записывать любые данные. Для переменных x и s использован строгий стиль описания: с указанием типа. При попытке записи в такие переменные значения другого типа появится сообщение об ошибке. Кроме того, если тип переменной точно указан, при наборе ее имени в редакторе кода появляется окно с подсказками, в котором перечислены все свойства и методы, применимые к этому типу данных.
Существуют три простых типа данных
var q; trace ( x ); trace ( q );в окно Output выдается два раза результат undefined, поскольку переменная x вообще неизвестна, а q объявлена, но никакое значение ей не присвоено.
Переменные типа Object могут хранить ссылки на объекты (например, клипы), то есть, их адреса. Например, если разместить следующий код в любом кадре главной временной шкалы
var x: Object; x = this; trace(x);в окно Output выводится _level0, то есть переменная x ссылается на главный монтажный стол.
myClip.x = 10;Если же код стоит внутри обработчика события клипа, можно написать this.x=10; или просто x=10, этот прием мы неоднократно использовали.
_global.x = true;К переменной x теперь можно обращаться с любого монтажного стола, она одна на всех. Чтобы не запутаться с глобальными переменными, им часто дают имена, начинающиеся с буквы g, например, gPower.
Функции объявляются с помощью слова function:
function qq() {
...
}
Имя этой функции qq, при ее вызове
qq(); выполняются все команды внутри фигурных скобок.
Многоточие здесь и далее означает любой код на ActionScript.
Функция может принимать параметры или аргументы они перечисляются через запятую в скобках:
function qq ( x ) { ... } function ww ( x:Number, s:String ) { ... }Функция qq принимает один параметр, его тип может быть любой. Функция ww принимает два параметра, причем их типы жестко заданы: первый число, второй символьная строка.
Функция может возвращать результат (число, строку, логическое значение и т.д.) с помощью оператора return. Например:
function Sum ( x, y ) { var s = x + y; return s; // или return x + y; }Чтобы использовать это значение, надо записать его в переменную:
w = Sum ( 2, 3 );
trace ( w );
function qq () { ... }
с другой временной шкалы (из обработчика другого клипа) она
вызывается как _root.qq().
Ту же функцию можно объявить по-другому:
qq = function() { ... }
При этом фактически создается переменная типа «ссылка на функцию»
и в нее записывается адрес кода.
Глобальные функции объявляются с помощью слова _global:
_global.qq = function ( x ) { ... }Эту функцию можно вызывать просто как qq() из любого места программы, в том числе из обработчиков событий клипов.
Локальные функции объявляются внутри другой функции и известны только там. В примере
trace(b); a(); function a() { function b() {} trace(b); }функция b локальная для функции a, поэтому первый вызов trace(b) даст результат undefined (не определено), а второй (изнутри функции a) [type Function], то есть, найдена функция с таким именем.
Пусть на текущем монтажном столе есть кнопка с именем btn (имя кнопки задается в левой части на панели Properties). Разберем такой код:
btn.onRelease = function () { trace("q"); btn.onRelease = second; } function second() { trace("qq"); btn.onRelease = null; }Вначале обработчик события кнопки это безымянная функция, которая выводит на экран букву q и, кроме этого, меняет обработчик события на адрес функции second.
При втором щелчке вызывается функция second, которая выводит две буквы q и уничтожает обработчик, записывая в него null. На последующие щелчки кнопка не будет реагировать.
Выделите клип-телевизор и добавьте к нему обработчик onClipEvent ( load ) { power = false; channel = 1; var p = new Object(); p.x = screen._x; p.y = screen._y; localToGlobal ( p ); screenX = p.x; screenY = p.y; } |
Теперь создадим обработчик кнопки включения питания.
Откройте клип-пульт в режиме редактирования, выделите кнопку
и добавьте обработчик события
on (release) { power(); } |
Добавьте в конец кода кадра 1 глобальную функцию power
_global.power = function () { tv.power = ! tv.power; if ( tv.power ) { tv.lamp.gotoAndStop("on"); channel ( tv.channel ); } else { tv.lamp.gotoAndStop("off"); obj = eval("_level" + tv.channel); obj._visible = false; } } |
При выключении питания лампочка гаснет (переходит на метку off). Затем выключается (делается невидимым) ролик включенного канала. Для получения ссылки на нужный клип используется функция eval. Если значение tv.channel равно 1, то строчка
obj = eval("_level" + tv.channel);запишет в переменную obj адрес _level1.
Теперь определим функцию для включения нужного канала.
Добавьте в код кадра 1 еще одну глобальную функцию
_global.channel = function ( no ) { if ( ! tv.power ) return; if ( no < 1 ) no = MAX; if ( no > MAX ) no = 1; for ( var i=1; i<=MAX; i++ ) { obj = eval("_level" + i); if ( i == no ) { obj._visible = true; obj._x = tv.screenX; obj._y = tv.screenY; } else obj._visible = false; } tv.channel = no; } |
Если задан номер канала меньше 1, включается последний канал с номером MAX. Если номер канала больше MAX, включается первый канал.
Далее в цикле перебираем все загруженные клипы. Для нужного клипа включаем видимость и устанавливаем координаты, равные абсолютным координатам экрана телевизора. Все остальные клипы выключаем (_visible=false).
В конце функции номер включенного канала записывается в переменную channel клипа tv.
Остается добавить обработчики для кнопок пульта.
Войдите в режим редактирования клипа-пульта и добавьте обработчик кнопки с цифрой 1:
on ( release ) { channel ( 1 ); }и обработчик кнопки перехода на следующий канал: on (release) { channel( _root.tv.channel + 1 ); }Аналогично составьте обработчики остальных кнопок. Сохраните файл и проверьте работу фильма. |
Фильм, представленный ниже, работает при наведении мышки. Стрелки слева и справа от фотографии позволяют переходить от одного объекта к другому.
Каждую фотографию сопровождает музыка, ход ее проигрывания показывает индикатор («бегущая линия») внизу. Когда музыка заканчивается, происходит автоматический переход к следующему объекту.
Нажав левую кнопку мыши на рисунке, можно увеличить в два раза интересующий фрагмент.
В левом верхнем углу работают баннеры (рекламные ролики), сменяющие друг друга случайным образом. Щелкнув по кнопке Баннеры вкл/выкл, расположенной над баннером, можно отключить и включить их.
Фон тоже содержит анимацию. Более того, фоновый Flash-ролик выбирается случайным образом и также загружается с диска.
Здесь использован переработанный пример из учебного курса фирмы Adobe, опубликованного на сайте www.intuit.ru. |
Часто для загрузки файлов используют пустые клипы символы, внутри которых ничего нет. На сцене они отображаются белым кружком, если его выделить, то на панели Properties можно увидеть, что это символ типа Movie Clip.
Откройте файл PRACTICE\11\aquarium.fla. |
В нашем клипе для загрузки изображений используется символ с именем Пустой символ, помещенный в библиотеку. Одна из таких «пустышек» находится в левом верхнем углу сцены (см. рисунок ниже).
Этот символ имеет имя back и служит для загрузки анимированного фона.
Создайте слой Программа и добавьте к кадру 1 код для случайного выбора фонового клипа:
backFiles = ["back0.swf", "back1.swf", "back2.swf"]; i = random ( 3 ); back.loadMovies ( backFiles[i] );Просмотрите результат. |
То же самое можно сделать иначе, с помощью кода
loadMovie ( backFiles[i], "back" );Это уже не метод объекта-клипа, а отдельная функция. В отличие от первого способа, здесь можно задать имя клипа, в который загружается файл, как второй параметр. То есть, его не обязательно знать заранее и можно построить «на лету», во время выполнения программы.
Если файлы закачиваются через Интернет, это может быть достаточно долго. Для того, чтобы выводить на экран индикатор загрузки, показывающий процент скачанной части, можно использовать объект MovieClipLoader, который умеет передавать эту информацию. Подробности можно найти в справочной системе. |
Если один фильм, скажем, inner.swf, загружается внутрь другого с именем main.swf,
то адрес _root
для обоих фильмов указывает на главный монтажный стол
фильма main. Поэтому обращения к свойствам
_root из внутреннего клипа будут некорректны и
он работать не будет. Чтобы этого избежать, достаточно добавить
в первый кадр фильма inner строчку кода
_lockroot = true;Этот оператор фиксирует адрес _root как адрес текущего монтажного стола и не будет его изменять при загрузке фильма в другой клип. |
Добавьте к кадру 1 код, загружающий случайную картинку в клип с именем picture:
info = new Array (["Акула", "image0.jpg"], ["Медуза", "image1.jpg"], ["Конек", "image2.jpg"]); MAX = info.length; i = random(MAX); newSlide ( i ); |
info = new Array(); info[0] = ["Акула", "image0.jpg"]; info[1] = ["Медуза", "image1.jpg"]; info[2] = ["Конек", "image2.jpg"];Для объекта с номером i название находится в элементе info[i][0], а имя файла-рисунка в info[i][1].
В переменную MAX записывается длина массива (количество объектов). Далее находим случайный номер объекта и вызываем функцию newSlide, которая выводит нужную информацию на экран:
Фотографии имеют размер в два раза больше, чем нужно (по каждой стороне). Это сделано специально, чтобы можно было увеличить их щелчком мыши и увидеть детали. Поэтому перед загрузкой нужно установить для клипа масштаб 50 процентов.
Добавьте функции к коду кадра 1: function newSlide ( no ) { if ( no < 1 ) no = MAX; if ( no > MAX ) no = 1; slideNo = no; name.text = info[no-1][0]; initPicture(); loadMovie ( info[no-1][1], "picture" ); } function initPicture() { with ( picture ) { _xscale = 50; _yscale = 50; } } |
Поскольку в функции newSlide сделана защита от неправильно заданного номера, легко написать обработчики для кнопок-стрелок (переход к предыдущему и следующему объекту).
Добавьте код для кнопки-стрелки «влево»: on ( release ){ newSlide ( slideNo - 1 ); }и аналогично для стрелки «вправо». Проверьте работу кнопок. |
При щелчке мышкой (событие mouseDown) проверяем, попадает ли точка щелчка на рисунок. Для этого применяем метод hitTest. Если попадает, то увеличиваем масштаб рисунка до 100% (полный размер) и начинаем перетаскивание.
При отпускании мыши (событие mouseUp) надо закончить перетаскивание, вернуть рисунок на прежнее место (в точку с координатами (x0,y0)) и установить масштаб 50%. Мы добавим эти возможности к функции initPicture. Так сделано специально, поскольку эта функция вызывается при загрузке нового слайда и все будет правильно работать даже тогда, когда происходит автоматическая смена слайда во время перетаскивания.
Выделите пустой клип с именем picture (он изображается кружком в левом верхнем углу
области рисунка) и добавьте к нему обработчики
onClipEvent ( load ) { x0 = _x; y0 = _y; } onClipEvent (mouseDown) { if ( ! hitTest(_root._xmouse, _root._ymouse) ) return; _xscale = 100; _yscale = 100; startDrag (this); } onClipEvent (mouseUp) { _root.initPicture(); } |
Измените код функции initPicture (код, связанный с кадром 1).
function initPicture() { stopDrag(); with ( picture ) { _xscale = 50; _yscale = 50; _x = x0; _y = y0; } }Проверьте работу клипа в режиме увеличения рисунка. |
Если вы сделали все правильно, фотография действительно увеличивается, но «вылезает» из области, отведенной рисунку, закрывает другие элементы. Чтобы ограничить область видимости, мы используем маску.
Открытая область та, где в маске что-то нарисовано (учитывается только заливка). Нам нужна прямоугольная область, поэтому мы создадим новый символ и нарисуем в нем прямоугольник.
Создайте новый символ Маска типа Movie Clip, нарисуйте в нем прямоугольник любого цвета без контура и установите (на панели Properties) координаты X=0 b Y=0. Выделите слой Панель просмотра и перетащите клип Маска из библиотеки в любое место сцены. Дайте ему имя mask (панель Properties). |
Чтобы установить маску для клипа picture, используется метод setMask:
picture.setMask ( mask );
Здесь mask имя клипа маски. Вся часть клипа
picture, которая не перекрывается клипом mask,
не будет видна.
Выделите клип picture и добавьте в обработчик события load код
with ( _root.mask ) { _x = x0; _y = y0; _width = this._width; _height = this._height; _visible = false; } setMask ( _root.mask );Проверьте работу маски теперь увеличенное изображение не должно выходить из области, отведенной рисунку. |
Область перетаскивания клипа это прямоугольник, из которого не может выйти точка регистрации перетаскиваемого клипа (в нашем случае левый верхний угол клипа picture). Она задается четырьмя значениями:
Чтобы в области рисунка при перетаскивании не появлялся серый фон, левый верхний угол рисунка должен находиться в заштрихованном прямоугольнике, для которого l=x0-_width, t=y0-_height, r=x0 и b=y0. Поэтому вызов функции startDrag принимает вид:
startDrag(this, false, l, t, x0, y0 );Второй параметр, равный false, говорит о том, что клип перетаскивается именно за то место, за которое его схватили. При значении true точка регистрации «прыгнет» к курсору мыши.
Добавьте в обработчик load клипа picture код
l = x0 - _width; t = y0 - _height;и измените вызов функции startDrag в обработчике mouseDown: startDrag (this, false, l, t, x0, y0 );Проверьте работу клипа. |
Исправить этот недостаток очень просто: при переходе в режим увеличения надо сразу сдвинуть координаты клипа так, чтобы точка щелчка оставалась неподвижной. При увеличении в два раза сдвиг по осям X и Y равен расстояниям от точки щелчка до левой и верхней границ клипа picture.
Перед вызовом startDrag добавьте код
_x -= _root._xmouse - _x; _y -= _root._ymouse - _y;Проверьте результат точка щелчка не должна перемещаться. |
Добавьте название музыкального файла в каждый элемент массива info:
info = new Array (["Акула", "image0.jpg", "music0.mp3"], ["Медуза", "image1.jpg", "music1.mp3"], ["Конек", "image2.jpg", "music2.mp3"]); |
snd.loadSound ( имя файла, флаг );
Второй параметр флаг это логическое значение.
Если оно равно true, загружается потоковый звук,
который может проигрываться в ходе загрузки. Если задать
значение false, проигрывание звука начнется только
после полной загрузки.
Добавьте в конец функции newSlide строчки snd.stop(); snd = new Sound(); snd.loadSound(info[no-1][2], true); |
У звукового объекта snd есть два свойства:
Если файл загружается из Интернета, свойство duration обозначает размер уже скачанной части файла. |
Выделите клип-индикатор в нижней части сцены и добавьте к нему следующий код:
onClipEvent (enterFrame) { part = _root.snd.position / _root.snd.duration; percent = Math.round(part*100); gotoAndStop(percent); } |
Наконец, мы обеспечим переход к новому слайду при окончании проигрывания мелодии. Для этого установим обработчик события soundComplete, которое возникает при завершении звука.
Добавьте в конец функции newSlide код:
snd.onSoundComplete = function(){ newSlide ( slideNo + 1 ); }Проверьте, как работает автоматический переход. |
Если в объект Sound загружен MP3-файл, можно получить доступ к его блоку данных (произведение,
альбом, жанр, исполнитель и т.д.). Этот блок еще называют метками ID3.
У такого объекта есть поле id3, его свойства
доступны из программы:
|
Добавьте к кадру 1 слоя Программа следующий код:
bannerFiles = ["banner0.swf", "banner1.swf", "banner2.swf"]; newBanner(); bInt = setInterval(newBanner, 3000); function newBanner() { i = random(3); loadMovie (bannerFiles[i], "banner"); } |
Кнопка под областью баннера служит для включения и выключения показа баннеров. При выключении прекращается периодический вызов функции newBanner (с помощью clearInterval), в переменную bInt записывается специальное значение null (это означает, что режм показа баннеров отключен) и сам баннер выгружается из клипа banner:
unloadMovie ( banner );
При включении вызывается функция newBanner
и снова запускается таймер, который будет вызывать ее
через каждые 3 секунды.
Ответ на вопрос «Что делать?» (включать или выключать) дает значение переменной bInt. Если оно равно null, значит баннеры сейчас отключены, если нет баннеры показываются.
Выделите кнопку для включения баннеров и добавьте к ней обработчик сообщения release
(отпускание кнопки мыши):
on (release) { if ( bInt != null ) { clearInterval ( bInt ); bInt = null; unloadMovie ( banner ); } else { newBanner(); bInt = setInterval ( newBanner, 3000 ); } }Сохраните файл и проверьте работу окончательной версии. |
Столкновения | Видео |
© 2007 К. Поляков