Статьи

Введение в ByteArray

ByteArray — чрезвычайно мощный класс, который может использоваться для многих вещей, связанных с манипулированием данными, включая (но не ограничиваясь) сохранение игровых данных в сети, шифрование данных, сжатие данных и преобразование объекта BitmapData в файл PNG или JPG. В этом введении мы будем использовать класс ByteArray, чтобы взять собственный объект AS3 и закодировать его в строку, которую можно сохранить на сервере для последующего восстановления, а затем декодировать позже.

В предыдущих уроках мы видели, как использовать XML и JSON для кодирования данных в текстовом (строковом) формате. Тем не менее, и XML, и JSON разработаны для удобства чтения, и в результате они намного длиннее, чем нужно. Также может быть сложно преобразовать определенные типы объектов AS3 в любой формат. ByteArray имеет несколько действительно продвинутых функций, но для начала мы рассмотрим один простой: он позволяет легко превратить объект AS3 в строку.


Давайте посмотрим на конечный результат, к которому мы будем стремиться:

Когда вы вставляете закодированную строку ByteArray в TextField и нажимаете кнопку «Загрузить», она расшифровывает ее и показывает сохраненные в ней свойства объекта. Вы можете попробовать следующие закодированные ByteArrays; скопируйте их в TextField и нажмите кнопку «Загрузить», чтобы увидеть, о чем я говорю:

1
2
//This ByteArray will show my data (This is the default ByteArray loaded)
CgsBFW9jY3VwYXRpb24GB0NUTw93ZWJzaXRlBiFodHRwOi8vaWt0LmNvLmlkCW5hbWUGDVRhdWZpawE=
1
2
//This ByteArray will show my current thought
CgsBIWZvb2RfZm9yX3Rob3VnaHQGgnVJIGFtIHRoaW5raW5nIG9uIHNoYXJpbmcgdGhlIHRlY2huaXF1ZSBpIHVzZWQgdG8gbWFrZSBhIEZ1bGwgRmxhc2ggRHluYW1pYyBXZWJzaXRlIFNFTyBGcmllbmRseSBmb3IgbXkgbmV4dCBUdXRvcmlhbCBpbiBBY3RpdmVUdXRzKy4uLiA8dT5XaGF0IGRvIHlvdSB0aGluaz88L3U+IDxiPmlzIGl0IGEgZ29vZCBpZGVhPC9iPj8B
1
2
//This ByteArray will talk about Flash and SEO and my experience with them
CgsBEXF1ZXN0aW9uBoEDPGI+PHU+Q2FuIGEgZnVsbHkgZHluYW1pYyBGbGFzaCBXZWJzaXRlIGJlIFNFTyBmcmllbmRseTwvdT48L2I+Pz8NYW5zd2VyBoM/SXQgY2FuLCBoZXJlIGlzIHRoZSBwcm9vZiwgPGEgaHJlZj0naHR0cDovL3d3dy5nb29nbGUuY28uaWQvc2VhcmNoP3E9Zmxhc2grc2VvJmllPXV0Zi04Jm9lPXV0Zi04JmFxPXQnIHRhcmdldD0nX2JsYW5rJz5odHRwOi8vd3d3Lmdvb2dsZS5jby5pZC9zZWFyY2g/cT1mbGFzaCtzZW8maWU9dXRmLTgmb2U9dXRmLTgmYXE9dDwvYT4sIGlrdC5jby5pZCBpcyByYW5rZWQgIzYgb3ZlciB0aGVyZQE=

Создать новый проект ActionScript

В окне «Flash Builder»:

  1. Откройте Flash Builder 4
  2. Нажмите меню файлов
  3. Наведите на новый
  4. Нажмите ActionScript Project

Настройка проекта ActionScript

В окне «Новый проект ActionScript»:

  1. Введите ‘TUTORIAL_ByteArray’ в поле Имя проекта
  2. Пожалуйста, помните, где вы сохранили свой проект
  3. Нажмите кнопку «Готово»

Скопируйте Base64.as в каталог вашего проекта com.

Скопируйте файл Base64.as в каталог 'com'
  1. Создайте новый каталог ‘com’ внутри вашего исходного каталога.
  2. Загрузите файл Base64.as из исходной загрузки.
  3. Поместите файл во вновь созданный каталог ‘com’.

Base64.as пригодится позже. Это Стив Вебстер, который жил на сайте dynamicflash.com (он покинул сообщество Flash пару лет назад).


Импортировать все классы, используемые в этом проекте

В классе TUTORIAL_ByteArray (который является основным классом), пожалуйста, импортируйте следующие классы для этого урока:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
package
{
    import flash.display.Sprite;
    import flash.text.TextField;
    import flash.text.TextFieldType;
    import flash.text.TextFieldAutoSize;
    import flash.text.TextFormat;
    import flash.events.MouseEvent;
    import flash.utils.ByteArray;
    import com.Base64;
     
    public class TUTORIAL_ByteArray extends Sprite
    {
        public function TUTORIAL_ByteArray()
        {
             
        }
    }
}

Проследите сообщение «Hello World»

Добавьте следующий код в конструктор TUTORIAL_ByteArray для очень простого теста.

1
2
3
4
5
public function TUTORIAL_ByteArray()
{
    var _test:String = «Hello world!»;
    trace(_test);
}

Нажмите клавишу F11, чтобы запустить этот проект, вы должны получить сообщение в окне консоли.


Локальная переменная доступна только внутри созданной функции

Теперь давайте попробуем отследить сообщение внутри переменной _test , но на этот раз мы сделаем это из другой функции:

1
2
3
4
5
6
7
8
public function TUTORIAL_ByteArray()
{
    var _test:String = «Hello world!»;
    TestFunction();
}
private function TestFunction():void{
    trace(_test);
}

Нажмите CTRL + S, чтобы сохранить ваш проект. Обнаружена ошибка после сохранения вашего проекта; это потому, что переменная, которая была объявлена ​​внутри функции, не будет доступна для любой другой функции. Так что для этого случая нам нужно объявить переменную _test снаружи:

1
2
3
4
5
6
7
8
public function TUTORIAL_ByteArray()
{
    TestFunction();
}
private function TestFunction():void{
    trace(_test);
}
private var _test:String = «Hello world!»;
Закрытые переменные доступны для всех функций внутри одного класса

Создайте все частные переменные для этого проекта

Пожалуйста, добавьте следующие частные переменные для этого проекта:

01
02
03
04
05
06
07
08
09
10
11
12
public function TUTORIAL_ByteArray()
{
    TestFunction();
}
private function TestFunction():void{
    trace(_test);
}
private var _test:String = «Hello World!»;
private var _loadButton:TextField;
private var _inputField:TextField;
private var _testObject:Object;
private var _testByteArray:ByteArray;

Давайте создадим простой пользовательский интерфейс для этого проекта.

Простой пользовательский интерфейс

Теперь, когда нам нужно отобразить что-то в нашем проекте, нам нужно объявить размеры нашей сцены (Check Line 13).

Переименуйте нашу TestFunction в функцию InitUI и вставьте следующую строку кодов внутрь. Пожалуйста, прочтите объяснение, прокомментированное внутри кода.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
[SWF(width=»550″, height=»400″, frameRate=»60″, pageTitle=»Tutorial ByteArray»)]
public class TUTORIAL_ByteArray extends Sprite
{
    public function TUTORIAL_ByteArray()
    {
        InitUI();
    }
    private function InitUI():void{
        //Initialize our TextFields so that we can use them
        _loadButton = new TextField();
        _inputField = new TextField();
         
        //Give a defaultTextFormat for both of them (Tahoma at 11pt, colored 0x777777)
        _loadButton.defaultTextFormat = _inputField.defaultTextFormat = new TextFormat(«Tahoma», 11, 0x777777);
         
        //Give both of them a border
        _loadButton.border = _inputField.border = true;
         
        //Set the autosize for our Load Button , so that it will automatically shrink / grow to fit the text inside
        _loadButton.autoSize = TextFieldAutoSize.LEFT;
         
        //Set the selectable of our Load Button to false, so that user cannot select the text in it
        _loadButton.selectable = false;
         
        //Set the multiline and wordWrap of our Input Field to true, so that a long text will automatically wrapped to the next line
        _inputField.multiline = _inputField.wordWrap = true;
         
        //Enable user to type something into our Input Field, by setting this type property
        _inputField.type = TextFieldType.INPUT;
         
        //Put some text into Both of them
        _loadButton.text = «Load»;
        _inputField.text = «»;
         
        //Add both of them into stage, so that they are visible to our visitors
        addChild(_inputField);
        addChild(_loadButton);
         
        //Position our Input Field and make it bigger
        _inputField.x = 25;
        _inputField.y = 25;
        _inputField.width = 200;
        _inputField.height = 150;
         
        //There is a reason why i did this, so that the Load Button is located directly below our Input Field
        //So you can position the Input Field anywhere you like, as long as there is this code, the Load Button will stick below the Input Field
        _loadButton.y = _inputField.y + _inputField.height;
        _loadButton.x = _inputField.x;
    }

Нажмите F11, чтобы запустить этот проект и увидеть простой пользовательский интерфейс, который мы создали.


Введите в поле и нажмите кнопку загрузки

Пожалуйста, прочтите объяснение, прокомментированное внутри кода

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
    _loadButton.y = _inputField.y + _inputField.height;
    _loadButton.x = _inputField.x;
     
    //Add an Event Listener for our _loadButton, so whenever the user clicks this button,
    //Flash will call _loadButton_CLICK() Method
    _loadButton.addEventListener(MouseEvent.CLICK, _loadButton_CLICK, false, 0, true);
}
//This method will be called whenever user click the _loadButton
private function _loadButton_CLICK(Events:MouseEvent = null):void{
    //Get anything that the user input and save them into our _test variable
    _test = _inputField.text;
     
    //Trace the _test variable
    trace(«User input the following message : » + _test);
}

Нажмите F11, чтобы запустить этот проект; попробуйте _inputField что-нибудь в _inputField и затем нажмите кнопку _loadButton . Это самый основной метод получения переменной от нашего пользователя и сохранения ее в нашей закрытой переменной.


Мы наконец достигли наших самых важных шагов в этом проекте, но прежде чем мы продолжим, позвольте мне дать умственный стимул для мышления. В настоящее время в нашем проекте мы можем получить String и сохранить ее в нашей закрытой переменной. Но это только строка; как насчет того, чтобы я хотел, чтобы пользователь _inputField что-то внутри _inputField чтобы я мог получить объект из него? Что должен ввести пользователь? Ответ — «Кодированный Base64 ByteArray»


Выход из нашего ByteArray

На этот раз мы будем действовать медленно, так что вы поймете класс ByteArray и сможете создавать свои собственные манипуляции с данными и применять их к своим собственным проектам. Пожалуйста, прочтите объяснение, прокомментированное внутри кода:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
public function TUTORIAL_ByteArray()
{
    InitUI();
    CreateByteArray();
}
private function CreateByteArray():void{
    //Initialize our _testObject variable, so that we can populate many dynamic properties and store String data in it (we will load them later whenever user clicked the _loadButton)
    _testObject = new Object();
    _testObject.name = «Taufik»;
    _testObject.website = «<a href=’http://ikt.co.id’>http://ikt.co.id</a>»;
    _testObject.occupation = «CTO»;
     
    //Initialize our _byteArray variable, so that we can start converting object into a ByteArray
    _testByteArray = new ByteArray();
     
    //Convert the Object into Byte Array, This is how you do it, to convert an Object into a ByteArray, IT IS SIMPLE isnt it?
    _testByteArray.writeObject(_testObject);
     
    //Lets see if everything works properly
    trace(«Our first ByteArray created :: » + _testByteArray.toString());
}

Нажмите F11, чтобы запустить этот проект. Посмотрите, насколько это просто, этот ByteArray — чрезвычайно мощный класс, и все же он совсем не сложен. Мы взяли собственный объект AS3 и преобразовали его в формат сообщения действия .

Перед отправкой данных в наш PHP-скрипт с использованием метода GET мы должны преобразовать их в строку Base64. Это потому, что Base64 может переноситься XML (и HTML).


Base64 String представление наших байтовых данных

Пожалуйста, прочитайте объяснение, приведенное в коде.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
private function CreateByteArray():void{
    //Initialize our _testObject variable, so that we can populate many dynamic properties and store String data in it
    //(we will load them later whenever user clicks the _loadButton)
    _testObject = new Object();
    _testObject.name = «Taufik»;
    _testObject.website = «<a href=’http://ikt.co.id’>http://ikt.co.id</a>»;
    _testObject.occupation = «CTO»;
     
    //Initialize our _byteArray variable, so that we can start converting object into a ByteArray
    _testByteArray = new ByteArray();
     
    //Convert the Object into Byte Array, This is how you do it, to convert an Object into a ByteArray, IT IS SIMPLE isnt it?
    _testByteArray.writeObject(_testObject);
     
    //Encode the ByteArray into Base64 String (so that we can send them via PHP or copy the text to notepad), again IT IS VERY SIMPLE!
    var encoded:String = Base64.encodeByteArray(_testByteArray);
     
    //Put the encoded Base64 String into our _inputField (so that we can copy them into notepad)
    _inputField.text = encoded;
}

Нажмите F11, чтобы запустить этот проект. Если преобразование объекта в ByteArray является простым, преобразование значения Byte наших данных в строку Base64 является простым, благодаря Base64.as.


Преобразование строки Base64 в объект и отображение ее свойств и значений

Мы будем пытаться декодировать введенную строку Base64 в объект всякий раз, когда пользователь нажимает _loadButton , меняем нашу функцию _loadButton_CLICK . Пожалуйста, прочтите объяснение, прокомментированное внутри кода:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
private function _loadButton_CLICK(Events:MouseEvent = null):void{
    //We have to catch any Errors
    try{
        //We decode our encoded Base64 String into a ByteArray, so that we can retrieve our Object back
        var DecodedByteArray:ByteArray = Base64.decodeToByteArray(_inputField.text);
         
        //If converting an Object into ByteArray is simple, retrieving an Object from ByteArray is as simple as this
        var LoadedObject:Object = DecodedByteArray.readObject();
         
        //Prepare to output all properties and their values inside the LoadedObject
        var Output:String = «»;
        for (var VarName:String in LoadedObject){
            Output += VarName + » : » + LoadedObject[VarName] + «<br>»;
        }
         
        //Output them into our _inputField
        _inputField.htmlText = Output;
    }catch(err:Error){
        _inputField.text = «Please input an Encoded ByteArray into this TextField before clicking the ‘Load’ Button. Error message :: » + err.message;
    }
}

Нажмите F11, чтобы запустить этот проект. Мы получаем нашу закодированную строку Base64 нашего _testObject внутри нашего _inputField ; нажмите кнопку _loadButton чтобы увидеть, как наш проект конвертирует эту строку Base64 обратно и отображает все ее свойства и значения. Вы можете попробовать скопировать и вставить строки Base64 в начале этого урока и прочитать все мои сообщения.


Класс ByteArray — чрезвычайно мощный класс, и, тем не менее, он очень прост в использовании. Я видел много отличных Flash-приложений, использующих этот ByteArray для выполнения столь большого количества умопомрачительных манипуляций с данными, таких как те, которые я упоминал в начале этого урока. Я слышал, что многие программисты Flash-игр используют XML для сохранения своих посетителей «Save Game Data», но, как мы все уже знаем, XML — это чертовски сложный класс; с ByteArray я могу сохранить что-то вроде этого легко.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
private function CreateByteArray():void{
    _testObject = new Object();
    _testObject.name = «Taufik»;
    _testObject.website = «<a href=’http://ikt.co.id’>http://ikt.co.id</a>»;
    _testObject.occupation = «CTO»;
    _testObject.level = 99;
     
    //Get the state of this Game Character Inventory
    var _inventory:Array = new Array({item_id:5, amount:1}, {item_id:85, amount:1}, {item_id:42, amount:5});
    _testObject.inventory = _inventory;
     
    //Get what is the skill they already level up
    var _skill:Array = new Array({skill_id:1, level:0}, {skill_id:2, level:1});
    _testObject.skill = _skill;
     
    //Initialize our _byteArray variable, so that we can start converting object into a ByteArray
    _testByteArray = new ByteArray();
     
    //Convert the Object into Byte Array, This is how you do it, to convert an Object into a ByteArray, IT IS SIMPLE isnt it?
    _testByteArray.writeObject(_testObject);
     
    //Encode the ByteArray into Base64 String (so that we can send them via PHP or copy the text to notepad), again IT IS VERY SIMPLE!
    var encoded:String = Base64.encodeByteArray(_testByteArray);
     
    //Put the encoded Base64 String into our _inputField (so that we can copy them into notepad)
    _inputField.text = encoded;
}

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

Я надеюсь, что вы нашли этот урок полезным. Спасибо за прочтение!