12 ноября 2014

Сохраняем объект в SharedObject

Всем привет!
Когда мы играем в игры, то хотим, чтобы наши достижения сохранялись. Зайдем ли мы завтра в игру или через неделю - оружие, прокачка, пройденные уровни - все это должно быть "на прежних местах". Игра должна выглядеть так, как будто мы и не выходили из нее.
Для сохранения локальных данных во флеше используется SharedObject. Раньше я всегда записывал только числовые значения - количество собранных звезд, номер пройденного уровня,  найденные секреты и так далее. Но сегодня мне стало необходимо записать целый объект. Казалось бы, никаких трудностей быть не должно... но, по обыкновению, сложность кроется там, где ее не ждешь.  Сегодня расскажу, как сохранить и прочитать целый объект во флеше.
Как сохранить простые элементы 
Об этом рассказано, например, здесь. Если кратко, то выглядит это так:
var shared:SharedObject = SharedObject.getLocal("mySharedObjectID");

// прочитаем значение
var myStoredValue: Number = shared.data.myStoredValue; 

// сохраним значение
shared.data.myStoredValue = myStoredValue;

// сохраняем на компьютер 
shared.flush();
После data. можно дописывать любое имя для записи/сохранения (в данном примере было myStoredValue) - все создасться как надо. Удобно, правда?

Объекты
Пробуем теперь сохранить объект таким же методом. Создаем класс:
class TestClass
{
  protected var fNumberValue: Number = 0;
  protected var fIntValue: int = 0;
  public function TestClass(): void
  {
    fNumberValue = 1.5;
    fIntValue = 1;
  }
}
 Сохраняем его:
var myStoredObject: TestClass = new TestClass;
shared.data.myStoredObject = myStoredObject;
А теперь читаем:
var myStoredObject: TestClass = shared.data.myStoredObject;
Если это сделать в той же сессии приложения - то все нормально. Но, если закрыть флешку, а потом открыть заново, то при чтении объекта из shared получаем ошибку совместимости типов. Оказывается, из SharedObject'а достается объект класса Object. (а нам-то нужен TestClass!)

Регистрирация
Чтобы класс объекта был правильным, нам необходимо зарегистрировать нужный класс объекта вот так:
registerClassAlias('TestClass', TestClass);
Теперь наш код сработает:
var myStoredObject: TestClass = shared.data.myStoredObject;
Казалось бы, вот она - победа! Но не совсем... Если закрыть игру, затем открыть и прочитать данные, то объект будет нужного класса, но многие значения внутри класса будут дефолтными... Как же так?

Public vs protected
Оказывается, не public-поля класса не сохраняются и не читаются из SharedObject'а, а остаются дефолтными. Чтобы все было хорошо, необходимые поля класса нужно перевести в public-секцию.
Теперь класс выглядит так:
class TestClass
{
  public var fNumberValue: Number = 0;
  public var fIntValue: int = 0;
  public function TestClass(): void
  {
    fNumberValue = 1.5;
    fIntValue = 1;
  }
}

Вот и все. Теперь все работает.

Итого
Ранее мне не приходилось сохранять объекты. Но сейчас возникла необходимость. Погуглил, разобрался, да здравствует флеш!
Я рад, что получилось, а то мой мега-объект был уже готов и не хотелось его "раскрывать" на элементарные частицы, чтобы сохранить. Так что я пожертвовал моими полями класса, перевел их в public-секцию и спокойно читаю/сохраняю.
На этом все. Да будет мир.

Сообщения, схожие по тематике:

0 коммент.:

Отправить комментарий