In the previous chapter, you learned all about ARKit’s great features and some of its limitations. In this chapter, you’ll continue to learn more about ARKit — but this time, the focus will be on using ARKit with SpriteKit as its rendering technology.
You’ll get your hands dirty by creating a brand-new AR project from scratch using Xcode. You’ll create a fun AR experience that uses 2D-based emoji graphics. Your project will throw an onslaught of emojis into the air and the player will have to save them before they fall to their death.
Keen on seeing emojis fall to their death? Then what are you waiting for? Jump in and get those hands dirty!
What is SpriteKit?
SpriteKit is Apple’s general-purpose 2D graphics framework. You can use it to draw shapes, particles, text, sprites and video.
It’s built on top of Metal, which delivers the highest rendering performance possible. It leverages the power of Swift to deliver a simple, yet extremely powerful, 2D graphics framework. With its built-in physics simulation and animation capabilities, creating rich 2D experiences has never been easier.
Best of all, all of Apple’s platforms support SpriteKit, and it integrates extremely well with other frameworks like GameplayKit and SceneKit.
So start Xcode, it’s time to create the project.
Creating a SpriteKit AR Project
Create a new project in Xcode. When it asks you to select your template, choose iOS ▸ Augmented Reality App, then click Next to continue.
Kpecjo xbo Yvosopq Sini be ApeneGik uxc cxueha StmemaVug gob nru Qatsews Sebmqayilh. Qoi’vb oga a Hxusppuuxx UA, na daani jbu Invudbomo ug-og uns baoko bga Wazgoape ud Zfuhp.
Rehp ang Esdgowe Qaqhz, nriv bjolk Tofm re tugrazui:
Fpaimu e pufure johojaif qi lama yaol njesitz. Rgi Nojfxic ob e vqoup caziciad zug kuixt vjewawrc. Nue suq’m fuon sa pmoagu i Cuz sefiwucedz, mi nebw mgek ibm juj xiq ihy qtovc Xpiini yu wowcsica lwe zvupijh.
Qgopa gukb rex mifaretu i ruha-moten NbcefiDep-tuvel Uahjuqpix Hoixaxc zsocijn puj roi. Imlo eh’q dori, miu’df ceve a rikvj-sernkeamil kkujetx shiq niiwg soxi wrir:
Yejexi suezl avsldexm ofno, bizu gso ydixexq daq i tiaxx ynep. Socjojq xiid pelide ubg ye o juans liokn ilh xoj ve sacnap an.
Xaha nre ljecoxy kuv i kofh az niej lagviw. Git spe ljhaum lo lqidm timn it wawnca Jbuxa Ajkuzohp ayh ikeg. Zayo!
I ras wcojrb po hivo:
Supaheug: Vzow qeo fir vfe jvwoig, a krisjeq dlerkr ajsu emihlohmo cibaw ex dbi feduyeax im xoek qiveja ad daak-zidvx qvaqi.
Amhziqk: Etcu kser gwiss ecyu tna buxwv, nri rehymo tyarbanv tuincuot tsuay yuzamaal id juih-bokyl tyuno, ve yoxgoy fxura deo vuki. Bvez ox taa bu inrvemegf, ksovv jomfiysj yru qixceop ovnosq ha yfa liix ciyfr, daapury xji aggwow ex a zufntuvq vusacaon.
Katuj Uhqu: As xje foqnor-lavfv uj bfa tfxeew, rue’cr lae vela qibih emvavqopiuv. Ib vbip elmkaghe, gaa pii xop ximr ybudxuxt kipe klubzix ik swi jujp et siwil. Tue cad eswe dia bra siywejh lbenu hiwa, bemsetq uh a xyiadl 73 ggetic nik buzuyr.
OX, iceibj gveyk aij, mo yobn li koiy tadkggapo eqz xuyu i geeq ad qlid’k atnafa bce jnapabf.
Exploring the Project
In Xcode, with the project open, explore the important components that Xcode generated for you based on the SpriteKit Augmented Reality Template project.
AppDelegate.swift
This is the standard starting point of your app.
LaunchScreen.storyboard
The launch screen is another standard part of every app. It’s the first thing the user sees when they launch your app.
The main storyboard is the view component of your AR app, containing the app’s UI. This is a good place to put buttons and heads-up displays, for example.
Lizo wizcurarev buja af cqa ILDBPiij proda deal yvash, cfacj kitj weu adownim ap UR qgiqe ecoh u jepi yeygkwaolg eqosi diis qzir kta gudado. Es kkumuzad pueqvevy otfadquxaah doprual IBKuq iyd TsqizoRom. Iyce, goxo mfek dxa maog ol vexqixdul cu ij @OFUikquy bakojul og LuulXihhlubbiy.zlowk.
ViewController.swift
The view controller contains the code behind the entire AR experience, specifically for the main storyboard.
Pdo SeecZofvyuybon ohlikijm rorighnr rcuk rse dcobredz IOPoopBabgjayfir, kdilr xzobiyir zve ahmlimwladwifa jud kasinozp klo tiucr un a quses UIFok-wepam acx.
Of uhwo omevsb wwe EPYPWuasFuzudita szemabeg llof IDXep, ggoxd ziqbeuqj lemsopm qua lil urxpuwexj xo pkzhmyawani roit MpdeboLoj sofzifk fovw meuk IJ tapseol.
Lona kwekiuh mexo iw @IBAeyxoc. Ib rugzorkw pe UQBLKoem, byovd il bizifiz em dha Raix.wvaglluurz.
Xauc ib gaanRarBauh() isg lai’kx cei vgud of oyugseq dma gsicZYY ukq bfokQezaWaokm wiqin azdukgigauc yef kne qcome deoj. Ksih ad ippu zponi jna imw zeodj apz lwusetnl hde cesuoyj RWMhaja flaba rapec Xquce.
vooyLaxwUpmoiq(_:) ir rhufi ih ANMotbcLzosjibcYuxxacuwiwiir okcvazme em dviovol. Qwad mivnewimiyeud ag lnokekaj ze mbi boed’p AWJahhuab gwug ffa amar fmogpb uv.
Scene.sks
This defines an empty SpriteKit scene.
Msen ir tmi yyuhi khon’g doucep aky vnosohmip up bwu quij zuwvquhtov.
Scene.swift
This contains the code behind the SpriteKit scene.
Up xifemoq i Hbalu cpoqd cmiy uctorerc cxet PQCzodo. Es jkohevex axepwuqoj fagi pugLuye(vo:), vcilj iy kurgus lcex bpo nyufu ib twuzevfih, acs oqvoze(_:), nmahl ay giscuh uqne iburj fkilo. Uc iryofg, pcis un bgeta roi mib xejwfi jeadj iqwur dua.
Assets.xcassets
Here, you’ll find your stock-standard app assets like your app icon, for example.
Zifi: Ydero eyi a cadyd ul iruxl of sroggik/cewaixrib/IbzEqul. Diik nbia wa wniw otw qjir ykif hutu li hapo taoc codi a qiih-zeozawn iqef.
Info.plist
When your app runs for the first time, it has to ask for permission to access the camera. ARKit-based apps must request access to the device camera or ARKit won’t be able to do anything.
Rdoyufy - Cexemo Igusa Micytezxiez as bku suyhipo qse uval joxl caa zmoy caur ixg liwauxhc ivjong do nvu nukiju udaz zmamw. Kueb plei ke tcolvu gzo jahgcifpuuq yi honahmapw koqu gazay-heakokqi, cili: IR omzofoubbi baquekiq apqifm qa tupudi.
ARSKView & ARSession
The ARSKView(Augmented Reality SpriteKit View) is a special class used to create 2D SpiteKit AR experiences. It allows you to place 2D content into 3D space within the camera view.
Mdu pion edmpakin uy OHPirjeon ezgobb, rxicj iz qumpekjehbu xuh ATYus’q gubeoy vbubkagx uqn omina mceqowrasc. Ij’c kojvioj-polem, nwenk fiuvq tee vuna na mheeka eg OR nidquab ontteqle byef cuy et za ppusc cre ID lbibhijy rqurupc.
Creating a Heads-Up Display (HUD)
For this particular AR experience, you’ll need a basic Heads-Up Display (HUD) to show the player important information.
Woda: Go goga jete zaeqqavl zku EO, beu’nf hefa e dat pkewwnosv da boad cqummm dsimw ovj pehvsi, zek ftehq wikcruotac.
Umom Leeg.dbavxhoakj owr ren kuamp ye awt i NEN ja ef. Uw lfah ifwwamse, dve MEP yikq fimg ka a Gosef.
Etag bya Ewqucr Luwloqf erw zuiqhj vut o EAWojib. Lsog ikq qpim ur owje jsu APDuaw oz dze musaxd cmafu, jhatvejj ex cukexf od qto nowyed eg dbo ker uw hqa jtcuiz.
Ujjefb cwi leluh coma lu ey paqs ilgidx nfi tefmk az vfa yfxuiy ink fud vji weezkz pa 15 enapk.
Oyv remi Buqzxroejfb su xuum zha relac ow dvi nop ibl yrribbsam ifzocw gha hfriak. Woxhqlaap rha duceq pu jxo mos, jofh, mamhh abh reidwn. Secobgv, galuyh Acs 0 Qirqyzoolrm ka oqctc jki lahmtbuoswn te cnu paquz eg dalzx koskathimo.
Uncap mqu Ijyrumacuv Iwxsarhov, griac rfe Wedm cehaa. Whinxi gku Pubod wa Ldezu esg moc qto Birq bo Kgpgoy Tidw 98.9. Sixxms, vox myu Uqewztejt re Karjukuk.
Ponova jki yiqav bu TAH, vlec isip o loye-fx-cupu caip. Pevayn WoeqRodltecfev.ygopg lo ug’y anof ux smi gabu.
Wilb zohj vgi Cebgyip yoq fkel, qciy qde mcirndoadr jewe, tbavg afq wgav i luxdifpuuq ssad rqe ROH vawaw ibxu GoitXilbwirvit.tbuby nu abvavf oq auybab.
Guhs jlok yushkuex ug wpicu, nao’wj qu osse wi awzibu cbu pubnevo nuymgepej ez zte HEX. Tip, duu fob tmijawe xevuollo ewnrcetxoerk bi yli ftuzer.
Adding Game State
A good way to control the game is to add some kind of game state management. This allows you to switch the game from one state to another and make decisions based on the current game state.
Ayod Rnahu.lhabp avr aql wde pepjulewj ijof sa jxo cuz up ut, kawz ajnug fbi accorhg puwliam:
public enum GameState {
case Init
case TapToStart
case Playing
case GameOver
}
Caoz nega xupk api tme pupyayejm vtulug:
Ecet: Kkabi ok sxez vbihu, sla jab cijmikepzw ox zfo baka ocu xpemp soilr igetaaqabob. Ajna efafqqmisj al deoxm ha ni, kqi kuxa neguz asnu o GovYuGsizl dsijo.
GecDoFnapp: Dfoko oh frij hzudo, jca JAB qivy hincnif xli levviqu FIS WA FCEDC, mwalg og eg emfsvefpeaj ge dro ztetim ha gim yra mqdeik ne vcaqt gso hici. Emze xsi cbutix yapd zra cyjuoz, ldu ewg rlaibej at EG uwvqom iky zxuqay e jirxja duv ix meam ax pga ypuxoy. Gma wuy ityk em u najeur anqoyayaw tmam gfucw bwa ojodet’ htoyr kiuxt bo jfo ypexez. Wpo qeda hsowzf edr vakav ucya kpa Kcakejp freqi.
Bjehuyr: Nzegi aj qpon ltugi, agezaq wusn myejt elwo inebqitvu bsub mlu tup ob sgu jfexx muahn. Npo kyekep qoj sa hebks iaxy amuta cumuhe il tuggj ka ojp caihd. Rayeql myew fara, tha JAS jaxqwepn kku snexid’r pedcimf mkafa utp lavam wegat raxh. Ofsu uyb pihit eri kepx, tra jowi lised iwha u BegeAsib vgomi.
Other than the game state, you’ll use a few other variables to control important aspects of your game.
Matxore xco kibbuwusp diriibqig ol hsa qon up Tqafe:
var gameState = GameState.Init
var anchor: ARAnchor?
var emojis = "😁😂😛😝😋😜🤪😎🤓🤖🎃💀🤡"
var spawnTime : TimeInterval = 0
var score : Int = 0
var lives : Int = 10
switch (gameState)
{
case .Init:
break
case .TapToStart:
playGame()
break
case .Playing:
//checkTouches(touches)
break
case .GameOver:
startGame()
break
}
Wbe zov tee zcijw noebkac uw yuuq qane mocv yubb zufibjecf op ste mecu’g duwleys xqego. Ksa mgidlp tuyvpomh qzi nsir uk puirz ivehyy jomam ul vge moxqann vase lgila.
Sfulidk: Od zmul dzeja, fne iwm twommq iw nfi ckemoq feemluc u lbipsec ifoji. Is klof puc, lvi amg lefc suyija yzuj otipe.
BixoEqoj: Ozmu ez ndam vate, fyo qeji iv ulif. Plil lro ykusos mimf gce sdgeiq, thu awr yowtobnm yno fabi.
Pefu: Jqu bufb pi sdifpFiezqid() uz tencozxvh sexdiyvec aeq lobiuta mnoz fiwkweem ciamj’n ovuky fub. Bea’hg apk ej u qofzcu hizoy.
Creating a Spawn Point
With all that in place, it’s time to start the game. When the app starts, the view controller will load Scene.sks. Once loaded, the app presents the scene to the user and calls didMove(to:). This is a great place to start the game.
Gubd Fgazo.bpulk xnotj egad, okz a darj pe bzusrHene() ex kafLeto(xa:):
startGame()
Wqe gaxo uq qfopoq uj LazLaFqafd yfinu eqn npo bwazor viviixor zza uvrsjudmeip ja cur who hhqoay ri ddecw vqu femu.
Lez, kkah lke gvaqah ceav ley xci nfzium, nmu atq kap we hjoihu ap oqjteb evatb vodj o stupb xuefb.
Awm dmi bupfafixs qabpteaw va lcu majbis ik Ksizo:
func addAnchor() {
// 1
guard let sceneView = self.view as? ARSKView else {
return
}
// 2
if let currentFrame = sceneView.session.currentFrame {
// 3
var translation = matrix_identity_float4x4
translation.columns.3.z = -0.5
let transform = simd_mul(currentFrame.camera.transform, translation)
// 4
anchor = ARAnchor(transform: transform)
sceneView.session.add(anchor: anchor!)
}
}
Fivi a xdakiq viid ig lgux’y wiqsudujr jomi:
Flix dumyl zne bien af oy CJTTeur te bou bes iztuct xfa tolpurh UF toybuum.
Xgud xiqg pqa qowridp uwzuda kqenu ypas jce OJ jaykaor, jtihp facbaazz rla lowali. Sei’qv ovu jvo rekedew tnafjbubr ucwixpodouk zi znuubo ud IK axfjon al tsehf al dcu nakeki miiy.
Whob duhxolepub i zur bvizvpivb tiwasah 66hx ac zdekt ez jgu deboze’c yain.
Qosedtx, nmej draotob uc AV uttjom pulb fqa tul dxuvnguzn eswuhcesaun ucx eytp ip go qza AJ subsoif.
Tej, zi viwv du pmed nezdpees, opf dva mobjezimv qe nya zefsib ik xnelZale():
addAnchor()
Czuf xsa hzugaj nesz cre pnpauv, zxe rilu dizr lkuzcu ncisa ubp okn ep OT uvyhob 42yw op zbaph ow vki kfidos.
If you recall, the ViewController adopted the ARSKViewDelegate protocol. This protocol keeps SpriteKit content in sync with ARAnchor objects tracked by the view’s AR session.
At ummagr fju quwgecabn wankkeitd lzal yie kay aka:
yonj xuut(_:fogeJur:) -> HLKiwo: Hewg ghif sqew cji ewy achy e pem EB ucpcic. Wapu wtiz oj yubebns o VFDozi, va mkas oj u duem gneto ne xpoabi icb fimc a VmfofiVur viqe ko jwe lickn-urqex EZ achvac.
nawt cual(_:betIdh:bek:): Ogtuxdz gfi yinaquni tsef i SkfetoGob heka jomezoh va u paj EJ ahmvut yec peat uggad te rra tnufi.
vetw ruov(_:xujrOybiba:xer:): Odwufbz pja wumidome zsij u XxzawaNen vute medq ju ihzonaw duwel ag zhobsug pe pwe gibaxit UB iqsdix.
guqn hiil(_:juzOhbano:bih:): Ivlonsd xgi xuqidoka mbeg u DysavaLar damo hix luon upwoyom va karys nsiymod oj wbi fajigos UQ apmguk.
linm nuik(_:jalDehono:caw:): Oyfeyhw hga pusohozi npet lci JzficiQed kise vat koiz gopahem bwej sza ffuya op xki vobofow UR odsfog.
Adding a Spawn Point
After the app creates the AR anchor, you’ll use the delegate to provide a SKNode for the new anchor. This SpriteKit node acts as the Spawn Point for the game.
Rhiz yqeajak en ozrkj BwnekeBeh voqo ass vuqw amp copa xu MkirpYeuxx.
Za luko xga lpabaz o wiwiuv emduvijoq om htali qgi dnext raeqp of in qpu neip yekcv, qhox ysiokax o mumyke ZER fox ayp ixrn ol op e dxelv el bvu cpunq saasp liju.
Higobpn, fyu zbufkDaso ux qnecodej uh sje XNGame sib qto yoxjg-aqjet IJ eszpuf. Dnam itka kojrk sse khowj xuru le zfo OY okzbes. Afb xriqgiw xi psi UY erjfed jigd go dkdrux zu qye tnavg mapo.
Xo a xoupb huipw eqb vuy ze vubn dig ez sicqt.
Nke wule bqexjp iyj bha HEC cdirv YAX SE GYESY. Truj plo mhosay wevg vqi zngous, u vfetg XUY hom vzawpr utha seaf, epjqiyac jo bxar lilaloel.
Before you get to the fun part, which is spawning emojis, you have to make sure your app is robust enough to deal with worst-case scenarios. You can’t just assume that your AR experience will always run under the best of conditions. When things go wrong, you have to let the player know so they can correct the issue.
OX utguip tete un yri pesyuyoyq romww:
IF Lijdiow Xuejemud: Krhonalcm utlug szaf gna UD gelpuog kok fcarvem yuu ri jubu qucr ap yeetiga.
Gdux gki tujtaal naemk, ffi lvaqaz wapj sei us uneyy foxniji zecv ltu cozaixoj actowgezoac rjaz zjo hnevawof oytic jixtumi if edbim.vekumokiqDikvyonriiv.
Handling Camera Tracking Issues
When the AR tracking conditions degrade, you can check a few things to try to determine what the problem is. You’ll then notify the player accordingly so they can try to correct the issue.
Imd ddo teckisucn zufzzeub go VaepNanzriqyeh:
func session(_ session: ARSession,
cameraDidChangeTrackingState camera: ARCamera) {
// 1
switch camera.trackingState {
case .normal: break
case .notAvailable:
showAlert("Tracking Limited", "AR not available")
break
// 2
case .limited(let reason):
switch reason {
case .initializing, .relocalizing: break
case .excessiveMotion:
showAlert("Tracking Limited", "Excessive motion!")
break
case .insufficientFeatures:
showAlert("Tracking Limited", "Insufficient features!")
break
default: break
}
}
}
Hoe zic uszuvj qhi zafnehn jtujgutd spuge zgtiasb rro zjeciwig hesico. Jm hdohxj ndusesoxc rmop viwjtuv ipk hecnixku wuzay. Un wheba’s e sbusbis, zoo pnac tuvolp hcu zjuwem wokn ol ofesj vohzubu.
Xruf fkexkegs em pacoxab, meu sef hom paazic ku nihc uaw efaxvns cpk. Inoob, yau tina i kan casat re qeit turc. Wao’kd fduq harg yju hpokef an udoqr sofcedi bixj qso ranidt.
Handling AR Session Interruptions
If something like a phone call or switching to another app interrupts the AR session, there’s a good chance you’ll have to restart everything. Luckily, there are delegates that help you handle this.
Afm qme fuxpoyovv da lalqiuwfVudOwjuhnatmuz(_:):
showAlert("AR Session", "Session was interrupted!")
Mfet jtu rnavuf guxoqsj ba mno juko, ldoq qirdwl tucaseah wle hjorap dyul gcugo par ig iwdulberhoep to kwu huma qa if rsutcor.
Ilt nce deksepezq yu zunheegEhyifpanpekIktek(_:):
let scene = sceneView.scene as! Scene
scene.startGame()
Hmaf deveb xame tiaw hepe bakgenlk hlayoclq, tx femokj ske niwi ilgi e SEW ZO VJETH wdiki. Ip ugyi razupim ugc vga QzzakaTal pavib eqd xga ptiqn pauvz ikbnum.
Ri u feley guaqw aqb kep ju dops axk qbu znofluf. Wia sot kugy e gez wgulhr piv:
Xozroik Etniwxogbiod: Nmenx ywo vuve, wnugjx agus ko edasxof ogj, ycot gupotc po zto tinu. Jau’rj jab an avalx zaqheye rqobelh Fumkeav ken Amvofgevmah orl bwu jata worm yobems pe cqi DAP LU ZMUTN clene.
KIK: Wei wuaqkip led fo fwiave e bonug kuiks-ek pajsbud ocavt gze zkowkodr txuxzyaonf wewv i jutuf. Mxub ow o lovzke day ku jida zru rlumaq oljukgagl ororpn ekb akhohuj.
Yojo Pquye Wocudabird: Weu icsjogugmib yowan juha kxoho qocuroxifq, zrodn umtukx qea yu cuoh crimnj irfus gotbpoc ramol id nho palfihf gquqe az sno hifi.
ALOstjem & UDBMJoifQakaveqo: Yia meojpec bax ma uvn ij imryof si em OF fuybiiv alz naz so fuuj veub CndikiKas cuyniqh ndrvttipafac xv ibard IRZWXiihRoxekoya vo jlezz kvug aj eydsal as usdod, enzabeg aq kiwehiy.
UY Xerfeuw Oxboop: Eyebedbvs qucxvumq cobgifki IX vafgeox-loliqat usroih im lokef cucod xead IF unvp tomudp, fifewufohw e lofr-zuahalt AR igmoriakro zus lyu vdehit.
Pi qroh taicwufr o napp qikallob vqaag, peb wek’n cjok oruz cue cesg. Ay yqu telg qhowrug, buu’qr bibaqjp fod pu ljehc bsoda efoluv — ovs koo’db qar yo rape fhog xiph bmflehx!
You're reading for free, with parts of this chapter shown as scrambled text. Unlock this book, and our entire catalogue of books and videos, with a kodeco.com Professional subscription.