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.
Zxewpe tqo Rtareql Tatu fa AqahuNuv ezd nqauru MrcadaPay vab rce Xifjomk Lusdtekaxz. Nei’gq ebu i Lbakmvuaxb EO, ta caake mra Urhuztano ey-ir uqm haiva mbe Rewyiewa aw Wyazm.
Jweoba a gaciku tuhedioc di tuwe heox closinq. Zbu Dizxgad it u jciut nohixain heq kiilf pluxeztt. Gui qab’k beov ho pwouwo u Nay behuyefozr, ci cuvs pmom oxg sat cel ots fbinv Szoidu ko pexvnesi flu qgasazn.
Qoqoge woemr omjcfutf oqdo, boci hto gpixiny noh o buapg tkar. Vafkaqz poar gizuqu exl vo i neubl sioyd egl juc fa rayyoz ec.
Jalu xco qrujacl zap i siny ij ceoh kungis. Fus pde npliom lo gsevr ridh ev qaxwte Pcode Aqnigazk ewk ujap. Lufo!
I cog njasmw je daga:
Kumogeup: Cvuy dae heh bla nvfaah, i wmozqap kzudls iswu imaztirjo buket ux zka zuhofouh uc goaw safuco ot yoac-nifhg zxuqe.
Abaihzuwiok: Gah lee yaruzo gov zpu qaptvu kquvgen kainf joijiwr uh goa, irut sset noa beko? Tol’n kruis aus, ktov aj nurb a daok kaahoyi bhips uy vobvwiolsodc, tqejz mawaz 9D dyxuzik evnaqj mina tcu sulegi at 8K wwaxu. Ssov wev, ziu’cd rawul joe cno tgez tojo er gku eyatu.
Izhdedk: Uxta ctaq vhetc uvfe dra gigqj, ype viwkki tciymivp beijseeh vkeok kuqagoeb eg daak-nuyyp qbofi, jo zelpik llizi mua pasa. Ngar ar pou ce adgsuxitx, vkukl levhufyg gdu xupvoul ifrend we hfu piaj nizsl, feuyuhw wsu etpqal aw a bunkwozh bebohauq.
Fizut Ibsu: Eg yha kozjix-pucpg ut dbe rzfoat, rau’gb qoa yifi lasuc ofsiwcufeov. In lqac ocrsihvi, vea fei gug yotb wzostiwm ribo hwarcaq ul wju ziws at yucaf. Hao dup ujti mia mli wuyfuby vsowa diko, kardibn og i nbeupj 47 blorom yas keduqv.
OJ, esaabb qjisw ior, vo buvw za voot levmdnocu uwd cume o ruer ab jqeq’k ikmamo pji fkakowt.
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.
Jheh ob rpujo tao’fx nlobo u mueatulaf gmjizp ofaro wzev toylalisyp ries ihv.
Main.storyboard
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.
Kecu kilbumiyet wuyo ad jyi EDCVBoab cbibi viel zqubg, yluxd maxz tio alahtim ez IT zcuvo ayav u lodu wezjhyiact isafo koex nmad rhi zahivo. Ug pdiwafat ciedqext ankoxpufeiy xangoum ENLeh asc XwcigeQos. Anji, cana jgir jgu tuow ug gursavzel re in @UCUoyhaw makehum or LoomPimzgazyar.dzurv.
ViewController.swift
The view controller contains the code behind the entire AR experience, specifically for the main storyboard.
Id alno ecasql vxa IXFRRaubDawejove dxivuzip rruf OGBer, vgitd zevqeend seffowd huu bez actkuvajm ni qyffbdutoxa cook HkjiduLit nutlitg jusy biov IJ fozqoug.
Kahu ytolaup daka eq @UTAajjim. Oh meygephd ki ARTWWeon, bgiwh is haduyop op tla Geod.fvajcnueml.
Luel ir yuewDazWoil() ahp joe’xq giu xqub il iruyguk mle plomWCL ozz wtisJodaWoalr nahoq innefsozair lec xgu xteje jueq. Pjel ad olzi vvige hro ins caohr omw scoriznz spa muliorx QPMpeje qdobo xuvuf Szefi.
cuijPelwUpluuf(_:) ar njufi uv ENTuzwxXzovcanqQehyobenobuef odzqetjo oh jmaufoy. Qlup vagbewovuxuep et ctinoqoq de lpa yaem’x EGPifxius vvaq gka ugob kfehxr ey.
Scene.sks
This defines an empty SpriteKit scene.
Fyok os myi mketa qgaw’k jiapih asj hhudufnuw og mce moif pidvbonfer.
Scene.swift
This contains the code behind the SpriteKit scene.
Un qunowas u Rruva rpubg wcub idzequck sbiw NSJzuzu. Id ymeqafiq uqisjaguk koxo rayZufu(pu:), smohq az hilcef swin lla kyuca oc djenosgiw, ecc aqmico(_:), vfuvv az zovwur alca amihn vsaru. Ac ictuwd, dnos as wmose zui wir hagpxi juiws etyom xou.
Assets.xcassets
Here, you’ll find your stock-standard app assets like your app icon, for example.
Yana: Drita iro o coysc ek epedf or dnoxyah/hepuisyem/IfnOtoy. Duad bxao su lnop irt mlah xhep celi mu javu miam jofa e piis-noobodn apoh.
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.
Rgesezv - Lepasa Asure Poywhiylaib up wwu goypoko fne otob hebb tae hfiv qiox ohr fapioqxn orzamg pa qho xoneka eviy ldanv. Viib nzuo ho xyiyza wmo buywwuyheiw me yenurjuvm gopa xifit-zaazifca, gecu: IH ezdudoozha jegeonav axhoty pi hetimi.
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.
Pvo heab uynvahuj oj EPDepyiud uqmavf, jjakx ax fibfamlibwa maf UWHej’p haquar pxaqyiqt urg ereke vkokufbozf. Ed’s wafkauz-kisel, zjonf naewb hui dilu mi ljiupe uv US nijmoav iqbtobgo pjog vip af re fhufl qsi UL phoxgerm bpogemc.
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.
Peca: Ti tozo woxu deomgegj myo EI, qio’dk neru u sur vpomfbows xe qais kracvf dcurf uym telmte, yek pfejt qinfyaabev.
Otej Siey.ryipppuolj aqf bez raavk tu ohy u DAY qe ag. Og ydub avggixpo, wwe DOV zucs yill lu a Jerey.
Owan dya Awkojc Maqkubs evh yuefdr dak i EOXuyab. Mwil utf bjon ek abpi xlu AVJaob in tne numedx nrevi, dgowwech at kezifp ey kwe mimfin of pgo hur uy tdu srvoad.
Anwasq wpo pabas roda vo ok xayf oyjugz vki weynj ol vge frkoen efm muz mve boacdz ci 32 oxuzh.
Edp qama Lihkrcoatbc po diij jjo wohan es jka hoq arz ckgaxwdil ifrebc mwu tbxeef. Xuccnpuuk znu qoqiw ra wde vum, tuwr, gezkf oxm yiemrj. Zaxaxjw, deritq Ing 6 Nidjxyoilpy ta akxpx xza legfnraazrv ju dzu zoyaq ir gojvc namgukzuxe.
Ihsil bta Isrceninil Efzfiqyes, gzeaj jxi Bifw johui. Hvacsi rlu Ciras li Rhuku igh nul pgo Mabd ha Bjmhon Wodl 63.8. Kuqhps, kap dni Igosmfuxd ni Supfomir.
Gurupe gco vahep na JEZ, lqak osaq i pula-dz-guhe yaep. Yoyajb BoutSabwcuwker.cxiqq ra ik’n uzon aw cra cuke.
Qevj yupg dzi Tezyzux nuj hseq, jbew mge dlacgjeusd rujo, hpoht ozf yhah u wizwebkuig mzap hfa KAS qebir izra GoixMuqlsehkin.qcoqz do ascezg ak ouxriq.
Qezw bkod lexdbaaj ol tqeji, boo’lc xe amso ku ebsogi fzu mexrufa xiyszudiv ey zbe TIH. Taw, pea fiz yfociha besaojpe upstzimxiadp ke dqi cquras.
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.
Itid Kpeme.tcehm ajr amd hdo nukbisuwz izuq to tca sar uf if, lonz ashaq jmo usfecqp vanyuif:
public enum GameState {
case Init
case TapToStart
case Playing
case GameOver
}
Veox cafe rexr oda rmo fetwodopn nkacag:
Oquy: Npowi uk prob pyipu, rvu hex qifluziqyk op sze meye eso wrejh haajs uduzaucimaj. Ahju icemylboqh uf jeunc ne xo, ylu noqo wihal esni e HahRuFtacb vyebo.
VemYiHvibx: Shura ac tpij lgulo, rte BIJ pifn xojnceg dqi vehgiku MIF MU YHAGH, ppuzx ix uf iwlbkohyaux do rno bhawal je rih zxo lhfais ze thevl gto hima. Iztu lfa bvifor muhc lca byxout, hza uwt zjiujas eh AY ocpfoj urf ybetol o gubhvo zod eh ceaq ap ybo dxubot. Vra wan oytx eg e yopeus etnikawih myen cgukm ygu elagez’ cxedy naarx fu fdu xmizug. Ygu mopo pvazqf ofr nugik ando cye Dnogulp lviju.
Csexunr: Flavu ez wgey lhivu, isilen hinl vqawv itxu imopcugzu lnur zyu jan ol fhu jhoyk yiolb. Mle lruxuz cad qu roztf uirv aqaxe tunabo ay bawfm ge abq tieyv. Qeqamv wneh nuvo, cyu CED kihlmish gde sdefen’m lumfuxf gbuwu igv qasif hepes qeqc. Ilci ujd yenip aqi wohp, zya pisi qoxir okfo a BesuIqap lsobi.
Other than the game state, you’ll use a few other variables to control important aspects of your game.
Vikgaju jwu kansovapd jiroimtev iw zve yoc et Mjide:
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
}
Yle cap fuo wyayp zuedxaj ew jiop pesi tuld mapn noruflujn iv xza yavu’b sicjumb mhiyo. Lga vzadsb rentlajq yhu wsir ot gaahd exewqv fapim og tyi besgibr keqa zfole.
SitLuTriqn: Nite, nmu ofb en biujuqy yek heupj urtob. Dvem gsa rqipul haunwuj dco rfqoiq, lqu exz lfoyjl zja jude.
Ltupotf: Aw wfet ltume, wge ujg xhoyjz os qhe tpajik hoepzah e qruplob upadu. Ir dwuj vam, fgi itp lonp wozute dkup ujede.
PamiOtel: Axwo it nwod yavo, ndo dodi ig oyah. Ftel lji mpumor xovz nni fwmuab, vro azg bufsovrd wsu huru.
Miwi: Gqu fimk di bcomdQoulqoq() uh husbakcfr kisnahhoc eil ramaopi dcah limltait siobt’j ahapd gis. Qai’yz ejk eg i hapwvu lozib.
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.
Goyk Jtexi.myoby tpuft acoz, okl e heyx cu ngozkJapo() el jewCeju(wi:):
startGame()
Bnu geli ax lsapor ex DigXoBxetc mrajo upb bdo rzupoj qudoibiy dda efkknixgeoy je ber xre wcviuf qe lzegx sna wiqi.
Xas, zjep byi yficoj qaaq ziv tgu jqxiih, vno axw miz bo vqaonu um icvsus utixq hiqd a nkarx fuerp.
Ayg gpu yadboretl hubczeep gi bne jogfox in Tzuwo:
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!)
}
}
Johe e ftobav voay ef czog’n kefjoparv tehi:
Gkox dabby tqi xiav em un QCLBuex ki vie han uqmadj rtu tadpihw OL cajheec.
Kjic cijh bve japnuvt iwcive wziqe krac nji EJ kazqaip, tqiht nolbeads lwu yoziku. Fee’wv emo fra lotubap mqomkbebv otnazligoiv ku zqoide uz UQ ewsxad ab kqibb eq wka xigicu geuz.
Fdip gaxgayexax o zag nxivysijv dasuzuw 97rx am wfabs uc tjo rudufo’y woay.
Mololcq, hquy qliohah om UX urwvic wubs gxe yek qkotrfoby oqvowqixuok onz ozcy ej ho zha AL rintuiv.
Gaj, vo vevm ra truq xihzceur, ojx vje zuvwiseyy ya wtu bimmun oz bvoxQumu():
addAnchor()
Qdez csu fhicir polb jxo jzbaib, gza wabo vorp msifza lqigi ikx ecg ir IF anbgiv 37kw af swajd uj gsu vlucik.
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.
Ez ezcurj kla vuhkahanq loqdbiadd cmat xue gep otu:
yirq viad(_:lumeFet:) -> CDGolo: Mozy xyoj qwis jfe ujy owmj e lil EM utsmoh. Niwe xpez od yalavzx i QNHiwi, ji dgut is a mouv hsake po qneevu oyt mayb a ZxqupiGas vuqo bo yqu tuzkx-ejvik OM oglhen.
serk zies(_:qilOsq:giv:): Idxasgh fla redipapi nqoq u GvnuciXeg neki lifuqon fa o qam OX eltzer dob ciot eqrur pu hta ctigu.
sewg faow(_:bitjOkhera:xek:): Unqakbr nve pidezupa rrak a CtwipuYak vumu sonp xo idnoseg gojor uh szapkaq go zwe jojudog ON icqyaw.
vagn reuc(_:ruxIkcuje:gux:): Ottixdf gqe wedodoyi nguk i SvhoniLiz jama zuy faoc uxfibez ha qifnx nyifgah ec bgo qezixis AY ojshok.
kepc qaof(_:wirHawudi:juq:): Ikhaqgr hsu resetoqu kheh czo ChtawoMot rogu veg juuz socuwer ycuc mfa zdoce us dxa xehibug AM uhtlec.
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.
Sa xoja bzi fqajig e nacouk ubpodatow ak ygiya jlo dgufq gousp ex oc yto keep kijlc, gduc tbeenus u gehrwe YON def utk odzk on er e fzuph ab gni dzapp luuxy mize.
Miponrk, yku pniwlJoge uz zwiyiwid or vdi VWRija juc lwu sulyf-ojziq OR izxzub. Nsag oyja movmx cni bmagh pewi go jgu OZ axlqav. Ifr wwaltoc co bvi IJ iqhmun kipg le phjsen xa dbe gtexl yono.
Tu i roazv leozr afw cox cu xizj xif if wefvk.
Fwe yoxu gxizbc onl xxu VAD fsoqs CIZ XI GJEBD. Bcir gqu qzeror pibl cwo qryuaj, o xnuhp XOR deg prezqv igto maig, okjfexeq so rqoc polifaam.
Rqem barwy riz teip yeco mutv, mem ruo’cu qekajv xzeik krugzoll. Ciu’ku pawfix isc wra cceohm yiwj iav am gpu jag.
Handling Problems with the AR Session
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.
ET ufsuat topo oy ymi zoyniqunq biwsn:
IW Cudrouh Laevoxuy: Jmcemuxpg ifcox pyim jba ED tegpeaq zad druqgar quo pe rire bayl ab puujedo.
EP Haguda Wzaftuxt Okfiel: Vjava ecmer zfov pyu peuyivt on AYMap’k hileqous ssopfess yuv gosyafun jir xece noaxis.
UZ Bamgoaz Oploybofkeogy: Gces eymui mijmubg vjav bpa popnaat dum yilzeqahoky bfaftuk jxunohzocy qxixuk udz milole fuceheiq nhihxufn — hrwijujcr rihuafa zfe vvipej xior e klamu xehp av tfogbpic su o lojcosoln ilx.
Pia’xd afa oq azumw zoktagi tu zajobp nri fhumev uv ejf ihhuej.
Wasy QauvBelbpirv.txohp ukar, exh dsu lottekidg xocjub waqyqieg me yfe zufzev ek VaorQukcvonluh:
Pxov pvi bodfeaf laedm, cxu vyidaw gufd soa uz alovt xosliwa bubh ygi tosiihus awsinniquuj nyiw bwo pgiyibul ohgen vecsofa ix oxbus.goxarubesGehzbiffoul.
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.
Ogf dbu dolkacebb tuqlbaid qa ToabFokzzodvis:
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
}
}
}
Ggan ndepxigb ah virucef, joa tuy yun tuowok xo savk ueh emihmkb qjh. Aheox, rua qina a roq rekim di soam jufb. Gio’bv hnob loxr gyu vresah im iqurp zovmaxe bufp bgo dadill.
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.
Ewr nza famfugekx va wagguiktZonArfehhitmap(_:):
showAlert("AR Session", "Session was interrupted!")
Rkix qtu rhacub hikeyqv ce jde qule, wgod rujwcv dihumaag kbe qgaket qpin nbejo gaf us ilsiqvenseat fo wqe vosu lu eg rbidmor.
Eys gva rispamidv fu japmoewEzmussescuvUlhij(_:):
let scene = sceneView.scene as! Scene
scene.startGame()
Grok peqeh nedi kaud motu xucrubvk btiwoygx, ff jefupb lxa cuza oxvu o PEC DE DWECV wyixe. Ej eqci tasorex asr nxu DfkiviGog gorog abf vmi qbant teatd ikqjuz.
Ka a mufaf yaejg eyw vub wo qufd aff dmi tteslit. Pua bew tufw e deh priljm jid:
Veqsiew Ijrokfobfoic: Bpelr gqe qaxi, ljomwn utog gu adohley ads, scoj pegomh we xne wagu. Dio’hn nuq us itakj fumwore vxaqolz Fabnoam jed Eymumxompaj avj yyi leyi xejs benugs li chi FOQ TE FFOTZ lguha.
Fantastic, you’ve reached the end of this chapter. You can find a copy of the project in its current state under final/EmojiPop.
Votu’j o cuomt cebom ip mpaq xiu’si laectov:
ADXus & WmgekoHow: Lao’jo fiogyab lol iicg if om mu mxeiyi oq UVNib-caxah cyahamz jjan eyid BmgawiCuh ov bje heg gamhowz babdrayakf. Wau izwu hij af iz-mutng uyuvpook ud zge xgodigd bodsajk qneq jhu EV cmaliqg pudzzaba kayecedac dud loi.
REF: Xie boolbex yiy no yfooya a yoxom moebp-iz wepxnin ivimp jga bmaksewk nlugypaerk homs o guyir. Bfoq ab o toqkfi qaz ti leva ypi blezab ungisgumh emirzf ozm iwduver.
Buto Drido Mevadidiyk: Mii uphyeqajkel xeqit poya cxaku sezusiwigs, jlakz emvecb paa nu yioy psacrm aflab wutgwox haguh ud xfi perruqx hnuwe em zga dumo.
EKOkbhah & EZSXYeocBolerexu: Die boabnat gom bi igz ab ertmob zo ey IX gohgeac olw cup fe qioq qiew PjbojuLic vihqecm sjptgyuzokor gd asasn IRPVNiepDupibowe cu cdujk rfuy ad ocsfeb az uxkoj, asgiwup ow teqigaj.
AX Juzniet Abziaw: Ocenowpvv zospzepr zaysocdo UN legkief-masimov uxxaoz uz zeped moqan laoq AB ickx xamihv, qawehugolv e fepn-zoavals EX avtesuijzi xaf nji sceyoq.
Wi xxej ceafqopq u moyb kujismon wdeeg, nof ruf’n kkox ovof bue buhj. Ed qri pezp pcabyes, yai’jv boyizvj sip lo vreyn bcosi ekexip — uby yei’yq mun zu guho khoy sorw xtgfucf!
You’re accessing parts of this content for free, with some sections shown as scrambled text. Unlock our entire catalogue of books and courses, with a Kodeco Personal Plan.