
- •Оглавление
- •Вступление
- •Глава 1. Язык сценариев. ActionScript: начальные сведения
- •Проект 1: Прыгающий мяч (программная анимация)
- •1.1. Среда разработки ActionScript: настройка и приемы работы
- •1.1.1. Различие между стандартной и профессиональной версиями Flash
- •1.1.2. Панель Actions
- •1.1.3. Режим упрощенного ввода кода. Панель Behaviors
- •1.1.4. Как упростить создание кода на панели Actions
- •1.1.5. Типы сценариев
- •1.1.6. Централизация кода
- •1.1.7. Инструменты работы с кодом
- •1.1.8. Настройки стиля кода
- •1.1.9. Сохранение ActionScript-кода
- •1.1.10. Функция trace() и панель Output
- •1.1.11. Справочная информация
- •1.2. Синтаксис ActionScript
- •1.2.1. Пробельные символы
- •1.2.2. Завершение предложений
- •1.2.3. Чувствительность к регистру
- •1.2.4. Зарезервированные слова ActionScript
- •1.2.5. Принципы присвоения имен
- •1.2.6. Комментарии
- •1.3. Основные понятия
- •1.3.2. ActionScript как скриптовый язык Flash-плейера
- •1.3.3. Интерпретатор ActionScript. Flash-ассемблер
- •1.3.4. Символы и экземпляры символов
- •1.3.5. Переменные
- •1.3.6. Функции
- •1.3.7. Условные предложения
- •1.3.8. Циклы
- •1.3.9. Массивы
- •1.3.10. Объектная модель ActionScript
- •1.3.11. Свойства _root, _parent, Leveln и ключевое слово this
- •1.3.12. Области видимости кода
- •1.3.1. ЕСМА-262 как основа ActionScript
- •Глава 2. Типы данных
- •2.3. Математические функции и константы. Объект Math
- •2.3.1. Особенности реализации математических функций
- •2.3.2. Возведение в степень и вычисление квадратного корня
- •2.3.3. Экспонента и натуральный логарифм
- •2.3.5. Случайные числа
- •2.3.6. Округление до целого числа
- •2.3.7. Сравнение пары чисел
- •2.3.8. Тригонометрические функции
- •2.3.9. Математические константы
- •2.4. Строки (тип string)
- •2.4.1. Создание строк
- •2.4.2. Элементарные операции со строками
- •2.4.3. Класс String
- •2.4.4. Определение длины строки. Свойство lengths
- •2.4.5. Соединение строк. Метод concat()
- •2.4.6. Выделение символа строки по индексу. Метод charAt()
- •2.4.7. Поиск в строке. Методы indexOf() и lastIndexOff()
- •2.4.8. Извлечение подстроки. Методы substring(), substr(), slice()
- •2.4.9. Преобразование строк в массивы. Метод split()
- •2.4.12. Преобразование строк в идентификаторы. Функция eval()
- •2.4.13. Текстовые поля
- •2.5. Кодировка символов. Уникод во Flash
- •2.5.1. Немного истории
- •2.5.2. Поддержка уникода Flash-плейером
- •2.5.3. Поддержка уникода средой разработки
- •2.5.4. Добавление символов уникода
- •2.6. Логические величины (тип boolean)
- •2.6.1. Класс Boolean
- •2.7. Тип undefined
- •2.8. Тип null
- •2.9. Объекты (тип object)
- •2.9.1. Атрибуты свойств
- •2.9.2. Изменение атрибутов свойств. Функция ASSetPropFlags()
- •2.10. Клипы (тип movieclip)
- •2.11. Преобразование типов данных
- •2.11.1. Правила преобразования типов
- •2.11.2. Автоматическое преобразование типов
- •2.12. Строгая типизация в ActionScript
- •Проект 2: Калькулятор
- •2.1. Определение типа объекта данных
- •2.2. Числа (тип number)
- •2.2.1. Виды чисел в ActionScript
- •2.2.2. Особенности представления чисел
- •2.2.3. Операции с числами
- •2.2.4. Класс Number — методы и свойства
- •2.2.5. Преобразование строк в числа. Функции parseInt() и parseFloat()
- •Глава 3. Переменные
- •3.1. Создание переменных
- •3.2. Особенности типизации переменных
- •3.3. Локальные переменные функций
- •3.4. Глобальные переменные
- •3.5. Особенности операции присваивания
- •3.6. Есть ли переменные в ActionScript?
- •3.7. Удаление переменных
- •Проект 3: Пружинный маятник
- •Глава 4. Функции
- •4.1. Создание функций
- •4.2. Вызов функций
- •4.3. Предложение return
- •4.4. Рекурсия
- •4.5. Особенности цепочки областей видимости функций
- •4.6. Объект arguments
- •4.6.1. Формальные параметры и объект arguments
- •4.6.2. Свойства объекта arguments
- •4.7. Особенности передачи в функции составных объектов данных
- •4.8. Функции как объекты
- •4.8.1. Класс Function
- •4.8.2. Свойство prototype
- •4.8.3. Методы вызова функции
- •4.9. Функции на стадии выполнения. Объект активации
- •Проект 4: Крестики-нолики
- •Глава 5. Операторы
- •5.1. Виды операторов
- •5.2. Иерархия операций
- •5.3. Сочетательность операций
- •5.4. Арифметические операторы
- •5.5. Операторы присваивания
- •5.5.1. Оператор =
- •5.5.2. Операторы присваивания с модификацией
- •5.5.3. Инкрементирование и декрементирование
- •5.6. Операторы равенства и сравнения
- •5.6.1. Операторы равенства
- •5.6.2. Операторы сравнения
- •5.7. Логические операторы
- •5.8. Условный оператор (?:)
- •5.9. Служебные операторы
- •5.9.1. Инициализаторы литералов
- •5.9.2. Оператор группирования
- •5.9.3. Операторы доступа к свойствам
- •5.9.4. Оператор вызова функции
- •5.9.5. Оператор new
- •5.9.6. Оператор super
- •5.9.7. Оператор delete
- •5.9.8. Оператор typeof
- •5.9.9. Оператор instanceof
- •5.9.10. Оператор void
- •5.9.11. Оператор «запятая»
- •5.10. Поразрядные операторы
- •5.10.1. Логические поразрядные операторы
- •5.10.2. Операторы поразрядного сдвига
- •Проект 5: 3D-конструктор
- •Глава 6. Предложения
- •6.1. Блок предложений
- •6.2. Предложения var и function
- •6.3. Предложения выражений и пустые предложения
- •6.4. Предложение return
- •6.5. Предложение with
- •6.6. Условные предложения
- •6.6.1. Предложение if
- •6.6.2. Предложение switch
- •6.7. Циклы
- •6.7.1. Циклы с предусловием (while и do—while)
- •6.7.2. Цикл с параметром (for)
- •6.7.4. Предложения break и continue
- •6.7.5. Ограничение на время выполнения кода
- •6.7.6. Циклы события onEnterFrame и временной диаграммы
- •6.7.7. Циклический вызов функций. Функция setInterval()
- •Проект 6: Тетрис
- •Глава 7. Массивы (класс Array)
- •7.1. Создание массивов
- •7.2. Извлечение и переопределение элементов массива
- •7.3. Длина массива. Свойство length
- •7.4. Добавление элементов в массив
- •7.5. Удаление элементов массива
- •7.6. Слияние массивов
- •7.7. Выделение фрагмента массива
- •7.8. Инверсия массива
- •7.9. Сортировка массива
- •7.10. Преобразование массива в строку
- •7.11. Многомерные массивы
- •7.13. Особенности реализации массивов в ActionScript
- •Проект 7: Пиксельное табло
- •Глава 8. События
- •8.1. Модель событий Генератор—Листенеры
- •8.1.1. Обработчики событий
- •8.1.2. Листенеры
- •8.2. Событийные методы
- •8.3. Модель событий Flash 5
- •8.4. Обновление экрана при событиях
- •Проект 8: Создаем события сами
- •Глава 9. Объектно-ориентированное программирование
- •9.2.1. Объекты
- •9.2.2. Свойства
- •9.2.3. Методы
- •9.2.4. Классы
- •9.2.5. Наследование
- •9.2.6. Создание надклассов и подклассов
- •9.2.7. Концепция создания надклассов Flash 6
- •9.2.8. Оператор super
- •9.2.9. Свойства и методы конструктора класса
- •9.2.10. Определение принадлежности объекта к классу
- •9.2.11. Цепочка областей видимости. Объект Global
- •9.3. Класс Object
- •9.3.1. Создание объектов класса Object
- •9.3.2. Метод registerClass(). Выделение экземпляров клипа в класс
- •9.3.3. Метод addProperty(). Свойства типа getter/setter
- •9.3.4. Методы watch() и unwatch(). События изменений свойств
- •9.3.5. Прочие методы класса Object
- •9.4.1. Создание классов
- •9.4.2. Задание наследуемых свойств и методов класса
- •9.4.3. Конструктор класса. Инициализация собственных свойств и методов объектов
- •9.4.4. Особенности задания методов в AciionScript2.0
- •9.4.5. Статичные члены класса
- •9.4.7. Динамические классы
- •9.4.8. Наследование
- •9.4.9. Интерфейсы
- •9.4.10. Свойства типа getter/setter
- •9.4.11. Выделение экземпляров символа в подкласс
- •9.4.12. Особенности контроля на этапе компиляции
- •9.4.13. Особенности импорта внешних классов
- •9.4.14. Пакеты
- •9.4.15. Встроенные классы. Директива intrinsic
- •Проект 9: Модель идеального газа
- •Глава 10. Клипы
- •10.1. Глобальные функции и свойства
- •10.2. Отличия клипов от объектов
- •10.2.1. Свойства клипов
- •10.3. Клипы как носители кода
- •10.3.1. Последовательность выполнения кода
- •10.3.2. Особенности использования свойств и методов класса MovieClip
- •10.4. Особенности основной временной диаграммы _root
- •10.5. Создание экземпляров клипов
- •10.5.1. Метод duplicateMovieClip()
- •10.5.3. Метод createEmptyMovieClip(). Создание пустого клипа
- •10.6. Виртуальные слои клипов
- •10.6.1. Изменение глубины клипа. Метод swapDepths()
- •10.7. Импорт внешних фильмов и изображений
- •10.7.2. Импорт внешних фильмов при помощи функций loadMovie() и loadMovieNum()
- •10.7.3. Импорт изображений
- •10.7.4. Импорт фильмов и изображений при помощи класса MovieClipLoader
- •10.7.5. Создание предзагрузчиков
- •10.7.6. Кэширование swf-фильмов
- •10.7.7. Изменение глубины основной временной диаграммы
- •10.7.8. Доступ из одного фильма к объектам другого
- •10.7.9. Обобщенные библиотеки
- •10.8. Имена экземпляров клипов
- •10.9. Ссылки на клипы
- •10.9.1. Свойство _lockroot
- •10.9.2. Определение пути к клипу
- •10.9.3. Инструмент Insert Target Path
- •10.10. Система координат клипов
- •10.10.1. Свойство _x и _y
- •10.10.2. Пересчет координат из одной системы в другую
- •10.10.3. Масштаб осей
- •10.10.4. Размер клипа
- •10.10.5. Границы клипа
- •10.10.6. Поворот системы координат
- •10.11. Прозрачность и видимость клипа
- •10.11.1. Свойство _alpha
- •10.11.2. Свойство _visible
- •10.12. Перемещаемые клипы. Метод startDrag()
- •10.12.1. Свойство _droptarget
- •10.13. Коллизии клипов. Метод hitTest()
- •10.13.1. Определение пересечения двух клипов
- •10.13.2. Определение принадлежности точки к клипу
- •10.13.3. Определение коллизии клипов с использованием поточечного перебора
- •10.14. Управление временной диаграммой
- •10.14.1. Начало и остановка проигрывания клипа
- •10.14.2. Переход на новый кадр
- •10.14.3. Определение номера проигрываемого кадра
- •10.15. Программные маски
- •10.16. Удаление экземпляров клипов и фильмов
- •10.16.1. Удаление экземпляров. Метод removeMovieClip()
- •10.16.2. Выгрузка содержимого экземпляров. Метод unloadMovie()
- •10.16.3. Выгрузка фильмов
- •10.17. События
- •10.17.1. Создание обработчиков событий в стиле Flash 5
- •10.17.2. Событие смены кадров (onEnterFrame)
- •10.17.3. Событие загрузки клипа (onLoad)
- •10.17.4. Событие выгрузки клипа (onUnload)
- •10.17.5. Событие поступления данных (onData)
- •10.17.6. События мыши (onMouseDown, onMouseUp, onMouseMove)
- •10.17.7. События клавиатуры (onKeyDown, onKeyUp)
- •10.17.8. «Кнопочные» события
- •10.17.9. События фокуса (onSetFocus, onKillFocus)
- •10.18. Программное рисование
- •10.18.1. Рисование прямыми отрезками
- •10.18.2. Рисование фрагментами парабол
- •10.18.3. Однородная заливка
- •10.18.4. Градиентная заливка
- •10.18.5. Удаление программной графики
- •10.19. Управление цветом клипов. Класс Color
- •10.19.1. Цветовые модели
- •10.19.2. Задание формулы цвета
- •10.19.3. Задание цвета клипа. Метод setRGB()
- •10.19.4. Цветовые трансформации. Метод setTransform()
- •Проект 10: Рисование 3D-объектов
- •Глава 11. Кнопки
- •11.1. Создание кнопок
- •11.2. Сходства и различия кнопок и клипов
- •11.3. События кнопок
- •11.3.1. Особенности событий кнопок
- •11.3.2. События кнопок в стиле Flash 5
- •11.4. Режим элемента меню
- •11.5. Вид указателя мыши
- •11.6. Отключение кнопок
- •11.7. Управление кнопками при помощи клавиатуры
- •11.7.1. Динамическое наведение фокуса
- •11.7.2. Свойство _focusrect
- •11.7.3. События onSetFocus и onKillFocus
- •11.7.4. Задание маршрута клавиатурного обхода
- •11.7.5. Особенности клавиатурного обхода и программного фокуса в случае клипов
- •11.8. Клипы как кнопки
- •Проект 11: Факел
- •Глава 12. Работа с мышью и клавиатурой
- •12.1. Работа с мышью
- •12.1.1. Определение координат указателя мыши
- •12.1.2. События мыши
- •12.1.3. Скрытие указателя мыши
- •12.1.4. Правая клавиша мыши
- •12.1.5. Определение выхода указателя мыши за пределы окна плейера
- •12.2. Контекстное меню
- •12.2.1. Настройка контекстного меню. Класс ContextMenu
- •12.2.2. Введение в контекстное меню собственных команд
- •12.3. Работа с клавиатурой
- •12.3.1. Особенности событий клавиатуры
- •12.3.2. События onKeyDown и onKeyUp
- •12.3.3. Определение кода нажатой клавиши. Метод getCode()
- •12.3.4. Определение кода введенного символа. Метод getAscii()
- •12.3.5. Проверка нажатия клавиши. Метод isDown()
- •12.3.6. Проверка активности специальных режимов. Метод isToggled()
- •Проект 12: Эластики
- •Глава 13. Работа с текстом
- •13.1. Создание текстовых полей
- •13.1.1. Создание текстовых полей при помощи инструмента Text
- •13.1.2. Переменная поля
- •13.1.3. Динамическое создание текстовых полей
- •13.2. Удаление текстовых полей
- •13.3. Текстовые поля как визуальные объекты
- •13.4. Задание и извлечение текста поля
- •13.5. Настройка текстового поля
- •13.5.1. Управление размером поля
- •13.5.2. Рамка и задний фон
- •13.5.3. Поля однострочные и многострочные
- •13.5.4. Ограничение на количество символов
- •13.5.5. Поле паролей
- •13.5.6. Ограничение на вводимые символы
- •13.5.7. Выделение текста поля
- •13.6. Настройка стиля текста. Класс TextFormat
- •13.6.1. Задание гарнитуры
- •13.6.2. Размер шрифта
- •13.6.3. Цвет шрифта
- •13.6.4. Начертание шрифта
- •13.6.5. Выключка
- •13.6.6. Подчеркнутый шрифт
- •13.6.7. Гиперссылки
- •13.6.8. Форматирование текста
- •13.6.9. Определение размерных параметров текста
- •13.7. Работа со шрифтами
- •13.7.1. Шрифты системные и встроенные
- •13.7.2. Ненаправленные гарнитуры
- •13.7.3. Особенности встраивания шрифтов
- •13.7.4. Встраивание в фильм целого шрифта
- •13.7.5. Встраивание глифов отдельных символов и последовательностей символов
- •13.7.6. Проблема читабельности при отображении мелкого текста
- •13.8. Событие onChanged
- •13.9. Прокрутка текстовых полей
- •13.10. Работа с фокусом
- •13.11. Форматирование текста при помощи HTML
- •13.11.5. Тег <FONT> ... </FONT>
- •13.11.10. Тег <TEXTFORMAT> ... <TEXTFORMAT>
- •13.11.11. Тег <SPAN> ... </SPAN>
- •13.11.13. Автоматическое удаление пробелов. Свойство condenseWhite
- •13.12. Форматирование текста с использованием каскадных таблиц стиля (CSS)
- •13.12.1. Основные положения технологии CSS
- •13.12.2. Создание объекта таблиц стиля
- •13.12.3. Применение объекта стиля к текстовому полю
- •13.12.4. Элементы CSS, поддерживаемые Flash-плейером
- •13.13. Работа с выделением. Объект Selection
- •13.13.1. Управление фокусом поля. Методы getFocus() и setFocus()
- •13.13.2. Событие изменения фокуса (onSetFocus)
- •13.13.4. Определение и задание положения курсора ввода
- •13.13.5. Динамическое задание выделения. Метод setSelection()
- •13.13.6. Динамическая замена выделенного текста. Метод replaceSel()
- •13.14. Работа со статичным текстом. Объект TextSnapshot
- •13.14.1. Создание объектов класса TextSnapshot
- •13.14.2. Считывание текста статичных полей
- •13.14.3. Поиск строки в статичном тексте
- •13.14.4. Программное выделение статичного текста
- •13.14.5. Определение ближайшего к точке символа статичного текста
- •13.15. Копирование текста в буфер обмена
- •13.16. Поддержка многоязычности. Панель Strings
- •Проект 13: Текстовые эффекты
- •Глава 14. Время и дата
- •14.1. Основные понятия теории измерения времени
- •14.2. Компьютерное время
- •14.3. Класс Date
- •14.3.1. Создание объектов класса Date
- •14.3.2. Методы класса Date
- •14.4. Определение времени, прошедшего с начала проигрывания фильма
- •Проект 14: Программные часы
- •Глава 15. Работа со звуком
- •15.1. Основные понятия теории цифрового звука
- •15.1.1. Частота дискретизации
- •15.1.2. Разрядность выборок
- •15.1.3. Количество каналов
- •15.1.4. Алгоритмы компрессии
- •15.1.5. Форматы хранения
- •15.2. Событийный (event) и потоковый (stream) звук
- •15.3. Операции со звуком без использования программирования
- •15.4. Создание объектов класса Sound
- •15.5. Динамическое присоединение звука. Метод attachSound()
- •15.6. Импортирование внешних МР3-файлов
- •15.6.1. Метод loadSound()
- •15.6.2. Отслеживание окончания загрузки. Событие onLoad
- •15.6.3. Создание предзагрузчиков для импортируемых звуков
- •15.7. Управление воспроизведением звуков
- •15.7.1. Запуск воспроизведения. Метод start()
- •15.7.3. Событие onSoundComplete
- •15.8. Свойства position и duration
- •15.9. Управление параметрами воспроизведения
- •15.9.1. Громкость звука
- •15.9.2. Баланс
- •15.9.3. Детальное управление стереозвучанием. Метод setTransform()
- •15.10. Чтение ID3-тегов МР3-звуков
- •Проект 15: МР3-плейер
- •Глава 16. Взаимодействие с локальным окружением
- •16.1. Взаимодействие с импортированными фильмами
- •16.2. Взаимодействие с плейером
- •16.2.1. Определение версии и типа плейера
- •16.2.2. Режимы масштабирования
- •16.2.3. Типы выравнивания
- •16.2.4. Определение размеров фильма и величины окна плейера
- •16.2.5. Событие onResize
- •16.2.6. Цвет фона
- •16.2.7. Качество отображения
- •16.2.8. Панель небезопасных настроек плейера
- •16.3. Дополнительные возможности автономного плейера
- •16.3.1. Проекторы
- •16.3.2. Функция fscommandf()
- •16.4. Взаимодействие между фильмами, проигрываемыми разными плейерами
- •16.4.1. Создание кода отправки данных
- •16.4.2. Создание кода получения данных
- •16.4.3. Пример использования класса LocalConnection
- •16.5. Взаимодействие с браузером
- •16.5.1. Теги <EMBED> и <OBJECT>
- •16.5.2. Передача данных из HTML-окружения при загрузке фильма
- •16.5.3. Решение проблемы кнопок навигации браузера
- •16.5.4. Передача команд браузеру. Функция getURL()
- •16.5.5. Взаимодействие с JavaScript при помощи функции fscommand()
- •16.5.6. Управление SWF-фильмом посредством JavaScript
- •16.5.7. Определение наличия в системе Flash-плейера нужной версии
- •16.6. Взаимодействие со средой разработки
- •16.6.1. Настройка панели Actions
- •16.6.2. Объект CustomActions
- •16.6.3. Взаимодействие с JSFL
- •16.7. Взаимодействие со средствами чтения с экрана
- •16.8. Получение информации об использующемся аппаратном и программном обеспечении
- •16.9. Сохранение данных на диске
- •16.9.1. Создание объектов SharedObject
- •16.9.2. Чтение данных из объектов SharedObject
- •16.9.3. Удаление sol-файлов
- •16.9.4. Серверные объекты SharedObject
- •16.9.5. Решение проблемы выделения цветом посещенных ссылок
- •16.10. Взаимодействие с принтером
- •16.10.1. Функции печати
- •16.10.2. Класс PrintJob
- •Проект 16: Создаем свой инструмент
- •Глава 17. Обмен текстовыми данными с сервером
- •17.1. Принципы сетевой безопасности Flash MX 2004
- •17.1.1. Правила определения идентичности доменов
- •17.1.2. Требование идентичности протоколов
- •17.1.3. Снятие ограничений на доступ к содержимому фильма
- •17.1.4. Снятие ограничений на доступ к внешним данным
- •17.1.5. Преодоление ограничений для сокетов
- •17.1.6. Создание приложений, отвечающих принципам безопасности
- •17.2. Загрузка текстовых данных с сервера
- •17.2.1. Создание файла сданными
- •17.2.2. Функция loadVariables()
- •17.2.3. Класс LoadVars
- •17.3. Взаимодействие с серверным скриптом
- •17.3.1. Запрос с выводом результата в браузере
- •17.3.2. Запрос с отправкой результата в фильм
- •17.3.3. Задание заголовков запроса
- •17.4. Работа с сокетами
- •17.4.1. Класс XMLSocket
- •17.4.2. Создание сокета-сервера
- •17.5. Работа с XML
- •17.5.1. Введение в ХМL
- •17.5.2. Объектная модель XML. DOM
- •17.5.3. Преобразование XML-текста в дерево объектов DOM
- •17.5.4. Обход дерева DOM
- •17.5.5. Создание и модификация XML-документа
- •17.5.6. Обмен XML-данными с сервером
- •Проект 17: Создаем сетевую игру
- •Дополнительные главы
- •Глава 18. Обмен с сервером сложными данными
- •Глава 19. Компоненты
- •Глава 20. Полезные мелочи
//При возникновении сбоя создаем текстовое поле и выводим в него об этом
//сообщение
listener.onLoadError = function():Void { clip.createTextField("error", 0, 50, 50, 0, 0); clip-error.autoSize = clip.error.border=true; clip.error.text = "Анимация не может быть загружена";
};
//По завершении загрузки первого кадра нужно сделать клип с анимацией
//невидимым, а также остановить его дальнейшую прокрутку listener.onLoadInit = function{):Void {
clip._visible = false; clip.stop();
}
//При загрузке очередной порции данных меняем длину шкалы прелоадера,
//а также обновляем значения в полях рrос и time
listener.onLoadProgress = function(clip:MovieClip, l_b:Number, t_b:Number): Void {
var percent:Number = l_b/t_b;
preloader.proc.text = Math.floor(percent*1000)/10; preloader.polosa._xscale = percent*100;
preloader.time.text = Math.round((1-percent)*(getTimerО-timer) / percent / 6000) /10; };
//При завершении загрузки удаляем предзагрузчик и ненужные более объекты.
//Затем делаем клип clip видимым и начинаем его прокрутку listener.onLoadComplete = function():Void {
preloader.swapDepths(1000), preloader.removeMovieClip(); delete loader, delete listener, delete timer; clip._visible=true, clip.play();
};
Огромное преимущество дают внешние прелоадеры при создании сайтов, так как позволяют существенно уменьшить объем скачиваемой информации. Дело в том, что обычно Flash-сайт образован значительным числом компонентов, каждый из которых подгружается индивидуально по мере необходимости. Если применять пред загрузчики внутренние, то для каждого компонента придется закачать прелоадер индивидуально. Если же используются предзагрузчики внешние, то соответствующий клип будет достаточно загрузить единожды.
Делая вывод, можно сказать, что внешние предзагрузчики гораздо лучше внутренних. Кстати, среди встроенных компонентов Flash MX 2004 имеются простейший внешний предзагрузчик и шкала загрузки — Loader и ProgressBar. Особенности их применения мы обсудим в главе, посвященной компонентам.
Заканчивая разговор о создании предзагрузчиков, упомянем еще о двух инструментах, предназначенных для реализации прелоадеров. Это глобальные свойства _framesloaded (количество загруженных кадров) и _totalframes (полное число кадров в фильме). Соответственно, чтобы определить, какая часть фильма уже подгрузилась, нужно поделить величину _framesloaded на значение
_totalframes.
На практике прелоадеры при помощи свойств _framesloaded и _totalframes создаются исключительно редко. Это связано с тем, что обновляться такой предзагрузчик будет лишь по полному завершению загрузки кадра. Естественно, что это может быть приемлемо лишь в том редком случае, когда в фильме очень много кадров и информация по ним распределена достаточно равномерно. Скорее, данные свойства имеют историческое значение (во Flash 5 они применялись довольно активно, так как тогда метод getBytesLoaded() возвращал вес загруженных кадров, а не число реально подкачанных байтов). Правда, _totalframes иногда применяется в коде, управляющем навигацией по временной шкале — о таком ее использовании мы поговорим в разделе 10,14.
10.7.6. Кэширование swf-фильмов
Широко использующимся в сети способом повышения производительности является сохранение на жестком диске пользователя загруженных ранее страниц па случай их повторного запроса. Этот
метод называется кэшированием, и его поддерживают все современные браузеры. Кэшируются все элементы, встроенные в страницу, в том числе и swf-фильмы. Более того, кэшированию подвергаются даже фильмы, закачанные автономным плейером или плейером среды тестирования Flash, а также фильмы, загруженные посредством функции loadMovie(). В этом можно убедиться двумя способами. Во-первых, можно обратиться к директории, я которой хранятся кэшированные файлы (в русифицированной Windows их принято называть временными файлами Интернета — Temporary Internet Files). В Windows 2000 путь к этой директории имеет приблизительно следую-
щий вид: C:\Documenls and Settings\user\Local Settings\Temporary Internet Files. Во-вторых, можно сравнить время, которое требуется на то, чтобы была проведена первая и последующие загрузки фильма. Повторный импорт фильма потребует несопоставимо меньше времени.
То, что swf-фильмы кэшируются, очень хорошо. Это означает, что если в вашем проекте один элемент загружается несколько раз, то существенного времени потребует лишь его первая закачка. Повторный же импорт будет осуществлен почти моментально.
Однако у кэширования есть и негативная сторона, связанная с отладкой. Например, представьте, что вы создаете предзагрузчик. Чтобы его тестировать, вы закачиваете некоторый swf-файл на сервер. Запустив фильм в первый раз, вы обнаруживаете ошибки и исправляете их. Однако проверить, корректно ли стал работать предзагрузчик, у вас не получится, так как реальная загрузка осуществляться не будет. Плейер просто возьмет копию фильма из папки Temporary Internet Files. Как же в такой ситуации провести отладку? Можно, конечно, менять имя фильма на сервере, но этот способ неэффективен. Более технично использовать один из следующих подходов;
•удалять копию фильма из папки Temporary Internet Files. Подход хороший, если загружается немного фильмов;
•воспользоваться тем, что URL может содержать придаток сданными (метод GET), причем один URL, но с разными данными воспринимается как разные ссылки. Следовательно, присоединяя к адресующему фильм URL случайное число, можно заставить плейер осуществлять загрузку из сети даже тогда, когда в кэше имеется копия фильма. Важное условие успешности описанного подхода следующее: ссылка на swf-файл должна быть абсолютной, а не относительной. Например:
this.createEmptyMovieClip("clip", 0); clip.loadMovie("http://www.mysite.ru/film.swf?"+Math.random());
Данный подход лучше предыдущего, так как он подходит для предотвращения кэширования на машине пользователя (это может быть необходимо, если фильм обновляется довольно часто).
Бороться с кэшированием фильмов, встроенных в HTML-страницу, также несложно. Для этого можно к URL, адресующему фильм, присоединять случайное число (посредством JavaScript). Также можно использовать серверный скрипт, который будет исполнять роль посредника. Наиболее же простой способ избежать кэширования заключается в создании следующего заголовка:
<НЕАD>
<МЕТА HTTP-EQUIV="PRAGMA" CONTENT="NO-CACHE"> </HEAD>
10.7.7. Изменение глубины основной временной диаграммы
Мы уже не раз отмечали, что не существует особых различий между основной временной диаграммой и клипами. Следовательно, должно иметься прямое сходство между виртуальными слоями клипов и уровнями. Так, главная временная диаграмма обладает, как и любой клип, глубиной. Ее значение можно прочитать, используя метод getDepth(), и переопределить при помощи метода swapDepths():
trace(_root.getDepth()); |
// Выводит: -16384 |
_root.swapDepths(1000); |
// Пробуем изменить глубину _root |
||
trace(_root.getDepth()); |
// Выводит: |
1000 (глубина была успешно изменена) |
|
trace(_root); |
// |
Выводит: |
_level0 (изменение глубины не |
|
// |
повлекло |
изменения уровня) |
Проанализировав приведенный код, можно сделать два важных вывода:
•Основная временная диаграмма загруженного первым фильма располагается на глубине, соответствующей максимально возможному ее значению в случае клипов. Как вы помните, у них глубина -16384 зарезервирована и никогда не занимается элементами внутренней структуры клипа. Самый нижний из объектов размещается на глубине -16383.
•Уровень, занимаемый фильмом, и глубина его основной временной диаграммы прямо никак не связаны.
Интересно, имеет ли глубина основной временной диаграммы хоть какое-то функциональное значение. Вполне вероятно, что это лишь рудимент, доказывающий ее тесное родство с клипами. Если это действительно так, то глубины основных временных диаграмм двух проигрываемых одновременно фильмов должны быть одинаковы. Чтобы это проверить, создадим новый документ и на его первом кадре наберем:
trace(_root.getDepth());
Затем опубликуем новый фильм на Рабочий Стол, назвав 1 .swf.
Далее создадим еще один документ и на его первом кадре наберем:
loadMovieNum("1.swf", 1);
Чтобы при тестировании данного фильма файл 1.swf попал в его область видимости, сохраняем соответствующий ему fla-файл на Рабочем Столе. Нажимаем <Ctrl> + <Enter>. В панели Output при этом появляется -16383. Пробуем заменить уровень, на который подгружается 1.swf, на 100-й. При этом в Output выводится число -16284.
Итак, оказывается, что уровень и глубина взаимозависимы. Более того, можно даже вывести однозначную формулу, связывающую глубину основной временной диаграммы с соответствующим ей уровнем: depths=-16384+level. Но почему тогда при изменении глубины не модифицируется уровень, по которому адресуется фильм (см. пример выше)?
А ответить на этот вопрос очень просто, предположив, что реально никаких уровней не существует. Имеются глубины, на которых действительно располагаются фильмы. Эти глубины полностью аналогичны виртуальным слоям обычных клипов. Их можно прочитать и даже изменить. Уровни же — это лишь удобная форма для именования проигрываемых в плейере фильмов и задания параметров для функций и методов семейства loadMovie (действительно, если бы отсчет велся от - 16384, работать с ними было бы гораздо сложнее). Итак _lеvel0 — это имя загруженного первым фильма, а не указатель на глубину, на которой он находится. Фильм с таким именем может располагаться и на миллионной глубине, отображаясь выше всех остальных фильмов.
Если наши предположения действительно справедливы, то изменение глубины основной временной диаграммы должно приводить к переменам в порядке отображения проигрываемых в плейере фильмов. Чтобы это проверить, создадим два фильма, имеющих различное графическое содержимое. В первый из них добавим кнопку but и наберем на том же кадре следующий код:
but.onRelease=function():Void { _root.swapDepths(1000);
}
Тут же расположим код, подгружающий второй фильм в первый:
loadMovieNum("2.swf", 1);
Сохраняем фильмы n одной директории как 1.swf и 2.swf. Далее запускаем проигрывание файла 1.swf. При этом в плейере содержимое второго фильма отобразится выше содержимого первого. После нажатия кнопки but объекты первого фильма окажутся выше объектов второго.
Таким образом, используя метод swapDepths(), можно менять порядок отображения фильмов в плейере точно так же, как и вложенных клипов. А это означает, что клипы являются по своей сути как бы маленькими swf-фильмами (точнее, что нет принципиальных отличий между объектами, которые мы называем клипами, и структурами, стоящими за термином «фильм»). В качестве дополнительного доказательства такого утверждения можно привести тот факт, что при помощи loadMovie() любой swf-файл может быть подгружен в клип.
Кстати, можно обменять два фильма глубинами, используя их имена. Для этого нужно использовать второй вариант синтаксиса метода swapDepths():
_level0.awapDepths(_level1);
Функции и методы семейства IoadMovie() не учитывают глубин фильмов. Поэтому запись loadMovieNum(«1.swf»,1) не всегда означает, что фильм будет помещен на глубину -16383. Если в плейере уже имелся фильм с именем _level1, то новый фильм просто заместит его. А располагаться он при этом может на любой глубине.
10.7.8. Доступ из одного фильма к объектам другого
Обратиться к одному из элементов внутренней структуры фильма из другого фильма ничуть не сложнее, чем прочитать из одного клипа свойство другого. Для этого достаточно указать уровень, на котором располагается фильм, и «адрес» нужного элемента. Например;
_level1.mov.start Drag(); // Клип mov фильма level1 становится протаскиваемым
Аналогичным образом можно прочитать значение переменной или даже вызвать функцию кода другого фильма.
Особенностью ActionScript является то, что объект Global существует в единственном экземпляре для всех подгруженных фильмов. Это означает, что глобальные переменные будут доступны для любого исполнимого кода любого фильма, а не только для кода того из них, директивами сценариев которого они были созданы.
Так как свойствами объекта Global являются конструкторы всех встроенных классов, то, сохранив в прототипе одного из них метод или свойство, вы сделаете данный элемент наследуемым всеми объектами соответствующего класса во всех проигрывающихся в плейере фильмах. Это означает, что, если один и тот же кол должен использоваться несколькими фильмами, достаточно сохранить его только водном, включив содержащую его функцию в цепочку наследования нужного класса (или сделав ее глобальной).
Так как уровни — это просто имена подгруженных в плейер фильмов, то создать переменную на незаполненном уровне невозможно. Например:
_level1.prop = "Привет"; trace(_level1.prop); // Выводит: undefined
Все, что мы говорили выше о доступе одного из проигрываемых в плейере фильмов к элементам другого, по умолчанию справедливо лишь в том случае, если оба фильма были получены с одного домена или же соответствующий фильму, к которому происходит обращение, swf-файл хранится локально. Если же фильмы были закачаны с разных доменов, то начинают работать ограничения, связанные с политикой сетевой безопасности Flash MX 2004.