2. Обработка касаний
В этом уроке мы загрузим несколько изображений и попробуем их передвигать касанием пальцев
Ресурсы, которые мы будем загружать в наше приложение, вы можете скачать здесь:
Положите их в корневую папку с проектом.
Подготовка
Загружаем фон
Для начала загрузим фоновое изображение и растянем на весь экран.
local _W = display.contentWidth;
local _H = display.contentHeight;
local bg = display.newImageRect("resources/background.png", _W, _H)
bg.x = _W/2;
bg.y = _H/2;
Первые две строчки - полезный трюк, который нам позволил растянуть наше изображение сразу на весь экран в функции загрузки изображения, а также отцентровать его.
Добавляем цифры
Давайте теперь загрузим объекты, которые мы будем двигать.
local numbers = display.newGroup();
local one = display.newImageRect(numbers, "resources/1.png", 32, 76);
one.x = 50;
one.y = 100;
local two = display.newImageRect(numbers, "resources/2.png", 52, 78);
two.x = 100;
two.y = 100;
local three = display.newImageRect(numbers, "resources/3.png", 51, 79);
three.x = 155;
three.y = 100;
Что за группы?
Вы могли заметить новую функцию, display.newGroup()
. Довольно часто
нам необходимо объеденить несколько объектов в какую-то группу, чтобы
например двигать их вместе или управлять из видимостью на экране. Для
этого группы и придумали.
Но как добавить их в группу?
Вы могли заметить, что я передаю группу numbers
первым аргументом
в функцию display.newImageRect
. Это один из возможных способов.
Также вы можете добавлять в группу другие объекты при создании,
это работает и для других функций: display.newRect, display.newCircle, ...
из первого урока
Что мы видим на экране?
Если вы все сделали правильно, у вас на экране должно отображаться, что-то вроде такого:
Двигаем цифры
Настало время самого интересного. Добавим обработку касаний. Сделаем так, чтобы цифры можно было двигать своим пальцем.
Для того, среагировать на события касания экрана, нужно подписаться на них и добавить обработчик:
function touchListener(event)
end
one:addEventListener("touch", touchListener);
Итак, начнем с конца. Как видно из названия функции, мы подписались на событие touch и указали, что это событие должна обрабатывать функция touchListener, которую мы объявили ранее.
Теперь перейдем к самой функции обработки. Эта функция вызывается при каждом событии касания экрана. Важно отметить, что это может быть не просто касание, а мы можем нажать прижать палец к экрану и двигать его. И на каждый сдвиг вызовется функция touchListener.
Эта функция вызывается с одним аргументом event, который содержит все необходимые данные, которые нам понадобятся для двигания цифр.
Оно двигается!!!
Добавим следующий код в тело функции:
one.x = event.x
one.y = event.y
Теперь попробуйте нажать на цифру 1 и подвигать мышкой, цифра должна двигаться.
Немного улучшений
Скорее всего вы заметили, что мы приравниваем координаты центра нашей цифры к координате касания. Из-за этого есть небольшой лаг, и как только мы касаемся цифры, она немного сдвигается. Давайте же исправим это!
Чтоб это исправить нам достаточно посчитать расстояние от центра объекта до координаты касания в момент первого касания и прибавлять его к новой координате каждый раз, когда мы двигаем объект.
Фазы события
Здесь стоит упомянуть, что события имеют несколько состояний. Мы можем
его узнать заглянув в поле phase объекта event: event.phase
В нашем случае у события будет 3 состояния:
- “began” - это когда мы только прикоснулись пальцем, но никуда еще его не сдвинули
- “moved” - тут как раз мы уже двигаем пальцем
- “ended” - это последнее состояние, когда палец с экрана убран.
Попробуйте добавить в touchListener следующую функцию:
print("Event phase: ", event.phase)
И понаблюдайте, что печатается в Corona Simulator Console когда вы двигаете объект.
Двиагем объект правильно
Итак, как я и сказал, у нас есть три фазы события. И фаза begun очень подходящее место, чтобы запомнить расстояние между центром нашей цифры и координатой касания. А вот в фазе moved, мы как раз можем изменять координаты объекта с учетом этой дельты.
Измените существующий код следующим образом.
local deltaX = 0;
local deltaY = 0;
function touchListener(event)
if event.phase == "began" then
deltaX = one.x - event.x;
deltaY = one.y - event.y;
elseif event.phase == "moved" then
one.x = event.x + deltaX;
one.y = event.y + deltaY;
elseif event.phase == "ended" then
deltaX = 0;
deltaY = 0;
end
end
Мы объявили две переменные deltaX, deltaY для запоминания дельты координат объекта и касания. А в самом обработчике, как и говорил, в фазе begun запоминаем эти дельты (двигать нам объект тут не нужно, мы же пока никуда его и не двигали). В фазе moved мы двигаем объект с учетом дельты, которую записали моментом ранее. Ну и в фазе ended мы чистим наши переменные, потому что мы хорошие разработчики и убираемся за собой.
Посмотрите на результат: объект теперь двигается правильно и без всяких лагов.
А как двигать несколько объектов?
Нарисовалась еще одна проблема. Мы добавили обработчик только для одного объекта, но что если я хочу двигать также цифры 2 и 3?
Ничего сложного. Давайте для них тоже добавим подписку на событие:
two:addEventListener("touch", touchListener);
three:addEventListener("touch", touchListener);
Также нам нужно немного поменять сам обработчик. В нем мы двигаем конкретный объект: one, а нам нужно двигать любой объект, на события которого мы подписались.
Для этого нам всего лишь нужно поменять one
на event.target
везде,
где мы меняем координаты. Должно получиться так:
function touchListener(event)
if event.phase == "began" then
deltaX = event.target.x - event.x;
deltaY = event.target.y - event.y;
elseif event.phase == "moved" then
event.target.x = event.x + deltaX;
event.target.y = event.y + deltaY;
elseif event.phase == "ended" then
deltaX = 0;
deltaY = 0;
end
end
Прекрасный event дает нам знать, что мы собираемся двигать.
Может подвигаем все цифры разом?
Помните я упомянул в начале про группы. И не зря. Сейчас мы одним легким взмахом сможем двигать все цифры разом.
Для начала уберите все подписки на отдельные объекты. И добавьте вместо них всего одну:
numbers:addEventListener("touch", touchListener)
Ого! Так просто, но теперь мы можем двигать все цифры разом. На этом урок окончен. Увидимся в следующем.