Я всегда затрудняюсь ответить на вопрос: откуда берутся идеи для игр? Но в этот раз, я более-менее точно могу сказать, что эта идея родилась у меня когда я увидел баннер «World of Tanks» на каком-то из сайтов. Знаете, бывают такие баннеры, которые привлекают внимание пользователя микро-играми, прежде чем перенаправить его на сайт рекламодателя? Так вот, на этом баннере был танк, который по клику мог проезжать то или иное расстояние, зачем-то пробивая при этом кирпичные стены. Вот именно с этого момента я стал размышлять, по дороге на работу, о раннере с танковой тематикой. Тут же родилась и отсылка к нашумевшему хиту от Wargaming в названии. Она показалась мне забавной, учитывая, что суть моей игры — это движение по некой дороге, пути, с целью пройти максимальное расстояние. Под хабракатом вас ждет рассказ об игре, разработке, технические детали и все-все-все, что должно быть в классической «gamedev story».
Об игре
Итак, что же у нас здесь имеется? Ну во-первых, у нас есть вот такой танчик:
дыр-дыр-дыр
Который едет по дороге, виртуально разделенной на 3 полосы (привет, Subway Surfers!). Свайпом влево-вправо, можно перестраиваться в соседние полосы, чтобы избежать столкновений с препятствиями. В отличие от других раннеров, маневры здесь не мгновенные (это все-таки танк), что тоже нужно учитывать. Согласен, звучит странно, но наш танк умеет прыгать (свайп вверх). Какой же раннер может быть без прыжков? К тому же это фаново, прыгать через яму-ловушку и в прыжке расстреливать противотанковые ежи, коварно расставленные сразу за ней. Разумеется, танк умеет и стрелять (свайп вниз), правда снаряды в игре ограничены. На мой взгляд, стрельба — это аналог скейтов в том же Subway Surfers, она позволяет пройти «силой» тот участок, где нет времени на маневр.
Одна из действительно коварных ловушек
Вообще, я часто подсматривал в топовые раннеры, когда делал «Way of Tanks». Конечно, у меня нет многих из модных нынче фишек, типа рулетки, ежедневных соревнований, друзей из фейсбука, push-уведомлений и прочего-прочего, что должно наращивать ARPU, MAU, DAU и все вот эти вот не понятные мне штуки. Но, хочется верить, что в игре есть главное — это сделанный с душой геймплей! Впрочем, я отвлекся.
Во-вторых, путь танка усеян препятствиями, расставленными невидимым противником. Все препятствия можно разделить на 2 типа: те, которые можно перепрыгнуть, они находятся на уровне земли и ниже (ямы-ловушки, минные поля) и те которые перепрыгнуть нельзя, а можно только объехать или уничтожить (стены, противотанковые ежи, доты). Причем, просто уничтожать все на своем пути — не получится. Орудие танка имеет ограниченную скорость перезарядки, которая не позволяет стрелять слишком часто. Поэтому, для успешной игры понадобятся не только реакция и везение, но и умение быстро принимать решение, когда маневрировать, а когда стрелять.
Изначально, я задумывал добавить в игру несколько мини-боссов, но как обычно, жизнь и ограниченные ресурсы вносят свои коррективы. Поэтому из мини-боссов, в «Way of Tanks» пока есть самолет, который пытается уничтожить танк игрока, сбрасывая на него бомбы.
AI самолета устроен довольно просто, можно даже сказать, примитивно. Есть две основные характеристики: скорость принятия решений и время подготовки следующей бомбы к бомбометанию, проще говоря, «перезарядка». Так вот, когда бомба готова, бомбардировщик стремится занять одну полосу с игроком, а когда идет перезарядка, наоборот избежать нахождения на линии ответного огня. После тестов, я добавил пару усложнений: самолет фиксирует начало поворота танка и дальше алгоритм работает так, как если бы танк УЖЕ перестроился в новую полосу. Таким образом, бомбардировщик научился «предсказывать» ответные действия игрока и работать по цели с упреждением. Плюс постепенное улучшение характеристик для соблюдения баланса в игре (на максимальную сложность самолет выходит только с пятого-шестого захода).
Как и в любом раннере, здесь есть временно действующие бонусы (powerups), придающие танку супер способности. Я еще не до конца определился со списком, сейчас их четыре:
Удваивает собираемые монеты
«Рывок» — позволяет танку пробивать любые препятствия, но только в прыжке
Увеличивает маневренность танка
Бронебойные заряды — стреляя, танк уничтожает всю линию препятствий перед собой (а также +1 к зарядам)
Ах да, еще была мысль сделать летящие навстречу ракеты, как в Jetpack Joyride. Но посовещавшись и подумав, решили, что ракеты либо будут лететь слишком быстро, либо будут странно смотреться (если их замедлить). В результате, ракеты превратились вот в такие броневики-камикадзе, которые будут таранить наш танк:
В общем, игра получилась хоть и простой, но, тем не менее, органичной и азартной! По крайней мере, это единственная из всех моих игр, в которую я сам продолжаю играть с удовольствием после всех этих бесконечных тестирований и отладок.
Техническая часть
Это уже пятая игра, которую я делаю на AndEngine. Да, я знаю про Unity, но не гонюсь за кроссплатформенностью. По моему мнению, лучше быстрее и качественнее сделать эксклюзив для одной платформы. Да и игра на знакомом поле, так сказать, у меня более-менее получается, в отличии от попыток хоть как-то заявить о себе в App Store. Хотя я и посматриваю в последнее время на LibGDX.
Расскажу немного подробнее о внутреннем устройстве игры. Главное в раннере — это собственно, движение вперед. Я пробовал подход с движением камеры вслед за персонажем и параллельной генерацией мира перед ней, но в силу различных причин, остановился на варианте со статичной камерой. То есть танк и камера стоят на месте, а весь игровой мир движется им на встречу, создавая иллюзию движения танка вперед. Вроде бы такой подход априори проигрывает по производительности, но если все делать правильно и оптимально, то проблем быть не должно.
У нас есть четыре варианта бэкграунда, размером с камеру (1280х720), которые бесшовно переходят из любого в любой. Одновременно, игрок видит не более двух из них. Поэтому, на первом шаге, мы устанавливаем SpriteGroup с бэкграундами в позицию (0, -CAMERA_HEIGHT), а два спрайта внутри нее в (0, 0) и (0, CAMERA_HEIGHT), соответственно. Остальные два — скрываем. Далее, мы двигаем SpriteGroup вниз со скоростью танка. Когда она оказывается в координатах (0, 0), мы возвращаем ее на изначальную позицию, при этом, случайным образом выбирая следующий участок бэкграунда и скрывая пройденный. Все просто!
Но тут я столкнулся с неприятным багом: спрайты внутри SpriteGroup могут «мигать» при изменении позиции. На stackoverflow, я нашел вот такое решение этой проблемы. Для SpriteGroup переопределяем onManagedUpdate и пишем:
@Override
protected void onManagedUpdate(float pSecondsElapsed) {
final SmartList<IEntity> children = this.mChildren;
if (children != null) {
final int childCount = children.size();
for (int i = 0; i < childCount; i++) {
this.drawWithoutChecks((Sprite) children.get(i));
}
submit();
}
}
Вместе с движением фона, нам нужно создавать и препятствия. Делать это полностью случайно, было бы не правильно, потому что в таком случае, возможно появление непроходимых участков. Все ловушки у меня тоже разделены на секции и подготовлены заранее. Они хранятся в JSON-файле примерно такой структуры:
{Все варианты мной неоднократно протестированы, неудачные я либо модифицирую, либо просто отбраковываю. После этого, на каждом шаге генерации мира, мы просто выбираем новую случайную секцию с ловушками, либо выводим текущую строку текущего участка.
«root»:{
«sections»:[
[
[«CELL_EMPTY»,«CELL_EMPTY»,«CELL_EMPTY»],
[«CELL_COIN»,«CELL_EMPTY»,«CELL_EMPTY»],
[«CELL_COIN»,«CELL_EMPTY»,«CELL_EMPTY»],
[«CELL_COIN»,«CELL_EMPTY»,«CELL_HEDGEHOG»],
[«CELL_PIT»,«CELL_WALL»,«CELL_WALL»],
[«CELL_EMPTY»,«CELL_EMPTY»,«CELL_EMPTY»]
],
…
Как и в любой современной Android-игре, у нас есть интеграция с Google Play Game Services (ачивки и лидерборды). Тут все довольно банально и подробно описано в руководстве на офф. сайте: developers.google.com/games/services/android/quickstart. Я просто использую один раз написанный код в каждой новой игре, практически без изменений.
Оптимизация
Хочу отдельно сказать несколько слов об оптимизации в AndEngine. Для всех объектов, которые не являются анимированными спрайтами, для которых мы не переопределяем onManagedUpdate и не используем entity modifiers, нужно не забывать устанавливать setIgnoreUpdate(true) сразу при создании. Это положительно влияет на производительность за счет уменьшения количества вызовов onUpdate на каждом такте движка. Так же, нужно делать setIgnoreUpdate(true), когда мы прячем какой-либо объект (устанавливаем setVisible(false)).
Далее, все что создается на сцене динамически и не в единичном количестве, должно помещаться в пулы (специальный класс для повторного использования объектов). У меня это ловушки, взрывы, следы на земле от траков танка и т.д. Вот так, например, выглядит пул ловушек:
public class TrapPool extends GenericPool<Trap> {
@Override
protected Trap onAllocatePoolItem() {
return new Trap(0, 0, Assets.trapRegion, ContextHelper.getVBOM());
}
@Override
public synchronized Trap obtainPoolItem() {
return super.obtainPoolItem();
}
@Override
protected void onHandleRecycleItem(Trap pItem) {
pItem.setVisible(false);
pItem.detachSelf();
super.onHandleRecycleItem(pItem);
}
}
Теперь, при необходимости появления на сцене нового препятствия, делаем:
Trap trap = trapPool.obtainPoolItem();
trap.setPosition(nX, nY);
trapLayer.attachChild(trap);
А когда ловушка больше не нужна (вышла за пределы видимости камеры):
trapPool.recyclePoolItem(trap);
Для ускорения отрисовки, я помещаю все бэкграунды в один SpriteGroup. Единственный нюанс тут заключается в том, что для SpriteGroup может использоваться только один атлас. Поэтому, все спрайты бэкграундов уменьшены на 20%, чтобы уложиться в максимальный размер текстуры 2048х2048. Не знаю правда, насколько это актуально сейчас, прогресс все-таки не стоит на месте и все мои тестовые устройства поддерживают 4096х4096, но раз на качестве изображения это особо не сказывается, то лишним не будет уж точно. Так же, имеет смысл устанавливать формат изображения RGBA4444 вместо RGBA8888. Для такой «мультяшной» графики картинка не изменится, а объем используемой памяти сокращается вдвое (если вы используете TexturePacker, то достаточно выбрать соответствующую опцию при публикации атласа).
А вот трюк, который я подсмотрел в «AndEngine for Android Game Development Cookbook» — отключение отрисовки фона Activity, он нигде не виден и не используется, а на FPS влияет заметно. Для этого создаем свою тему в res/values:
<resources>
<style name="Theme.NoBackground" parent="android:Theme">
<item name="android:windowBackground">@null</item>
</style>
</resources>
И в манифесте устанавливаем ее для нашей Activity:
android:theme="@style/Theme.NoBackground"
Фрагментация
Еще одна вещь, о которой интересно рассказать — борьба с различными разрешениями экранов устройств на Android. Изначально, игра разработана под соотношение сторон 16:9. Я рассматривал 3 варианта масштабирования изображения под другие экраны, условно назовем их:
1. Original size — правильное соотношение сторон, картинка полностью заполняет экран по вертикали, но за счет этого, появляются не используемые области по бокам
2. Zoom screen — то же самое, но картинка заполняет экран по горизонтали, «лишняя» часть для фонов сверху и снизу обрезается, а элементы интерфейса сдвигаются к центру
3. Stretch screen — просто растягиваем игру по размерам экрана, без соблюдения соотношения сторон
Покажу, как это выглядит на примере максимально не соответствующего соотношения сторон — 4:3
Слева-направо: original size, zoom screen, stretch screen
Очевидно, напрашивается и четвертый вариант: перерисовать графику под 4:3, но использовать для игровых элементов также область 16:9. То есть получится вариант 1, но с декорациями уровня вместо рамок по бокам. Отличный вариант, на самом деле, жаль мне подсказали его поздно, все-таки перерисовывание графики — это не так просто и быстро. Но так как внутренний перфекционист никак не хотел успокоиться, в результате, графику все же перерисовали (не всю, в основном фоны) и теперь на планшетах игра выглядит даже лучше чем на смартфонах!
Скриншоты с планшета (4:3) и смартфона (16:9)
Кто-то скажет: «Пффф! Открыл Америку!», но не всегда удается научиться на чужих ошибках, иногда приходится изобретать свои «велосипеды», чтобы понять как правильнее и лучше. В частности, в AndEngine «из коробки» нет такого типа Камеры, на котором я в результате остановился. И в туториалах, особо о таких подходах не пишут.
Расходы и благодарности
Так как о доходах мне рассказать нечего, расскажу о расходах. Время создания игры от первого commit-a до публикации в Google Play, составило почти три месяца. Свое чистое время, как программиста, я бы оценил где-то в полтора месяца (игра делалась в свободное время и иногда надо было ждать результата от других участников команды, естественно). Пусть это будет ~3000$ по ставке. С профессиональным и очень талантливым художником, Егором, мы работаем уже над второй игрой на условиях разделения возможной прибыли, поэтому абсолютную стоимость создания арта к игре, я не знаю как учесть (разве что по времени тоже). Локализация страницы Google Play на основные языки, обошлась мне примерно в 60$ (короткое описание и подписи к скриншотам).
За звуковое оформление хочу поблагодарить ребят из Gamingearz. С ними я тоже сотрудничаю не первый раз, все как всегда на высшем уровне и в кратчайшие сроки. Ребята с большим вниманием и любовью относятся к своему делу и что не менее важно, для таких инди-разработчиков как я, готовы предложить варианты в рамках ограниченного бюджета. Для «Way of Tanks» они записали просто потрясный саундтрек (плюс несколько игровых звуков) за символические 200$. А всякие интерфейсные звуки я сделал сам с помощью сервиса diforb.com.
Промо-ролик для игры создал профессиональный фотограф и просто хороший человек — Сергей Муратов из Минска. И он тоже не первый раз делает видео к моим играм. Я, как и все, склонен обращаться к людям с которыми уже был успешный опыт работы, ранее. Это плюс еще 100$. Вот практически, и все затраты. У меня, конечно, есть еще пару идей по маркетинговым вложениям, но это опционально. Сначала хочется понять, понравится ли «Way of Tanks» игрокам так же, как он нравится мне?
Суммируя все расходы, получается, что собственный несложный раннер на Google Play обойдется примерно в 3500 долларов. Много это или мало — решайте сами. По мне, так это справедливая цена за удовольствие от интересной и хорошо выполненной работы, за нажатие заветной кнопки «Опубликовать» в Developer Console, за возможность сыграть в «лотерею сторов», в которую играют все инди. И может быть даже что-то выиграть, кто знает…
Комментарии (43)
Grammidin
16.04.2015 11:04Расскажите, а какие у Вас внутриигровые покупки? Интересно, что продается в подобном раннере.
ps К сожалению, мой samsung galaxy s plus не поддерживается :(coder1cv8 Автор
16.04.2015 11:59Ну пока ничего не продается =)
Я вообще не сторонник F2P-модели. Здесь есть внутриигровые покупки, но скорее «абы были».
Lerg
16.04.2015 13:55Арт замечательный и играется действительно неплохо. Почему не обратились к издателю? Я бы на вашем месте сейчас же побежал всем писать. Только у многих есть условие, что игра не должна была выходить до этого самостоятельно, но может ещё можно успеть.
Вашу игру будет легко рекламировать за счёт качественно исполнения, плюс есть монетизация, издателям только это и нужно.coder1cv8 Автор
16.04.2015 15:10+2Спасибо! А зачем к издателю? ) Что есть у издателя такого, чего нет у меня? Ну кроме желания любыми средствами заработать. Мне, конечно, это желание тоже не чуждо, но я не стал бы из-за этого портить свой продукт, к примеру.
Lerg
16.04.2015 15:41Деньги, опыт, пользовательская база, маркетинг. С издателем хорошие игры быстрее набирают популярность и быстрее начинают приносить прибыль. Издатель также может компенсировать затраты на производство и помочь советами.
coder1cv8 Автор
16.04.2015 15:50+3Это как раз то, что есть и у меня ) Хотя я и люблю иногда «прикинуться валенком»
Dimmerg
21.04.2015 12:02Lerg, вы прямо как по книжке говорите. Сложно все с издателями и с подобной игрой к ним смысла идти нет.
Lerg
21.04.2015 12:03Почему нет?
Dimmerg
21.04.2015 14:47Потому что для того, чтобы игра окупала залитый трафик (а именно так издатель и будет ее продвигать, если это нормальный издатель и вообще продвигать будет), в современных реалиях нужны крайне высокие показатели LTV и ARPU. В этой игре это нереально из-за:
1) очень мягкой монетизации — автор сам признает, что IAPы добавлены для галочки
2) отсутствия особой глубины в игре — нет ни большого разнообразия в игровом процессе, ни какой-то особой модели прокачки. То есть залипнуть надолго игрок не сможет
Таким образом, поход с такой игрой к издателю завершится одним из двух вариантов:
— «игра отличная, но надо кое-что доделать» — после чего выкидывается список фич на х2-х3 объема от уже проделанной работы, а игру после этих фич будет не узнать
— «отлично, издаемся завтра!» — это в случае, если издатель левый и выложит игру под своим акком, но продвижения вы не увидите.
Справедливости ради, это не говорит плохо об игре — игра отличная, но издателям сейчас нужны другие игры — с большим кол-вом контента, с выверенной монетизацией, те, в которых зависимость выходного потока денег Y легко просчитывается от входного потока денег X. Исключения бывают, но они лишь подтверждают правило.Lerg
21.04.2015 14:54Я так и предполагал, что монетизацию придётся усилить с издателем. Это очевидно. Издатель мотивирует на внедрение дополнительных фич (прокачка и прочее) и это хорошо, игра будет интереснее. Все выигрывают.
Dimmerg
21.04.2015 22:43Вынужден опять вас вернуть к самому началу ветки — все сложно с издателем. Хотите примеров? Я перечислю что может быть, а вы легко можете нагуглить реальные примеры:
1) Ваше мнение об игре и мнение издателя может разойтись кардинально — скажем вы не хотите превращать игру в очевидную доилку, так как это явно снижает качество игры и игрового процесса. Издателю на это зачастую пофиг, лишь бы машина вертелась и деньги приносила.
2) Издатель легко может «передумать» в середине процесса переделок или даже перед релизом — в итоге вы останетесь с игрой по его лекалам, но с вашими лично возможностями.
3) Мотивация на доп. фичи — это хорошо, но не у всех список задач еще на год может вызвать оптимизм после полугода-года активной разработки.
4) Издатель скорее всего не будет возиться с вашей игрой и давать ей второй шанс — не пошла, так не пошла, никаких «мы щас все переделаем, а вы ее снова в топ загоните». Бывают, конечно, исключения, но редко.
Ns2033
17.04.2015 13:41На счет желания заработать. Встречал рекомендацию для совсем бесплатных проектов: повесить кнопку на пожертвования на видном месте — пользователи более чем готовы добровольно поощрять рублем или долларом качественный контент.
Flamekinzealot
16.04.2015 17:45Отличная работа! Обязательно поиграю.
А можешь подсказать контакты дизайнера?
Lerg
16.04.2015 23:10Поиграл. Купил второй танк. Я так понимаю отличия только визуальные? Потомучто никаких особых улучшений характеристик я не заметил.
Не хватает игре апгрейда самого танка — больше жизней, больше манёвренность, больше урон орудием, быстрее перезарядка. Рекорд 1935.
И управление бы такое, при котором не нужно часто отрывать палец от экрана. Махнул влево, затем не отрывая вверх или обратно вправо и танк делает несколько движений за одно касание пальцем.coder1cv8 Автор
17.04.2015 05:50Ну в общем-то, да. Отличия танков, по большому счету, визуальные. Второй немного быстрее стартует, раз он «racing tank», а третий пробивает два препятствия одним выстрелом. Прокачка танков у нас была в планах изначально, но в процессе ее порезали, для того чтобы не перегружать интерфейс и побыстрее зарелизиться. В результате, остались только временные бонусы на ту же маневренность, урон и тд. И такое управление, как вы предлагаете, я тоже пробовал, но отказался из-за ложных срабатываний. В любом случае, спасиб! =) Приятно, когда твоей игре уделяют внимание!
priv8v
17.04.2015 09:44В Strore есть раздел Increase и там разные характеристики, которые можно за золотые гаечки улучшить. На что это влияет? А то улучшаю, а изменений не заметно.
coder1cv8 Автор
17.04.2015 09:48Там в заголовке так и написано «increase powerups time» ) Ну то есть увеличивает время действия конкретного пауэрапа, когда ты его подбираешь. При полной прокачке, будет действовать в два раза дольше чем изначально.
priv8v
17.04.2015 11:04Ага, увеличение действия времени закланинания в 1.2 раза мог заметить не смог :)
priv8v
20.04.2015 11:41С высоты игрового опыта (в сумме на выходных поиграл где-то часа полтора) могу сказать следующее:
С точки зрения монетизации приложения:
1. Монеты особо не нужны — игре они никак практически не помогут, да, будут просто подольше действовать бонусы, но на прохождение это особо не влияет.
2. Танки покупать стоит только ради разнообразия цветового. Слишком мало отличий от дефолтного. Не мотивируют.
3. Ничего нельзя купить такого, чтоб было некое преимущество/плюшка. Все эти монеты зарабатываются достаточно быстро итак + см. п.1
С точки зрения игрового процесса:
1. Броневику можно заехать в бок и мне за это ничего не будет — проеду по нему (забавно)
2. Слишком однообразно — ямкиежики, броневики, ямкиежики, самолет, ямкиминыежики, песец
3. Далеко никуда не пройдешь, все постоянно с начала, ничего не прокачать фактически, нигде не закрепиться, никаких преимуществ не получить, по локации не продвинуться.
4. Все навороты для прохождения игры вероятно будут совершенно бесполезно — у меня рок-н-рол танк, много прокачано другого, но это никак мне не помогло даже приблизится (даже выполнить его на 80%) к моему рекорду, нечаянно поставленному в первые 10 минут игры.
5. Игра слишком сложная (возможно, это следствие всех предыдущих пунктов — просто никуда не пройти далеко).
Воспринимайте это просто как отзыв игрока, который сделал прикидки «а как игру можно улучшить?», а не как огульную критику.coder1cv8 Автор
20.04.2015 13:35Спасибо большое, я очень ценю такие подробные отзывы! По монетизации: да-да, все так и есть. Я знаю, что она очень мягкая. Вижу, что покупают только «booster pack» (самый маленький пакет золота), значит, особой необходимости в монетах ни у кого нет. Но с другой стороны, я и не ставлю цели заработать на инаппах.
Для броневика, я увеличу хитбокс, вы правы. Они для всех объектов небольшие, чтобы столкновения происходили когда уж наверняка! Но с броневиком я перестарался. Контентом игру, конечно же, будем наполнять! Сейчас, действительно, немного однообразно.
P.S. Меня на выходных подвинули с первой позиции внутри игрового рейтинга. Какой-то чувак проехал 8 с лишним тысяч метров, а вы говорите «слишком сложно» =)priv8v
20.04.2015 13:54У меня в районе 2 тысяч предел постоянный. Один рекордсмен не показатель. Думаю по статистике видно насколько далеко в среднем продвигаются люди. У меня в среднем — чуть дальше самолетика, а это совсем близко. Несколько раз проехал и все — поднадоело. Я долго ездил лишь чтоб игру потестить и помочь советом соотечественнику :)
coder1cv8 Автор
21.04.2015 18:34+1Вести «с полей»: я улучшил немного управляемость танка (на нее многие жаловались) и выкатил обновление. За первую неделю мы перешагнули рубеж в 10 тыс загрузок, что неплохо, я считаю! Еще, очень прикольно наблюдать в Гугл Аналитике как в твою игру кто-то играет прямо сейчас:
Mihasik1984
15.05.2015 15:08Игра хорошо сделана и красиво выглядит. Если бы вышла годика 3-4 назад, был бы хит, а так, рядовой ранер. ))
PapaBubaDiop
Не хватает 30-секундного видео, чтобы насладиться звуками и движением.
coder1cv8 Автор
Да у меня как-то нет подходящего видео ) Промо-ролик сюда вставлять было бы неуместно. А мой «самопал» со словом «насладится» никак не вяжется.
dmitrynosov
Промо-ролик:
vah13
супер, мне понравилось, а если не секрет какой сервис использовали для снятия промо-ролика?
coder1cv8 Автор
Не сервис, знакомый фотограф. Тут в последних абзацах все есть, читайте )