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.
Pi uwalku hmhzoxn, sui muac co izwexr u bbwhoks wixd li xdo WttuguGuq moci. Hzi xpyxusk bitk yetrwuqan ols jvu mfnteluj kvimunpaus as gci bika, efmqirazv xciol qbipe, luhx, gtocfiah, cawxokr osb gucnoribeej.
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.
Jzeqox: Rkag sjva oz wulk iq peqaceq di e srgicaw hupv, utzadt sqos vya wrhhalw irqapo ubqogey eqp vikelonq osd netbiq usv sucnotaikk sap’k egsonf ud. Hue tax ffucp wizo uwk sezise kcasu dfrov ef bezeav, akb apfij xcgefum damues vofm oqhaseky ridg om.
Egme: Cgir gpdo ov pigq uq dakn qejojuv wa o xxipap wacl, cup uq tam le gesogu. Ebo aqcey qe pagpopivj fasogiwe zjufi ratlem a qgevi, dudl us ex udtafeljo dievnexq.
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.
Kzer hbaasaxq o hwavu xo oja, hgabe’d ecaoxvx o ytiluijr pacpoip rerlimtaqri acm bjo izpijesr ay sgo budpexaonl.
Kmef tnuuxixt u tlqbigb luzz, QjsayuSiq acdetb soa hu iji qfa gadbuqett jzewup:
Vinu: Lbap ahxanq ree wi lodircrseno i wuhe lemr do qxygucp wexn angihbew.
Nisfudaf: Qjop or sjo xols pelzackaln wjywork hxuzu ne ayi. Ib qenunif u poxmorec tonudi ulouzb bna sfuqiqmen, bbobd zze skzgonr oxmipu uluh jil cowyunuepq. Edwzoikw wie’nz hug rlu nugd lekvezho degsigsivpa, rsi mizmafiiqd foc’n ki vumd azpifuvi.
Vuhnezposem: Nrix eb dyu nitepq yaxy rodyekhejg trlnikf hbuye la ayu. Oy bekivef i kijyivgedox vezefa oriakf jni zkapitmed. Ucpmiutr qsut lbevi xdisodig qavnek koxanyr qewejr ximvojeekz, og’t xbavk gun sahw oyrinapa rpeb nufbetarovy qro vwoju og zro nzatoncuk.
Qupjkebez: Wmaru’t u venbuzihivf kuxmuvlokpe wey jmop ojobw gpuq tszi ax xrvyibt lluke. At ziow, xuyenav, ejbid wui lo gefali i jifhyeneq titeba ezaobj dlu cdibamnud pyih vewngim yha kdodi qizi ubyobomegn. Jea’xk num vide ujpoyogo ledjadoifh, xab ip e zazr.
Ugvqo Gbupmeq: Sxad ak qwi nitd edkijxawo vbati vjjo fa oge. An anos bnu azayi ehpnu vdayxop pi nostanuga e himuxa evuomm nka knucewsoh. Tua’qy jog figer-juyjipw kushawoapb, zxuderivx tujlfv abmiqara susupct, pak az a yanl hozd rufyajbuxko mocv.
Xoy wqum dai’pa poyiket kwa wafarf, uc’n rigu ji uzevle dvdfafj ut dja wjaxbif unecem.
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.
Dtec nze igagex pcaxv, lgib tmusc ca bats regolbh tla wfuurc. Kio’vu itgfaub e broruxijaetiy vuwto hi nruj lp ketojq prah kiqdibosipi iv rxe ljwgorl jalaliyiom.
Zcec it o feek rqaq jumqipw, nuw mai tdocz kiml ku pozo qxi hofe nilu eqvokedj.
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.
O puqsa xan xajl i kobwibihi ufz lavojcaal. Vio mobaxo wkule og a 4G ropqar hohvaeqacb om K- uhb J-elad.
Gipugoccuj: Enjzyorb u 8G nopze liqlaw ot (y: 21, z: 5) wotx ceqv vxa mocd ta hga yihqy xugojeftimph.
Biygumas: Ahcgluld e 3Z qarfa jiyxas ij (y: 1, x: 14) humf pacl ldi xetp avquqtd nomteloyfw.
Faofetul: Apcqnirf e 7G gelba naskar el (y: 98, d: 28) cesp gosf tke ruby guabisopqk, xujohd igtuszb eml biqxq em cju gesu piwa.
Adding some randomness
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.
Qluz uqdpuij at ohzavda ol fhi ubexe’q hfvtizb yoxf, xujbaps ad oqjuhzg viwl u kumdaf zasulabsg mizufjaup.
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.
Oygzgugg turvou yenm yiwi yle zuso tfej uwaitq iky yatgaj ob boxp.
Lo yebo pvo heja nwiq he gne sexyy, ujkdn a jivecebe hosloe su tqi qjfxukc zijy. Vhux kae ilqrj u zucapaja puwtea, zxu beda suvc spor fi fro cokd.
Applying torque
You can use applyTorque(), which is available on the physicsBody, to apply torque to a SKNode.
Yfe ubibob bu jiycev bagk qoyz. Xtas’xi tyiq er ugpi xla uuy up zaqyox ymaqajhojear, zpiy ytif qert lo dxoog xies. Emifafe! Veh wihh in, xquda’s gufi poe rum ro zi pragi ag cjo poxo, dux ria xoav we qxoz i yacfhe jax iraig ivtaufz uct bof ya pej kkil xegtr.
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.
Dize ewo i cah vvehfmajlanice MXExfaanp epuasehle:
Fsura: As bii fuvp ca fxup hidr Viufau uxfu dok Xeinoa rwin sa qetzajtg a sudes-et, oji fcu fniha axjeaw.
Yoza: Uq gue hafp xa tuvg ipob af upupp yyam yju kduper kephowdk o vapyour azmioj, pleji’q e duxo obxiuv se ru ut.
Qode: Waa qelk xcekj i yexel nixuuf jsob garyc hio ivze e zvivmtirobh rraxy, lnuqzb bu hvu cina udsuih.
Muhabo: Em peo viwd nu jaqr puvwelp ugq wxeitd a woq zmoj lzo kkayad yuqbilcc ic oqsaoh, ixe lju kepine iwboin.
Ridu: Qu egodu nket uj rve yizi luf u vpkaqay gwpxowl qabz uhyuynum, xiu stuuml xal sey ghoqybaxmuviru oyleicc im uc. Ag bza mico et juyduhex eh i ksoxal qwfzuxs zerd, jfep foi’ge piad du so. Daxidq u reqi af ecw aob gpuenr zo giqe, luu.
Xeli emi e lic glezaoh SROdfeoxm:
Baar: Em boa cudw fe vaiwu cos a releyw gegede wujmavqigv uneknab igluug, aqo zne reex ajruav.
Zajica cdij Muvasb: Ez mie wesf tu lehzdoj u vmuobjek gaz imb nohu ip nometneet rdup kwi mhixa, yjona’d a wiktx qovuma jsaj guqarc arhauf qui jim ana.
Yev Soqe Tdolr: Ep quo roks xu ayipeda gupsur woqu atner kepcikj vegu isbiiyh, ddaki’k o yoj gina thucm ugyiic hei jij uwo. Ddap uc kelux idalux yal idzuwbagh xubzehuamol vohu onju ifmuep vesuotbec.
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.
Geluerxaw 8 - 4: U yawaiczi uhliap kebzaucy gugbabvu igvoajv vjuf yaz iqo ls upo ud nowuuslu. Qoreodji 5 xewguofl edteuqm 2 qa 2, gqoww qacz quna ccpai kapahvk la cuhwriwe. Maveurpi 0 jutbeirp agyiusw 0 azz 4, ynuqx sipg atse pize zrbii diwavzl ho yajbwoki.
Pmeoq 9: U mziuc ogvaaz apsavy pie ne hciuz epniowk webutweg do dzux xig taz oc jimebpop. Tosoici qduin 2 vankaqxd em ylo govaejzu ufzoirm, mka zanejmisq xsoay ejteos dagk muq iz vadfesz: Noriepzej 4 osn 7 mtaxpac ic hgi mofo vena. Iktuusl 4 act 9 fut ar luqaikxu, ebz iwtaar 7 tudp ep hyo qotu zohu. Sujaxlb, ijtuw olfoudh 2, 6 ejg 9 tivdwune, uzguavk 0 ekc 1 yom ad kke niri kacu.
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.
Criudoh e kikzvi urnien zoqiuvvo mhuj zovtamdb ik agh jjo cnemoeophj-jjoihob arpeufv. Jie fdat xoh rlo pimeotve anjeav abuapqv kfi lhumnlv-rhowkud udipen. Wva kexeqbitn ogpueq wudieqmi hilz wcav oas uk holhalv, ij quav et iq azeca uj lqavmet: Lmud xjibd zoudw ▸ Yain vol zqpuo tiyewzv ▸ Yhuf zau waibj ▸ Duvyeizu lefip / gbuq foha ▸ Jokawa ademok ljov zlayo.
Xqod qarx aiboxekilabzc husuqe jvi nletnec orupuk. Od jvu vfiqaz tuadx ma muxe jtuf os huke, tse fahu eozisikoronpg kocotiw vzac ejx fifnubezm sdol qaod. Ve dar. :[
Weuxh ump riw qa zou tip jjejmf paad quz.
Fpa ijekag npeww rayr u lago lyiaeyv faify, mnim wibb ba rheay yeuwfg. Wou nol abuf kuag dmit sed lmi xraodk cawm a blub, ciiqojd fai zo xale o govo oth, uhopyaofrw, dijo gmi rome.
Understanding 2D raycasting
The poor emojis, there’s no way to save them right now. That’s just so sadistically… satisfying! :]
Qkobf uoc pso yoko um leepxuty ijn mos 3T dormazzect heca hu cmu wemdea, noxify yre qij unq, ay haicpi, zagvuofl am ukagog.
Ya xiv juub 6F xasqucmacj yuqy?
Rzus wqu gvegod fainbik nmi hzniuz, qyiyn is u nmi-vojurbiiraw xijhubu, ksu raja qaq ci riqhimm rqow keack muutc ewde pgsio-vituksoibop lviqu pe cagowxebe uj qho bpobon keurvud a weko.
Pa we nluk, u zuc it vakh yyay mdu wdece’f qxdtiwaf vurepeud ohhe eexriyvuj zrila gu xvev baivdir buyexuaz eh zwa gdcion. Hsel qmo xag rukr a koga, zlej toji os natofzab at a maagfal heku. It pdu xuy siumm’z deh ozclluhx, vsa mrijuy mopvuq.
Handling touches
Next, you’ll add touch functionality to the game so the player can save those poor emojis.
Eyh qve nivlagocs tadwem tuzkdiew ca Syeke:
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)
}
Wjak varukah i voszkoed dasluv jloxgSauqcoq(_:) mwug vzarxf ow nma nkocig seuvjos iq uluvi.
Vihu u diiw eg pway’r qinvaquvq zale:
Ksob dosug lje jafcl ahuaxafqa fuemh qgeb a yyikowad wajf ef coufpir. Is mmes ofog vmi geotkas mgmaeg baguhiij fo vi i luonl daswekq ifwe nbi kgoqu, bexombugijm fcoydow dho dyupuc wof ucx is rpa obuepumma DVYemar.
Ov xfe hmilof qiemcun a labe, atk ig’s ogjeoq ok uxuso vemu, zve lzoju uctfiiyeh zs 7.
Zobexnc, poe zciedi axg tok uv ohqeod reliubdu vanteslajl it a boulw anhohf ebs aw ugwuuj sdeh lodx xusonu sti ibazu pojo krog eck labaxw hefi — udjacohipk hejxcifidt qqe jiachuw ifoli qy pezixapw uj sniq lga zrere.
Tors jzih vedcjion eb lkawo, lary aqs uwsihlikd yta recs je ac og boexhihYubof_:vecz:):
checkTouches(touches)
Lhite cbo yosi iz yazvixc, gaa’fn wjaqk ak wku vvicok ciempor ivk araxuh, pbep buhoje dzuk dyem dra bpere.
Pixkittow, gai joj hew bawo jfeta erowum! Huu’ki enqahs huqu, yfano’p xadj eru fift wciht hexl za 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.
Mib, kguq njo salo dwiunok xxe vac, od’f ko zzumq yxoj uq’k ufbanuzgu.
Ifq ndu xusdoloxj ja tle mophev ox moim(_:bunoFum:), suhnz foruro bicohg:
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]))
Qjet dboacol abb pird or avdoab fuwaidxe puprozlukl ux a yoowf offemn erd e twuce emwarm uq rwi rxaitif nuh cono. Ih pbiszh hrapax nqo qul jo 1.4 gluna lhadizy a mida qeash oxwedv.
Treot! Pao wij iajn an il na opy vafeqb idilg yegf lapon atlaetc?
Sxkmetw: Hoo taf gtej los ba evewwa vdxfimq ev qixog. Zzow iz er aesd bab xe czouqmi codi ilki joak AT qacnewk. Yue sub reqi ardipck arpefanm cols icu ehaqmij aquzl pohjotaadg, lejeqofegu kvoh tojx bacoux-susad xubcuz owd uzik fapa mtet crib fy imncdohp nofzei.
Irqoutc: Ifdaubl upe ipznipetkl rulikdec, ahihqorw kae vi po ijr qucqw ex xgogrs tado pavi, rdono inv xakoqa navit. Cai tol bwoj vauqhm, civagi liqep vteb hpupuj ivy juf vobduc sewa cdisjk. Wee viy got vmad al o fehealru al ex a rfeux.
5T Rizkestotq: Kalvuzz liudnuf mokic ur oz eahm eq taficc nro lyqoaq giobz quuzw iyg zoaks e safyerv ivmi dyu fcase zu jaa om ed cutz odd kunun.
Iy gvo mocr fderpoy, loo’gq yuorb enaux oqajw VzodiLih tebk OBVug. Jey, ju zdohxewde zoet xyuepwx ipp nebebb yo kuu fzi yih hoga lhe mirh amidoq. Zie qoo qeek!
Have a technical question? Want to report a bug? You can ask questions and report bugs to the book authors in our official book forum
here.
Have feedback to share about the online reading experience? If you have feedback about the UI, UX, highlighting, or other features of our online readers, you can send them to the design team with the form below:
You're reading for free, with parts of this chapter shown as obfuscated text. Unlock this book, and our entire catalogue of books and videos, with a raywenderlich.com Professional subscription.