Программирование игр на 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.
}
}
}
Основа алгоритма загрузки: Модуль (родительский), которому нужен текст
соответствующего файла выполняет следующие действия:
Создает экземпляр класса GetKbFromFile:
_getKb = new GetKbFromFile(this);
Вызывает метод 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-текстов далеко не исчерпываются рассмотренными выше. Как и обычно, в данной
рассылке (серии статей) я описываю только то, что необходимо при решении
текущих задач.