Статьи

Совместное использование данных с помощью жестов: настройка приложения Corona SDK

В этом уроке мы собираемся запустить серию, которая позволит двум мобильным устройствам передавать информацию жестом «Удар». Это приложение потребует сочетания программирования на стороне клиента и на стороне сервера, и мы рассмотрим все шаги для кодирования обоих аспектов. С этого момента это приложение будет ласково именоваться «Удар».

Основной функцией нашего приложения «Thump» будет передача данных между устройствами через веб-сервер-посредник. Конец одного из двух мобильных устройств будет казаться конечному пользователю как локальное соединение между устройствами, когда фактически веб-сервер обработал обмен данными. Поначалу идея локального обмена данными между устройствами может показаться наиболее практичным подходом, но на практике она полна межплатформенных зависаний и ночных кошмаров о безопасности! Поэтому вместо этого мы будем использовать приложение Rails, размещенное на платформе Heroku, для обработки получения сообщений с наших устройств и доставки сообщения предполагаемому получателю.

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

Хотя этот метод не совсем совершенен, он обеспечивает статистическую вероятность того, что наши два устройства предназначены для связи друг с другом. Одной из больших проблем с таким сервисом (и наше приложение не исключение) может стать событие, похожее на выставку, или где-то, где множество людей могут пытаться «забить» все одновременно. Хотя это может быть маловероятным, оно может потенциально позволить передачу сообщения непреднамеренному получателю.

Мы начнем с создания некоторых основных функций для нашего мобильного приложения. В нашем файле main.lua мы добавим несколько важных строк кода, чтобы начать работу.

1
2
3
4
5
6
local ui = require(‘ui’)
 
system.setLocationAccuracy( 10 )
 
local isSimulator = «simulator» == system.getInfo(«environment»)
local deviceId = system.getInfo(«deviceID»)

Первая строка требует, чтобы мы включили библиотеку пользовательского интерфейса, которая очень помогает в создании собственных компонентов в Corona. Этот код будет включен в zip-файл с исходным кодом, прилагаемый к этому учебному пособию по Mobiletuts +. Далее мы установим порог точности определения местоположения для наших устройств. Нам нужно, чтобы устройство старалось изо всех сил, чтобы найти местоположение с погрешностью не более 10 метров. Если расстояние больше этого, мы рискуем подхватить случайные удары с устройств, которые находятся не в непосредственной близости. Чтобы упростить процесс разработки, мы обнаружим, запущено ли наше приложение в симуляторе Corona или на устройстве. Это будет в первую очередь предотвращать странное поведение функций, которые в настоящее время не поддерживаются симулятором. Наконец, нам нужно идентифицировать устройство с уникальным значением. Подобный DeviceID не позволит серверу пытаться доставить сообщение обратно на устройство, которое его отправило, вместо предполагаемого получателя.

1
2
3
4
5
local bg = display.newRect(0, 0, display.contentWidth, display.contentHeight)
 
local logo = display.newImageRect(«logo.png», 172, 107)
logo.x = display.contentWidth / 2
logo.y = (display.contentHeight / 2) — 150

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

01
02
03
04
05
06
07
08
09
10
local titleLabel = ui.newLabel{
        bounds = { 15, 5, 290, 55 },
        text = «Message»,
        font = native.systemFontBold,
        textColor = { 12, 12, 100, 255 },
        size = 24,
        align = «center»
}
titleLabel:setReferencePoint(display.TopCenterReferencePoint)
titleLabel.y = logo.y + 60

Приведенный выше код использует доступ библиотеки UI к собственным компонентам дисплея для устройства. В этом случае мы просто отображаем слово «Сообщение» в темно-синем цвете. В сферу этой статьи не входят все тонкости встроенной библиотеки отображения, поэтому я советую взглянуть на сайт Corona, если вы новичок в SDK. Координаты Y устанавливаются на 60 пикселей больше, чем положение логотипа, который мы только что отобразили.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
if isSimulator then
    — Simulator (simulate the textField area)
    textField = display.newRect( 20, titleLabel.y + 60, 280, 30 )
    textField:setFillColor( 200, 200, 200 )
else
    local function fieldHandler( event )
        if ( «submitted» == event.phase ) then
            native.setKeyboardFocus( nil )
        end
    end
    textField = native.newTextField( 20, titleLabel.y + 60, 280, 30, fieldHandler )
end
 
textField:setReferencePoint(display.TopCenterReferencePoint)
textField.x = display.contentWidth / 2
textField.y = titleLabel.y + 60

Одним из ограничений симулятора является то, что он не может правильно отображать все нативные компоненты мобильных устройств. Чтобы предотвратить появление ошибок, мы обнаружим, запускаем ли мы приложение в симуляторе, и отобразим серое поле вместо поля ввода. Это поможет нам с нашим расположением элементов. Если приложение не работает в симуляторе, мы собираемся отобразить собственный компонент «textField», который позволит конечному пользователю напечатать сообщение. Обратный вызов fieldHandler необходим для обнаружения фазы «отправлено», или, другими словами, пользователь нажимает кнопку «возврат». Улавливая это событие, мы можем скрыть клавиатуру после того, как пользователь закончил печатать свое сообщение.

1
2
3
4
5
local removeKeyboard = function( event )
        — Hide keyboard
        native.setKeyboardFocus( nil )
end
bg:addEventListener( «tap», removeKeyboard )

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

01
02
03
04
05
06
07
08
09
10
11
local latitudeText = «»
local longitudeText = «»
if isSimulator then
    local alert = native.showAlert( «Error», «GPS not available in Simulator» )
else
    local locationHandler = function(event)
        latitudeText = string.format( ‘%.8f’, event.latitude )
        longitudeText = string.format( ‘%.8f’, event.longitude )
    end
    Runtime:addEventListener( «location», locationHandler )
end

Теперь о хороших вещах! Сначала мы обнаружим, работаем ли мы в симуляторе, и просто выведем сообщение об ошибке, что GPS недоступен. Когда мы работаем на устройстве, мы создаем прослушиватель времени выполнения, который непрерывно захватывает наше местоположение из службы определения местоположения устройства и вызывает наш метод locationHandler с этими данными. Мы преобразуем это, чтобы иметь 8 десятичных знаков точности, которые должны быть более чем точными для наших целей.

1
2
3
4
5
6
7
local getThump = function(event)
    if event.isShake == true then
        local alert = native.showAlert( «Thump!», «Location: «..latitudeText..»,»..longitudeText..»\r\nMessage: «..textField.text, {«OK»} )
        system.vibrate()
    end
end
Runtime:addEventListener(«accelerometer», getThump)

Наконец, мы создадим еще один прослушиватель событий времени выполнения, который берет данные с акселерометра устройства и передает их нашему методу getThump. Внутри этого метода мы обнаружим, было ли это событие «встряхиванием». Событие встряхивания — это еще одно название того, что произойдет, когда мы «свалим» два устройства вместе в надежде передать сообщение. Поскольку мы еще не написали наш серверный компонент, мы просто отобразим эти данные в окне предупреждения, чтобы показать, что наше приложение работает до сих пор. Чтобы проверить это, вы можете просто напечатать сообщение и встряхнуть устройство, на котором работает приложение.

Следите за новостями второй части этой серии на следующей неделе, где мы рассмотрим функции сервера в Rails на Heroku!