Создание игр для мобильных телефонов
Шрифт:
В копилку Игрока
То, как телефон хранит данные, зависит от конкретной модели. В современных мобильных телефонах обычно используется память устройства, но в будущем телефоны могут иметь и микро жесткие диски или какие-либо другие средства хранения информации. Хорошо, что, с точки зрения программирования, способ хранения данных не важен.
Понятие о записях и хранилищах записей
Хранилище записей – это упрощенная база данных. Запись – это единица информации, имеющая уникальный числовой идентификатор (ID). Хранилище записей можно представить
Рис. 19.1. Хранилище записей состоит из отдельных записей, имеющих уникальный ID
Каждое хранилище записей в RMS ассоциировано с пакетом мидлета и имеет текстовое имя, идентифицирующее ее. Так, например, хранилище списка рекордов для игры Space Out может называться HiScores, доступ к нему может быть получен только через приложение Space Out. Если вы распространяете другие игры вместе со Space Out в одном пакете, то остальные игры также будут иметь доступ к этому хранилищу.
В копилку Игрока
Пакет мидлетов определяется JAR-файлом. Чтобы создать пакет мидлетов, просто упакуйте несколько мидлетов в один JAR-файл и создайте необходимый дескриптор (JAD) для каждого из них. Все примеры игр и программы, приведенные в книге, упакованы в отдельные JAR-файлы.
Данные, находящиеся в хранилище, – это массив байтов. Независимо от того, сохраняете ли вы строку текста или целые числа, они сохраняются в виде последовательности байтов.
Позже в этой главе вы узнаете, что любые стандартные данные Java очень легко конвертировать в массив байтов и обратно, и научитесь делать это.
Изучаем класс RecordStore
MIDP API поддерживает RMS через пакет javax.microedition.rms. В этом пакете находятся класс и несколько интерфейсов, поддерживающих создание и работу с хранилищами данных. Эти функции выполняет класс RecordStore, он предоставляет программируемый интерфейс для одного хранилища данных. Этот класс выполняет чтение и запись хранилищ записей.
Использование класса RecordStore обычно подразумевает выполнение следующих шагов:
1. открытие/создание хранилища записей;
2. запись/чтение данных в/из хранилища записей;
3. закрытие хранилища записей.
Вам также может потребоваться выполнить особые задачи, например, удалить определенную запись или целое хранилище, эти действия также можно выполнить, используя класс RecordState.
Ниже перечислены некоторые методы класса RecordState, используемые для работы с записями:
► openRecordStore – открывает хранилище данных для чтения/записи;
► getNumRecords – возвращает число записей в хранилище;
► getRecordSize – возвращает размер определенной записи;
► getRecord – возвращает данные определенной записи;
► addRecord – добавляет данные в хранилище;
► deleteRecord – удаляет определенную запись;
► deleteRecordStore – удаляет хранилище данных;
► closeRecordStore – закрывает хранилище данных.
Как вы видите, эти методы выполняют основные задачи по управлению записями в хранилище. Конечно, в классе RecordStore есть и другие методы, но перечисленных методов вполне достаточно для хранения и управления списком рекордов.
Чтобы начать работу с хранилищем записей, необходимо создать экземпляр класса RecordStore:
RecordStore rs = null;
Чтобы создать сам объект REcordStore, необходимо вызывать
статический метод openRecordStore:try {
rs = RecordStore.openRecordStore("HiScores", true);
}
catch (Exception e) {
System.err.println("Failed creating hi score record store!");
}Первый параметр, передаваемый в метод, – это название хранилища записей, в данном случае – хранилища списка рекордов. Второй параметр определяет, нужно ли создать новое хранилище записей, если указанного хранилища не существует. Значение true говорит о том, что хранилище записей будет открыто или создано, если значение параметра равно false, то хранилище будет открыто, только если оно существует. Вот почему переменная rs инициализируется значением null – вы сможете проверить, было ли открыто хранилище. Когда хранилище открыто, вы готовы начать чтение и/или запись данных. Если вы вспомните, о чем шла речь ранее, то запись состоит из уникального числового ID и массива байтов. Давайте рассмотрим, как можно добавить данные в хранилище, используя метод addRecord класса RecordStore:
try {
rs.addRecord(recordData, 0, recordData.length);
}
catch (Exception e) {
System.err.println("Failed writing hi scores!");
}В приведенном коде переменная recordData – это массив байтов, содержащий помещаемые в хранилище данные. Метод recordData принимает три параметра: байтовый массив данных, смещение, с которого начинаются данные в массиве, а также число байт записываемых данных. Если вы хотите записать весь массив данных, то вторым параметром передайте 0, а третьим – длину массива байтов, как показано в примере.
Чтение данных из хранилища несколько сложнее, чем запись, потому что вы не знаете, сколько данных находится в хранилище. Чтобы прочитать данные из хранилища, необходимо выполнить следующие ходы:
1. пройти по всем записям хранилища;
2. получить размер текущей записи;
3. при необходимости изменить указатель записи, чтобы вместить всю запись;
4. прочитать запись.
Я мог бы вам показать, как прочитать одну запись, однако в большинстве случаев необходимо считать все содержимое хранилища. Описанные выше шаги уже дают представление о том, как это реализовать, – пройти по всем записям хранилища. Ниже приведен код, выполняющий это:try {
int len;
byte[] recordData = new byte[8]; //В размере записи (8 байт) нет ничего магического – это просто предположение о среднем размере записи
for (int i = 1; i <= rs.getNumRecords; i++) {
// выделить память при необходимости
if (rs.getRecordSize(i) > recordData.length) //Если размер записи больше 8 байт, этот код выделяет необходимый объем памяти
recordData = new byte[rs.getRecordSize(i)];
// считать данные в массив
len = rs.getRecord(i, recordData, 0);
// Do something with the record data
... //Здесь вы напишете игровой код, конвертирующий и сохраняющий данные в обычный формат, например, int
}
}
catch (Exception e) {
System.err.println("Failed reading hi scores!");
}Этот код показывает, как пройти по всем записям хранилища, считывая по одной записи. Важно отметить, что при необходимости выделяется память для записи. Обычно этого не требуется при работе со списком рекордов, поскольку все записи в данном случае имеют приблизительно одинаковый размер, но осторожность не повредит. Есть ряд ситуаций, когда может потребоваться удалить все хранилище записей. К счастью, в классе RecordStore для этого есть статический метод deleteRecordStore. Все, что необходимо сделать, – это передать ему название хранилища записей, например, так: