Уроки Flash: Создание информера

Источник: demiart
MOHCTEP

Добрый всем час, дорогие друзья!
В этом уроке я расскажу вам как, на основе xml данных, сделать собственный Flash информер. Урок готовился и тестировался в 8 версии Flash.
Для обеспечения работы проекта, необходимо иметь входные данные, которые, затем, нужно обработать и показать. И самый лучший вариант - это прямые ссылки на данные в формате xml, их Flash расщелкает, как орешки.
В качестве примера могут служить rss странички. Допустим портал новостей.
Кстати и подобную информацию вы сможете таким же образом обработать и выставить и, тогда, ваш информер превратится в ньюсридер.
Для этого урока мы воспользуемся прямыми ссылками, любезно предоставляемыми погодным проектом Gismeteo.ru .
Обязательно сделайте в информере ссылку на сайт Gismeteo.ru. Это является условием использования информации.
К сожалению, я не смогу представить вам рабочий вариант информера, из-за ограничений политики безопасности, но локально он у вас работать будет, после «прописки» его в «песочнице».

Подготовка

В процессе выбора между текстовым и мнемоническим вариантами информера, мною был создан этакий мутант с сознательным нарушением дизайнерских канонов. Перенасыщенность информацией обусловлена моим желанием показать вам оба варианта, «в одном флаконе».

Я создал новый однокадровый документ с 4 слоями размерами 200х150 и расположил элементы и объекты, как на рисунке.

Создание информера. *


На слое "as" расположен код
На слое "pics" расположены 2 мнемонических клипа, показывающие: первый - состояние облачности и осадков, а второй - направление ветра.
На слое "bg" расположена верхняя подложка под названием города
На слое "txt" расположены текстовые поля, их инстансы вы видите на рисунке, а также кнопка со ссылкой на сайт Gismeteo.ru.
Клип-флюгер имеет инстанс «wind» и состоит из 2 слоев. На нижнем слое нарисован компас, а в верхнем расположен клип со стрелкой направленной вверх, имеющей точку регистрации посередине и инстанс «arrow».
Погодный клип с инстансом «weather», тоже имеет 2 слоя. В нижнем слое расположен клип с картинками облачности и инстансом «cloudiness», в верхнем - клип с картинками осадков и инстансом «precipitation».Разобраться в структуре этого «бутерброда», вы сможете здесь. Полупрозрачные бирюзовые области - кликабельны.

Теперь нам осталось, на главной сцене проекта выделить кадр на слое "as" и нажать «F9», вызвав панель «Actions for Frame».

Программирование

Если вы рассмотрите исходную xml страничку, полученную с Gismeteo.ru, по, выбранной вами, ссылке, то вы увидите, что основную информацию содержат 4 «потомка» с одинаковой структурой, но разными значениями узлов. Каждый потомок информирует о состоянии погоды в определенное время суток.
При успешной загрузке xml, в процедуре парсинга, мы, для каждого состояния погоды, создадим свой объект, «приделаем» ему уникальные погодные свойства и запомним его в массиве.
Потом, поочередно будем брать данные из объектов и показывать их в информере.
Поскольку данные на Gismeteo.ru обновляются 4 раза в сутки, мы будем ежечасно перезагружать их, для авто обновления.



CODE

/*******Инстансы динамических текстовых полей********
city - Название города
today - Прогнозируемые дата и время суток
phenomena - Облачность и осадки
termo - Температура воздуха
pressure - Атмосферное давление
relwet - Относительная влажность
windspeed - Скорость ветра
*********Свойства объекта-хранителя текущего состояния погоды*********
o.today - Дата
o.daytime - время суток
o.cloudsNum - Индекс облачности
o.cloudsStr - Облачность
o.precipitationNum - Индекс осадков
o.precipitationStr - осадки
o.power - возможность осадков
o.pressureMin - Минимальное давление
o.pressureMax - Максимальное давление
o.thermoMin - Минимальная температура
o.thermoMax - Максимальная температура
o.wind_dir - Индекс направления ветра
o.windMin - Мин. скорость ветра
o.windMax - Макс. скорость ветра
o.relwetMin - Мин. относительная влажность
o.relwetMax - Макс. относительная влажность
********************************************/
//Направление ветра
var wind_dir:Array = ['северный', 'северо-восточный', 'восточный', 'юго-восточный', 'южный', 'юго-западный', 'западный', 'северо-западный'];
//Облачность
var clouds:Array = ['Ясно', 'Малооблачно', 'Облачно', 'Пасмурно'];
//Осадки
var precipitation:Array = ['', '', '', '', 'дождь', 'ливень', 'снег', 'снег', 'гроза', '', 'без осадков'];
//Время суток
var timeday:Array = ['ночью', 'утром', 'днем', 'вечером'];
//День недели
var weekday:Array = ['', 'Воскресение', 'Понедельник', 'Вторник', 'Среда', 'Четверг', 'Пятница', 'Суббота'];
//Месяц
var months:Array = ['', 'января', 'февраля', 'марта', 'апреля', 'мая', 'июня', 'июля', 'августа', 'сентября', 'октября', 'ноября', 'декабря'];
//В этот массив сохраним объекты с состояниями погоды
var current:Array;
//Кукиш, хранящий время последнего обращения к XML страничке
var lso:SharedObject;
//Таймер
var id:Number;
//Время задержки, на просмотр состояния погоды
var delay:Number = 10000;
//Кол-во доступных состояний погоды
var total:Number;
// Индекс выбранного состояния
var select:Number;
//Объект, для загрузки и хранения данных о погоде в XML формате.
var meteo:XML = new XML();
meteo.ignoreWhite = true;
//Адрес XML страницы
var meteo_adress:String="http://informer.gismeteo.ru/xml/27612_1.xml";//Moskva
/******************ПРОЦЕДУРЫ***************************/
//Обработка нажатия на ссылку "Гизметео". Условия ©.
link.onRelease = function() {
getURL('http://informer.gismeteo.ru/#graph","_blank');
};
/*Функция загрузки XML данных и перезаписи времени начала загрузки.
С нее стартуем и ее-же будем вызывать ежечасно, чтоб обновлять данные*/
function renew() {
lso = SharedObject.getLocal('meteo');
lso.timesaved = new Date().getTime();
lso.flush();
meteo.load(meteo_adress);

}
//При успешном окончании загрузки XML документа, командуем парсинг. Аргументом будет его блок с данными
meteo.onLoad = function(success:Boolean) {
success ? parse(this.firstChild.firstChild.firstChild) : null;
return;
};
/*Расшифровка аргумента. В процессе создаем нужное кол-во объектов, наделяем их "погодными" свойствами
и запоминаем в массиве. Потом командуем циклический показ состояний погоды*/
function parse(arg:XML) {
//Обнуление массива, таймера и индексов
current = [];
clearInterval(id);
total = select=0;
//Расшифровка названия города
var na = arg.attributes.sname.split('%');
var addr:String = '';
var lnum;
for (i=0; i<na.length; i++) {
 lnum = Number('0x'+na[i])<128 ? Number('0x'+na[i]) : Number('0x'+na[i])+848;
 addr += String.fromCharCode(lnum);
}
//Показываем название города
sity.autoSize = 'center';
sity.text = addr;
/********Получаем погоду********/
//Кол-во погодных записей
total = arg.childNodes.length;
for (var i = 0; i<total; i++) {
 //Для каждой записи, создаем свой объект и начинаем наделять его свойствами
 var o:Object = new Object();
 var curW:XML = arg.childNodes[i];
 //строка: текущие день недели, дата и время суток
 var str:String = weekday[curW.attributes.weekday]+' '+curW.attributes.day+' '+months[curW.attributes.month];
 str += ' - '+timeday[curW.attributes.tod];
 o.today = str;
 o.daytime = Number(curW.attributes.tod);
 /*Данные о погоде на текущее время суток (атрибутами). Индексы:
 0 - атмосферные явления (облачность, осадки, гроза)
 1 - атмосферное давление
 2 - температура воздуха
 3 - сила и направление ветра
 4 - относительная влажность воздуха
 5 - термо комфорт
 ***********************************/
 //атмосферные явления
 var aw:XML = curW.childNodes[0];
 o.cloudsNum = Number(aw.attributes.cloudiness);
 o.cloudsStr = clouds[aw.attributes.cloudiness];
 o.precipitationNum = Number(aw.attributes.precipitation);
 o.precipitationStr = precipitation[aw.attributes.precipitation];
 //Фразеологическая эвристика :)
 switch (o.precipitationNum) {
 case 8 ://Гроза
  o.power = aw.attributes.spower == '0' ? 'Возможна ' : 'Ожидается ';
  break;
 case 10 ://без осадков
  o.power = aw.attributes.rpower == '0' ? 'Возможно ' : 'Ожидается ';
  break;
 default ://дождь, снег
  o.power = aw.attributes.rpower == '0' ? 'Возможен ' : 'Ожидается ';
 }
 //атмосферное давление
 aw = curW.childNodes[1];
 o.pressureMin = aw.attributes.min;
 o.pressureMax = aw.attributes.max;
 //температура воздуха
 aw = curW.childNodes[2];
 o.thermoMin = Number(aw.attributes.min)>0?'+'+aw.attributes.min:aw.attributes.min;
 o.thermoMax = Number(aw.attributes.max)>0?'+'+aw.attributes.max:aw.attributes.max;
 //сила и направление ветра
 aw = curW.childNodes[3];
 o.wind_dir = Number(aw.attributes.direction);
 o.windMin = aw.attributes.min;
 o.windMax = aw.attributes.max;
 //относительная влажность воздуха
 aw = curW.childNodes[4];
 o.relwetMin = aw.attributes.min;
 o.relwetMax = aw.attributes.max;
 current.push(o);
}
//А теперь - шоу!
showInfo();
}
/*Процедура, вызывает себя, с интервалом времени = "delay".
При каждом вызове, циклически обрабатывается следующий объект из массива "current".
Данные, взятые из текущего объекта, формируются и распехиваются по текст.полям.
Кроме этого, модифицируем состояние мнемонических клипов.
После каждого полного прохода цикла, сравнивается текущее время с записанным в кукиш.
Если разница меньше часа, то повторяем цикл показа, иначе - перезагружаем XML документ.*/
function showInfo() {
clearInterval(id);
var o:Object = current[select];
today.text = o.today;
phenomena.text = o.cloudsStr+'.\n'+o.power+o.precipitationStr;
termo.text = o.thermoMin+'.. '+o.thermoMax+' C';
pressure.text = 'Давление '+o.pressureMin+'.. '+o.pressureMax+' мм. рт. ст.';
relwet.text = 'Влажность '+o.relwetMin+'% - '+o.relwetMax+'%.';
windspeed.text = o.windMin+' - '+o.windMax+' м/сек.';
wind.arrow._rotation=o.wind_dir*45;
weather.cloudiness.gotoAndStop(o.cloudsNum+1);
weather.precipitation.gotoAndStop(o.precipitationNum);
select++;
select %= total;
if (!select) {
 var timedif:Number = Math.floor((new Date().getTime()-lso.timesaved)/1000);
 timedif>3600 ? renew() : null;
}
id = setInterval(showInfo, delay);
}
//Запуск программы
renew();


Страница сайта http://test.interface.ru
Оригинал находится по адресу http://test.interface.ru/home.asp?artId=10307