КРОК 4 - Створення персонажа героя

Герой героя буде об'єктом гри, що складається з наступних компонентів:

Spine Модель

Це дає нам паперову ляльку, подібну до маленької жаби, частини якої можуть бути акуратно (і дешево) анімовані.

Об'єкт зіткнення

Це дозволить виявити зіткнення між жабою героя та речами на тому рівні, на якому він може працювати, які небезпечні або які можна підібрати.

Сkрипт

Це набуває користувача введення і реагує на це, робить лягушку героя стрибати, анімувати і справлятися зі зіткненнями.Почніть з імпорту зображень тіла частини, а потім додати їх до нового атласу, який ми називаємо героєм.atlas:


  • Створіть нову папку, клацнувши правою кнопкою миші в Провіднику проекту та обравши Нова ▸ Папка. Не забудьте вибрати папку, перш ніж натиснути, або нова папка буде створена всередині позначеного. Назвіть папку "герой".
  • Створіть новий файл атласу, клацнувши правою кнопкою миші папку героя і обравши New ▸ Atlas File. Назвіть файл hero.atlas.
  • Створіть нові зображення в підпапках у папці героя. Клацніть правою кнопкою миші папку героя та виберіть Нова ▸ Папка.
  • Перетягніть зображення bodypart з папки героїв-зображень в пакеті активів до папки зображень, яку ви щойно створили в Project Explorer.
  • Відкрийте hero.atlas, клацніть правою кнопкою миші корневий вузол у контурі та виберіть Додати зображення.
  • Позначте всі зображення частини тіла та натисніть "ОК".
  • Зберегти файл атласу.
Hero atlas
Також нам потрібно імпортувати дані анімації хребта та створити для неї смужку.



  • Перетягніть файл hero.json (він входить до пакету активів) до папки героїв в Project Explorer.
  • Створіть файл слинної сцени. Клацніть правою кнопкою миші папку героя та виберіть Новий ▸ Шпильковий файл сцени. Назвіть файл hero.spinescene.
  • Двічі клацніть новий файл, щоб відкрити та редагувати смужку сцени.
  • Встановіть властивість spine_json для імпортованого файлу JSON hero.json
  • . Клацніть на властивості, потім натисніть кнопку вибору файлу ..., щоб відкрити браузер ресурсів.
  • Встановіть властивість атласу посилання на файл hero.atlas.
  • Зберегти файл.
Hero spinescene

Файл hero.json експортується у форматі Spine JSON. Вам потрібні анімаційні програми Spine або Dragon Bones для створення таких файлів. Якщо ви хочете використовувати інше програмне забезпечення для анімації, ви можете експортувати свої анімації як спрайт-листи та використовувати їх як анімацію фліп-книги з джерела Tile Source або Atlasresources.
Див посібник з анімації для отримання додаткової інформації.
Створення об'єкта гри

Тепер ми можемо почати будувати герой ігровогооб'єкта:


  • Створіть новий файл hero.go (клацніть правою кнопкою миші папку героя та оберіть New ▸ File Object Game.
  • Відкрийте файл об'єкта гри.
  • Додайте до неї компонент моделі хребта. (Клацніть правою кнопкою миші на корінь у контурі та виберіть «Додати компонент», а потім виберіть «Модель спини»).
  • Встановіть властивість компонента хребта сцени до героя файлу.
  • spinescene, що ви тільки що створили, і виберіть "run_right" як анімацію за замовчуванням (ми правильно виправимо анімацію пізніше).
  • Зберегти файл.
Spinemodel properties
    Настав час додати фізику для зіткнення на роботу:
  • Додайте компонент об'єкта зіткнення до об'єкту гри героя. (Клацніть правою кнопкою миші корінь в Outline і виберіть Add Component, потім виберіть «Collision Object») 
  • Клацніть правою кнопкою миші новий компонент і виберіть "Додати шаблон". Додайте дві форми, щоб покрити тіло жаби. Сфера і коробка зробить. 
  • Клацніть на формі та використовуйте Інструмент переміщення (Сценарій ▸ Інструмент переміщення), щоб перемістити фігури у хороші позиції. 
  • Позначте компонент Object Collision і встановіть властивість Type у "Kinematic".
"Кінематична" зіткнення означає, що ми хочемо зареєструвати зіткнення, але фізичний двигун не буде автоматично вирішувати зіткнення та моделювати об'єкти. Двигун фізики підтримує ряд різних типів об'єктів зіткнення. Ви можете прочитати більше про них у документації з фізики.
Physics documentation.

Важливо вказати, яким повинен бути об'єкт зіткнення:



  • Встановіть властивість Group до нової групи зіткнень, яка називається "героєм".


  • Встановлення властивості маски в іншу групу "геометрія", щоб цей об'єкт зіткнень реєстрував зіткнення з. Зауважте, що група "геометрія" ще не існує, але ми незабаром додамо об'єкти зіткнення, що належать до нього.
Hero game object
Нарешті, створіть новий файл hero.script і додайте його до об'єкту гри.

  • Клацніть правою кнопкою миші папку героя в Провіднику проекту та виберіть Новий файл ▸ Сценарій. Назвіть новий файл hero.script.
  • Відкрийте новий файл, потім скопіюйте та вставте цей код у файл сценарію, а потім збережіть його. (Код досить простий, крім розв'язувача, який відокремлює форму колізії героя від того, з чим він стикається.
  • Це зроблено функцією handle_geometry_contact ().)


Причина, з якою ми самі справляємось зі зіткненнями, полягає в тому, що якщо ми замість цього встановимо тип на об'єкт зіткнення жаби до динамічного, двигун буде виконувати ньютонівські симуляції відповідних органів. Для такої гри подібне моделювання далеко не оптимально, тому замість того, щоб боротися з фізичним двигуном з різними силами, ми отримуємо повний контроль.


Тепер
щоб зробити це і обробляти зіткнення належним чином вимагає трохи векторної математики. Ретельне пояснення того, як вирішити кінематичні зіткнення, наведено в Physics documentation.
-- gravity pulling the player down in pixel units/sˆ2
local gravity = -20

-- take-off speed when jumping in pixel units/s
local jump_takeoff_speed = 900

function init(self)
    -- this tells the engine to send input to on_input() in this script
    msg.post(".", "acquire_input_focus")

    -- save the starting position
    self.position = go.get_position()

    -- keep track of movement vector and if there is ground contact
    self.velocity = vmath.vector3(0, 0, 0)
    self.ground_contact = false
end

function final(self)
    -- Return input focus when the object is deleted
    msg.post(".", "release_input_focus")
end

function update(self, dt)
    local gravity = vmath.vector3(0, gravity, 0)

    if not self.ground_contact then
        -- Apply gravity if there's no ground contact
        self.velocity = self.velocity + gravity
    end

    -- apply velocity to the player character
    go.set_position(go.get_position() + self.velocity * dt)

    -- reset volatile state
    self.correction = vmath.vector3()
    self.ground_contact = false
end

local function handle_geometry_contact(self, normal, distance)
    -- project the correction vector onto the contact normal
    -- (the correction vector is the 0-vector for the first contact point)
    local proj = vmath.dot(self.correction, normal)
    -- calculate the compensation we need to make for this contact point
    local comp = (distance - proj) * normal
    -- add it to the correction vector
    self.correction = self.correction + comp
    -- apply the compensation to the player character
    go.set_position(go.get_position() + comp)
    -- check if the normal points enough up to consider the player standing on the ground
    -- (0.7 is roughly equal to 45 degrees deviation from pure vertical direction)
    if normal.y > 0.7 then
        self.ground_contact = true
    end
    -- project the velocity onto the normal
    proj = vmath.dot(self.velocity, normal)
    -- if the projection is negative, it means that some of the velocity points towards the contact point
    if proj < 0 then
        -- remove that component in that case
        self.velocity = self.velocity - proj * normal
    end
end

function on_message(self, message_id, message, sender)
    if message_id == hash("contact_point_response") then
        -- check if we received a contact point message. One message for each contact point
        if message.group == hash("geometry") then
            handle_geometry_contact(self, message.normal, message.distance)
        end
    end
end

local function jump(self)
    -- only allow jump from ground
    if self.ground_contact then
        -- set take-off speed
        self.velocity.y = jump_takeoff_speed
    end
end

local function abort_jump(self)
    -- cut the jump short if we are still going up
    if self.velocity.y > 0 then
        -- scale down the upwards speed
        self.velocity.y = self.velocity.y * 0.5
    end
end

function on_input(self, action_id, action)
    if action_id == hash("jump") or action_id == hash("touch") then
        if action.pressed then
            jump(self)
        elseif action.released then
            abort_jump(self)
        end
    end
end
  • Додайте сценарій як компонент сценарію до об'єкта героя (клацніть правою кнопкою миші корінь героя.go в контурі і виберіть «Додати компонент з файлу», потім виберіть файл hero.script).


Якщо ви хочете, тепер ви можете спробувати і тимчасово додати жаба героя до основної колекції і запустити гру, щоб побачити, як вона падає у світ.




Останнє, що нам потрібно для того, щоб герой функціонував, є вхідним. У наведеному вище скрипті вже містяться функція on_input (), яка реагує на дії "стрибок" та "дотик" (для сенсорних екранів).

  • Додамо прив'язку вхідних даних для цих дій.
  • Відкрийте "input / game.input_bindings"
  • Додайте ключовий тригер для "KEY_SPACE" і назвіть дію "стрибати"
  • Додайте сенсорний тригер для "TOUCH_MULTI" і назвіть дію "торкнутися". (Імена дій є довільними, але вони повинні відповідати іменам вашого сценарію. Зауважте, що ви не можете мати одне ім'я дії на декількох тригерів)
  • Зберегти файл.


Input bindings

Немає коментарів:

Дописати коментар

Kоментарі неуkраїнсьkою видалятимуться