Введение в ByteArray
Russian (Pусский) translation by Yura Bobrov (you can also view the original English article)
ByteArray чрезвычайно мощный класс, который может использоваться для многих вещей, связанных с данными, включая (но не ограничиваясь) сохранение данных игры в режиме онлайн, шифрование данных, сжатие данных и преобразование объекта BitmapData в файл PNG или JPG. В этом введении мы будем использовать класс ByteArray для того, чтобы принять нативный объект AS3 и закодировать его в строку, которая может быть сохранена на сервере для последующего восстановления, а затем декодирована позже.
В предыдущих руководствах мы видели, как использовать XML и JSON для кодирования данных в текстовом формате (String). Однако как XML, так и JSON предназначены для чтения человеком, и в результате они гораздо больше, чем это необходимо. Также может быть сложно преобразовать некоторые виды AS3 объекта в любой формат. ByteArray имеет некоторые действительно передовые функций, но чтобы начать с чего-то, мы просто рассмотрим один простой пример: который позволяет очень легко превратить AS3 объект в строку.
Конечный результат предварительного просмотра
Давайте взглянем на конечный результат, в направлении которого мы будем работать:
Когда вы вставить закодированную строку ByteArray в TextField и нажмите кнопку Load, она будет расшифрована и покажет свойства объекта, сохраненные в нем. Вы можете попробовать следующие закодированные ByteArrays; скопируйте и вставьте их в текстовое поле и нажмите на кнопку Load, чтобы увидеть о чем я говорю:
//This ByteArray will show my data (This is the default ByteArray loaded) CgsBFW9jY3VwYXRpb24GB0NUTw93ZWJzaXRlBiFodHRwOi8vaWt0LmNvLmlkCW5hbWUGDVRhdWZpawE=
//This ByteArray will show my current thought CgsBIWZvb2RfZm9yX3Rob3VnaHQGgnVJIGFtIHRoaW5raW5nIG9uIHNoYXJpbmcgdGhlIHRlY2huaXF1ZSBpIHVzZWQgdG8gbWFrZSBhIEZ1bGwgRmxhc2ggRHluYW1pYyBXZWJzaXRlIFNFTyBGcmllbmRseSBmb3IgbXkgbmV4dCBUdXRvcmlhbCBpbiBBY3RpdmVUdXRzKy4uLiA8dT5XaGF0IGRvIHlvdSB0aGluaz88L3U+IDxiPmlzIGl0IGEgZ29vZCBpZGVhPC9iPj8B
//This ByteArray will talk about Flash and SEO and my experience with them CgsBEXF1ZXN0aW9uBoEDPGI+PHU+Q2FuIGEgZnVsbHkgZHluYW1pYyBGbGFzaCBXZWJzaXRlIGJlIFNFTyBmcmllbmRseTwvdT48L2I+Pz8NYW5zd2VyBoM/SXQgY2FuLCBoZXJlIGlzIHRoZSBwcm9vZiwgPGEgaHJlZj0naHR0cDovL3d3dy5nb29nbGUuY28uaWQvc2VhcmNoP3E9Zmxhc2grc2VvJmllPXV0Zi04Jm9lPXV0Zi04JmFxPXQnIHRhcmdldD0nX2JsYW5rJz5odHRwOi8vd3d3Lmdvb2dsZS5jby5pZC9zZWFyY2g/cT1mbGFzaCtzZW8maWU9dXRmLTgmb2U9dXRmLTgmYXE9dDwvYT4sIGlrdC5jby5pZCBpcyByYW5rZWQgIzYgb3ZlciB0aGVyZQE=
Шаг 1: Создание нового проекта ActionScript



В окне «Flash Builder»:
- Откройте Flash Builder 4
- Нажмите на File Menu
- Наведите курсор на New
- Нажмите на проект ActionScript
Шаг 2: Настройка New ActonScript Project



В окне «New Project ActionScript»:
- В поле Project name введите «TUTORIAL_ByteArray»
- Пожалуйста, запомните, где вы сохраняете проект
- Нажмите кнопку «Finish»
Шаг 3: Base64.as
Скопируйте Base64.as в каталог «com» вашего проекта.



- Создайте новый каталог «com» внутри вашего каталога src.
- Скачайте файл Base64.as из источника загрузок.
- Поместите файл в созданную директорию «com».
Base64.as пригодится позже. Это по Steve Webster, который привык находиться в dynamicflash.com (он покинул Flash-сообществj пару лет назад).
Шаг 4: Необходимые классы



В классе TUTORIAL_ByteArray
(который является основным классом) пожалуйста импортируйте следующие классы для этого руководства:
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() { } } }
Шаг 5: Привыкаем к Flash Builder I



Добавьте следующий код в конструктор TUTORIAL_ByteArray
для очень простой проверки.
public function TUTORIAL_ByteArray() { var _test:String = "Hello world!"; trace(_test); }
Нажмите клавишу F11 для запуска этого проекта, вы должны получить сообщение внутри окна консоли.
Шаг 6: Привыкаем к Flash Builder II



Теперь давайте попробуем проследить сообщение внутри переменной _test
, но на этот раз мы будем делать это с другой функцией:
public function TUTORIAL_ByteArray() { var _test:String = "Hello world!"; TestFunction(); } private function TestFunction():void{ trace(_test); }
Нажмите сочетание клавиш CTRL + S, чтобы сохранить проект. Ошибка обнаружена после того, как вы сохранили ваш проект; это потому, что переменная, которая объявлена внутри функции не будут доступна для любой другой функции. Так что в этом случае, мы должны объявить переменную _test
снаружи:
public function TUTORIAL_ByteArray() { TestFunction(); } private function TestFunction():void{ trace(_test); } private var _test:String = "Hello world!";



Шаг 7: Необходимые приватные переменные



Пожалуйста, добавьте следующие приватные переменные для этого проекта:
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;
Шаг 8: UI
Давайте создадим простой пользовательский интерфейс для этого проекта.



Теперь, когда нам нужно отображать что-то в наш проект, мы должны объявить нашей сцене размеры (проверьте строку 13).
Переименуйте нашу TestFunction в функцию InitUI и поместите следующую строку кода внутри. Пожалуйста, прочитайте закомментированные объяснения внутри кода.
[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, чтобы запустить этот проект и увидеть простой пользовательский интерфейс, который мы создали.
Шаг 9: Добавление интерактивности



Пожалуйста, прочитайте закомментированные объяснения внутри кода
_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
, а затем нажмите _loadButton
. Это самая базовая техника получения переменной от нашего пользователя и хранение ее в нашей приватной переменной.
Пища для размышлений
Мы, наконец, достигли наших наиболее важных шагов в рамках этого проекта, но прежде чем мы продолжим, позвольте мне обеспечить умственный стимулом для размышления. В настоящее время в нашем проекте, мы способны получить String
и хранить ее в нашей приватной переменной. Но это только строка; как насчет если пользователь захочет ввести что-то внутри _inputField
так, что я могу получить Object из него? Что следует пользователю напечатать? Ответ является «В кодировке Base64 ByteArray»
Шаг 10: Введение в ByteArray



Мы будем действовать медленно на этот раз, так что вы поймете класс ByteArray и будете иметь возможность делать собственные манипуляции с данными и применять их в ваших собственных проектах. Пожалуйста, прочитайте закомментированные объяснения внутри кода:
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='https://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 и превратили его в Action Message Format.
Перед отправкой данных в PHP-скрипт, с помощью метода GET, мы должны преобразовать его в строку Base64. Это потому, что Base64 может передаваться через XML (и HTML).
Шаг 11: Кодирование ByteArray в строку Base64



Пожалуйста, прочитайте закомментированные объяснение в коде.
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.
Шаг 12: Преобразование кодированной строки Base64 в объект



Мы будем стараться декодировать введенные строки Base64 в объект всякий раз, когда пользователь кликает _loadButton
, измените нашу функцию _loadButton_CLICK
. Пожалуйста, прочитайте закомментированные объяснение внутри кода:
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 для сохранения данных своих посетителей «сохранить данные игры», но как мы все уже знаем, XML чертовски сложный класс; с ByteArray, я могу сохранить что-то вроде этого ЛЕГКО.
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 и извлечения их обратно для дальнейшего использования. Все что я должен сказать, с Byte данными вы можете достичь много вещей, и некоторые могут быть решением, которое вы так долго искали все это время.
Я надеюсь, что вы нашли это руководство полезным. Спасибо за чтение!