Компания
54,82
рейтинг
15 марта 2014 в 00:47

Разное → Flappy Bot для Flappy Bird

image
Сумасшедшая игра. Какой хлопец не слышал про Flappy Bird? Про 50 000 долларов дохода в день? Игре посвящены финансовые отчеты, веселые песни, желтые статьи и научные исследования. Китайские ребята даже изобрели механического робота, гоняющего птицу.
Ах, и я установил приложение на любимый iPhone 2007 года. В моем возрасте смотришь на ползунок загрузки и думаешь А не последнее ли приложение в своей жизни ты качаешь?
Да. Погонял птичку минут 20. Дальше 10-ой башни пройти не смог. Поиграл еще минут десять. О, 22 башни — мой потолок. Нервы ни к черту.
И решили мы с приятелем Кириллом создать своего ро-бота. Забить китайцам баки, как говорил Остап.

Читайте, как это было и смотрите, что получилось.
Под кнопкой трехкилобайтный текст и минутное видео.


Монета в пол-франка


Прежде всего, наш робот не механический. Нажатия на экран можно имитировать не механической палкой, а электрическим зарядом. Приклеиваем к экрану iPad монетку. К монетке приматываем синей изолентой провод. Подаешь по проводу ток на монетку — iPad срабатывает на нажатие. В этом месте надо говорить умные слова Ёмкостной экран и важно покачивать головой.
image
Фотограф из меня конечно никакой.

Для управления током необходим iPhone. Он снимает на видео игру, запущенную на iPad, распознает момент времени, когда надо нажать на игровой экран и посылает сигнал монетке. Как? По аудио-проводу. Генерим сигнал частотой 20КГц и длительностью 20 миллисекунд. Можно проиграть wav-файл, а лучше моделировать сигнал программно, так точнее. Тем не менее, задержка от начала команды Пи-и-и-и-и-и-и до момента имитации нажатия составляет 100-110 миллисекунд. Запомним это число.

Пример кода? Боже, это скучнее, чем новости по ОРТ, сегодня без кода, ок?

Итак сигнал от iPhone через аудио-выход бежит к конденсатору, конденсатор соединен проводом с нашей монеткой — вуа-ля, схема работает.

image

Повторим наш план

  • На iPad-е запускаем игру Flappy Bird.
  • К экрану iPad приклеиваем монетку
  • Монетка соединяется с конденсатором
  • Конденсатор соединяется с аудио-входом iPhone
  • На iPhone пишем программу, которая через видео камеру наблюдает за игрой на iPad и посылает звуковой сигнал-команду Жми, Малешкин!
  • Конденсатор посылает ток на монетку, монетка имитирует нажатие на iPad
  • Птичка послушно прыгает


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

image
При подаче аудиосигнала с уровнем >=1V pnp транзистор открывается и подает логический «1» на вход первого инвертора, вызывая изменение полярности двухзатворного FET транзистора.

Открывание FET соединяет висевшую «в воздухе» монету с землёй, увеличивая измеряемую экраном ёмкость до уровня, принимаемого за касание. Ёмкость канала затвор-сток в закрытом состоянии составляет 5pF. Транзистор смонтирован непосредственно на монете для уменьшения паразитной ёмкости соединительных проводов.
Предшествующие этому решению попытки подключения монеты к транзистору экранированным кабелем были неудачными.

Не показано на схеме: земля платы соединена с землёй планшета аудиокабелем.


Коробка из-под ксерокса


Мини-студия для робота была сделана из б/у коробки. Коробку располовинили, завалили набок, на дно бережно уложили игровой iPad с заранее приклеенной монетой. В потолке коробки проделали отверстие для видеокамеры iPhone и положили телефон сверху, так чтобы камера видела игровой экран низлежащего iPad. Уф-ф, потерпите, уже скоро конец.

Под iPad пришлось подложить книгу Численное моделирование Бахвалова, чтобы игровой экран целиком заполнял видео-кадр.
Все.

Распознавание игрового поля, птички и столбов


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

Поскольку углы поля практически прямые, поймать черную рамку не представляет труда. Пробегать весь массив 1280 на 720 точек видео-буфера не надо. Я пускаю диагонали от четырех углов до нахождения первой точки игрового экрана. Это примерно 5000 операций сравнения для каждого угла. Копейки.

Да! Совсем забыл.

Какой режим видео выбрать на нашем iPhone? требуется хорошая частота.

Попробовал Low-режим видео. 192 на 144 пиксела. Частота — 20 кадров в секунду. Не годится.
Стандартный видео-захват 480 на 360 точек. Дает частоту 30 кадров в секунду. Лучше, но мало.
А вот прямой перебор видео-режимов находит 60 кадров в секунду при разрешении видео 1280 на 720. Метод перебора взят со stackoverflow.com.

П-парадоксально получается — чем выше разрешение, тем чаще кадры. А что Вы хотели от Стива Джобса? Он еще и не такие сюрпризы преподносил.

Для тех, кто шарит в iOS
@implementation ViewController

static AVCaptureDevice *cam;
static AVCaptureSession *sess;

const float requiredFps = 60.0f;

- (void)viewDidLoad
{
    [super viewDidLoad];
	// Do any additional setup after loading the view, typically from a nib.
    sess = [AVCaptureSession new];
    cam = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
    NSError *err = nil;
    AVCaptureDeviceInput *input = [[AVCaptureDeviceInput alloc] initWithDevice:cam error:&err];
    if (err) {
        NSLog(@"Failed to create AVCaptureDeviceInput: %@", err.description);
    }
    [sess addInput:input];

    AVCaptureDeviceFormat *bestFmt = nil;
    int64_t bestDim = 0;
    CMTime tfps = CMTimeMake(10, 10 * requiredFps);

    for (AVCaptureDeviceFormat *fmt in cam.formats) {
        NSLog(@"Format: %@", fmt);
        for (AVFrameRateRange *fps in fmt.videoSupportedFrameRateRanges) {
            if (fps.maxFrameRate >= requiredFps) {
                if (CMFormatDescriptionGetMediaSubType(fmt.formatDescription) ==
                    kCVPixelFormatType_420YpCbCr8BiPlanarFullRange)
                {
                    CMVideoDimensions dimensions = CMVideoFormatDescriptionGetDimensions(fmt.formatDescription);
                    int64_t sq = dimensions.height * dimensions.width;
                    if (sq > bestDim) {
                        bestDim = sq;
                        bestFmt = fmt;
                    }
                }
            }
        }
    }
    if (bestFmt) {
        if ( [cam lockForConfiguration:&err] ) {
            NSLog(@"Selected format: %@", bestFmt);
            cam.activeFormat = bestFmt;
            cam.activeVideoMaxFrameDuration = tfps;
            [cam unlockForConfiguration];
        } else {
            NSLog(@"Failed to lock camera config: %@", err.description);
        }
    } else {
        NSLog(@"Failed to find a %f FPS format", requiredFps);
    }
    AVCaptureVideoDataOutput *output = [AVCaptureVideoDataOutput new];
    [sess addOutput:output];
    dispatch_queue_t queue;
    queue = dispatch_queue_create("cameraQueue", NULL);
    [output setSampleBufferDelegate:self queue:queue];
    [output setVideoSettings:[NSDictionary dictionaryWithObject:[NSNumber numberWithInt:kCVPixelFormatType_32BGRA] forKey:(id)kCVPixelBufferPixelFormatTypeKey]];
    [self.view bringSubviewToFront:cameraReal];
    cameraReal.transform =CGAffineTransformMakeRotation(M_PI_2);
   
   //   [sess startRunning]; turn on/off when view appear/disappear
}

- (void)viewWillDisappear:(BOOL)animated
{
     [sess stopRunning];
    [super viewWillDisappear:animated];
}

- (void)viewWillAppear:(BOOL)animated
{
    [sess startRunning];
    [super viewWillAppear:animated];
}




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

Зачем знать скорость? Из-за задержки команды нажатия в 110 миллисекнд. Приходится вычислять параболу движения птички, чтобы заранее пикнуть.

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

Думаю легко доведем это дело до 1000 и успокоимся.

Всем приятного просмотра.



Внимание, реклама


Разумеется, я написал свой клон этой игры. Игру никто не скачивает, она секретная, но специально для Вас, дорогие читатели я даю ссылку на приложение Winter Jumping.
В честь дня рождения она бесплатная и без рекламы.

Спасибо


Спасибо за внимание.
Автор: @PapaBubaDiop
Papa Buba Diop
рейтинг 54,82
Реклама помогает поддерживать и развивать наши сервисы

Подробнее
Спецпроект

Похожие публикации

Комментарии (47)

  • +26
    Переживал за птичку, будто сам проходил.
  • +8
    С Днем рождения :)
    • +1
      Спасибо :)
  • +4
    Оператор на видео порадовал:)
  • +6
    Боюсь спрашивать, за счёт чего ваш лыжник подлетает. =))
    • +2
      Это реактивная сила))
    • +1
      Это пукан
  • +10
    Написана здесь. Нами.
    Лучший about. Ever.
  • +39
    Автор, все круто и технично… ну блин!

    • 0
      Мир меняется. Не все смотрят видео в пейзаже. Хотя, конечно, человеческие глаза расположены по горизонтали, это не изменить.
      • +2
        Если лечь на бок, то они будут по вертикали. =))
  • 0
    Теперь ждем от разработчиков клонов уменьшение контрастности картинок (чтобы ботам было сложнее распознавать) и очень скоро будем играть в полноценную капчу, вместо игры. Даёшь лозунг: «только человек может играть в Flappy Bird!»
    • +2
      Правда у бота играть получается лучше чем у подавляющего большинства.
      • +17
        Иногда мне кажется, что современную капчу распознавать у ботов тоже лучше получается…
    • +1
      В MMORPG это уже давно не фантастика, особенно мне понравилась таковая в Aion
      Прямо в полете при сборе висящего в нескольких сотнях метров над землей ресурса, когда время полета еще и ограниченно механикой игры
      • 0
        Вспомнилась картинка про неправильное применение капчи:
        Развернуть
        image
  • 0
    Рекорд у меня 87, потом начинают вытекать глаза :) Идея не нова, но реализация интересная. Автору плюс!
  • 0
    Хабр снова торт!
  • НЛО прилетело и опубликовало эту надпись здесь
    • +11
      Я тоже не слышал. Но играл в неё. Только вместо птички был вертолетик. И на сеге.
  • +2
    Сумасшедшая игра. Какой хлопец не слышал про Flappy Bird?

    Я не слышал.

    Edit: блин, не успел.
    • +2
      Рад, что расширил Ваш кругозор.
  • +9
    Элегантное решение эмуляции нажатия, а то таких велосипедов понаделают
    image
    • +4
      Еще более элегантное решение:

      image
      • +8
        Точно, пойду поем!
        • +2
          Приятного аппетита.
      • +3
        Мультитач упаковка
  • +1
    с приятелем КирилЛом

    статья супер!
    • +2
      Он просил не называть его имени)) А Вы назвали, я не виноват.
  • +1
    А почему в Winter Jumping минимальная ios 7.0? Что там такое, что на 6 нельзя запускать?
    • 0
      Не могу проверить на 6-ой версии, всюду перешел на 7-ку.
  • 0
    Пожалуй, надо сделать чисто программного бота, странно, что ещё никто не пробовал.
  • +3
    Я игрался в клон — Clumsy Bird на Android, за час больше 10 не научился набирать, подпилил кое-что в APK, и птичка стала летать скозь стены, но вы ребята, конечно, отлично заморочились!
    image
  • –3
    В Flappy Bird я набил 57. Но она мне не нравилась своей тормознутостью в плане рестарта и невозможностью выхода по Back. Ну и нет ее уже в маркете. Не могу с семьей поиграть, так сказать, помериться. Нашел в Google Play «Ловкий апельсин» (NImble Orange) и нормально рубимся наперегонки. Правда пока 38, зато нет тормозов в рестарте и нормально работает выход из приложения.
    • 0
      Ты очень слаб
      • 0
        Попробуй ка ответить сам себе
        • –1
          Ответь на ответ
    • –1
      Ну как ты повторил свой рекорд?
  • НЛО прилетело и опубликовало эту надпись здесь
    • +3
      А вы и не сможете :)
      • НЛО прилетело и опубликовало эту надпись здесь
        • +3
          она утонула
          • +1
            Птичку жалко :(
            • +3
              Выпьем же за то, чтобы как далеко мы не доходили, никогда не отрывались от коллектива!
  • +3
    Эх… в свое время:
    Скрытый текст
    image

    А птичка наверняка была вдохновлена этим уровнем:
    Скрытый текст
    image


    Про сложность прохождения пиратской версии, писали на хабре.
  • –1
    Да. Погонял птичку минут 20. Дальше 10-ой башни пройти не смог. Поиграл еще минут десять. О, 22 башни — мой потолок. Нервы ни к черту.

    Спокойней надо быть и всё получится. Это одна из не многих игр, где результат зависит фактически только от тебя, а не от рандома. У меня пока потолок 107, но то, что я набираю 40-80 часто, думаю, это не предел.
  • 0
    Только так в неё и можно играть

Только зарегистрированные пользователи могут оставлять комментарии. Войдите, пожалуйста.

Самое читаемое Разное