Список лучших игроков

В большинство Flash-игр играют через Internet. Это значительно увеличивает число желающих сыграть. Самый простой способ воспользоваться преимуществами коллективной игры - это включить в игру список лучших игроков. Сервер будет вести счет очков, набранных участвующими в игре людьми, а они, в свою очередь, смогут увидеть лучшие результаты.
Однако добавить к игре список лучших игроков - не простая задача. Навыков только Flash-программирования будет недостаточно, потому что подобная программа должна быть написана таким образом, чтобы Internet-сервер смог получить, обработать и упорядочить заработанные очки.

Как работает список лучших игроков

Список победителей можно создать разными способами. Один из них -написать программу на основе языка Java с использованием XML Socket, с которой ваша Flash-игра могла бы поддерживать связь через объект XML. Другой вариант - разместить на связанной с сервером Web-странице вашу Flash-игру, которая посылает и получает количество очков с помощью языка сценариев на основе Java.
Наиболее простым способом вести учет очков будет использование языка Perl, ориентированного на работу в сети. Именно об этом и пойдет сейчас речь. Значит, вам придется познакомиться с языком Perl и работой CGI-сценариев.
Сценарии CGI (Common Gateway Interface - общий шлюзовой интерфейс) - это программы, которые выполняются на стороне сервера по запросу клиента. Язык Perl (Practical Extraction and Report Language) - это язык программирования, схожий с языком ActionScript, но предназначенный для использования на Web-серверах. Обычно программы, написанные на языке Perl, имеют расширение .pi или .cgi, а не .html, которое характерно для простой Web-страницы. Когда пользователь просматривает программу, написанную на языке Perl, то, в отличие от текста программы, сохраненной как HTML-страница, ее команды воспринимаются сервером как команды языка Perl. Если Perl-программа получает какой-либо результат, он отсылается обратно на Web-сервер или, как в данном случае, передается Flash-ролику.

Язык Perl достаточно сложен, и его рассмотрению стоит посвятить отдельную книгу (и не одну). В действительности о Perl написано гораздо больше книг, чем о Rash. Если вы хотите получить более подробную информацию о Perl, идите в ближайший книжный магазин и выбирайте подходящую книгу.

В данном примере для составления списка лучших игроков используются две программы на языке Perl. Первая - Submitscore.pl - отвечает за получение нового результата игры из ролика Flash. Вторая программа, Get-scores, pi, отбирает 10 лучших результатов и отсылает обратно во Flash-ролик. Каждой из этих программ необходимо иметь доступ к небольшой базе данных, где будут храниться заработанные игроками очки. CGI-программы обычно обращаются к базе данных, находящейся на сервере, например СУБЛ MySQL. Однако в нашем примере используется более простой вариант - обычный текстовый файл. Каждая строка этого текстового файла содержит отличный от других строк результат игры. Каждая запись включает: имя игрока, набранные им очки и время, когда данный результат был занесен в базу данных. Имя игрока и его очки заносятся в программу Submitscore.pl из Flash-ролика, а время программа вводит самостоятельно.
Программа Getscores.pl просматривает текстовый файл с результатами игры и выполняет две функции. Во-первых, она анализирует каждую запись и переписывает текстовый файл, убирая результаты, слишком долго находящиеся в базе данных. Это позволяет периодически обновлять список лучших игроков. Во-вторых, программа Getscores.pl размещает десять лучших результатов по порядку и затем отправляет их обратно во Flash-ролик. Именно этот список демонстрируется игрокам.

Мне нравится идея исключать из базы данных устаревшие записи. Это не дает возможность одному или нескольким рекордам лидировать в списке лучших результатов на протяжении нескольких лет. Кроме того, подобный подход побуждает хороших игроков вновь и вновь возвращаться к игре, чтобы снова побороться за право называться победителем.

Программы на языке Perl

Исходные файлы: Submitscore.pl, Getscores.pl

Программы Submitscore.pl и Getscores.pl, написанны на Perl. Чтобы эти программы работали на вашем сервере, понадобится загрузить эти файлы и отладить их. Если вы прежде этим не занимались, проконсультируйтесь с администратором сети или Internet-провайдером. Учтите, что не все серверы могут выполнять программы, созданные с помощью CGI. Если вы пользуетесь услугами дешевого хостинга или ваш провайдер предоставляет бесплатное Web-пространство для своих пользователей, будьте готовы к тому, что CGI-программы не будут работать на вашем сервере.
Хотя этот раздел не называется "Руководство по программированию на Perl для начинающих", ниже приведены листинги программ Submitscore.pl и Getscores.pl с краткими пояснениями, как работает каждая из их частей. Если вы незнакомы с программами, использующими стандарт CGI, обратитесь за разъяснениями к людям, сведущим в этой области.
Комментарий в языке Perl начинаются с символа #. Программа Submit-score.pl начинается с комментария, который на самом деле используется Web-сервером для определения адреса программы, интерпретирующей сценарии Perl. Нижеприведенный путь широко распространен и должен работать на вашем сервере. Если возникнут какие-либо проблемы, свяжитесь с вашим Internet-провайдером.

#!/usr/bin/perl

Первая строка текста самой программы начинается с отправки результативных данных обратно во Flash-ролик. Именно за это отвечает выражение Content-type: text /html, за которым следуют две пустые строки. Первая строка любого файла, посылаемого с Web-сервера, сообщает браузеру (в данном случае Flash-ролику) о типе передаваемых данных. В этом примере передаваемые данные - обычный текст.

# Устанавливаем метку для текстового документа, отсылаемого
# назад браузеру.
print "Content-type: text/html\n\n";

Затем данные из Flash-ролика передаются в программу, где для их временного хранения используется переменная $get_data:

# Получаем переданные данные.
$get_data = $ENV{'QUERY_STRING'};

Когда данные пересылаются через сеть, они обычно кодируются таким образом, чтобы не допустить их некорректную передачу. Буквы не кодируются в отличие от пробелов, которые передаются как знак "+", и небуквенно-цифровых символов, передающихся как символьные последовательности, например %ОА. Чтобы раскодировать данные, необходимо дополнить программу следующими строками:

# Преобразуем закодированные символы.
$get_data =~ s/%([\dA-Fa-f][\dA-Fa-f])/pack ("С",hex($l))/eg; #get_data =~ tr/\+/ /;

Далее нужно получить текущее время, измеренное на Unix-сервере в секундах, прошедших с 01.01.1970. Эти данные вы будете использовать как то время, когда был получен результат. Лучше оперировать именно этим показателем, а не временем, которое показывает сам Flash-ролик: игроки могут находиться в разных часовых поясах, а у некоторых из них может быть неправильно установлено время на их компьютерах.

# Вносим в базу данных время, оказываемое сервером, в секундах. $server_time = time();

Следующий шаг - организация цикла, который берет последовательность символов, хранящуюся в переменной $get_data, и разделяет ее на части. Например, такая последовательность имеет вид: name=Gary&score=967. Она разделяется на два элемента: до и после символа &, а затем каждый из этих элементов подразделяется еще на два - на ключ и на значение, теперь уже благодаря символу =.

# Обрабатываем полученные данные и создаем массив.
@split_data = split("&",$get_data);
foreach $data_item (@split_data)
{
($key, $value) = split("=",$data_item)
$info{$key} = Svalue;
}

Текстовой базой данных, где хранятся лучшие результаты, служит файл Highscore.txt. Чтобы запустить этот файл, загрузите его и настройте таким образом, чтобы с помощью программ на языке Perl можно было вводить в него информацию. Для этого предназначены следующие кодовые строки:

# Определяем имя файла, который будет содержать базу данных.
$filename = "highscore.txt";
# Открываем базу данных.
open(OUTFILE, "»$filename") || exit;

После того как файл будет открыт, программа внесет в него единичные записи, содержащие набранные очки, имя игрока и время, например: 967&Gary&978887513.

# Вносим информацию в базу данных.
print OUTFILE "$info{'score'}&$info{'name'}&$server_time\n";

Программа Submitscore.pl заканчивает свою работу, закрывая текстовый файл и пересылая определенную информацию во Flash. В данном случае переменной resultText присваивается символьная строка ОК.

# Закрываем базу данных.
Close(OUTFILE);
# Подтверждаем ввод данных,
print "resultText=OK\n";
# Завершаем программу,
exit;

Программа Getscores.pl несколько сложнее, чем Submitscore.pl. В ее задачу входит просмотр базы данных, удаление устаревших записей и затем выдача списка десяти лучших результатов. Начало этой программы аналогично началу Submitscore.pl. Далее файл открывает базу данных и перебирает все ее записи с использованием переменной типа "массив" @score_text.

#!/usr/bin/perl
# Устанавливаем метку для текстового документа,
# получаемого на выходе.
print "Content-type: text/html\n\n";
# Указываем имя файла, содержащего базу данных.
$filename = "highscore.txt";
# Просматриваем записи базы данных,
open(DATABASE,$filename) || exit;
@score_text = ;
close(DATABASE);

Затем программа подсчитывает, какое время (в секундах на сервере) было ровно семь дней назад.

# Определяем время на сервере.
$server_time = time();
# Выясняем, как долго сохранять полученные результаты.
# (7 дней * 24 часа * 60 минут * 60 секунд)
$keep_time = 7*(24*60*60) ;

Теперь база данных открыта и готова для записи. Старый файл перезаписывается с учетом новых данных.

# Открываем базу данных для перезаписи.
open(DATABASE,">" . $filename) || exit;

Следующий цикл проверяет каждую запись и определяет, как давно она была внесена в базу данных. Если запись устарела, то она не переписывается в новый файл.

# Просматриваем каждую запись.
foreach $score_line (@score_text) {
# Получаем данные о набранных очках.
@score_item = split(/&/,$score_line);
# Определяем время занесения результата.
$score_time = $score_item[2];
# Если запись не устарела, переписываем ее в новый файл.
if ($score_time > ($server_time-$keep_time)) {
print DATABASE "$score_Iine";
# Закрываем базу данных. close(DATABASE);

Далее программа сортирует результаты игры. Так как в начале каждой строки базы данных содержатся набранные очки, именно по ним упорядочиваются записи, от лучшего результата игры к худшему.

# Упорядочиваем набранные очки.
@score_text = sort { $b <=> $а } @score_text;

Следующий цикл отбирает первые десять результатов и выдает их как выходные данные. Каждый элемент строки специальным образом форматируется. Эта строка выглядит, например, следующим образом: "l.Gary 967". После номера строки ставится точка. Затем идет имя игрока: если оно содержит меньше 18 символов, оставшееся место заполняется пробелами. Далее выводятся набранные игроком очки - они выравниваются по правому краю, и если число цифр меньше девяти, то свободные места с левой стороны также заполняются пробелами.

# Определяем число результатов,
# которые программа отошлет как выходные данные.
$num_scores = 10;
$score_count = 1;
# Просматриваем первые записи и отправляем данные,
print "highScoresText=";
foreach $score_line (@score_text) {
# Прочитываем записанные данные и создаем массив.
@split_data = split("&",$score_line);
# Выводим номер строки с точкой после него.
printf("%2i. ", $score_count);
# Выводим имя игрока, выравниваем по левому краю, оставшиеся
# свободные места до 18 символов заполняем пробелами,
printf("%-18s ",$split_data[l]);
# Выводим набранные очки, выравниваем по правому краю,
# оставшееся слева место до девяти символов заполняем
# пробелами.
printf("%9i\n",$split_data[0]); $score_count++;
if ($score_count > $num_scores) { last; } }
# Выходим из программы,
exit;

Если вы прежде программировали только на Flash и никогда раньше не сталкивались с Perl, вам будет достаточно сложно писать программы на этом языке. Можете не беспокоиться по этому поводу, потому что обычно подобные проекты разрабатываются двумя программистами совместно: один из них владеет языком Flash, другой - Perl. Если возможно, постарайтесь с кем-нибудь объединиться.

Демонстрация списка лучших игроков

Исходный файл: Highscores.fla

На Web-сайте надо разместить две программы, с помощью которых и будет формироваться список лучших игроков. Первая программа представляет собой демонстрационный ролик, показывающий, как набранные очки заносятся в базу данных и как они затем из нее извлекаются.
Кадр такого ролика, Highscores.fla, изображен на рис. 17.5. Область слева внизу позволяет вам ввести новый результат, а в области справа отображается список лучших игроков.

Рисунок 17.5 Ролик, отображающий список лучших игроков, позволяет проверить правильность работы программ, написанных вами на языке Perl

Имена игроков и очки выровнены по левому краю (Рис 17.5). Я использовал моноширинный шрифт (Courier). Если использовать другие шрифты, например Ariel, то будет не так просто выровнять столбцы в рамках одного текстового поля.

Все программные коды в файле Highscores.fla привязаны к двум кнопкам (см. рис. 17.5).
Часть "Добавить результат" отображает имя игрока и набранные им очки в текстовых окнах, содержимое которых может изменяться. Когда вы запускаете эту программу, вы можете ввести имя и набранные очки, а затем щелкнуть по кнопке Submit Score (Добавить результат). Ниже приведен текст программы, закрепленной за этой кнопкой.

on (press) {
// Путь к файлу
submitscore.pl. url = "submitscore.pl";
// Определяем объект LoadVars.
myLoadVars = new LoadVars();
myLoadVars.name = name;
myLoadVars.score = score;
// Пересылаем данные.
returnedVars = new LoadVars();
myLoadVars.sendAndLoad(url,returnedVars,"GET" resultText = "Sending...");
// Задаем результат.
returnedVars.onLoad = function!) { resultText = "Done."}}

Вы уже использовали объект LoadVars в главе 12 для создания игр-викторин. Тогда вы не отсылали никаких данных серверу, вам требовался лишь текстовый файл. В этом примере вы вызываете программу, написанную на Perl, чтобы отсылать данные на сервер. Элемент GET В конце команды SendAndLoad сообщает Rash, что данные будут передаваться с помощью протокола GET. Это один из вариантов, второй - использование протокола POST. Названные протоколы соотносятся с двумя способами передачи данных из форм, которые используются HTML-страницами. Данные, которые мы передаем, - это два свойства объекта myLoadVars: name и score. Когда передача завершается, выполняется функция, определяемая методом onLoad. В нашем случае она выводит сообщение в текстовое поле resultText. К кнопке Get Scores (Обновить список) также прикреплена небольшая программа, но здесь не требуется пересылать значения каких-либо переменных:

on (press) {
// Указываем путь к программе getscores.pl.
url = "getscore.pl";
// Запрашиваем данные.
myLoadVars = new LoadVars();
myLoadVars.load(url);
highscoresText = "Getting High Scores...";
/ / Данные получены.
myLoadVars.onLoad = function() {
highscoresText = myLoadVars.highscoresText;
}

Текст, выдаваемый программой Getscores.pl на выходе, начинается с high-ScoresText=. За счет этого оставшаяся часть текста помешается в одноименную переменную. Функция onLoad получает это значение из объекта myLoadVars и помешает в текстовое поле с соответствующим именем. Как только заканчивается пересылка текста, он выводится на экран.

Добавление списка лучших игроков в игру

Исходный файл: Whackafoxwithscores.fla

Как пример еще одной игры с использованием списка лучших игроков приведем файл Whackafoxwithscores.fla. Это все та же игра "Поймай лису", которую мы рассматривали в главе 8, но здесь она содержит еще и список лучших игроков.
К этой игре достаточно легко добавить список лучших результатов, потому что она подразделяется на три части. Сцена "Начало игры" была изменена таким образом, что уже при загрузке игры выводится список лучших игроков. Поэтому к стандартной команде stop О в начале первого кадра этой сцены вам понадобится добавить те коды, которые будут отвечать за отображение списка лучших игроков:

// Указываем путь к программе getscores.pl.
url = "getscore.pl";
// Запрашиваем данные. loadVariables (url,this);
// Выводим на экран информацию о том, что по кнопке щелкнули.
highscoresText = "Getting High Scores...";
stop() ;

Текстовое поле под названием highscoresText добавляется посередине экрана (рис. 17.6).

Рисунок 17.6 Теперь при загрузке игры "Поймай лису" на экран выводится список лучших игроков


В конце игры, в сцене "Игра закончена", появляется клип с несколькими текстовыми полями и кнопкой Submit Score. При этом очки, набранные в игре, должна подсчитывать и выводить сама программа. Сама по себе игра управляется действиями, которые относятся к клипу "actions" сцены "Игра". Поэтому переменная score привязана именно к этому клипу, а не к основной временной шкале. После добавления к тексту программы строки _root.score = score в основной временной шкале также появляется переменная score, которой присваивается число набранных очков. Когда приходит очередь сцены "Игра Закончена", первый кадр помешает набранные очки в клип "Добавление результатов". Одновременно удаляется предыдущее значение переменной name этого клипа.

sendscores.name = "" ;
sendscores.score = score;
stop();

На рис. 17.7 показан кадр из сцены "Игра закончена". Здесь вы можете видеть, что клип "Добавление результатов" содержит набранные игроком очки, текстовое поле, куда игрок должен ввести свое имя, и кнопку Submit Score.
Игрок вводит свое имя в первое текстовое поле, в то время как другое поле уже содержит набранные им очки, и он не может изменить результат. После этого игрок может щелкнуть по кнопке Submit Score, которая запустит следующую программу:

on (press) {
// Указываем путь к программе submitscore.pl.
url = "submitscore.pl";
// Отправляем значения переменных:
// "score" - счет игры,
// "name" - имя игрока.
loadVariables(url,this,"GET");
// Меняем кадр, чтобы по кнопке Submit нельзя было
// щелкнуть дважды,
play();
}

Рисунок 17.7 Последний кадр обновленной игры "Поймай лису" дает игроку возможность записать результат своей игры Набранные очки пересылаются серверу таким же образом, как и в демонстрационном файле Highscores.fla. Отличие заключается в добавлении команды play(), благодаря которой происходит смена кадра. Второй кадр аналогичен первому, за исключением того, что здесь отсутствует кнопка Submit Score. Это сделано для того, чтобы игрок не мог несколько раз щелкать по кнопке, вводя таким образом несколько результатов.

Сложности применения списка лучших игроков

Многие считают, что игра только выигрывает от добавления списка лучших результатов. Однако применение этого списка может вызвать определенные затруднения, которые вы, скорее всего, не приняли во внимание.
Давая игрокам возможность вводить в качестве их имен любую информацию, вы тем самым бесплатно предоставляете им на своем Web-сайте пространство для деятельности. Конечно, большинство игроков введут свое имя или прозвище, но найдутся и те, которые воспользуются случаем написать что-нибудь нехорошее.
Почему бы не проверять Flash-игру или Perl-программу на наличие нецензурных выражений? Вы можете так и поступить, но это не решит проблему окончательно. Одни из игроков могут слегка изменить написание слов либо использовать между ними пробелы или тире, другие абсолютно нормальными словами скажут что-нибудь неприличное. Иначе говоря, совсем избежать неприятных ситуаций, скорее всего, не удастся.
Большие, профессионально сделанные сайты обычно требуют, чтобы перед тем, как сохранить результаты своей игры, пользователь зарегистрировался. Однако система учета очков зарегистрированных игроков гораздо сложнее примеров, которые описываются в этой главе. Для ее внедрения потребуется готовая система баз данных со встроенной системой зашиты.
Другая проблема - это жульничество. Как только будут объявлены лучшие результаты, игроки станут искать способы смошенничать. И это достаточно легко сделать. Можно использовать различные методы - от остановки игры в решающий момент, чтобы перевести дух и найти решение в сложившейся ситуации до использования "взламывающих" программ, которые могут считывать информацию из памяти компьютера игрока и записывать новые данные. Таким образом, 42 балла можно легко превратить в 42 миллиона баллов. Однако, если эти сложности вас не пугают и вы все-таки решили включить в игру список лучших игроков, не ограничивайте свои возможности только описанными здесь приемами. Попробуйте использовать другие языки программирования. Например, РНР - очень популярный язык, схожий с языком Perl. С равным успехом CGI-программы можно создавать на основе более старых и известных языков, таких как С и C++.