Отправляет email-рассылки с помощью сервиса Sendsay
  Все выпуски  

Программирование игр на Flash/Flex XML-файлы: Загрузка и обработка


Здравствуйте, уважаемые читатели!

В этом выпуске (статье) рассмотрим некоторые возможности работы с XML-файлами в языке ActionScript. В предыдущем выпуске мы использовали файл такого формата для представления справочной информации об игре Ним. Замечу мимоходом, что загрузка текстовых (в том числе XML), графических, и других информационных структур позволяет уменьшить объем Флеш-ролика, передаваемого по запросу пользователя.


XML (eXtensible Markup Language )- это язык структурированного описания информации. Первоначально этот язык разрабатывался  как универсальное гибкое средство хранения и передачи произвольных информационных структур. Современная версия языка ActionScript содержит набор функций (методов), предназначенных для исключительно удобной обработки файлов и структур данного формата. Не представляют ни малейшей трудности такие стандартные операции, как поиск и чтение содержимого любых узлов и атрибутов, загрузка файлов с сервера, модификация содержимого. Все это благодаря тому, что плеер и среда программирования поддерживают так называемую спецификацию ECMAScript for XML.

Структура XML-файла должна соответствовать определенным требованиям. Пример правильно оформленного текста на языке XML - текст файла stoneRules.xml помощи для игры Ним:

<?xml version="1.0" encoding="koi8-r"?>
<rules>
<rule txt="Правила">
Ним - это игра для двух игроков, каждый из которых по очереди делает ход. Перед игроками располагается поле с камнями. В данном проекте правила игры таковы:
Камни раскладываются в три ряда.
Начальное количество камней в этих рядах выбирает пользователь.
Игроки по очереди забирают камни из любого ряда.
Нельзя за один ход брать камни из двух, и более рядов.
За один ход игрок должен взять хотя бы один камень.
Выигрывает тот, кто возьмет последний камень.
</rule>
<rule txt="Программа">
В начале игры установите на трех элементах управления числа, соответствующие количеству камней в каждом ряду. Нажмите на кнопку.<br/>
Если желаете сделать первый ход, снимите пометку с флажка "Ход компьютера".<br/>
При своем ходе устанавливайте число снимаемых Вами камней в одном из элементов управления и нажимайте на кнопку.<br/>
При ходе компьютера нажимайте на кнопку.
</rule>
<rule txt="Результат">
При определенной комбинации камней и при Вашем ходе в начале партии у Вас появляется шанс выиграть. Если Вы этот шанс не используете, выиграет компьютер.
</rule>
<rule txt="Игра"/>
</rules>

Как видите, корневым тегом в данном тексте является <rules>, внутри три раздела, содержащиеся в зоне действия тегов <rule>. Назначение каждого из этих тегов определяется атрибутом txt. Схема документа представлена на рисунке:

 

 

 

 

На рисунке изображено не три, а четыре раздела rule. Назначение четвертого (пустого) тега с атрибутом txt= "Игра" будет рассмотрено позднее, а сейчас рассмотрим проблему загрузки файла и способ ее решения.

Загрузка xml-файла

Рассмотрим содержание класса:

// Класс GetKbFromFile - загрузка текстового и xml-файла.
package {
import flash.events.*;
import flash.net.*;
import flash.utils.*;
public class GetKbFromFile{
private var __parent:Stones; // Связь с родительским модулем
public function GetKbFromFile(pa:Stones) {
__parent = pa
}
public function ask(what:String):void { // Метод вызывается родителем. Параметр what - имя (URL) запрашиваемого файла
var loader:URLLoader=new URLLoader();
loader.dataFormat = URLLoaderDataFormat.TEXT;
loader.addEventListener(Event.COMPLETE, handleComplete); //Слушатель события "Завершение загрузки"
loader.load( new URLRequest(what)); // Запрос к серверу
}
private function handleComplete( event:Event ):void {
__parent.answer(event.target.data); // Загрузка завершена. Родительский модуль получает результат.
// для этого он должен иметь метод answer.
}
}
}

Основа алгоритма загрузки: Модуль (родительский), которому нужен текст соответствующего файла выполняет следующие действия:

  1. Создает экземпляр класса GetKbFromFile: _getKb = new GetKbFromFile(this);          
  2. Вызывает метод ask, передавая в качестве параметра ссылку на загружаемый файл. Эта ссылка в общем случае может быть Интернет-адресом (URL): _getKb.ask("stoneRules.xml"); //чтение файла помощи с сервера. Формат файла XML

После завершения загрузки вызывается метод handleComplete данного класса. Этот метод является слушателем события "завершение загрузки". Его функция предельно проста: отправить результат. Для этого он вызывает метод answer родительского модуля

Такая упрощенная схема взаимодействия модулей хорошо работает только при условии достаточно хорошего качества связи клиента и сервера. Для повышения надежности работы Вашей программы можно использовать таймер, и с его помощью установить время ожидания. Остальное, полагаю, понятно: если время ожидания истекло, методу answer главного модуля нужно передать, например, такую строку (пустой тег): <Error/>. Главный модуль, получив эту информацию, может вывести на экран сообщение о невозможности продолжать работу с данным сервером.

Обработка XML

В игровой программе Knim, рассмотренной в предыдущих выпусках, текст xml-файла помещен в объект rules, Главного модуля. Заметьте, что в результате проведенных экспериментов выяснилось, что помещать его в другой модуль не следует.

Ниже следует фрагмент программы, обрабатывающий содержимое этого объекта.

var xx:uint = 5;
var yy:uint = _area.height-45;
var npart:uint =0;
for each(var element:XML in rules.elements()){ //чтение файла помощи и создание кнопок для его демонстрации
                    _texts.push(element.text()); // Для смешанных узлов нужно вызывать этот метод. Текст записывается в массив.
                    var txt:String = element.@txt;    // Читаем значение атрибута txt.
                    var bt:Button = new Button(); // Создаем новую кнопку
                    bt.width = 95;            // и задаем ее параметры
                    bt.label = txt;    // Надпись на кнопке = значению прочитанного атрибута txt
                    bt.x=xx;
                    bt.y = _area.y+ _area.height;
                    bt.name = "b"+npart.toString(); // Имя объекта (кнопки) будет использоваться в обработчике события "нажатие"
                    bt.addEventListener(MouseEvent.CLICK,btclick); // Назначаем обработчик события "нажатие"
                    xx += bt.width + 2;    // Позиция следующей кнопки по оси Х
                    _panel.addChild(bt); // Добавляем кнопку в область видимости.
                    npart++;
 }

Цикл for each(...) перебирает все элементы xml-объекта rules. Получаемая информация используется так: значения атрибутов тегов txt помещаются на кнопках. Посмотрите, насколько просто и изящно получается эта информация (значение атрибута) в соответствии со спецификацией ECMAScript for XML! Достаточно написать: что-то = element.@txt; Ставим перед именем атрибута амперсанд - и дело сделано. Чтобы оценить красоту этого и других подобных соглашений достаточно немного поработать со средствами разбора (парсерами) xml-текстов в других программных системах, например, в РНР, или Delpi.

Столь же просто получаем и текст элемента. Для этого можно использовать разные (и очень простые) средства, но наиболее универсальным является применяемый в данной программе метод text());

В нашем примере получаемые текстовые фрагменты помещаются в массив и используются для демонстрации соответствующих разделов помощи.

В заключение можно отметить, что возможности ActionScript по обработке xml-текстов далеко не исчерпываются рассмотренными выше. Как и обычно, в данной рассылке (серии статей) я описываю только то, что необходимо при решении текущих задач.

 

 


В избранное