Air Hockey

Недавно, каким-то чудом пробившись через толпы индусов, выиграл я заказ на vworker (сайт такой для фрилансеров, если кто не знает, бывший rentacoder). Подумал, что вам будут любопытны некоторые моменты.

Заказчик хотел сделать Air Hockey. Правила очень простые. На поле ездит шайба, а мы двумя клюшками её толкаем. Саму игру по понятным причинам я выложить не могу, но вот что-то похожее можете посмотреть здесь вот.

Интерес проекта в том, что игра должна была работать на multitouch столе. В выборе платформы для разработки предоставлялась определённая свобода и я решил что буду делать на флеше. В версии 10.1 как раз сделали поддержку мультитача и довольно удобный API.

В качестве физического движка — порт Box2D. В самом деле, не самому же физику писать. :)

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

Для того, чтобы связать объект с мышкой в Box2D существует mouse joint, но он, к сожалению, не подошёл. Перемещение клюшки должно быть моментальным, вместе с движением мышки, а вот mouse joint позволяет сделать только плавное движение. Возьмите камень, привяжите к нему верёвку, опустите в воду и поводите туда сюда. Вот ощущения примерно такие. Рука в данном случае — мышка, камень — изображение клюшки, верёвка — joint.

Поэтому был применён грязный хак. Каждую итерацию цикла, если двигается мышка, объекту устанавливался большой velocity (скорость), чтобы он моментально достигал местоположения курсора, а затем velocity обнулялcя.

Следующее неудобство, но про него подробно написано в документации — Box2D не любит, когда для описания мира используются большие числа. Ведёт себя нестабильно и тормозит. Поэтому в обязательном порядке надо писать функции для конвертирования пикселов в некие условные единицы и наоборот.

Я опущу описание того как я подбирал параметры вроде трения, это не очень интересно, т.к. выполнено методом тыка.

А вот теперь самый неприятный косяк.

До поры до времени программа тестировалась у меня на мониторе со специальными драйверами, которые позволяли ему делать вид что он поддерживает multitouch и на настоящем multitouch мониторе у заказчика. До стола заказчику было далеко идти, поэтому тестов поначалу там не проводилось И всё было хорошо.

Но вот он загрузил на стол, проверил и выяснилось что если два игрока начинают усердно елозить клюшками, то в некоторые моменты FPS падает до 15 (а надо 60). В итоге дедлайн был сорван практически в три раза. Игра была готова в срок, но всё остальное время было потрачено на тестирование и поиск этой баги. Вдобавок, заказчик был из Канады, поэтому от отправки очередного тестового билда до ответа проходило немало времени.

Я обрезал все необязательные фичи, которые можно было отключить. Упростил все алгоритмы до предела. Например, убрал поддержку нескольких касаний на шайбе, а оставил по одному касанию на каждую. FPS стал падать не так резко, где-то до 20-30, что заказчика удовлетворило, но к моему неудовольствию проблема не решилась.

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

В общем, какой же итог всего сказанного? Пользуйтесь multitouch функциональностью флеша с большой опаской. Обязательно тестируйте на целевом устройстве сразу.