Students Save 30%! Learn & create with unlimited courses & creative assets Students Save 30%! Save Now
Advertisement
  1. Code
  2. Xcode
Code

Ўвядзенне ў GameplayKit: частка 2

by
Difficulty:IntermediateLength:LongLanguages:
This post is part of a series called An Introduction to GameplayKit.
An Introduction to GameplayKit: Part 1
An Introduction to GameplayKit: Part 3

Belarusian (беларуская мова) translation by Alex Grigorovich (you can also view the original English article)

Гэта другая частка Ўвядзення ў GameplayKit. Калі вы яшчэ не прайшлі першую частку, я рэкамендую спачатку вывучыць яго, перш чым пераходзіць адразу да кроку 2.

Ўвядзенне

У гэтым уроку я раскажу вам яшчэ аб двух функцыях сістэмы GameplayKit, якімі вы можаце скарыстацца:

  • агенты, мэты і паводзіны
  • пошук шляху

Выкарыстоўваючы агенты, мэты і паводзіны, мы збіраемся пабудаваць некаторы базавы штучны інтэлект (AI) у гульню, які мы пачалі выкарыстоўваць у першай частцы урокаў. ІІ дазволіць нацэліцца нашым чырвоным і жоўтым кружочкам суперніка і рухацца да кропкі блакітнага гульца. Мы таксама збіраемся укараніць функцыю пошуку шляху ў ІІ для навігацыі вакол перашкод.

Для гэтага ўрока вы можаце выкарыстоўваць копію завершанага праекта з першай часткі або загрузіць новую копію зыходнага кода з GitHub.

1. Агенты, мэты і паводзіны

У GameplayKit агенты, мэты і паводзіны выкарыстоўваюцца ў спалучэнні адзін з адным, каб вызначыць, як розныя аб'екты перамяшчаюцца ў адносінах адзін да аднаго ць ўсім полі. Для асобнага аб'екта (або SKShapeNode у нашай гульні) вы пачынаеце з стварэння agent, прадстаўленага класам GKAgent. Аднак для 2D-гульняў, падобных нашай, нам трэба выкарыстоўваць канкрэтны клас GKAgent2D.

Клас GKAgent з'яўляецца падклас GKComponent. Гэта азначае, што ваша гульня павінна выкарыстоўваць структуру на аснове сутнасцяў і кампанентаў, як мы гэта рабілі ў першым ўроку нашых туторыалаў.

Агенты ўяўляюць сабой становішча, памер і хуткасць аб'екта. Затым вы дадаеце да гэтага агенту паводзіны, прадстаўленае класам GKBehaviour. Нарэшце, вы ствараеце набор мэтаў, прадстаўленых класам GKGoal, і дадаеце іх у аб'ект паводзін. Мэты могуць выкарыстоўвацца для стварэння мноства розных элементаў геймплэя, напрыклад:

  • пераход да агента
  • пераход ад агента
  • групоўка блізка да іншых агентам
  • мигрирование па пэўнай пазіцыі

Ваш аб'ект паводзін кантралюе і вылічае ўсе мэты, якія вы дадаеце да яго, а затым перадае назад гэтыя дадзеныя агенту. Давайце паглядзім, як гэта працуе на практыцы.

Адкрыйце праект Xcode і перайдзіце да PlayerNode.swift. Спачатку нам трэба пераканацца, што клас PlayerNode адпавядае пратаколу GKAgentDelegate.

Затым дадайце наступны код у клас PlayerNode.

Пачнем з дадання ўласцівасці да класа PlayerNode, так, каб заўсёды мець спасылку на аб'ект агента бягучага гульца. Далей мы рэалізуем два метаду пратаколу GKAgentDelegate. Выкарыстоўваючы гэтыя метады, мы гарантуем, што адлюстроўваецца на экране кропка гульца заўсёды будзе адлюстроўваць змены, якія вырабляе GameplayKit.

Метад agentWillUpdate(_:) выклікаецца непасрэдна перад тым, як GameplayKit праглядае паводзіны і мэты гэтага агента, каб вызначыць, куды ён павінен рухацца.  Аналагічна, метад agentDidUpdate(_:) выклікаецца адразу пасля завяршэння GameplayKit гэтага працэсу.

Рэалізацыя гэтых двух метадаў гарантуе, што адлюстроўваецца на экране вузел адлюстроўвае змены, якія вырабляе GameplayKit, і што GameplayKit выкарыстоўвае апошнюю пазіцыю вузла пры выкананні сваіх вылічэнняў.

Затым адкрыйце ContactNode.swift і заменіце змесціва файла наступным:

Укараняючы пратакол GKAgentDelegate ў клас ContactNode, мы дазваляем ўсім астатнім кропках ў нашай гульні быць у адпаведнасці з GameplayKit, а таксама нашай гульнявой кропкай.

Надышоў час наладзіць паводзіны і мэты.  Каб зрабіць гэта, нам трэба паклапаціцца аб трох рэчах:

  • Дадайце кампанент агента ў вузел аб'ектаў гульца і вызначыце яго паўнамоцтвы.
  • Наладзьце агенты, мадэлі паводзінаў і мэты для ўсіх нашых варожых кропак.
  • Абновіце ўсе гэтыя агенты ў патрэбны час.

Па-першае, адкрыйце GameScene.swift і, у рэшце метаду didMoveToView(_:), дадайце наступныя два радкі кода:

З дапамогай гэтых двух радкоў мы дадаем агент ў якасці кампанента і ўсталёўваны яго як самастойны вузел.

Затым заменіце рэалізацыю метаду initialSpawn наступнай рэалізацыяй:

Самы важны код, які мы дадалі, знаходзіцца ў стане if, які ідзе за станам switch. Давайце прайсці праз гэты код парадкова:

  • Спачатку мы дадаем агента да аб'екта ў якасці кампанента і наладжвальны яго паўнамоцтвы.
  • Затым мы прызначаем пазіцыю агента і дадаем агент да захавання масіву, agents. Мы дадамо гэта ўласцівасць у клас GameScene за хвіліну.
  • Затым мы ствараем аб'ект GKBehavior з дапамогай адзіночнага GKGoal для таго, каб накіраваць агента бягучага гульца. Параметр weight у гэтым инициализаторе выкарыстоўваецца для вызначэння таго, якія мэты павінны мець прыярытэт над іншымі. Напрыклад, уявіце, што ў вас ёсць мэта - канкрэтны агент і іншая мэта адысці ад агента, але вы хочаце, каб мэта на агента была пераважнай. У гэтым выпадку вы можаце задаць вага гэтай мэты 1 і вага 0,5 для іншай мэты. Затым гэтыя паводзіны прымацоўваецца да вузла варожага агента.
  • Нарэшце, мы наладжваем ўласцівасці mass, maxSpeed ​​і maxAcceleration для агента. Яны ўплываюць на тое, як хутка аб'екты могуць перамяшчацца і паварочвацца. Не саромейцеся гуляць з гэтымі ўласцівасцямі і вы заўважыце, як гэта ўплывае на рух варожых кропак.

Затым дадайце наступныя дзве ўласцівасці ў клас GameScene:

Масіў agents будзе выкарыстоўвацца для сувязі з агенты суперніка ў сцэне. Ўласцівасць lastUpdateTime будзе выкарыстоўвацца для вылічэнні часу, які прайшоў з моманту апошняга абнаўлення сцэны.

Нарэшце, заменіце рэалізацыю метаду update(_:) класа GameScene наступным: 

У метадзе update(_:) мы вылічаем час, якое прайшло з моманту апошняга абнаўлення сцэны, і затым абнаўляем агенты з гэтым значэннем.

Стварыце і запусціце прыкладанне і пачніце руху па полі. Вы ўбачыце, што варожыя пункту павольна пачнуць рухацца да вас.

Targeting enemies

Як вы бачыце, у той час як варожыя пункту нацэльваецца на бягучага гульца, яны не перамяшчаюцца па белым межаў, замест гэтага яны спрабуюць прайсці праз іх. Давайце зробім ворагаў трохі разумнейшыя з дапамогай пошуку шляху.

2. Пошук шляху

З дапамогай фреймворка GameplayKit вы можаце дадаць складаную траекторыю ў сваю гульню, аб'яднаўшы фізічныя цела з класамі і метадамі GameplayKit. Для нашай гульні мы збіраемся наладзіць траекторыі так, каб варожыя кропкі былі нацэлены на кропку гульца і ў той жа час перамяшчаліся па перашкодам.

Пошук шляху ў GameplayKit пачынаецца з стварэння графічнай мадэлі вашай сцэны. Гэты графік ўяўляе сабой набор асобных месцаў, таксама званых вузламі, і іх злучэнняў паміж месцазнаходжанне. Гэтыя злучэнні вызначаюць, як канкрэтны аб'ект можа перамяшчацца з аднаго месца ў іншае. Графік можа мадэляваць даступныя шляху ў вашай сцэне адным з трох спосабаў:

  • Бесперапыннае прастору, якое змяшчае перашкоды: Гэтая мадэль графіка дазваляе плаўна перамяшчацца па перашкодам з аднаго месца ў іншае.  Для гэтай мадэлі графа выкарыстоўваецца клас GKObstacleGraph, клас GKPolygonObstacleдля перашкод і клас GKGraphNode2D для вузлоў (месцазнаходжанне).
  • Простая двухмерных сетка: у гэтым выпадку дапушчальнымі месцазнаходжанне могуць быць толькі тыя, у якіх ёсць каардынаты, выяўленыя цэлым лікам.   Гэтая графічная мадэль карысная, калі ваша сцэна мае выразную структуру сеткі, і вам не патрэбныя прамыя шляху. Пры выкарыстанні гэтай мадэлі аб'екты могуць перамяшчацца толькі гарызантальна ці вертыкальна ў адным кірунку ў любы момант часу.  Для гэтай мадэлі клас GKGridGraph выкарыстоўваецца для графа і клас GKGridGraphNode для вузлоў.
  • Калекцыя месцаў і сувязяў паміж імі: Гэта найбольш агульная графічная мадэль і рэкамендуецца для выпадкаў, калі аб'екты перамяшчаюцца паміж рознымі прасторамі, але іх канкрэтнае месцазнаходжанне ў гэтай прасторы не з'яўляецца істотным для гульнявога працэсу. Для гэтай мадэлі клас GKGraph выкарыстоўваецца для графа і класа GKGraphNode для вузлоў.

Паколькі мы хочам, каб гулец у нашай гульні перамяшчаўся па белым межаў, мы збіраемся выкарыстаць клас GKObstacleGraph для стварэння графіка нашай сцэны. Каб пачаць, заменіце ўласцівасць spawnPoints у класе GameScene наступным:

Масіў spawnPoints зменіць некаторыя пункту з'яўлення ў гэтым ўроку. Гэта звязана з тым, што ў цяперашні час GameplayKit можа толькі вылічаць шляху паміж аб'ектамі, якія адносна блізкія адзін да аднаго.

З-за вялікай адлегласці паміж кропкамі па змаўчанні ў гэтай гульні неабходна дадаць пару новых кропак з'яўлення, каб праілюстраваць пошук шляху. Звярніцеўвагу, што мы таксама аб'яўляем ўласцівасць graph тыпу GKObstacleGraph, кабзахаваць спасылку на графік, які мы створым.

Затым дадайце наступныя два радкі кода ў пачатку метаду didMoveToView(_ :):

У першым радку мы ствараем масіў перашкод ад фізічных тэл ў сцэне. Затым мы ствараем аб'ект графа, выкарыстоўваючы гэтыя перашкоды. Параметр bufferRadius у гэтым инициализаторе можа выкарыстоўвацца, каб прымусіць аб'екты не знаходзіцца на пэўнай адлегласці ад гэтых перашкод. Гэтыя радкі павінны быць дададзены ў пачатку метаду didMoveToView(_ :), таму што ствараецца граф неабходны да моманту выкліку метаду initialSpawn.

Нарэшце, заменіце метад initialSpawn наступнай рэалізацыяй:

Мы пачынаем гэты метад, ствараючы аб'ект GKGraphNode2D з каардынатамі гульца па змаўчанні.  Затым мы злучаем гэты вузел з графікам, каб яго можна было выкарыстоўваць пры пошуку шляхоў.

Большая частка метаду initialSpawn застаецца нязменнай. Я дадаў некалькі каментароў, каб паказаць вам, што пошук шляху частка кода знаходзіцца ў першым аператары if. Давайце пройдзем праз гэты код крок за крокам:

  • Мы ствараем іншы асобнік GKGraphNode2D і падлучальны яго да графіку.
  • Мы ствараем серыю вузлоў, якія складаюць шлях, выклікаючы метад findPathFromNode(_:toNode:) на нашым графіку.
  • Калі серыя вузлоў шляху была паспяхова створана, мы ствараем шлях з іх. Параметр radius працуе аналагічна параметры bufferRadius ад before і вызначае, наколькі аб'ект можа адысці ад створанага шляху.
  • Мы ствараем два аб'екта GKGoal: адзін для пераходу па шляху і іншы для знаходжання на шляху. Параметр maxPredictionTime дазваляе разлічваць, якім найлепшым чынам ён можа апярэджваць час, ці будзе што-то перарываць аб'ект, вынікаючы або застаючыся на гэтым пэўным шляху.
  • Нарэшце, мы ствараем новае паводзіны з гэтымі двума мэтамі і прызначаем іх агенту.

Вы таксама заўважыце, што мы выдалілі вузлы, якія мы ствараем з графіка, у канцы працы. Гэта карысная практыка, так як яна гарантуе, што створаныя вамі вузлы пазней не будуць перашкаджаць іншым вылічэннях па пошуку шляхоў.

Стварыце і запусціце прыкладанне ў апошні раз, і вы ўбачыце, што кропкі з'яўляюцца вельмі блізка адзін да аднаго і пачынаюць рухацца да вас.  Магчыма, вам прыйдзецца запусціць гульню некалькі разоў, калі абедзве з'яўляюцца як зялёныя кропкі.

Pathfinding enemies

Важна!

У гэтым уроку мы выкарыстоўвалі функцыю адсочвання GameplayKit, каб круціць пункту, нацэленыя на гульцоў, вакол перашкод. Звярніце ўвагу, што ўрок быў накіраваны для вывучэння на практыцы пошуку шляху.

Для рэальнай якая працуе гульні было б лепш рэалізаваць гэтую функцыянальнасць, аб'яднаўшы фукнционал гульца з функцыяй абыходу перашкод, якая была апісана раьше ў нашым ўроку, створанай з дапамогай метаду init(toAvoidObstacles:maxPredictionTime:), пра які вы можаце прачытаць больш у Даведнік класа GKGoal.

Выснова

У гэтым уроку я паказаў вам, як вы можаце выкарыстоўваць агенты, мэты і паводзіны ў гульнях з кампанентнай структурай. Хоць у гэтым уроку мы стварылі толькі тры мэты, наперадзе яшчэ шмат, пра іх вы можаце прачытаць у Даведніку класа GKGoal.

Я таксама паказаў вам, як рэалізаваць пошук шляху ў вашай гульні, стварыўшы графічную мадэль, набор перашкод і мэты, якія дапамогуць прытрымлівацца гэтым шляхах.

Як вы можаце бачыць, у GameplayKit маецца велізарная колькасць функцый. У трэцяй і апошняй частцы урокаў я распавяду вам пра генератарах выпадковых лікаў GameplayKit і пра тое, як стварыць сваю ўласную сістэму правіл, каб увесці ў гульню нявызначаную логіку.

Як заўсёды, калі ласка, пакідайце свае каментары і водгукі.

Advertisement
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.