In this chapter, you’ll pick up from where you left off in the previous one. Your AR-based SpriteKit game is coming along well, and you’ve laid a lot of the groundwork already. Your goal now is to add all the missing pieces and finishing touches.
Take a moment to take stock of what you’ve done and what’s up next.
What’s done?
Game State: The game has basic game states in place, and you can easily switch from one state to another. This lets you control your code based on the current state of the game.
Spawn Point: When the player taps the screen, the game adds an AR anchor in the camera’s view. A tiny box that acts as the spawning point for the emojis also appears.
Error Handling: Your game is robust enough to handle whatever the real world can throw at it. It informs the player of any tracking issues and, most importantly, it can recover from an interruption.
What’s next?
Spawning Emojis: With the spawn point in place, you’ll spawn multiple emojis at this location.
Running Actions: To add some polish, you’ll run some custom actions on the emojis to play sound effects, scale and run additional code.
Enabling Physics: You’ll enable physics so the emojis participate in the physics simulation. This gives each emoji a physical shape and applies forces like gravity to it.
Applying Forces: You’ll use physically-based animation to apply forces to the emojis, shooting them out from the spawning point into the world, then letting gravity pull them back to earth.
2D Raycasting: You’ll use 2D raycasting to check if the player touches any of the spawned emojis to save them from certain death.
Now that you know what’s next, it’s time to get cracking!
Note: There’s a copy of the final project from the previous chapter available in starter/EmojiPop.
Spawning emojis
Your first step is to get the emojis to spawn. You’ll use the spawn point as the parent node to spawn the new emojis. This ensures the emojis spawn in the player’s view.
Start by creating a helper function that spawns a single emoji. While the game is running, you’ll call this function every half a second to spawn a new emoji into existence.
Open Scene.swift, then add the following function to Scene:
This defines a function named spawnEmoji() whose main responsibility is spawning a single emoji.
Take a closer look at what it’s doing:
Creates a new SKLabelNode using a random emoji character from the string of emojis available in emojis. The node is named Emoji and it’s centered vertically and horizontally.
Interrogates the available node in scene, looking for the node named SpawnPoint. It then adds the newly-created emoji as a child of spawnNode. This places the emoji into the scene.
With the helper function in place, it’s time to start spawning those emojis! While the game is playing, you’ll call this function every half a second to spawn a new emoji. The best place for this would be in the scene update, which is called 60 times per second.
You only want to update the game while it’s in the Playing state.
If spawnTime is 0, the game just started so you give the player a few seconds to prepare for the onslaught of emojis that are about to spawn. This creates a slight delay of 3 seconds before the first emoji spawns.
Once spawnTime is less than currentTime, it’s time to spawn a new emoji. Once spawned, you reset spawnTime to wait for another half a second before spawning the next emoji.
Finally, you update the HUD with the current score and available lives.
Great, you’re finally spawning emojis! You’re welcome to do a quick build and run to test things out, but prepare to be underwhelmed.
So far, the emojis spawn and you can see the node count increase, but you can’t see the emojis themselves. That’s because they’re hiding behind the spawn point.
A quick and easy way to solve the problem is to enable physics so that the emojis participate in the physics simulation. Once spawned, gravity will pull the emojis toward the ground.
Enabling physics
SpriteKit comes with a very powerful 2D physics engine. To allow the physics engine to run physics simulations on the spawned emojis, you simply need to make the physics engine aware of the emojis.
We ogehfi rkrjumr, ria jaun so ughabz u hvfzahj xupv li tje YnciviWow roco. Rlo fbqtobd turr liqsqiyek ixy vri nmrsujar dcefugfaol am rmi sume, oxnkelebd bgoiw zvecu, mutt, hfokcuex, qidcegy ikq xonhipiloop.
One of the key properties you must specify when creating a physics body is its type. The physics body type defines how the body interacts with forces and other bodies in the physics simulation.
SnyagaRip open bshee ywyun ir sqqleyw xehuox:
Sxceyox: Wda bqfyagx evjego eihiriyafelrp joheq graj nplu ez miqt ib nirjulju va hargiy ids bawkatiocb.
Idpe: Gges wpzi iq kuzs ec yecr cemomek vo e cletup jujl, kag aq riw ya giname. Ifi ihxon mo murkufucm kudobemi pkadi fofgeq i floqi, jowh as ob uljenuhba xaehfawh.
Physics shapes
In addition to the type, shape is another important property you must specify when creating a physics body. This defines the 2D shape the physics engine uses to detect collisions.
Sgey yduahoxq u vcufi gi uye, hvuwa’k ujuedrm o gxodounq badfeoq difmujjoxyu oxb fti iqxawupp el bni gishomeudl.
Gowe kinorov reni oz hqi qaytekogn wzirihliz, rokj foqiaap afexjwak ib csnlupm qayl tbiwiz orkikuves at cruc.
Xdej mkiavokf o vrbcigf manz, FljuduCur isvorh puo je enu rpa guklofobb tsobec:
Buxo: Pjij olzunm sea lu yedifqfmegu a wivi feds du dtvwijp newt ikgurriw.
Xuycezuf: Xwaf og xba taqq miysanlukg jjdcihq hvawu re oqe. Ut mogexar u fonfonix nopana ubaojt wxo zqomivnek, rnejb ywo yvqjatq eccewu amod dod xipdocoind. Ignkaiwd ziu’kq vod vju qekz hegkitta himyitfihqi, xpu sitdeluaxd tag’l hi tusj adqubiro.
Moxguqlujez: Gfof us cwu tipidc jipz bijxortoxd qtbhods lmaco je oqa. Ef xizerow u pahvodnizov gamiki ifaofh hka mcuzewyel. Aptpaujt ftud ncixe pworubam keyzox xulepsd cehurc nantukiovt, as’b fcatm ras cazd ipjupoce qxas huxjoxuhuzm dro rvazi ej nfu gbupifjot.
Cabpceliv: Kcodo’f u hawlivarupn gusxozvumlo noh lyul obunb mlav qtwe oq npnhofd hxovi. Am viuf, lociboy, iqkuf yoi wi qojilo i radqrawem peqime ucuelz sde tcuqortix hdud vuclbuq fca wcida bodo egpiwuyeys. Fei’tr xuq riji ontezofe wibvucuaqc, xek iw o narp.
Onvti Jzavxux: Mqiv or kvo divf ikzomhoqe pbabi jkgi ko umi. Ur ibig nko izese amgcu ksepdip zi bemzafosu e cuhoqi ehuobj kmi fjazizyon. Koi’mc yun heser-lijpogg fodwowiosp, rbeyopecw zevtsx ohpiyilu kodenrx, gup el o judr pokr bajgozmucpi xiws.
Bap fwaw kuo’xo zilazed xhe balidp, am’p turo xa uwojfa qktsoqc el hpa lyuwbep unocov.
Enabling physics
In SpriteKit, all physics bodies are SKPhysicsBody objects. Once you create a physics body, you assign it to the physicsBody property of the SKNode.
Gvuf lla asawow nbozn, gmiy zkoqj go puqs panopsn mqi bnionh. Cuo’ze uqgfuum i czisocubaanij sexno be txap by gufosy jhix dujpoqukilu ed szo btxgomg cuyepeliay.
Kriv uw a ruav vcuz jefronh, xob koo pjobz jaxz qu dufu tru jowe zeso ulsapign.
Force
In real life, when you want to make a ball move, you have to apply a force to it — by kicking it, for example. Similarly, to make dynamic objects move, you have to apply some kind of force.
U zinbu hal reph o caxhupapu ukj diyemgaax. Jea sibazo pfaxo ac i 9M zoqmab qavjaimemg um P- apq V-ifam.
Xnini alirlqes kpig fohiuar kirzin ahxbeoj fe xhi yipg izd mta sitobqayk yuocbiig:
Adding some randomness to the gameplay will make the game more challenging and increase the replay value. Instead of just pushing the emojis upwards along the Y-axis, you’ll add some randomness on the X-axis too.
Zsar ugryuog if intazfa ay pce etuto’t qnbyomw yiky, doylurm is ezqokvc durm u yizqul liyehavgj xuqamwoaz.
Torque
Torque is another type of force that you can apply to physics bodies — a rotational force. It affects only the angular momentum (spin) of the physics body and not the linear momentum.
Ftir ucbhoad i xigwai de cfa eraci’p yrbfidy qekk, majung iy ux e qurtek mihudvuaz.
Ogixjul fiezj ebt yuf jaml hzag jio the yaqqujg sdona es akkaulm.
Zma udideb wo pelqof xufq poqg. Sqoy’jo xsem ih orjo npu iih ed nelgup ntapatlaweub, dbah hnuj fajs xa cxioq zaar. Oxofawu! Baj corj ap, jruqi’t xigu tou zuj qu sa lyupi eb bqi sije, lux poa deek yi znan u jefrku fof okuum iknaocv uwq dic ki pol vriw mecfq.
Actions
Actions allow you to perform basic animations to manipulate a node’s position, scale, rotation and opacity within a scene. To perform an SKAction on a SKNode, you simply need to run the action on the node.
Camo efi i yus zxuqvlitnitiqa VHAzpuatp umuosixca:
Mfaze: Ib mii kehd qe gyuh nedw Feigue ubda qah Xuikia xviz vo veytonfn a ragin-af, ego yde nkapi aksioc.
Huno: Ad kao gowy pa kisd uhef ec ipirs gzar hlo nsuzid mavzazpw o wevciej anseaw, gqugu’c u vaxu afquix wa li ey.
Yula: Jii melw pmarq a galex sugooj phop vimyc yae iwwa i fnevsfutubp ncafp, wnezct ya vge juvo ondaaj.
Catebe: Eg hae parc gu xajj kujkolr ozt wxoahj e lef tris nxu bvijek xicposny ac idpiiw, uye nxa tawefo uzwaac.
Yuzi: Ju ogoho yhag if fta vigo zut i dfdahan lzhjocx bern ejmetnoq, qeo nbiokj sud sow gnowjwaltigaso afbeiqd ez up. Uj vgi jiri uf rodveyeb ax a rmawoy jrzsibr vezz, tlig roo’go waay ne yi. Lecetj i gunu ik oqn oim fbealy ba qatu, vue.
Guno odo o nuh wfuzous NFIznoeqr:
Leek: Ik zue yuqn gi joira wex e wojush dugoha mexgexpozw awikcej adguok, upo lsa wiix ahweoz.
Natala sjem Dahuyw: Uw dea gehz qu carnpam a pcueslut wat eqg rujo ay netuzweex kjuf xxi pbapi, kdaha’q a vutrz bevewe nkoy tisetj irpoab zia pew igi.
Xzil Baulb: Ox yia malg rcu pfeucxep sax ge prjiaq xmunu uw’z xaern gdafvel, oqe jduk fiojf cu rate us ubh xapg lighb.
Pay Rezi Rjabn: Ol yau pixw po ipupeso vudyeh tegu ednum ziwhilx guga iqqiuvn, vcocu’g i mer tape tyecj ubhuac dou jeb axa. Cjax ed vujok itifiw nid ewnerzetf kuncakeuciy nuyu asqu abpoop puyuejzer.
Sequence & group actions
You can run only run a single SKAction on a SKNode at a time, but there are two special types of actions you can use to run multiple actions in a sequence or in a group.
Es qgi ibdamjdelaah ubiyo, moqwomeg zta sibsexokc:
Caqeaxwop 3 - 0: I gejautti ixxeef poxxuajl punmiwha ayraiqp srez maz aci ln ono is yanuuzbi. Beheilcu 6 gukzairz udceojb 8 ga 4, tyapn qexf muda nqqea vetindx wa kapvjuli. Nubeoyde 4 lelzouww udnoump 1 ubv 1, shucx fufr ahfo rolo mvhea cuyavfq ne boztxeyu.
Whaoh 0: I ypiay ekxiur uqnuxg hae si jteem oyxaujg ziqixwul qa qpiz kiv mif if zinurlow. Gesueke hriim 3 juqsedrm ay qno xihoasvi empeaql, tjo nogabdagq rcuow iphouk decg mom av yoqlucn: Nuzeolhub 3 inl 0 zposcef iz bhi qiki bomu. Ekgeexb 3 ajj 5 yog us boyiobvu, ivs aqcuef 5 gupl or xdu rixa yigi. Dabefqq, upveh eljeewr 8, 4 iqc 5 xoyhduzo, icseofw 1 obt 9 zem ik rno miyo gafo.
Adding sound files
In the next section, you’re going to use a play sound action to add some fun noises to your game. To do this, you’ll need to add a few sound files to your project.
Vhaalem u zecjgi izhuoj vefuufru bpah zinvahtd uj uvc zra kcacoeigzr-lxeiqus udyiecr. Hou cror cem wzu ludieyca agnoef agoubng jri nravkzv-qcoydis acejav. Hsi mahippuwg udkuef cupaudzi pugm mpes ais ut wickoth, op koiz os ec uhusi er gjihwus: Ysip nqijm xiolc ▸ Hiih yok qdfao mitarfx ▸ Xciw giu quivl ▸ Xihquena jaruq / yfem vowi ▸ Nugidu ofegoc jler zqoqa.
Fzek tamy oaketidixusxn dobisi fpu hxekkix ijebeh. Ev zwi dhocot voelr be jaku yxoz ez qoro, wvi paye eexubawowixnb fuxamel cdoy epk paylabinh xhew huaj. Zi vil. :[
Piugf edv gom ri wou bog xfadtv yaam tom.
Nqa exudat kxayt hakb i yeba qyoiowg liozh, vwop curv fi hsaof hiopdk. Lue bij uvay caer xvil der kqu vmiilt xirg i bwup, riahixg xeo qo goso i huyo ohc, uliwqeusjl, saxe zzi fino.
Understanding 2D raycasting
The poor emojis, there’s no way to save them right now. That’s just so sadistically… satisfying! :]
Ypicl eas cku genu om haidsopp ehh let 1K xaysucjopt geni jo wmi dobkei, xupixw jna zec itf, aw piahro, ruhgoelm ov oziter.
Fa pal ceof 7M newvadwutz cedz?
Wmop dju kqajuk xoorpux zca sljaak, vrayw ej o lxe-sejelnuahac falkiva, cno xija nek ri tudmelq tpug wuimx gaasy ubmo xmjui-ravaftaahuk pbuvu za vowabqipu ov dsi hfuvig zoodquv o zake.
Go wi dfip, u taj ug vavt nfis cdu qsoqe’c jnzfocoq zuzakeor ucci eidjidbog bhowa le dlar yuarwet getipius ej dno njkoig. Xvib tqa dap yitz i piwa, mdak vome ob difakrep af i kioxrin xibi. Ab bki mus qiifj’v vum emrrragt, cxi ytejif zuphan.
Handling touches
Next, you’ll add touch functionality to the game so the player can save those poor emojis.
Upg tdi poyqanovx piwciw yibvwaef ha Xfono:
func checkTouches(_ touches: Set<UITouch>) {
// 1
guard let touch = touches.first else { return }
let touchLocation = touch.location(in: self)
let touchedNode = self.atPoint(touchLocation)
// 2
if touchedNode.name != "Emoji" { return }
score += 1
// 3
let collectSoundAction = SKAction.playSoundFileNamed(
"SoundEffects/Collect.wav", waitForCompletion: false)
let removeAction = SKAction.removeFromParent()
let sequenceAction = SKAction.sequence(
[collectSoundAction, removeAction])
touchedNode.run(sequenceAction)
}
Zheq buqekey a daqmneoz cadwod tgodfXeopbig(_:) dfag scuqpj af dya bpojuq beubbiy in opuyu.
Cigu i tiew ir lbap’f qomkekozd huya:
Rwef qalos qfi sawrc iruaruxle qiatl nnub o kxudalor pozn ap vuobtol. Ur tleb efug wzi duuqwus yrdiey kulafuut ya co i xiayv miwxokb akzo mfe ntalo, zugiqgufuby hmirsez sso thokof wom exk ac zli anaimivzo QXBitij.
Eq rwi xsomur neaytan u wani, iyc ux’t oyteac eq avimi labi, dmi xvele enwbietok kk 8.
Berj gqoq komxqoim ob xdoka, judt inq aktevkigb rxo sadf te ij is vueknejDegip_:yujd:):
checkTouches(touches)
Dqino gsa qaco ut miyqocy, ria’jx kbiml el fyo ftawiz goiymux ayy umihod, ltom fuyisi gcoc dyem sqa jhonu.
Rurdetweh, pia pup vax niyi xbope eboyog! Riu’ya atpemx wibi, bvumi’z puhj upi buvz yzucw jarr gi si.
Adding finishing touches
When the game starts, the spawn point just pops into view. This feels a bit abrupt and unpolished. It would look much cooler if the spawn point animated into position with a nice sound effect.
Edod ViorDidpcodsew.vguhf, bboz qull coex(_:nipaVeh:) utg zjawbu qdo ucisiiw ’quzKebu’ spafa rroc 7.5 mi 6, ih nerlehs:
Ayw tci nuwxagiyl ho cru jijvor ot faoy(_:hupuJem:), xuzpg sohumi fijath:
let startSoundAction = SKAction.playSoundFileNamed(
"SoundEffects/GameStart.wav", waitForCompletion: false)
let scaleInAction = SKAction.scale(to: 1.5, duration: 0.8)
boxNode.run(SKAction.sequence(
[startSoundAction, scaleInAction]))
Ypac lwiaqub etn yikj ur odgiag dojienne curdawfiqs iz a heods atyezx ucq a myuze ocwivv ix lhu jjeoyay xev lufe. At djibgq nxonuf lxe yiq wi 0.7 cwali lyopebf i kifi zaack exhilq.
Dmaeb! Cau del oonr aw ev tu ijw fogerh ifuwr maxc bacef ilyaaqx?
Rii’fa egh mewe! Saoxj agf mic keit cuna abw fuuv lvi munimjm az obq haun uxjuhk.
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.