Разработка тайловой игры на JavaScript (Robbo)

Дорогие жители Хаброхабра!

В этот раз я принёс вам историю про javascript, atari и canvas! Игра называется Robbo и является портом одноименной игры 1989 года.
image

Сама игрушка. Игрушка с выключенным звуком. Ссылка на github.
Управление осуществляется стрелками. Если есть патроны, то shift+стрелка выстрелит в нужном направлении.

История

Кому не интересна предыстория — пролистывайте сразу следующие несколько абзацев до раздела «Техническая реализация».

В детстве у меня был компьютер Atari 130 XE. Родители купили его когда мне было 2 года. По их рассказам именно в этом возрасте я падал со стула с джойстиком, убегая от совы на втором уровне Robbo.

Robbo

Эта игра была написана польским програмистом Janus Pelc и выпущена в 1989 году. Это была моя любимая игра детства.

В институте моей маме преподавали программирование и она решила в 4 года научить меня бэйсику. Тогда и была предпринята первая попытка переписать роббо самостоятельно. Плохо было то, что я знал только операторы PRINT, INPUT и POKE. Ни к чему хорошему это не привело/ Z не мог даже представить как возможно написать такую игру, то что я делал было похоже на брутфорс по всем ходам. Пользователь нажал вправо и отпринтилось состояние где персонаж смещен на одну клетку вправо, то есть это была аскиарт стэйтмашина в чистом виде. Если бы я знал о текстовых квестах, то их бы таким методом реализовать вышло, но я не знал.

Следующая итерация была в девятом классе. Это был уже Visual Basic и AMD-K6 II 500. В то время журнал Upgrade решил выпустить свой первый номер с диском, а у меня как раз была некоторая реализация игры. В MS Paint была нарисована груда спрайтов с их фирменными пионерами, после чего я выслал им эту игрушку. Через несколько месяцев сдох винт и код был утерян. В коде были только массивы, даже структуры не использовались, один алгоритм обхода лабиринта по правилу правой руки NPC занимал восемь А4 страниц кода (я не шучу). Нормального интернета тогда ещё не было, только диалап.

В 11 классе всё на том же Visual Basic была написано новая версия. Тут код стал заметно лучше, я не расписывал разное поведение для 4 направлений движения.

Прошло 8 лет. Познание паттернов, чтение уймы литературы и практического опыта, изучение вереницы языков, любовь к функциональному стилю и js в частности, развитие HTML 5. И я вновь вернулся к Robbo. Все эти годы я иногда вечерами запускал эмулятор атари (Atari800Win) и играл в любимую игру детства. За 2 дня я написал код, где было намного меньше строк чем раньше. После чего наступило прозрение что это надо отрефакторить. Рефакторинг растянулся на несколько месяцев. Это некоммерческий проект, то есть хобби, потому я старался вылизывать код, хотя до сих пор остались огрехи за которые мне стыдно. Более подробно с чем я столкнулся я опишу в технической части.

GnuRobbo.

Есть похожий open source проект GnuRobbo. Они реализовывали robbo на c++ кроссплатформенно (сейчас есть даже рабочая версия под Андроид в гугл плэй). Последние несколько лет когда меня тянуло вспомнить robbo — я запускал именно эту реализацию. Когда я начал работу над этим проектом меня подмывало посмотреть как что сделано у них, так вот, при общей схожести (если переключить скин в classic) создаётся ощущение что это robbo, но на самом деле отличающихся мест чертовски много. Создаётся ощущение что разработка не была пропитана любовью, как бы странно это не звучало.

Техническо популярная часть.

Любая игрушка, где есть живой мир строится вокруг некоторой реализации бесконечного цикла. Тут нет ничего сложного, обычный вызов функции через setInterval. В этой функции находится расчёт нового состояния мира и перерисовка изменившихся частей.

Рассмотрев игру я понял что многие объекты в этом мире реализуют одинаковое поведение. Так бомбу, камень, некоторые пушки, звездолёт можно двигать, уперевшись в них.

Сами объекты получились предельно простыми. Вот, для примера код двери (door.js):

(function( R ){     'use strict';     R.objects.Door = {         // дверь можно взорвать         explodable: true,         // если ткнуться в дверь, то случится поведение поедания двери         eatable: true,         eat: function( eater ){             // если у того кто хочет съесть дверь есть хотя бы один ключ             if( eater.keys > 0 ){                 // отнимем у него один ключ                 eater.set( 'keys', eater.keys - 1 );                 // уничтожим дверь                 this.game.setCell( this, 'Empty' );                 // и сыграем звук отворяющейся дверь                 this.game.playSound('door_default')             }             // функция eat вызывается извне, и если она возвращает false, то это значит             // что объект на самом деле есть нельзя. В случае двери она сама уничтожает себя,             // потому что в оригинальном роббо мы не едим дверь как болт, а только отворяем её.              return false;         }     }; } )(window.R); 

С таким подходом сделать простые объекты вышло быстро. А вот с лавой, бомбами, взрывами, пулями и телепортом пришлось повозиться.

Бомба и взрыв

image
Бомба — это объект, который взрывается и разносит всё что находится на расстоянии одной клетки от него. В оригинальном роббо это действительно похоже на взрыв, а в gnuRobbo на всю красоту забили.
Было записано большое количество видео того как взрывается бомба в эмуляторе, после чего на бумагу была переписана раскадровка спрайтов взрыва. Два дня я созерцал цифры. За это время я узнал что аниация взрыва имеет 5 состояний сначала взрыв усиливается, а потом затухает, но делает он это не равномерно во всех направлениях, а по некоторому паттерну. На форуме гнуроббо кто-то уже замечал что взрывы отличаются и предполагали что это рэндом, но нет, это не мог быть рэндом. В те времена получение псевдослучайных чисел было дорогой забавой.

Насмотревшись на цифры достаточно я вывел закономерности и две матрицы взрывов. Матрица накладывается на соседние клетки и там где число больше нуля ставится объект взрыва с анимацией, соответствующей числу из матрицы. Если там уже был взрыв, то к его анимации добавляется число из матрицы, после чего делается max( 5, animation ).
1) Матрица момента после касания бомбы пулей или соседним взрывом:

0, 0, 0, 0, 0, 2, 5, 4, 5</code> В этот момент бомба ещё жива как объект и визуально.  2) На следующем такте  накладывается матрица: <source lang="dos"> 5, 4, 5, 4, 3, 2, 0, 0, 0 

Для одной бомбы результат получается идентичен оригинальной игре.
Для нескольких бомб — ещё не идентичен. Выглядит похоже на оригинальную анимацию, но ещё требует доработки (стыдно).

Сам взрыв же представлен объектом, занимающим одну клетку и уменьшающим свою анимацию на 1 за каждый шаг. После взрыва этот объект умеет позвать коллбэк или выставить на своё место заранее заданный другой объект.

Фактически взрывов в игре много:
Дым от разорвавшегося патрона, уничтожение объекта, взрыв бомбы, телепортация из, телепортация в (тут анимация взрыва идёт в обратном порядке)

Телепорт

image
Телепорт работает собственно как телепорт. Перемещает роббо из одной части карты в другую. Во входной точке роббо дематериализуется, а на выходе — материализуется обратно. Если войдёт справа, то выйдет с левой стороны. Интересные случаи начинаются когда в выходной точке нужный выход заблокирован, иногда и все стороны выхода закрыты, а иногда точку выхода могли взорвать. Телепорты не обязательно связаны попарно, они могут быть закольцованы и большим числом выходов. В своей реализации я сделал возможность выхода и не в другом телепорте, но это на будущее, когда буду делать игру со своей идеей. На эмуляторе я проверял все эти состояния и записывал что к чему приводит. Любовь к оптимизации пришла ко мне из ассемблера, потому я постароил таблицу начальное -> конечное состояние и свёл выбор выходной клетки к выражению без условного оператора. Это была больше игра в подбери выражение, в данном случае она не оправдана, но раз уж потратил время, то оставил. Фактически вышло что надо инкрементивно проделывать операцию xor текущего направления с 11|10|11|10.
У нас есть входное направление. Допустим мы вошли справа, что соответствует направлению 2 (вошли справа, значит шли в левую сторону). Алгоритм попробует клетки 2 (влево), 1 (вниз) (10^11 = 01), 3 (вверх) (01^10 = 11), 0 (вправо) (11^11 = 0), после чего вернёт направление в исходное состояние (в случае если все выходы заблокированы).

В виде алгоритма это выглядит так:

var tryCell, i; for( i = 0; i < 4; i++ ){     tryCell = this.game.getCell( R.addDirection( this.teleportX, this.teleportY, obj.direction ) );     if( tryCell.is( 'Empty' ) )         break;     obj.direction = obj.direction ^ ( 3 - i % 2 ); } 
Лава.

image
Объект, который двигается слева направо (или наоборот) всей строкой. Сметает на своём пути всё кроме стен. Сначала я пытался реализовать это поведение на уровне одной клетки, как у остальных объектов, но оказалось что гораздо проще в одном шаге одного объекта рассмотреть всех соседей на горизонтальной линии, ограниченной стенами, подвинуть их и сказать им что в этом шаге мира их действия больше не нужны.

Техническая часть

Код игры разделён на логические модули, основные: контроллер, вьюха, менеджер спрайтов, обработчик клавиатуры, объекты (по модулю на каждый отдельный объект и фабрика объектов).

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

Изначально мне показалось что перебирать всё игровое поле и смотреть является ли объект живым — не самый оптимальный подход. Так родился список активных объектов. В шаге мира обрабатывается только их поведение.

В контроллер были вынесены общие функции работы с картой, такие как:
swap — поменять местами два объекта. Активно используется при перемещении одиночных объектов (шаг, одиночный выстрел, npc)
getCell( x, y ) — вернёт объект с заданной позицией
getCell( obj ) -> вернёт объект, находящийся в координатах obj.x, obj.y

setCell( x, y, obj, data ) — ставит объект в заданную позицию. Obj может быть как другим объектом, так и именем объекта (например, ‘Explosion’). В случае имени объекта — позовётся фабрика объектов.
setCell( obj1, obj2, data ) -> делает то же самое, только координаты выдирает из obj1.x, obj1.y

Всё выглядело просто, пока не началось тестирование оригинального геймплея. Тут выяснилось что в оригинальной игре если упереться камнем в летающую вверх-вниз птицу справа, то в следующем шаге роббо умрёт, а если слева, то проскочит над ней. Пришлось сортировать actionObjects в соответствии с порядком обхода оригинальным игры.

Спрайты

Перерисовывать всё игровое поле на каждом шаге было бы неправильно с точки зрения производительности (хотя и не критично для современных компьютеров). Здесь я реализовал хэш по изменным спрайтам объектов, который состоит из координат key: y объекта, а в нём лежит хэш всех объектов, измененных с последней отрисовки в этой строке с key: object.x, а value: самим объектом. Этим я убил сразу двух зайцев: не делается лишний обход всего поля и отрисовывается измененная клетка только один раз, даже если там было несколько изменений (например, птица передвинулась в клетку вниз, а потом её поглотила лава, и всё это за один шаг мира).

Сами спрайты были сначала честно утянуты из gnu robbo, но очень скоро я понял что это было сделано зря. Проще было сразу делать оригинальные, чем возиться и играть в пикселькэтчинг (некоторые они допиксельартили до большего разрешения, неоторые доантиалиасили, а некоторые придумали свои), также у них не хватало процентов 80 спрайтов стен (их в игре оказалось заметно больше, чем я предполагал).

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

Отдельной главы заслуживает палитра спрайтов.

Я не сразу заметил что в оригинальном роббо на каждом уровне используется свой набор цветов.
Это очень частое решение тех лет разработки игр и демосцены. Памяти было мало, а визуальных эффектов уже хотелось, потому в старых компьютерах была простая возможность поменять соответствие номера из палитры к непосредственно цвету.
Решение было сделано в лоб — в конфиг каждого уровня добавились все цвета, выдранные из оригинальных уровней игры, все спрайты были приведены к 4 общим цветам. На загрузке уровня идёт попиксельное перекрашивание всей картинки в новую цветовую схему.

Буквально на прошлой неделе я сделал отдельный проект (будет пост, если интересно), который позволяет производить изменение палитры без попиксельных манипуляций. Поразительно, но этот метод работает в IE7.
Но эту технологию я ещё не втянул в текущий код игры.

Заключение

В игре ещё есть некоторые огрехи.

В планах:

  • Доразрулить взрыв группы бомб.
  • Сделать поддержку старых браузеров.
  • Вытянуть цвета общего фона вокруг игрового поля и цифр из оригинальной игры.
  • Сделать кончающиеся жизни (сейчас это уже олдскул, но ведь и игрушка сама из тех времён).
  • Доделать поддержку тач управления для мобильных платформ, сделать поддержку smart tv для игры с пульта телевизора.
  • Ну и, конечно, портировать финальный мультик.

В отдалённых планах:

  • Сделать редактор уровней с редактором объектов, где пользователь сможет нарисовать свой объект, нарисовать ему цепочку спрайтов и выбрать различные поведения из обширного предефайнд списка. Это даст возможность сделать из роббо сокобан, пакмэна (тут надо ещё межклеточное перемещение продумать), боулдердаш, тетрис, да хоть арканоид.
  • Сделать общую базу уровней, где пользователи смогут добавлять свои, а другие смогут голосовать за понравившиеся.

Я пообещал себе выложить этот релиз до нового года и написать в общих чертах о разработке. Вроде удалось. Есть ещё места, за которые мне стыдно (в частности вся работа с загрузкой уровней, анимация смены уровней).
Всех с наступающими праздниками!

ссылка на оригинал статьи http://habrahabr.ru/post/207920/

Выставка «Информатика в США»: документальный фильм о выставке

С наступающим Новым Годом, Хабр!

Сегодня, в канун Нового Года, я хотел бы поделиться с уважаемым сообщетвом удивительной находкой — документальным фильмом о проходившей в 1987-1988 годах в крупных городах СССР выставке, посвященной теме применения информационных технологий в различных сферах жизни США.
Статья про выставку на Википедии

Итак располагаемся поудобнее, выставляем на табло год 1987, запускаем двигатель и разгоняем DeLorean до 88 миль в час…86…87…88… Поехали!

ссылка на оригинал статьи http://habrahabr.ru/post/207918/

Как начать майнить для начинающих

Идея и название статьи подсказано юзером Xao в комментарии к недавнему посту Что делать с Bitcoin нам, обычным людям, а также многочисленными вопросами на Тостере. Эта инструкция поможет начать майнинг на обыкновенных компьютерах и ноутбуках под управлением ОС Windows или Linux в составе пула совместной генерации криптовалюты.

Как верно заметил dzzh

Смысла нет сейчас биткоин майнить. Какие-то мелкие монетки генерировать и через биржи в биткоин выводить — еще да.

Поэтому начать майнинг придется с выбора криптовалюты. Данная инструкция состоит из 5 простых шагов:

  1. Выбор форка
  2. Выбор пула
  3. Выбор майнера
  4. Запуск майнинга
  5. Вывод на свой кошелек

1. Выбор форка

Уже появилось довольно много форков Bitcoin, а также основанных на собственном исходном коде криптовалют. Основным критерием для выбора является профитность майнинга криптовалюты. Второстепенным критерием, например, для меня является ее ликвидность, т.е. простота обращения криптовалюты в т.н. «живые деньги» (рубли, доллары, евро на вашем счете в банке).
Также имеет значение используемый алгоритм шифрования. Bitcoin основан на SHA-256, майнить биткоины сейчас имеет смысл владельцам дорогостоящих ферм. Но например, scrypt интенсивно использует оперативную память. Это делает проблематичным использование и создание специальных процессоров ASIC для scrypt криптовалют и дает возможность эффективно использовать для майнинга обычные компьютеры c видеокартами.

Профитность майнинга

Другими словами, сколько можно заработать криптовалюты на единицу вычислительной сложности (в качестве ее можно взять единицу hashrate, измеряется hash/s).
Имеет смысл оценивать профитность лично для себя, например, в количестве монет, получаемых вами в сутки или в месяц.
Например, моя видеокарта Nvidia GTX 770 позволяет мне майнить Feathercoin со скоростью 210 khash/s, получая от пула ~6 FTC в сутки, что в зависимости от курса на бирже дает мне профитность 60-100 рублей в день.
Оценить профитность помогут следующие ресурсы:

  • Калькулятор энергозатрат и профитности www.coinwarz.com
  • Калькулятор с таблицей сравнения популярных форков (введите снизу свою скорость) dustcoin.com
Ликвидность криптовалюты

Ее помогут оценить следующие ресурсы с временными графиками курсов форков:

Или можно просто выбрать из тех форков, которые торгуются на русскоязычной бирже btc-e.com, где мы будем «обналичивать» заработок от майнинга. Это позволит избежать дополнительного шага на пути к получению профита от майнинга. Если же вы все-таки выберете форк, не торгуемый на бирже, добро пожаловать на обменникcryptsy.com.

2. Выбор пула

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

3. Выбор майнера

Для майнинга криптовалют на алгоритмах SHA-256, scrypt можно использовать любой из популярных майнеров:

  • cudaminer — для майнинга на видеокартах (GPU) Nvidia
  • cgminer — для майнинга на видеокартах (GPU) ATI
  • pooler cpu miner (minerd) — для майнинга на процессорах (CPU)

4. Запуск майнинга

В случае использования майнера cgminer, например, для Linux без графического интерфейса наберите в командной строке:

./cgminer --scrypt  -o stratum+tcp://хост_пула:порт -u Weblogin.Worker -p Worker_password 

где Weblogin.Worker — имя Вашего воркера, а Worker_password — его пароль
Пример подразумевает, что пул поддерживает протокол strtatum, что является де-факто стандартом для всех современных пулов.

Майнинг на CPU

В случае отсутствия видеокарты майнить можно на центральном процессоре.
Загрузите Pooler CPU Miner 32bit или 64bit для Windows.
Распакуйте архив и перейдите в созданную папку.
Создайте текстовый документ со следующим содержанием:

minerd.exe --url stratum+tcp://хост_пула:порт --userpass Weblogin.Worker:Worker_password 

где Weblogin.Worker — имя Вашего воркера, а Worker_password — его пароль
Сохраните документ, после чего переименуйте, например, в miner.bat
Если верно настроены параметры авторизации и URL адрес пула, вы увидите после запуска окно с информацией о майнинге в пуле.

5. Вывод на свой кошелек

Скачайте кошелек с официального сайта выбранного форка.
Создайте адрес в своем кошельке для получения заработанных в пуле монет и введите его в разделе Аккаунт — Выплаты вашего пула.
Допускаются выплаты напрямую на биржы криптовалют, например btc-e.com, там необходимо предварительно зарегистрироваться и создать адрес для пополнения выбранной вами криптовалюты.

Не стоит забывать о комиссии с транзакций на вывод — чем чаще вы выводите криптовалюту с баланса пула, тем чаще оплачиваете эту комисиию.

ссылка на оригинал статьи http://habrahabr.ru/post/207844/

Новогоднее поздравление от робота

Уже началось 31е, совсем скоро Новый год. Спать еще не хочется, хочется ощущения праздника. И тут взгляд падает на моего пыльного Arduino-робота, до которого уже пару месяцев не доходят руки. Что же новогоднее может сделать робот? Конечно же сыграть Jingle bells! Два часа усилий, борьба с отсутсвием музыкального слуха, и вот он — результат:

Всех с наступающим!

Под катом код, и немного комментариев

#pragma once  void beep(int tone, int duration) {   for (long i = 0; i < duration * 1000L; i += tone * 2) {     digitalWrite(BEEPER, HIGH);     delayMicroseconds(tone);     digitalWrite(BEEPER, LOW);     delayMicroseconds(tone);   } }  void play_note(char note, int duration) {   char names[] = { 'c', 'd', 'e', 'f', 'g', 'a', 'b', 'C' };   int tones[] = { 1915, 1700, 1519, 1432, 1275, 1136, 1014, 956 };    for (int i = 0; i < 8; i++) {     if (names[i] == note) {       beep(tones[i], duration);     }   } }  void jingle_bells() {   char sounds[] = "b1b1b2b1b1b2b1d1g1a1b4c1c1c1c1c1b1b1b1b1a1a1b1a2d2b1b1b2b1b1b2b1d1g1a1b4c1c1c1c1b1b1b1d1d1c1a1g6";   const int length = sizeof(sounds) / 2;   char* notes = new char[length];   int* beats = new int[length];   for (int i = 0; i < length; ++i) {     notes[i] = sounds[2 * i];     beats[i] = atoi(&sounds[2 * i + 1]);   }   static const int tempo = 300;   for (int i = 0; i < length; i++) {     play_note(notes[i], beats[i] * tempo);     delay(tempo / 2);    }   delete[] notes;   delete[] beats; } 

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

Формат звука такой — нечетные символы — ноты, четные — их длительность.
BEEPER — это номер контакта arduino, к которому подключена пьезо-пищалка.
Перед использованием jingle_bells стоит установить контакт пищалки в OUTPUT (например в функции setup): pinMode(BEEPER, OUTPUT);

ссылка на оригинал статьи http://habrahabr.ru/post/207912/

Spine — первые шаги

Привет Хабр!

Относительно недавно на кикстартере завершился сбор денег на новый инструмент для игроделов, но на Хабре это не было освещено. Spine —программа для создания скелетной 2d анимации. Этот инструмент будет интересен не только инди-разработчикам и начинающим гейм дизайнерам, но также опытным игрокам рынка. Простота в использовании и притягательный дизайн создают впечатление творящегося на экране волшебства.

Всех заинтересовавшихся прошу под кат (много картинок).

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

1. Подготовка к работе

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

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

Таким образом у нас есть папка где лежат рисунки частей тела — плоть нашего чудовища, а также исходное изображение. А вот теперь начинается самое интересное.

2. Готовим сборочный стол

Запускаем Spine. В главном меню выполняем команду New project.
В окне иерархии выбираем пункт Images и с помощью кнопки Browse выбираем нашу папку с картинками.

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

4. Собираем скелет

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

а затем инструмент Create new bones

Старшей костью после root выберем кость таза (pelvis), и создаем ее простым нажатием на нужное место изображения. Вокруг этой кости будут вращаться все остальные. Другие кости создаем путем протягивания курсора (Drag-and-drop) от конца старшей кости до необходимого размера. Желательно, но не критично, чтобы кость соответствовала по длине размеру части тела.
Иерархия костей получаеться следующая.

5. Пришиваем мясо к костям —монстр уже почти готов

Теперь каждой кости нужно поставить в соответствие изображение части тела. Выбираем файл изображения и нажимаем на кнопку Set Parent.

Курсор приобретает новое очертание и мы можем кликнуть на ту кость к которой будет приложено данное изображение. Мы можем поворачивать (Rotate), перемещать (Translate) и масштабировать (Scale) наши изображения и кости, добиваясь правильного расположения согласно шаблону.

А выглядеть все должно в конечном итоге примерно так:

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

6. Оживление —IT’S ALIVE

Нажимаем на переключатель и переходим в режим анимации .
Каждый уважающий себя Франкенштейн должен уметь ходить. Выбираем в окне иерархии строку Animations, нажимаем на кнопку New Animation и создаем анимацию с именем walk.

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

В окне Dopesheet должен появиться первый ключевой кадр на нулевой отметке времени. Белые, зеленые, синие и красные палочки показывают сделанные нами изменения. Чтобы выделить их все нужно нажать на самую верхнюю белую палочку в строке walk.

Выделив весь первый кадр, скопируем его и переместим указатель на новое место временной шкалы (8 к примеру), куда и вставим этот кадр. Теперь у нас два одинаковых кадра на нулевом и на восьмом делении. Теперь нужно изменить кадр на восьмом делении так, будто тело пошевелилось и зафиксировать изменения.

Теперь когда мы зафиксировали новые изменения Spine сам будет плавно перемещать изображения от первого кадра ко второму. Эти перемещения показаны серыми горизонтальными линиями на временной шкале.
Скопируем эти два кадра и вставим их на 20 и 28 деления соответственно. Теперь нужно лишь поменять местами правые и левые конечности. Там где была правая нога стала левая нога, там где была левая рука стала правая рука и наоборот.
На 40 деление просто скопируем самый первый кадр, для того чтобы сделать анимацию цикличной.

Нажимаем на кнопку play (дергаем рубильник) и вот наш монстр оживает. Это еще не Disney но к уровню Машиных сказок мы уже приближаемся. В свойствах воспроизведения можно установить скорость и способ воспроизведения.

Теперь анимация готова, осталось только экспортировать ее в нужный нам формат.
Есть три типа экспорта: данные, изображения и видео. Первый тип включает в себя json и bin. В таком виде наша анимация передается в игровой проект с использованием Spine runtime — специального API для работы с анимацией Spine.
Для любителей хардкорной покадровой или gif анимации можно экспортировать проект, как последовательность кадров (jpeg, png) или записать все в формате gif. Также есть возможность представить анимацию, как видеозапись avi или QuickTime. Но все эти функции увы, только в полной платной версии (60$).

6. Управляем нашим монстром

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

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

Чтобы не быть голословным представляю свою зверушку на суд людской: (.jar и .exe).

ссылка на оригинал статьи http://habrahabr.ru/post/207904/