Привет всем подвальным дефолдерам и не только
В этом теме мы создадим виртуальный джойстик, перемещение игрового объекта и запуск снарядов с его помощью:
Вы можете как создать новый проект, так и использовать существующий проект.
Добавьте в ваш проект в качестве зависимости Defold Input от britzl : cсылка на github с библиотекой.
Если вы не знаете как добавить библиотечную зависимость, то ознакомьтесь с этим руководством: Как добавить библиотечную зависимость в проект на Defold.
Модуль On-screen
Модуль onscreen
в Defold позволяет легко реализовать виртуальные кнопки и джойстики для мобильных устройств или других сенсорных интерфейсов.
Он делится на две основные реализации:
Создание виртуального джойстика из .script, прикрепленного к GO:
Добавим изображения джойстиков и игрового персонажа в проект:
Создадим atlas с изображениями:
Создадим скрипт
player.script
и добавим в него код:
function init(self)
msg.post("joystick", "register")
msg.post("joystick", "register_analog", { id = "stick", radius = 50 })
-- joistick — имя игрового объекта, в которой находится gui-скрипт с джойстиками
-- можно поменять значение
self.speed = vmath.vector3()
end
function final(self)
msg.post("onscreen", "unregister")
end
function update(self, dt)
go.set_position(go.get_position() + self.speed * dt)
end
function on_message(self, message_id, message, sender)
--print("Position:", go.get_position(), "Speed:", self.speed)
if message_id == hash("onscreen_analog") then
if message.pressed then
self.joystick_ready = false
elseif message.released then
self.speed = vmath.vector3()
else
if not self.joystick_ready then
self.joystick_ready = true
return -- пропускаем первый кадр
end
self.speed.x = message.x * 200
self.speed.y = message.y * 200
end
end
end
function on_input(self, action_id, action)
-- Важно! Передаём события касаний в модуль onscreen
msg.post("onscreen", "touch", action)
end
Создадим игровой объект персонажа player.go
и добавим к нему два компонента: спрайт с изображением из атласа и созданный скрипт player.script
:
Создадим gui-файл
joystick_go.gui
.Добавим в качестве текстуры подготовленный ранее атлас с изображениями джойстика.
Добавим в этот файл две ноды: base и stick:
Каждой ноде выберите изображение в качестве текстуры:
Создадим коллекцию для примера, в которой создадим такую иерархию файлов:
Запустим проект (ctl + B или f5):

Как создать запуск снарядов?
Добавляем изображения для снаряда, кнопки геймпада в проект. Добавляем их в атлас.
Создаём в gui-файле новую ноду, назовём её: button_a
.
Добавляем ей текстуру.
Создаём игровой объект снаряда. Добавляем в атлас.
Переходим в коллекцию, где находятся игровые объекты player
и joystick
.
Добавляем в игровой объект player
фабрику, называем её как угодно, у нас будет laserfactory
. В качестве прототипа будет игровой объект снаряда, созданный вами ранее.
Изменяем код player.script
:
function init(self)
msg.post("joystick", "register")
msg.post("joystick", "register_analog", { id = "stick", radius = 50 })
msg.post("joystick", "register_button", { id = "button_a" })
self.speed = vmath.vector3()
end
function final(self)
msg.post("onscreen", "unregister")
end
function update(self, dt)
go.set_position(go.get_position() + self.speed * dt)
end
function on_message(self, message_id, message, sender)
print("Position:", go.get_position(), "Speed:", self.speed)
if message_id == hash("onscreen_button") and message.id == hash("button_a") and message.released then
print("laser")
local pos = go.get_position() + vmath.vector3(0, 50, 0)
local id = factory.create("#laserfactory", pos)
go.animate(id, "position.y", go.PLAYBACK_ONCE_FORWARD, pos.y + 1500, go.EASING_LINEAR, 0.8, 0, function()
go.delete(id)
end)
elseif message_id == hash("onscreen_analog") then
if message.pressed then
self.joystick_ready = false
elseif message.released then
self.speed = vmath.vector3()
else
if not self.joystick_ready then
self.joystick_ready = true
return -- пропускаем первый кадр
end
self.speed.x = message.x * 200
self.speed.y = message.y * 200
end
end
end
function on_input(self, action_id, action)
-- Важно! Передаём события касаний в модуль onscreen
msg.post("onscreen", "touch", action)
end
Создание виртуального джойстика внутри .gui_script:
Создание виртуального джойстика с использованием gui-скрипта:
Добавим изображения под джойстик, игрового персонажа в ваш проект и включим их в какой-нибудь атлас:
Для примера создадим отдельную коллекцию
joystick_gui.collection
.Создадим
joystick.gui_script
, joystick_gui.gui
, player.script
.Добавим в
player.script
код:
function init(self)
self.speed = vmath.vector3()
end
function update(self, dt)
go.set_position(go.get_position() + self.speed * dt)
end
function on_message(self, message_id, message, sender)
if message_id == hash("move") then
if message.released then
self.speed.x = 0
self.speed.y = 0
else
self.speed.x = message.x * 200
self.speed.y = message.y * 200
end
end
end
В joystick.gui_script
добавим ноды под джойстик, и в качестве текстуры атлас с изображениями джойстиков:
Нодам под джойстик добавим текстуры:
У вас должно получиться что-то подобное:
В
joystick.gui_script
добавим код:
local onscreen = require "in.onscreen"
function init(self)
msg.post(".", "acquire_input_focus")
self.analog = gui.get_node("stick") -- нода, которая будет двигаться
onscreen.register_analog(self.analog, { radius = 80 }, function(action, node, touch)
msg.post("player", "move", touch) -- player — игровой объект, который будет двигаться
end)
end
function final(self)
onscreen.reset()
end
function on_input(self, action_id, action)
onscreen.on_input(action_id, action)
end
Настроим иерархию в joystick_gui.collection
подобным образом:
Выберем в качестве скрипта к
joystick_gui.gui
наш скриптовый файл joystick.gui_script
:Не забудьте изменить стартовую коллекцию в настройках game.project
:
Запустите проект (ctrl + B или f5):
Как создать запуск снарядов?
Добавляем новую ноду для кнопки в joystick_gui.gui
и добавляем ей в качестве текстуры вашего изображение.
Добавляем изображение пули в наш проект.
Добавляем это изображение в атлас.
Создаем игровой объект для пули:
К игровому объекту персонажа добавляем фабрику в коллекции с
joystick_gui.collection
:В качестве прототипа указываем игровой объект пули:
В joystick.gui_script
добавляем код:
self.button_a = gui.get_node("button_a")
onscreen.register_button(self.button_a, nil, function(action, node, touch)
msg.post("player", "laser", touch)
end)
В player.script
добавляем создание снарядов через созданную фабрику:
function on_message(self, message_id, message, sender)
if message_id == hash("laser") then
if message.released then
print("laser")
local pos = go.get_position() + vmath.vector3(0, 50, 0)
local id = factory.create("#laserfactory", pos)
go.animate(id, "position.y", go.PLAYBACK_ONCE_FORWARD, pos.y + 1500, go.EASING_LINEAR, 0.8, 0, function()
go.delete(id)
end)
end
elseif message_id == hash("move") then --предыдущий код
if message.released then
self.speed.x = 0
self.speed.y = 0
else
self.speed.x = message.x * 200
self.speed.y = message.y * 200
end
end
end
Запустим проект (ctrl + B
или f5
):