обзор
Всем нравится хорошая физическая игра, но давайте посмотрим правде в глаза: гораздо веселее, когда вы взрываете вещи! Из этого туториала вы узнаете, как использовать физический движок Corona для создания взрывов в вашей игре.
Настроить
Для начала давайте начнем с создания файла build.settings со следующим кодом:
01
02
03
04
05
06
07
08
09
10
11
|
settings =
{
orientation =
{
default = «landscapeRight»,
supported =
{
«landscapeLeft», «landscapeRight»
}
}
}
|
Детали всех опций этого файла выходят за рамки данного руководства. Приведенные выше настройки приведут к ориентации мобильного устройства в горизонтальный или горизонтальный режим. Поскольку у нас есть только один набор графики, форсирование альбомной ориентации облегчит задачу.
физика
Далее мы начнем с настройки нашего физического движка в нашем файле main.lua:
1
2
3
|
local physics = require(«physics»)
physics.start()
display.setStatusBar( display.HiddenStatusBar )
|
Легко ли? Корона потрясающая! В этом разделе мы также добавили строку, чтобы скрыть строку состояния. Это позволяет нам взять на себя весь экран мобильного устройства без каких-либо собственных компонентов.
Графика
Теперь, когда у нас есть основы, давайте добавим красивый фон и отцентрируем его положение относительно центра мобильного устройства:
1
2
3
|
local background = display.newImage( «bricks.png», 0, 0, true )
background.x = display.contentWidth / 2
background.y = display.contentHeight / 2
|
В приведенном выше коде мы добавляем фоновое изображение на сцену с помощью метода display.newImage. Это начальная позиция в верхнем левом углу 0,0, как указано 2-м и 3-м параметрами. По умолчанию Корона поместит изображения с узловой точкой в его точном центре. Мы используем методы x, y для объекта фона, чтобы расположить опорную точку изображения в точном центре экрана.
Прежде чем добавлять какие-либо динамические объекты на экран, давайте добавим слово, на котором они будут сидеть:
1
2
|
local floor = display.newImage( «floor.png», 0, 280, true )
physics.addBody( floor, «static», { friction=0.5 } )
|
Мы добавляем изображение так же, как и для фона, размещая его в нижней части экрана. Затем напольный объект добавляется на сцену как «статическое» физическое тело. «Статический» в этом случае означает, что объект будет взаимодействовать с другими физическими объектами на экране, но не будет подвержен гравитации или инерционным силам движущихся объектов.
Динамические объекты
Нашим следующим шагом будет создание набора ящиков с ненадежной сумкой, которые только и ждут, чтобы их качали:
1
2
3
4
5
6
7
8
|
local crates = {}
for i = 1, 5 do
for j = 1, 5 do
crates[i] = display.newImage( «crate.png», 140 + (i*50), 220 — (j*50) )
physics.addBody( crates[i], { density=0.2, friction=0.1, bounce=0.5 } )
end
end
|
Приведенный выше код на первый взгляд может показаться сложным, но на самом деле он очень прост. У нас есть два вложенных цикла, которые мы циклически повторяем, чтобы создать набор ящиков шириной 5 и высотой 5, увеличивая значения x и y. Каждый из этих ящиков добавляется на сцену как «динамическое» тело. «Динамический», хотя и не указан в коде, является типом по умолчанию для всех физических тел. Мы добавили несколько параметров, чтобы определить поведение объекта при воздействии на него сил. Значение плотности для каждого ящика будет важно позже, когда мы определим силу нашего взрыва. Чем плотнее объекты, тем больше сила, необходимая для их перемещения. Хотите попробовать что-нибудь веселое? Увеличьте значение отказов до 1,0 и посмотрите, что происходит с ящиками.
Установка бомбы
Уф! Готовы к веселью? Давайте взорвать эти вещи. Принцип, лежащий в основе создания взрывов, заключается в определении эпицентра взрыва и радиуса взрыва и воздействия на все объекты, которые в нем находятся. Для этого примера эпицентр взрыва будет определяться тем, где мы касаемся экрана. Давайте начнем с добавления этого поведения:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
|
local circle = «»
local function setBomb ( event )
if(event.phase == «began») then
circle = display.newCircle( event.x, event.y, 80 )
circle.myName = “circle”
circle:setFillColor(0,0,0, 0)
physics.addBody( circle, «static», {isSensor = true} )
circle.collision = onLocalCollision
circle:addEventListener( «collision», circle )
end
if(event.phase == «ended») then
circle:removeSelf()
end
end
background:addEventListener(«touch»,setBomb)
|
Здесь мы определили метод setBomb, который генерирует невидимый круг с радиусом 80. Круг расположен там, где пользователь коснулся экрана. Физическое тело, которое мы добавляем, имеет специальный параметр isSensor, установленный в true. Сенсорные объекты присутствуют в физическом движке, но не подвержены гравитации и не влияют на другие объекты. В этом случае мы используем сенсорный объект, чтобы просто определить, какие ящики с ним контактируют. Контакт будет определен путем прослушивания событий столкновения между ящиками и нашим датчиком. Любой ящик, который сталкивается с нашим датчиком, находится внутри радиуса взрыва и, следовательно, будет подвержен воздействию силы взрыва.
Kaboom!
Следующий метод будет выполнен при обнаружении столкновения любого объекта с датчиком, который мы создали в приведенном выше коде.
* Для справки: следующий код должен быть определен в коде перед указанным выше методом setBomb. Однако из соображений потока мы разместили его позже в руководстве.
01
02
03
04
05
06
07
08
09
10
11
12
|
local function onLocalCollision( self, event )
if ( event.phase == «began» and self.myName == «circle» ) then
local forcex = event.other.x-self.x
local forcey = event.other.y-self.y-20
if(forcex < 0) then
forcex = 0-(80 + forcex)-12
else
forcex = 80 — forcex+12
end
event.other:applyForce( forcex, forcey, self.x, self.y )
end
end
|
Основная идея этого метода заключается в применении силы к любому объекту, который столкнулся с нашим сенсорным кругом. Мы создали две переменные, называемые forcex и forcey. Мы используем расстояние от центра ящика до центра нашего сенсорного круга, чтобы определить силу силы, которую мы будем применять. Делая это, мы создаем для бедного человека способ уменьшения силы взрыва по мере удаления объекта от эпицентра взрыва. Все эти числа сильно зависят от физических свойств объектов, которые мы взрываем.
* Примечание: силы как числовые значения намного выше, чем свойства объектов по плотности, трению и отскоку. Не стесняйтесь поиграть с этими значениями, чтобы получить интересные результаты!
Вывод
И там у нас это есть. Этот урок должен стать отличной отправной точкой для создания всевозможных классных игр, включающих взрывы. Потратьте некоторое время, чтобы поэкспериментировать со свойствами и значениями всех переменных в этом упражнении.
Во второй части этого урока мы добавим несколько дополнительных функций в структуру взрыва, чтобы сделать ее еще более разрушительной!
Оставьте несколько комментариев и дайте мне знать, что вы думаете о части I.