Данный пост, фактически, является дополнением к довольно старому посту «ActionScript 2.0: таблица рекордов». Отличие в том, что flash-клиент будет на ActionScript 3.0, а не на ActionScript 2.0. В остальном отличий нет (хотя некоторые вещи я сейчас сделал бы по-другому). Поэтому я не буду повторно объяснять некоторые моменты, а сразу перейду к главному...
Код php я оставил прежним...
Код php-скрипта для PHP 5 (test2.php):
<?php
/*
проверяем, пришли ли переменные, необходимые для работы скрипта
*/
if(isset($_POST['id']) && isset($_POST['q']) && isset($_POST['key'])){
/*
адрес текстового файла, в котором будем хранить информацию
*/
$filename = "test2.txt";
/*
$skey - секретный ключ
*/
$skey = "Natasha";
/*
обрабатываем полученные переменные
*/
$user = trim($_POST['id']);
$q = trim($_POST['q']);
$h = trim($_POST['key']);
/*
если данные истинны и не равны пустоте, то запускаем работу скрипта
*/
if(md5(strtolower($user.$q.$skey))==$h && strlen($user) && strlen($q)){
$arr = array();
$arr = unserialize(file_get_contents($filename));
if($q > $arr[$user]){
$arr[$user] = $q;
}
$str = serialize($arr);
file_put_contents($filename,$str);
echo '&q='.$str;
}
}
или
Код php-скрипта для PHP 4 (test2.php):
<?php
/*
проверяем, пришли ли переменные, необходимые для работы скрипта
*/
if(isset($_POST['id']) && isset($_POST['q']) && isset($_POST['key'])){
/*
адрес текстового файла, в котором будем хранить информацию
*/
$filename = "test2.txt";
/*
$skey - секретный ключ
*/
$skey = "Natasha";
/*
обрабатываем полученные переменные
*/
$user = trim($_POST['id']);
$q = trim($_POST['q']);
$h = trim($_POST['key']);
/*
если данные истинны и не равны пустоте, то запускаем работу скрипта
*/
if(md5(strtolower($user.$q.$skey))==$h && strlen($user) && strlen($q)){
$arr = array();
$fr = fopen($filename,"r");
$arr = unserialize(fread($fr,filesize($filename)));
fclose($fr);
if($q > $arr[$user]){
$arr[$user] = $q;
}
$str = serialize($arr);
$fw = fopen($filename,"w");
fwrite($fw,$str);
fclose($fw);
echo 'q='.$str;
}
}
Этот php-сценарий сохранён у меня на сервере как test2.php. Особое внимание обращаю на то, что PHP-файл надо сохранять в кодировке UTF-8.
Теперь переходим к flash-клиенту. Он организован точно также, как и в уже упоминавшемся уроке. Те же мувики, текстовые поля и кнопки. И имена у них прежние. Различается только код...
Код ActionScript 3.0:
/*
Импортируем необходимые классы.
*/
import flash.display.Sprite;
import flash.display.Stage;
import flash.text.TextField;
import flash.text.TextFormat;
import flash.text.TextFormatAlign;
import flash.net.*;
import flash.events.*;
import org.sepy.io.Serializer;
import com.adobe.crypto.MD5;
/*
Объявляет необходимые переменные и присваиваем им значения.
*/
var arr:Array = new Array();// это массив, в котором будут хранится данные для таблицы рекордов
var page:Number = 0;// текущая страница таблицы рекордов
/*
Путь к директории, в которой лежит php-скрипт.
*/
var strUrl:String = "http://edapskov.ru/applications/";
/*
Секретный ключ.
*/
var skey:String = "Natasha";
/*
Ограничения на символы, которые можно ввести через поля ввода.
Вам, скорее всего, это не потребуется, так как данные не будут браться из полей ввода.
Впрочем, фильтрация и проверка корректности данных - штука полезная :-)
*/
id.restrict = "0-9a-zA-Z";
score.restrict = "0-9";
/*
Функция сортировки многомерного массива.
*/
function sortScore(a, b)
{
var aN:int = parseInt(a[1],10);
var bN:int = parseInt(b[1],10);
if (aN > bN)
{
return -1;
}
else if (aN < bN)
{
return 1;
}
else
{
return 0;
}
}
/*
Функция, которая генерирует окно с глобальной таблицей рекордов.
*/
function tabl()
{
/*
Создаём необходимые переменные и присваиваем им значение.
*/
var sw:int = stage.stageWidth;
var sh:int = stage.stageHeight;
var pages:int = Math.floor(arr.length / 10) - 1;
/*
Форматирование текста.
*/
var format:TextFormat = new TextFormat();
format.size = 14;
format.font = "Verdana";
format.color = 0x999999;
format.bold = true;
format.align = TextFormatAlign.CENTER;
/*
Создаём спрайт, который будет для таблицы рекордов контейнером.
*/
var cont:Sprite = new Sprite();
cont.name = "tableofrecords";
addChild(cont);
/*
Создаём спрайт, который будет для таблицы рекордов фоном и будет перехватывать мышиные события.
*/
var fon:Sprite = new Sprite();
fon.graphics.beginFill(0xffffff,1);
fon.graphics.moveTo(0, 0);
fon.graphics.lineTo(sw, 0);
fon.graphics.lineTo(sw, sh);
fon.graphics.lineTo(0, sw);
fon.graphics.endFill();
cont.addChild(fon);
fon.mouseEnabled = true;
/*
Создаём контейнер для таблицы рекордов.
*/
var tfCont:Sprite = new Sprite();
cont.addChild(tfCont);
/*
Генерируем таблицу рекордов.
*/
var max:int = (page + 1) * 10;
var n:int = page * 10;
for (var i:int = 0; n + i < arr.length && n + i < max; i++)
{
for (var j:int = 0; j < arr[n + i].length; j++)
{
/*
Столбец с указанием места игрока.
*/
var num:TextField = new TextField();
tfCont.addChild(num);
num.x = 0;
num.y = i * 20;
num.width = sw / 6;
num.height = 20;
num.border = true;
num.borderColor = 0xcccccc;
num.selectable = false;
num.defaultTextFormat = format;
num.text = " - " + (n + i + 1) + " - ";
/*
Столбец с указанием уникального идентификатора игрока.
*/
var user:TextField = new TextField();
tfCont.addChild(user);
user.x = sw / 6;
user.y = i * 20;
user.width = sw / 6 * 2;
user.height = 20;
user.border = true;
user.borderColor = 0xcccccc;
user.selectable = false;
user.defaultTextFormat = format;
user.text = arr[n + i][0];
/*
Столбец с результатами игрока.
*/
var score:TextField = new TextField();
tfCont.addChild(score);
score.x = sw / 6 * 3;
score.y = i * 20;
score.width = sw / 6;
score.height = 20;
score.border = true;
score.borderColor = 0xcccccc;
score.selectable = false;
score.defaultTextFormat = format;
score.text = arr[n + i][1];
}
}
/*
Навигация по страницам глобальной таблицы рекордов.
*/
var nav:TextField = new TextField();
tfCont.addChild(nav);
nav.x = 0;
nav.y = 10 * 20 + 20;
nav.width = sw / 6 * 4;
nav.height = 20;
nav.selectable = false;
nav.defaultTextFormat = format;
nav.addEventListener(TextEvent.LINK, linkText);
if (Math.ceil(arr.length / 10) > 1)
{
if (page == 0)
{
nav.htmlText = '<a href="event:exit">Exit</a> | <a href="event:next">Next >></a>';
}
else if (page > 0 && page < pages)
{
nav.htmlText = '<a href="event:prev"><< Prev</a> | <a href="event:exit">Exit</a> | <a href="event:next">Next >></a>';
}
else
{
nav.htmlText = '<a href="event:prev"><< Prev</a> | <a href="event:exit">Exit</a>';
}
}
else
{
nav.htmlText = '<a href="event:exit">| Exit |</a>';
}
/*
Позиционируем контейнер с глобальной таблицей рекордов.
*/
tfCont.x = sw / 6;
tfCont.y = (sh - (12 * 20)) / 2 - 20;
}
/*
Функция, которая отвечает за навигацию по многостраничной таблице рекордов и закрывает окно с таблицей рекордов.
*/
function linkText(event:TextEvent):void
{
var str:String = event.text;
if (str == "prev")
{
page--;
tabl();
}
else if (str == "next")
{
page++;
tabl();
}
else
{
removeChild(getChildByName("tableofrecords"));
}
}
/*
Функция, которая запускается после успешного получения ответа от сервера.
*/
function onComplete(event:Event)
{
animLoad.visible = false;
/*
Очищаем поле вывода ошибок.
*/
mes.text = "";
/*
Очищаем массив, в котором хранится таблица рекордов.
*/
arr.length = 0;
/*
По умолчанию показываем первую страницу глобальной таблицы рекордов.
*/
page = 0;
/*
Принимаем данные от php-скрипта и переводим их в формат, удобный для работы в ActionScript.
*/
var obj:Object = Serializer.unserialize(event.target.data.q);
/*
Можно, конечно, работать и с ассоциативным массивом, но лично мне привычнее иметь дело с индексированным массивом.
Поэтому я ассоциативный массив превращаю в индексированный.
*/
for (var name in obj)
{
arr.push([name, obj[name]]);
}
/*
Сортирую массив по результатам игроков (я исхожу из того, что результат игрока является числовым значение).
Если результат игрока представлен строкой, то данную сортировку пропускаем.
*/
arr.sort(sortScore);
/*
Запускаем функцию, генерирующую глобальную таблицу рекордов.
*/
tabl();
}
/*
Функции, которые будут вызваны в случае возникновения ошибок при работе с сервером.
*/
function onSecurityErrorHandler(event:SecurityErrorEvent):void
{
mes.text = "SecurityErrorEvent";
}
function onIoErrorHandler(event:IOErrorEvent):void
{
mes.text = "IOErrorEvent";
}
/*
Отправляем данные и готовимся к получению ответа от сервера.
*/
btn.addEventListener(MouseEvent.CLICK, btnFunc);
function btnFunc(event:MouseEvent):void
{
animLoad.visible = true;
var url:URLRequest = new URLRequest(strUrl + "test2.php");
url.method = URLRequestMethod.POST;
var variables:URLVariables = new URLVariables();
variables.id = id.text;
variables.q = score.text;
variables.key = MD5.hash(String(variables.id + variables.q + skey).toLowerCase());
url.data = variables;
var loader:URLLoader = new URLLoader();
loader.dataFormat = URLLoaderDataFormat.VARIABLES;
loader.addEventListener(Event.COMPLETE, onComplete);
loader.addEventListener(SecurityErrorEvent.SECURITY_ERROR, onSecurityErrorHandler);
loader.addEventListener(IOErrorEvent.IO_ERROR, onIoErrorHandler);
loader.load(url);
}
/*
Делаем мувик-псевдопрелоадер невидимым.
Этот мувик будет видимым только тогда, когда идёт обмен данными между сервером и флеш-приложением.
*/
animLoad.visible = false;
animLoad.mouseEnabled = true;
Результат:
Скачать все исходники к данному посту (.fla под Adobe Flash CS 5 + PHP-скрипты + классы Serializer и MD5) можно здесь - скачать исходники.
Вот и всё :-)
ЗЫ: ошибки исправил ... я надеюсь :-)
Придётся всё переделывать:
1.) В php-скрипте сохранять не одну переменную $q, а сразу массив из переменной $q и времени (время можно получить с помощью функции time()).
2.) Изменения в AS-скрипте + сортировка уже именно по времени.