Е. Буткевич Пишем программы и игры


Глава 15 Защита приложений



страница13/15
Дата22.06.2019
Размер2.79 Mb.
ТипКраткое содержание
1   ...   7   8   9   10   11   12   13   14   15
Глава 15

Защита приложений

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

Проблема заключается в том, что наряду с процессом компиляции, который пере­водит программу из текстового вида в машинные команды, существует обратный процесс декомпиляции, который позволяет восстановить исходный вид програм­мы из конечного приложения. Конечно, есть альтруисты, которые практикуют «open зоигсе»-программирование и публикуют все исходники программ, но если мы хотим получать за наши труды хоть какое-то материальное вознаграждение, то попытки расковырять наш продукт нужно пресекать.

Java Decompiler

Посмотрим для начала врагу в лицо и разберемся, как получить текст чужой про­граммы (конечно же, только с образовательной точки зрения). Брать чужое нехо­рошо, особенно извлекать из этого коммерческую выгоду, поэтому мы ограни­чимся лишь просмотром и редактированием в своих, сугубо личных целях. Можно адаптировать приложение для своей модели телефона, жизней побольше поста­вить в игрушке или модернизировать полезную программку.

В первой главе мы рассматривали, как при помощи дата-кабеля и соответству­ющих программ закачать приложение в телефон. Аналогичным образом можно из­влечь приложение из телефона. Далеко за примером ходить не будем и вытащим стандартный сборник шахматных задач «Chess Puzzle» из Nokia 6100 или чего-то похожего. Если вы уже благополучно его стерли или никогда и не имели, то найти это приложение в Интернете в свободном доступе не составит труда. Итак, вот он, заветный файл chesspuzzle. jar, и нам, как совсем юным мобильным программис­там, ну очень интересно развинтить его и посмотреть, как он устроен. Вооружаемся отверткой типа WinRAR и смотрим, что же внутри у этого приложения (рис. 15.1).

Здесь мы наблюдаем два файла ресурсов 1ang.xx и Puzzl es. BIN, папку с картинками icons и папку с манифестом приложения МЕТА-INF. Все самое интересное запрятано в глубине папки с названием com. В ней мы обнаружим несколько файлов с расши­рением *. class. Это файлы откомпилированных классов приложения. Вытащим их



162 Глава 15. Защита приложений

из архива и сохраним у себя на компьютере. Внутрь этих файлов лучше и не совать­ся: машинный язык доступен нам, простым смертным, лишь с переводчиком.







.yfcwttands ^av^fcai-"-Option .:Help:i'


extract To ;' Test :: .,..viimy Deist*


Ш ■ ЦШ chesspuzzle.jar - ZIP archive, unpacked яге 5S 475 bytes







feme О

Hzal

Type

r-todifiad




•com О icons Qmeta-inf

lang .xx


697


9 586

Папка Папка Папка

453 File xx 7120 File BIN

10,06.2005 16:40 10.06.2005 16:40 10,06,2005 16:40 10.06.2005 16:40 10.06.2005 16:40

0A33DB1A i 2A48634B ;



Рис. 15.1. Архив мобильного приложения изнутри

Теперь самое интересное. Простой отверткой нам уже не обойтись, нужны более мощные средства. Благодаря идеологии языка Java, связанной с транспортабель­ностью приложений, очень много информации можно восстановить из конечного приложения. Переводчик с машинного языка на привычный уже нам язык J2ME называется Java-декомпилятором (Java Decompiler). Думаю, вы без труда найде­те программное обеспечение подобного рода. В рамках этой книги мы рассмот­рим лишь один из возможных декомпиляторов под названием DJ Java Decompiler (по адресу dj.navexpress.com — информация о программе и разработчиках, а также свободное распространение последней версии).

Качаем, устанавливаем, запускаем. А теперь смело открываем основной класс приложения ChessPuzzleMidlet.dass и видим вот такую чудесную картину (рис. 15.2).

Создадим в обычном J2ME WTK проектс названием ChessPuzzleMidlet,декомили-руем все классы приложения и сохраним в папке исходного кода /src с расшире­нием .Java. Классы со знаком $ в названии декомпилировать не нужно, поскольку они уже содержатся внутри класса, название которого предшествует знаку $. Фай­лы ресурсов Lang.xx, Puzzles.BIN и картинки разархивируем и сохраним в папке ресурсов /res с сохранением структуры каталогов.

Обратим внимание, что все классы объединены в один пакет package com.nokia. mid.appl .chep, поэтому, чтобы компилятор обнаружил необходимые классы, нуж­но в свойствах созданного проекта заменить название основного класса мидлета на его полное имя, содержащее название пакета: com.nokia.mid.appl .chep.Chess PuzzleMidlet. Делается это следующим образом: в пункте меню Project (Проект) выбираем команду Settings (Параметры), где идем на вкладку MIDlets и редакти­руем поле Class (рис. 15.3).


Java Decompiler 163

I chp«ru« I e Midl et. j ad [} J 1 av a Decompile r -

-|eaKh:'-№w" Settlmji" language "joA^fliSt*':!'1"'1-'''



it CvciittpiM to/ DJ v'J. S. 6. i' 7 Copyright £003 АШаа fieohkw Duo: Ob * ft Ж '■' Иогы* Psgt? i)tip'J/fiWf?!t>&fe,fattun6Cify.cci!T)tfie6l>l«MftfjJit/ni - Check often ?! Lvzcompikir оргдал-э. pscfafrtpQrtbfi}

: tt-52 if ij




packaae com.nokia.mid.appl.chep;




[>♦

import java.io.PrintStrearn; import Java. util.Timer; impart javax.microedit ion.lcdui.'*; import javax. micro edit ion. midlet.MIDIet;







11 Referenced classes of package corn nokis. mid appl .chep: FuiiCawasScreen, CbessRMS, CheasBosrd, HtghScoms, ;, Loca!




; (и

public class ChessPuzzleMidlet extends MIDIet implOTisni-s CommandListener

(


1

I:*

i\ :: . -.;.;:; ::.; ::■.;-:- .' - :•. ;-; ..:..:■; ■ j

. m

.Ш.






















Рис. 15.2. Декомпилированное приложение снова доступно для нашего понимания



Рис. 15.3. Изменение названия основного класса мидлета

Пришло время попытаться откомпилировать наш проект. Здесь все, как в детстве с заводными игрушками: после того как разобрал и снова собрал, главное — чтобы опять заработало. Возможны небольшие различия в трактовке кода разными ком­пиляторами. Мне пришлось добавить несколько приведений возвращаемых



164

Глава 15. Защита приложений

типов, чтобы WTK перестал ругаться и выдавать ошибки. В остальном операция прошла успешно, и пациент ожил на эмуляторе в лучшем виде.

Теперь весь исходный код приложения в нашем полном распоряжении. Разби­раться в чужой программе всегда не очень просто, однако ничего нового для нас мы не увидим, поскольку практически все классы и методы нами уже рассмотре­ны. Любое приложение начинается с метода startApp(), это и есть та печка, от ко­торой мы будем плясать.

Как мы видим, в программе используются классы Ful I Canvas и Devi ceControl из Nokia API, то есть кроме как на аппаратах Nokia данное приложение нигде работать не будет. Благо, мы уже знаем, как адаптировать мидлет и расширить его модельный ряд. Для этого нужно заменить класс Ful lCanvas на обычный Canvas, а также акку­ратно вырезать всю иллюминацию и любые упоминания о классе DeviceControl. В успешной транспортабельности приложения вы можете сами убедиться. Хотя немного не совпали размеры экрана и часы заехали на доску, но это не такая боль­шая проблема (рис. 15.4).

Рис. 15.4. Перекомпилированное приложение успешно запущено на телефоне другого производителя

Вопроса локализации (перевода на другой язык) приложений мы уже касались в одной из глав. В программе шахматных задач у нас есть возможность поучиться хорошему стилю программирования. Весь текст, который выдает приложение на английском языке, — инструкции, пункты меню и прочее — содержится в файле ресурса lang.xx. Все вопросы локализации решаются в одном классе Local. Рас­смотрим процедуру получения требуемого текста:

public static synchronized String getText(int i. String as[]) { try {



Java Decompiler 165

if(loc — null)

loc - new Local:

InputStream inputstream = loc.getClassO.getResourceAsStream

(Viang." + phoneLang); if(inputstream — null)

inputstream = loc.getClassO.getResourceAsStreamC71ang.xx"); if (inputstream — null )

return "NoLang";

DataInputStream datainputstream = new DatalnputStream(inputstream); datainputstream.skipBytes(i * 2); short wordO » datainputstream.readShortO: datainputstream.skipBytes(wordt) - i * 2 - 2); String s = datainputstream.readUTFO; datainputstream.close(): if(as != null)

if(as.length == 1) {

s = replaced. "XU", as[O]):

} else {

forOint j = 0; з < as.length: j++)

s - replacets. T + j + "U", as[j]):

}

return s;



}

catch(Exception exception) { return "Err";

public static final String phoneLang =

System.getProperty("microedition.1ocale"):

Видим, что для перевода приложения на русский язык достаточно посмотреть код локализации телефона, возвращаемый методом getProperty системного класса System, и создать файл 1angс полученным расширением. Ниже в классе Local опре­делены числовые константы для всех выводимых строчек. По коду следует разоб­раться, каким образом проиндексирован файл ресурса. Сначала указаны номера позиций файла, с которых начинаются требуемые строчки, затем идут сами строч­ки. Осталось корректно сформировать файл с русским переводом. Возможно, по­требуется дополнительная логика перевода в Unicode, которой мы пользовались в программе BookReader. Вот и вся локализация. Если вы внимательно читали книгу и выполняли упражнения, то вполне способны справиться с этой задачей самостоятельно.

Как вы уже поняли, все необходимое в наших руках, и можно воротить все, что душе угодно. Например, не нравится нам возможность обнуления установленно­го рекорда: что это за рекорд такой, который можно отменить одним нажатием. Дело за малым: найти место, где формируется меню Top Scores, а затем исключить



166

Глава 15. Защита приложений

из него последний пункт Reset. В основном классе приложения видим, что любое меню формируется с помощью метода InitMenuScrdnt i, int ai[]. ...)спомощью следующих команд:

for(int k = 0; k < ai.length: k++)

m_ListScr.append(Local,getText(ai[k]). null):

Видим, что пункты меню формируются из строчек, представленных константа­ми, переданными методу в массиве ai. Теперь ищем вызов метода InitMenuScr, со­ответствующий формированию раздела меню Top Scores. Без труда обнаруживаем нужный вызов в методе MainMenuScreenDone:

case 4: // Ч0041 int ai3[] - { П. 10. 23

}:

InitMenuScr(HIGHSCORE_MENU_SCR, ai3. Local.getText(25). null. null. 0);

break;

В массиве ai3 содержатся константы, представляющие три пункта меню: Easy, Difficult и Reset. Очевидно, что следует оставить только два первых элемента мас­сива, а последний аккуратно удалить:

int ai3[] = { 11. 10 };

Ломать — не строить. Мы удалили всего лишь несколько символов. Главное - най­ти точку применения, а сами усилия могут быть мизерными. Компилируем и за­пускаем приложение. А теперь, как говорится, найдите десять отличий (рис. 15.5).





Рис. 15.5. Ликвидация пункта меню сводится к удалению из кода трех символов

Кроме бесценного опыта программистов от Nokia, что еще полезного можно из-влечьиз кода данного приложения? Решили вы, например, написать шахматы для



Обфускация 167

мобильного телефона, чтобы в дороге играть с товарищем. Кое-что можно будет использовать, например доску, фигурки, алгоритм перемещения фигур по доске и секундомер. Однако если вы решите продавать свои шахматы, то придется ри­совать и программировать все заново, чтобы не нарушить авторские права. Пре­имущество заключается в том, что всегда можно проконсультироваться с гото­вым кодом и разобраться, как это делают профессионалы.



Защита приложений

Легальное распространение мобильных приложений происходит через W AP-сай-ты или SMS-сервис специализированных мобильных издательств, которые вни­мательно следят за авторскими правами и отчислениями разработчикам продук­тов. При уведомлении об успешной загрузке приложения на ваш телефон система инициализации генерирует счет, который вы оплачиваете через вашего операто­ра сотовой связи. Удобно, надежно, а если что, можно обратиться в службу под­держки издательства: крупные и солидные конторы обычно заботливо относятся к своим клиентам.

Теперь допустим, что вы приобрели какое-то приложение легальным образом. Кто мешает скачать его с телефона в компьютер и выложить на общий доступ в Интер­нет? Кто после этого будет платить деньги, когда ту же самую игру можно получить бесплатно? Для защиты от подобного копирования можно ввести регистрацию: сам продукт распространяется бесплатно, а вот его активация или расширение проб-ной версии до полнофункциональной стоит денег. Вам потребуется реализовать алгоритм регистрации и организовать удобную систему оплаты. Как вариант, мож­но при первом запуске приложения сгенерировать случайным образом уникаль­ный ключ и сохранить его в хранилище записей. Регистрационный механизм дол­жен выслать код активации, соответствующий лишь данному ключу. При вводе кода активации приложение генерирует собственный код, соответствующий сгенериро­ванному ключу, и при совпадении разблокирует необходимую функциональность.

Существует масса методов защиты и регистрирования, однако вернемся к началу этой главы. Казалось бы, что может быть проще: декомпилировать упрямое прило­жение, вырезать все проверки авторизации и запросы регистрационных кодов, а затем вернуть в исходное положение. Против таких умельцев, как мы, и действий, именуемых не иначе, как «взлом», существует способ защиты, называемый обфус-кацией. Не пугайтесь этого слова. Оно образовано от английского obfuscate — запу­тывать, сбивать с толку. Сам метод заключается в предварительной модификации исходного кода программы с целью затруднить процесс декомпиляции и анализа приложения,



Обфускация

Более всего распространена символьная обфускация, которая меняет имена пе­ременных, названия классов, полей и методов на бессмысленный набор симво­лов. Например, был у нас метод GetPassword(), а после обфускации он превратил­ся в LK23gdcasjJKHKJh(). Однако многие декомпиляторы уже справились с этим



168 Глава 15. Защита приложений

подвохом и заменяют длинные нечитаемые имена на более удобные, типа Method_l(), Method_2() и т. п.

Существует и другой метод символьной обфускации, реализованный вJ2ME WTK, работу которого мы рассмотрим на примере. Этот метод действует с точно­стью до наоборот, и переименовывают классы, поля и методы однобуквенными именами, повторяющимися в каждом классе. Согласитесь, чтобы понять вот та­кой пассаж: Ь a = а.с(а. с.а);

потребуется немало усилий и тщательного изучения всей структуры программы, которая может быть совсем не маленькой.

Обфускатор — это не что иное, как утилита, модифицирующая исходный код при­ложения до неузнаваемости. К символьным относится, также обфускатор, встро­енный в J2ME WTK. Для того чтобы скомпилировать приложение с предвари­тельной обфускацией, при упаковке проекта вместо пункта Create Package (Создать архив) следует выбрать команду Create Obfuscated Package (Создать архив с обфус­кацией). Попробуем в деле встроенный обфускатор на тех же шахматах.

Попробуем теперь декомпилировать получившиеся классы. Сразу бросается в глаза, что название сохранил лишь основной класс приложения, остальные на­зываются теперь нехитро: а, Ь, с, d, e, f,... Посмотрим на оригинал конструктора основного приложения. Так он выглядел до нашей обфускации:

public ChessPuzzleMidletO {

m_Display = null;

m_HighScoreArray = null;

m_Cu rrentScreen = 0:

m_LastScreen » 0;

MAIN_MENU_SCR = 1;

MODE_MENU_SCR - 2;

PUZZLE _MENU_SCR = 3;

HIGHSCORE_MENU_SCR = 4;

SPLASH_SCR = 5:

PUZZLE_SCR = 6:

LEVEL_MENU_SCR = 7:

HIGHSCORE_DIS_SCR - 8:

HIGHSCORE_DEL_SCR = 9:

INSTRUCTION_SCR = 10;

TIMEO_MODE = 1:

CASUAL _MODE = 0;

m_LastSelectedMenuIndex = 0;

m_AppMessage - "":

m_PlayMenu - false;

m_ScreenWidth = 128;

m_ScreenHeight - 128;



Обфускация 169

С такими именами констант и переменных разобраться в программе и внести в нее изменения нам не составило труда. Боюсь даже предположить, сколько бы это заняло времени и сил, если бы код выглядел следующим образом:

public ChessPuzzleMidletO

(

d - null: flddo - null: ab - 0: S - 0; p- 1; W - 2: Y = 3: f - 4: 1 - 5: z - 6; aa = 7; T =8; D=9: ac = 10; _fldchar = 1; 0-0:



_fldcase = 0;

p = ....

ae - false; v - 128; ' m = 128;

Если и до этого разобраться в чужой программе было не так просто, то теперь это становится пыткой не для слабонервных, и поверьте, потраченное на расшифров­ку время уж точно не стоит двух-трех долларов.

Кроме символьной, существуют и другие методы обфускации, реализованные в обфускаторах второго порядка. Такие обфускаторы наряду с методами символь­ной обфускации используют также обфускацию данных и графа потока управле­ния. Здесь есть большой простор для введения людей в заблуждение: изменение структур и местоположения данных, кодировка данных, объединение данных в мас­сивы или наоборот, разделение массивов на отдельные переменные; добавление неиспользуемых данных и формирование на их основе ложных условий, замена статических присваиваний на вызовы методов; замена условий циклов на более сложные и масса других хитростей, об которые можно сломать мозги, пытаясь ра­зобраться в зашифрованном алгоритме. Следует отметить, что если обфускаторы первого порядка немного сокращали размер программы, экономя на названиях, то второй порядок обфускации может разбазарить столь ценные нам килобайты. Как вы сами понимаете, обфускация не является панацеей от взлома, будь то не­санкционированное расширение пробной версии или просмотр секретного алго-

170 Глава 15. Защита приложений

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

Как ни печально, но на этом этапе нам придется распрощаться. Я надеюсь, что чтение не прошло для вас даром, что вы многому научились и открыли для себя увлекательный мир мобильного программирования. Реализация приведенных примеров, их понимание и совершенствование — вот золотой ключик от дверей в чудо-мир мобильных технологий. Пробуйте, ошибайтесь, но не опускайте руки. Опыт приходит с практикой!



* * *

Эта книга не является учебником, документацией или серьезным методическим пособием, это именно самоучитель — практические советы, минимум теории и максимум практики, личные наблюдения автора, начиная с самого нуля. Если эта книжка уже вся исчиркана разными пометками, изрядно потрепана и залита кофе, значит потраченное мной и вами время не прошло даром.

Если вы действительно серьезно увлеклись мобильным программированием, то у вас неизбежно появится масса вопросов, благо на сайте разработчиков языка java.sun.com/j2me/docs/ имеется исчерпывающая документация, масса книг и ста­тей (правда, на английском языке). Также за советом можно сходить на специа­лизированные форумы, например, forum.juga.ru/, раздел которого так и называет­ся: J2ME — форум о Java в мобильнике. Пользуйтесь поиском, не стесняйтесь спрашивать: программисты любят помогать друг другу.

Количество обладателей мобильных телефонов уже приблизилось к двум милли­ардам (!) и неуклонно растет, и каждый из них — потенциальный пользователь ваших программ. Простота в использовании и всеобщая доступность в любое вре­мя — вот залог успеха. Будущее именно за мобильными, портативными техноло­гиями, так что запрыгивайте в поезд, пока не поздно. В качестве бонус-трека вас ожидают практические советы по продаже мобильных приложений. Удачи вам!



Bonus

Распространение мобильных приложений. Практические советы по продажам мобильного контента

Теперь у нас есть все необходимое для разработки игр и приложений для мобиль­ных телефонов: аппаратс поддержкой J2ME, кабель для соединения с компьюте­ром, необходимое программное обеспечение, а главное — знания и практические навыки.

Если вы уже начинили свой телефон самодельными играми и приложениями, по­делились ими с друзьями, похвастали перед коллегами, то можно сделать и следу­ющий шаг: попытаться продать свои труды. И пусть вас не смущает, что програм­мка вышла коротенькая, а разработка заняла не более нескольких дней: специфика программирования для мобильных устройств играет сейчас нам на руку.

Игры для мобильных телефонов существенно отличаются от обычных компью­терных игр, которые пишут целые команды разработчиков, крупные фирмы с боль­шим штатом сотрудников, а потому написать что-то конкурентоспособное на этом рынке одному человеку просто не под силу.

Ограниченная функциональность платформы, жесткие требования к размеру при­ложения не позволяют писать зрелищные, интерактивные побоища типа Quake. Маленькое 64-килобайтное тельце программы не способно вместить логику серь­езной военно-экономической стратегии, да и не стоит велосипеду тягаться с го­ночной машиной. Игра для мобильника и не должна быть сложной и наворочен-ной. Обычно она заполняет небольшую паузу ввиду доступности в любое время и в любом месте.

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

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

172 Распространение мобильных приложений

процент они размещают ваш продукт на своей платформе, рекламируют его, осу­ществляют всю техническую поддержку, связанную с процедурой продажи.

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

Обычно договор не передает фирме все права на продукт, а только предоставляет право распространения. То есть договор не должен препятствовать вам заклю­чать соглашения параллельно с несколькими фирмами.

Устоявшаяся цена в России на момент написания этой книги, которую платит
конечный пользователь за скачанную игру или программу, — 2 доллара. Теперь
посмотрим, какая часть от этой суммы окажется у вас в кармане. Деньги за прило­
жение снимаются со счета пользователя и поступают оператору сотовой связи.
Оператор, как правило, половину этой суммы забирает себе, а половину перево­
дит на счет фирмы-распространителя. *

На этом этапе фирма имеет свой интерес и делит с вами прибыль согласно дого­вору. При заключении договора не стесняйтесь торговаться в пределах разумно­го. Здесь ставка по России колеблется в пределах 30-50 центов в пользу разра­ботчика за каждую проданную копию программы.

Очевидно, что повышение вашего благосостояния напрямую зависит от числа лю­дей, скачавших программный продукт. Дело за малым: заинтересовать пользовате­ля полетом своей фантазии, оригинальностью, новизной, практической пользой. Здесь уже все в ваших руках.

Особое внимание следует уделить соблюдению авторских прав, ответственность за нарушение которых лежит целиком на разработчике. Когда речь идет о ком­мерческом использовании, последствия нарушений могут быть очень серьезны­ми, и наступают они куда с большей вероятностью, чем при установке операци­онной системы с пиратского диска. Так что использование текстов, картинок, программного кода не должно идти вразрез с чьими бы то ни было интересами.

Чтобы не быть голословными, приведем конкретные примеры и адреса наиболее крупных в России фирм-распространителей контента для мобильных телефонов: www.playmobile.ru, www.pLayfon.ru, www.infon.ru, www.javagames.ru. В любом случае, такие фирмы совсем не трудно найти в поисковиках по любому запросу с ключе­выми словами данной тематики. Серьезные фирмы отличаются качественно вы­полненным сайтом, ежедневно обновляемыми новостяги, наличием менеджеров, готовых оперативно выйти на связь.

Если вы попробовали свои силы на российском рынке мо» ильного программиро­вания и чувствуете высокий коммерческий потенциал ваш й программы, то мож­но шагнуть и за границу. Здесь также существуют давно на 1аженные схемы рас­пространения программ, например через сайт forum.nokia.со n/business.

В современном мире сотовый телефон стал неотъемлемым атрибутом нашей жиз­ни. Человек без мобильника вызывает сейчас не меньшее удивление, чем лет 10 назад человек с мобильником. Именно поэтому технология чрезвычайно перс­пективна. Каждый третий человек на планете — обладатель мобильного телефо­на, а значит, и потенциальный потребитель программного продукта. Всех благ!

Приложение 1

Полный листинг программы «Змейка»

// ,

// Пример игры "Змейка" для телефона Nokia

//

// Реализован в рамках книги

// "Программируем игры для мобильных телефонов"

//

// (с) Voolkan

//

import javax.microedition.midlet.MIDIet:

import javax.microedi ti on.lcdui.Canvas; import javax.microedition.lcdui.ChoiceGroup; import javax.microedition.lcdui .Command: import javax.microedition.lcdui.CommandListener; import javax. microedition.lcdui .Display; import javax.microedition.lcdui.Displayable; import javax.microedition.lcdui.Form; import javax.microedition.lcdui. Gauge: import javax.microedition. lcdui.Graphics: import javax.microedition.lcdui. Image; import javax.microedition. lcdui.Imageltem: import javax.microedition.lcdui.Item; import javax.microedition.lcdui. List; import javax.microedition.lcdui. Stringltem;

import javax. microedition.rms.RecordStore; import javax.microedition.rms.RecordEnumeration: import javax.microedition. rms.RecordStoreException;

import java.util.Vector: import java.util.Random;

import java.io.IOException: import com.nokia.mid.ui.FullCanvas:

174 Приложение 1. Полный листинг программы «Змейка»

import com.nokia.mid.ui.DeviceControl: import com.nokia.mid. sound.Sound:

// основной класс SnakeGame. реализующий сценарий смены экранов public class SnakeGame extends MIDlet implements CommandListener {

private Display display: // менеджер дисплея

private Snake curSnake; // объект змейки

private List menu: // стартовое меню

private Command ok: II команда выбора пункта меню

private ChoiceGroup levelChoice: // меню выбора уровня сложности игры

private Command set; И команда выбора уровня сложности игры

public void destroyAppCboolean destroy) { curSnake=null : notifyDestroyed():

public void pauseAppO {}

// стартовый метод мидлета public void startAppO {

// массив строк с названиями пунктов меню

String menuQptionsn - {"New Game"."Set Level"."High Score"}:

// создать стартовое меню

menu = new ListC",List. IMPLICIT,menuOptions.null):

// создать команду выбора пункта меню

ok = new Command("Ok", Command.OK, 1):

// добавить команду в меню

menu.addCommand(ok):

// создать команду установки уровня игры

set = new Command("Set", Command.BACK, 1):

// установить блок прослушивания команд для меню

menu.setCommandListener( this);

// получить ссылку на менеджер дисплея

display - Display.getDisplay(this):

// отобразить на экране стартовую заставку Image title = null; try {

// создать объект заставки

Полный листинг программы «Змейка» 175

title » Image.createlmage("/title.png"); } catch (IOException ioe) {}

// создать новый элемент формы

Imageltem item = new Image ltem C". title. ImageItem.LAYOUT_CENTER.""):

// отобразить заставку

showNewScreent'"SNAKE".ok.item):



i! блок прослушивания команд

public void commandAction(Command с Dispiayable d) { // если была команда Ok из главного меню игры if (с ~ ok && d - menu) {

// получить выбранный пункт меню

int selIndex • menu.getSelectedlndexO;

switch(selIndex) {

// первый пункт меню: новая игра case 0 :

// создать объект змейки curSnake - new Snake():

// создать объект треда автоматического передвижения Thread moveThread • new Thread(curSnake): // начать выполнение треда moveThread. start O: // отобразить змейку на экране di splay.setCurrent(curSnake); break;

// второй пункт меню: установить уровень сложности case 1 :

// массив строк с названиями пунктов меню String levelOptionsn - {"Level 1"."Level 2", "Level 3"."Level 4"}; // создать меню выбора уровня игры levelChoiсе = new ChoiceGroupC".List.EXCLUSIVE.

levelOptions.null);

// выделить пункт меню, соответствующий // текущему уровню сложности levelChoice.setSelectedIndex(5-getParameter(l).true); // отобразить новую форму showNewScreen("Set Level ".set. 1evelChoice): break:

■ // третий пункт меню: посмотреть текущий рекорд case 2 :

И получить строку с текущим рекордом

176 Приложение 1. Полный листинг программы «Змейка»

String strScore - (new Integer(getParameter(0))).toStringO;

// создать объект элемента-строки

Stringltem highScoreltem » new StringltemC"". strScore);

// отобразить новую форму

showNewScreenC'HIGH SCORE".ok. highScorel tem):

break;

// если была команда Ok. вызванная не из меню if(C"-ok && d!=menu)



// отобразить на экране стартовое меню

display. setCurrent(menu);

// если была команда Set из меню установки уровня сложности if(с — set) { try {

// массив параметров игры byte buff[] = {0.5}:

// открыть хранилище записей с именем "SNAKE" RecordStore recordStore = RecordStore.openRecordStoreC"SNAKE".

true);


// получить список записей хранилища RecordEnumeration re = recordStore.enumerateRecords(null, null.

false);


// если хранилище не пусто if (re.numRecords()!=0) {

// получить id записи параметров игры int id = re.nextRecordldO: // считать запись с параметрами игры buff = recordStore.getRecord(id); // вычислить текущий уровень игры buff[l] = (byteИ5 - levelChoice.getSelectedlndexO): // записать параметры игры recordStore. set Record(id. buff. 0. 2); } else {

// добавить новую запись параметров игры recordStore.addRecord(buff. 0. 2);

} catch(RecordStoreException rse) {



)

II отобразить на экране стартовое меню

display.setCurrent(menu);



Полный листинг программы «Змейка» 177

// метод showNewScreen создает и отображает форму с элементом item private void showNewScreentString title.Command сItem item) {

// создать форму для нового экрана

Form newScreenForm - new Form(title):

// добавить команду для возврата из формы

newScreenForm.addCommand(c);

// добавить элемент в форму

newScreenForm.append(item);

// установить блок прослушивания команд

newScreenForm.setCommandListener(this);

// отобразить форму на экране

display. setCurrent( newScreenForm);

// метод getParameter считывает из хранилища записей параметры игры // и возвращает один из них, определенный входным параметром index private byte getParameter(int index) { // массив параметров игры byte buff[] = {0.0}; try {

// открыть хранилище записей с именем "SNAKE" RecordStore recordStore = RecordStore.openRecordStoreC 'SNAKE".

true);

// получить список записей хранилища RecordEnumeration re = recordStore.enumerateRecordstnull, null.



false);

// если хранилище не пусто if (re.numRecords()!=0) {



II получить id и считать запись параметров игры buff = recordStore.getRecord(re.nextRecordldO):

} } catch(RecordStoreException rse) {

}

// вернуть параметр



return buff[index]:

// класс SnakePart представляет каждый элемент змейки private class SnakePart extends Object {

private int x: // координата х

178 Приложение 1. Полный листинг программы «Змейка»

private int у; // координата у private int part; // код части тела змеи private int dir: // код направления движения

// конструктор; принимает все прля как аргументы public SnakePartCint _x. int _y. int _part, int _dir) { x=_x:


Каталог: Техника -> Информационные%20технологии
Информационные%20технологии -> Методические рекомендации по построению систем защиты узлов интернет 1 требования к системе защиты узла интернет 2
Техника -> Учебная программа для специальности: 1-23 01 73 Средства массовой информации
Техника -> Ремонт китайских телефонов
Техника -> Для профилактики и лечения насморка Зачем промывать нос во время насморка?
Техника -> Учебная программа для специальности: 1-23 01 73 Средства массовой информации


Поделитесь с Вашими друзьями:
1   ...   7   8   9   10   11   12   13   14   15


База данных защищена авторским правом ©vossta.ru 2019
обратиться к администрации

    Главная страница