Шрифт:
Вы должны придерживаться концепции CLDC и MIDP API, когда речь идет о ваших игровых данных. Не заключайте данные в класс, если для этого нет значимой причины. Наоборот, намного лучше использовать стандартные типы данных, которые намного эффективнее объектов.
Если используете объекты, то применяйте их повторно
Очевидно, что нельзя полностью избежать применения объектов в мобильных играх. Объекты играют очень важную роль в Java-программировании, и мидлеты не являются исключением. Один из способов минимизировать затраты памяти на объекты – повторно использовать их. При этом отпадает необходимость создавать объекты заново. Конечно, такой подход можно применить только в случае, если необходимо использовать объект одного типа несколько раз, но вы будете удивлены, насколько часто такой метод применим при разработке мидлетов.
Совет Разработчику
Хороший пример повторного использования объектов – это использование одного объекта класса Sprite вместо удаления и создания нового. Изменение объекта можно сравнить с удалением старого и созданием нового. Такой подход широко применялся в мидлете High Seas, разработанном в главах 12 и 13.
Повторное использование объектов позволяет избежать ненужного динамического выделения памяти. Например, если вы создаете объект, а затем прекращаете его использовать, сборщик мусора Java удалит его из памяти. Если впоследствии вам понадобится объект такого же типа, вы создадите новый, и под этот объект будет вновь выделена память. Вместо этого вы можете использовать предыдущий объект, заново проведя инициализацию.
Удаление объектов
Говоря о повторном использовании и уборке мусора, следует упомянуть о последнем приеме оптимизации, связанном с удалением объектов из памяти. В традиционном программировании J2SE или J2EE вы создаете объекты по необходимости, а удаляются они сборщиком мусора Java, когда становятся ненужными. В J2ME все аналогично, но стандартный сборщик мусора – это не очень эффективное средство высвобождения памяти. Сборщик мусора запущен как низкоприоритетный фоновый поток, который определяет и удаляет неиспользуемые объекты. Объект является используемым до тех пор, пока он не выйдет за границы области видимости или не станет равным null.
Один из способов помочь сборщику мусора определить неиспользуемый объект – это по окончании работы с объектом явно присвоить ему значение null, тогда занимаемая память будет освобождена при первой же возможности. Все объекты рано или поздно будут удалены из памяти, однако этот прием позволяет ускорить удаление ненужных объектов сборщиком мусора.
Минимизация сетевых данных
Вы знаете, что мобильные телефоны работают с беспроводной сетью, которая имеет сравнительно низкую скорость передачи данных. Поскольку сетевые мобильные игры должны использовать эту сеть, существуют значительные ограничения на объем передаваемых/получаемых по сети данных. Меньше всего игрок хочет ждать загрузки данных, описывающих ход оппонента, например, в шутере или лабиринте. Это может прозвучать очевидным, однако разработчики игр для персональных компьютеров или игровых консолей не сталкиваются с чрезвычайно ограниченной пропускной способностью сетевых соединений, поэтому минимизация объема передаваемых данных для них не является первостепенной задачей.
Исключение ненужной графики
Вероятно, вы думаете, что графика очень важна в создаваемых вами играх, но в реальности это может быть не так. Например, если в вашей игре есть графика, отличающаяся углом поворота, то, вероятно, вы зря расходуете память. Класс Sprite позволяет поворачивать спрайтовые изображения (на углы кратные 90 0) или зеркально отображать их. Используя это, вы потенциально можете сократить объем графических ресурсов на 75 %.
Рассмотрим пример High Seas, созданный в главах 12 и 13. В этой игре спрайт пиратского корабля состоит из четырех фреймов (рис. 17.1), которые содержат изображения корабля, повернутого на север, восток, юг и запад. Эти положения соответствуют поворотам одного спрайтового изображения на 90 0, следовательно, можно избежать применения всех изображений, если использовать возможности класса Sprite (рис. 17.2).
Рис. 17.1. Спрайт пиратского корабля из игры High Seas состоит из четырех направленных спрайтов
В копилку Игрока
Использование преобразования спрайтов может отрицательно сказаться на реалистичности некоторых элементов графики игры. Например, пиратский корабль в игре High Seas 2 показывает лицевую и обратную стороны паруса, а также тень, отбрасываемую кораблем. Хотя эти детали незначительны, они теряются, если использовать описанную выше методику (рис. 17.2). В результате пиратский корабль выглядит менее реалистично.
Основной недостаток использования преобразований спрайтов – снижение скорости при снижении размера. Для того чтобы преобразовать спрайт, требуется немного больше времени, чем просто вывести его на экран, однако при этом выигрыш в размере значителен.
Приемы оптимизации Java-кода
Пока мы обсудили оптимизацию, не рассматривая конкретные примеры. В последующих разделах я продемонстрирую вам методы написания кода, которые вы можете применять в разрабатываемых играх для увеличения быстродействия. Большая часть приводимого кода позволяет увеличить скорость выполнения приложения, а не сократить необходимый объем памяти.
Вы не должны задумываться об оптимизации скорости каждого бита создаваемого вами кода. Некоторые части кода вызываются чаще других. Зная это, вы должны оптимизировать именно такие фрагменты. Помните, что нереально оптимизировать каждую строку медленного кода игры. Ваша цель – оптимизировать те фрагменты, в которых это можно сделать, не прикладывая много усилий. Чуть позже вы узнаете, как выделить фрагменты кода, которым следует уделить особое внимание при оптимизации.