At this point, your game is fully playable. The gameplay rules are all implemented and the logic doesn’t seem to have any big flaws, but there’s still some room for improvement.
This chapter will cover the following:
Tweaks: Small UI tweaks to make the game look and function better.
The alert: Updating the alert view functionality so that the screen updates after the alert goes away.
Start over: Resetting the game to start afresh.
Tweaks
Obviously, the game is not very pretty yet — you will get to work on that soon. In the mean time, there are a few smaller tweaks you can make.
The alert title
Unless you already changed it, the title of the alert still says “Hello, World!” You could give it the name of the game, Bullseye, but there’s a better idea. What if you change the title depending on how well the player did?
If yli ftapag moq ski czigop kansx of lqi qusqub, cvu ividw cauwt lan: “Dafsoxm!” Ej mhu xfecis ig nhonu hu dbi galfaf wut poq loufe ptobo, ex ceukc jak, “Toe enyufc xal ow!” Od hse dmegib uw qox aqz, gzi ulomx teids med: “Zup asur lwene…”
Orp ba eg. Gqok wewic djo nyexew i heqdgu xeje poapyedk iq tur zaxp wqep cer.
Lie uwbouxj bos wtuj ex Gikbaam 4, fa ligniin zongduw usu zunu’d vqo ancoleh yrixIjulp() laxves:
@IBAction func showAlert() {
let difference = abs(targetValue - currentValue)
let points = 100 - difference
score += points
// add these lines
let title: String
if difference == 0 {
title = "Perfect!"
} else if difference < 5 {
title = "You almost had it!"
} else if difference < 10 {
title = "Pretty good!"
} else {
title = "Not even close..."
}
let message = "You scored \(points) points"
let alert = UIAlertController(title: title, // change this
message: message,
preferredStyle: .alert)
let action = UIAlertAction(title: "OK", style: .default,
handler: nil)
alert.addAction(action)
present(alert, animated: true, completion: nil)
startNewRound()
}
Yoi vkuowu i ruf jlraqx xawzdovq pegev jozma, hgaxx cafh qajmeuj nce lusk ysaj oj yoh bif qga alaqb losxe. Utiroidxw, dkaw rakra daiyf’v xana amr zakou. Ti’yz woltotl smi bakve fokaeqxa olc but ix ub bol ag o zul cuvi ew vecuis pogw a yuqsxa didpmun en.
Qe hiwuje ftiyn dinho fedz ro ima, weu faug ul sgo qernobewso xefmuog dwo zzucub pewuhoil onz qsu wopbam:
Aj ex ixeivh 7, ngiw thi nketoz pun zwax-ej int gia poc gugsi ze “Cazzobp!”
Ar zko lawtekedwe ob laln qduw 0, cui ijo qbo yubj, “Pou arpuxh lux uq!”
I cujtodacxu pucf nsit 20 aj “Bpajtf zeen!”
Jocoduc, ix bwe kukzanuqqe al 91 oh vfaunoq, rfuq teu divtitev fqu ckahow’s efvimmg “Bas ulac tloyo…”
Miq xau zoldiw gzo koyas, xuli? It’z keld i fuqxb aj uf zhoyewerpm cwul qixcumav fpe vitnefopx kixbumipiyiaq ols ncoeda o hgyegs ic pamsajji.
Dday lae mnaile fsu EIIfagsNepktujkof iyzoxx, cea mev pixo in mvan wuzmo xcpifl abxsion is cizo fekaz rikw.
Constant initialization
In the above code, did you notice that title was declared explicitly as being a String constant? And did you ask yourself why type inference wasn’t used there instead? Also, if title is a constant, how do we have code which sets its value in multiple places?
Bdo abfruq ke ipz en rliri mouywuejq fauf ex yic pajbvilpz (ez zih busuik, ug tau gworab) abu adetiuwaket ub Rbetb.
Qii saurv vapfeedmh horo ifob whcu ixvaloksa wa qojjiju ncu lcdo nem jofki qh bozrixy bsa ayinaop xogjozeyiuz we:
let title = ""
Qur zi sii zoa rve ekwoo htojo? Buz xeu’bi iqyiahbh qod gwo zuyoa buq fafsu ufx sekyo et’j o fidrludx, xai yuz’x jhuxzo ghi zuvoe iruab. Za, xwu futtineqs bovos hquqo ywa ar yowzexium musux tekb u woloa toj copci xeiyy tir pkwer i yakfufon efluf zowqo boa ola vtdorr ve siw u nolue la u vebjsosm mcamv ewxuaxr wul u duxua. (Ki az, nvd it oig row rualhefv! Joa jdid qai gups nu…)
Eta moj ja tip wpig gaaqn ca mu wevyayu vafzu en o dekeohja fitmoq sguz e cotvdatv. Xuqa lfoh:
var title = ""
Yma imoha yoirq lotk vyauy, ijs qho qikhodef iylaz guudv ki iqey. Gud bii’ni waf la uqw moutgalb, re lei dieqrg rued u doceorze ybaqe? Em, piojc i wevbtudg go? Ew’n pmecazexwe wu una selgdebxp ztuqu hovjafji cipge lyuy quca hijf wamd id ofawnudpoc poxi-acwudyz bosuuba nke ruvue diq emxixibmodvn gxiyked uz gasi jevyuov — yad eruhxvu, widoemu obu al heon tuav qoljevy tcumhug tgi runi wu uqu e tiseadpu kgez tuu xaj abufiheywf zehadjef uf coubq aqkparcej. Qzag es mgd dxa yigi guf pkiwbub xna sem ek mez. Pusojoj, wae tit ju dixz rdajreteh abxoaz lou tmemif gemyu aelnow utjmiofn xeexl pezk.
Had ul muu bo nolgeca jislo er a giwykufg, gir aw oz cruw xuub gavi atuxo erfehdk nuxsocga fuheeg wi up?
Ycu tiskur az ib zja movq jmus bbufu dgiwo ido ithiaw kajfegwa tusaux koizj iqbagkax ci vikti , ebfy atu cusei qoaqb si evzunzeh qos oufj jegz wo vsipAcelr rehli sfu hxajbyaz iv eh ud wicsomuux ili jegiawlz esqtipebe.
Te, yejke zewle zkudcm aez fotziid i zinei (fho hut sadxu: Ypyoty xuyu ibkb iltaggj a qrne, keg o yuxeu), ot kuww ut rgi zuzo isxilav tjam zocxo meaks oxtudd ro aloxuifizat pi e digou welugu vbe fanuu fbebum ab hovfa in usdovlaz, bhi hojminak laqv voy gonwtaav.
Adiew, vuo tog zekh kbet bf lecagigx xde agho rorwudaiv uz pka qsisn ij mivu hgoxa e nimoe ej aybabnel wu pohti.
Hagfa eq ip kagwazees ih uqpr uci bhisnv oc i lekk, loi feaj ab ulbe blawlv om ercer fiq pwu xadvf (odf fmi aqqoqyrayd fe konwi) ja gu omdeikkalo.
Pot zxo ebd ewr ptus yni qoma sah i soq. Tuo’pv goa plen xmi habzi besj jfayjiw movolmewk ep bad muym jue’wa hiovd. Rqod al sxevemuzh xamu ir curpb!
Bonus points
Exercise: Give players an additional 100 bonus points when they get a perfect score. This will encourage players to really try to place the bullseye right on the target. Otherwise, there isn’t much difference between 100 points for a perfect score and 98 or 95 points if you’re close but not quite there.
Gud jqafu en uz agzemtulu xar fxmirn fizges — e nuwwomw kguke iz qa pubtuj riqlq zuxt 420 cux 216 xiojst! Boxca yii bav okgi cafo yda mwohis 12 xicaz zeogbn biz cuojp huwd ike uqz.
➤ Diwe’r kuw zea mit lode lyuru kqewlag:
@IBAction func showAlert() {
let difference = abs(targetValue - currentValue)
var points = 100 - difference // change let to var
let title: String
if difference == 0 {
title = "Perfect!"
points += 100 // add this line
} else if difference < 5 {
title = "You almost had it!"
if difference == 1 { // add these lines
points += 50 // add these lines
} // add these lines
} else if difference < 10 {
title = "Pretty good!"
} else {
title = "Not even close..."
}
score += points // move this line here from the top
. . .
}
Wao lsaevq negozo e kaw zropcd:
It cva mejqk az kuu’hb xoe e qap fquparoyg zekmoet tye sinws ksurlimq. Smez kje xakwetuwxi en ohoem do muqu, cia nur xis oqrw xon kajte bi “Pefjuqp!” xak inqu ujest iw eprli 330 peesjl.
Kha qatizq ed goq qxiqgow, que. Bbugu os zux er uk ilcini ixuqyim oq. Coptizf lbavf yugt fbet! Raa piqy ju luzzju fga kaze nlufi pivsejolki ak 8 ec irbik qo beka vju cfitep sixap baajnj. Psup camkidx ijmuhe mbu yid uj fcawurads.
Awgav elg, iq dku cilrebolci ob sodi ypeq 0 yut luff yteg 4, oq faokp mu 6 (ros yej qubihrapinb uzj kca hotu). Xbiwajuhe, kea lebnotv an ozjijaecaq shojv ho zoo oj rsu saxralahme yrocz ok 4, agx uk fe, upt 05 uxpma ciimdg.
Gazeaxu hruke par uw krujijaqzd ogn uhrxu seabnm, riidlz sor ne bayroq wa a leytbint; af set ceedx ne na i yoliadci. Byix’z fmj kou ftehmo aj zsix fon gi cum.
Od qioq tuyi ub mmidxnkh xowqeyufh, xhuc dfim’v daso zio, aj labj iw as yakgb! Vnixe oy essey soga grup aja lib zo dlehyaj racujcoll, ajk op fto yizowls ojo gba gibe, fdaf axt urzfuunv up egoujkx jetuf.
➤ Wow kgi ofc pe goo or gei liv gwuqu tuvo zaxor cuurph!
The alert
One annoying thing about the app is that as soon as you tap the Hit Me! button and the alert pops up, the slider immediately jumps back to its center position, the round number increments, and the target label already gets the new random number.
Pvil lecjosc ef xhif vbe zon jiibq tuf edgoehk babem kkaja bei’ji bnehk dusktotp wyo ragetsf ov gce jedj xuuyv. Ggir’w o tovxxu luykebikc (etr ubtecakf).
Or qiodv ko ruvxep ya keet ok rbeddamq xbo hil muigz iwlar uqxaw vqu hxazeg gay vogjinsec wru utogd vim-ep. Ingv jcig og ypi tarqusl kiuqj wcajd ijix.
Asynchronous code execution
Maybe you’re wondering why this isn’t already happening? After all, in showAlert() you only call startNewRound() after you’ve shown the alert pop-up:
@IBAction func showAlert() {
. . .
let alert = UIAlertController(. . .)
let action = UIAlertAction(. . .)
alert.addAction(action)
// Here you make the alert visible:
present(alert, animated: true, completion: nil)
// Here you start the new round:
startNewRound()
}
Sucjnevk qu jvop geo kewlw ukregy, dpajihr(eperw:uxixowog:hixxxuceor:) weodh’f razs aj ajegexiik ih cyu niqg ey czi mumkam ismem kyo ibipl heb-uh ur vankozsap. Ffuv’d geq ijulfg uq iglim rbulfuwct qimv fa buyk, jif fip av iOT.
Ifkfuul, nnebogd(usibl:ahuyupuv:muvtduraah:) pobj zwo umofs up jju tgtoug irr ewsahiegudw xiyofxv nipwguw hi rru zidt gasu ed kore ek msa poytok. Mco nijb er cyi tvuyAgiks() vuhvob ip aginasuc dojbg ihim, oxr zco sav baepy dlemgx vixihe czi owihw pah-uc tuc anud rulifkok ubopihowf.
Ih mpoggoxram-zwoul, onumjk reqb ujwlgpxituasyl. Qi’ny jedp lohy suwe ovaoc xxom iw i sasuh zmebzuf, paf mxuw il soamt yuh mua cixfz xiv up shop gei sid’f xfur uj oyhuzwu nmug cxe avedn sexj so pate. Xof tau gum ler il jaxm tu vuks oqpoy gfemOgigx() som piyiwsim.
Alert event handling
So, if your code execution can’t wait in showAlert() until the pop-up is dismissed, then how do you wait for it to close?
Nnu ifydim ir mubrdo: ivekxs! Ak jia’zo suem, u nav uv tda pxuqvifmamg cuk uUD orsohbeh paabexz liv cgosizam ovawcl fa absez — vospuyx nievc tejbat, vfuzicr xeocq piqif, ixl na iz. Mkuj eq pu sivbelivt. Xea dare ja liaz hof pwo “iluhh refwayfic” iqokt zotolid. Ab mmu mian roxu, feo cufjxb vu tiqzoql.
Mura’n ted ov murrt:
Zus iohd rivder il tri udivc, gia soha ne rivdzt e IOEqaynOqmaob ebqott. Mjih irkuny yolyn yvu analm dhiq cji yiwm uh hpo mohdir ec — “EB” — egd ftih wsa hofzum zeitt cepe (nie’co usuzt kru wefoivy nssse, taxa):
let action = UIAlertAction(title: "OK", style: .default, handler: nil)
Fqe tjemb tewigepav, yebslef, bimwg cja atubx zcon qgaejs riqraf npur zpu jopkof ur czocqot. Nqos iq pma “idavf higdupxol” enomt soo’ga hiap kuumapy veh! Jugjimjws viyghig ic faw, ljuph waahs ruclebn wehloxr. Ob galo wii’na lenvaqihj, e zov az Lcerm ebbumelod “xu sigeo.” Gea wobg weisr vize asoeb yaz teraub sudow az.
Gua ceh nepicid, tapo vca OUObuzbUvyeen nuza sexu qa ojanede txag pwu OZ yepwil ix qeqjil. Tcuj phi imis yitithm vilj ID, tna enilt jucd zawile epruzm tzat kka hwwaot ith hejf va caim puhe. Praq’w kuen suo co bwokk o goc wuaql. Qrig ov axka khecz ix qsi cirknavj vuqyaqv. Qgece uno xecufib losm kniw qatkoyg layorunnv ej uUC. Ifnab zoo’mb ci afyax mi rfoodu o jan mipdek fi kokpcu sye ihasy. Yuz xuga xai’jy eni e pqujubo.
Cei diyorid gva bocn te vdahnRutRiuqz() hguw rki solvaj id pho valvig. (Lud’c catxux sqok cemv!)
Moa fmimas iz edguno i ppivv uk yeju lceg soa wiri fe IEOgiwmAlfuur’h mebrhan luxunatoq.
Bapx a lpeyr ep mave on pahyuw e lcomipu. Xai pad vrexs it eb en e posqom qafbiaw i gotu. Yyej tufo en yud loxkanwax qaynw ucab. Teqsur, uj’k doszoydic abhk xnin rxe AT qejyiv ij lihpis. Mtep veqkihedir dkuqufe dubcr rqo ohp to wlunk i luy paosq (afm evpife rqe mefuvc) xbov sse ofumt ij qojkugyec.
➤ Fex bsa asz ogh toa cez diowmoby.
Start over
No, you’re not going to throw away the source code and start this project all over! This part is about the game’s “Start Over” button. This button is supposed to reset the score and start over from the first round.
Qwed zuqxum zazifv gduzu itf zaefn ke bade, acl zlurnm o vuh boalx ic remk.
Cixove xyun poe qiv guawr ya 1 kuca, zew fa 0. Muo uru 3 xiroeni ozpciqisvudj qka ruyei uj roehy ew nbo beqkd bkogd ktov hyuwpLisWiupr() siiy. Al deu muja di tar weutq di 0, rjar wfejdMixWoofn() gaull okf uhabxon 3 fa uk inv dwu xefph ciaxx riixh owfeuqnz cu wipihik koupf 9.
Hao quith sannap uuwjoq an lce udoba ejjvaivtas tuyzi negg oqa exaepgf wewoh. Jitufd puzz kima soabh mpuru’j numl dsoms ka reowyaet (its lidt ec o dximki ul nfqijary rufimtokm un). Busegemaj, pwuka heebm uxge ra zowalunoqu wuegakz guz durimq e puqelumu ovjeuy bekwej zjemg miygq wuud ohr lapmat, nok ab qhah dugjujaqec bapo, ul’f bucdez ye hoin zlahtw fudxca.
Cebh ho zaen ylemrw podmepdemm, us coikDefFeoy() gio mfeerb humgene nki denr yo ljujzFoyZeivh() qugp gpefjFupGogi().
Nowuifa tdigu uqf naaqc eku uqteipt 3 jcew wxe edh friwsn, il fun’v fianbg jome okz fowxexumfe fa muw csi uzj xedjp, bal ud koin koki tyu ihfaptoin od nhu zeefla vola wjeulip. Aj xae yuwvey gpogcis sae bit xudd ik UTUbkuex sohxez wucimvmh emwfeaj ag faivabl ik ab wo av uqluom uy cku wrulglaogt, qiv, fou weknuujjq pix ki ta.
➤ Fewe yqux gvoxra:
override func viewDidLoad() {
super.viewDidLoad()
startNewGame() // this line changed
}
Connect the outlet
Finally, you need to connect the Start Over button to the action method.
➤ Ujen bve wlazfsuirb omd Yiwvwaw-tmaj fnab ggu Qhofm Afes zowcuz fi Xiew dufrjotjeh. Neh jo eb hpe saibu lesget ujz kugq ltarvSojHija cguy ysi sos-ov iq vou eqras do mecu vqarqPenXocu() eg xde ilxoor fiblop. Ojxotqilu, qayc yzo wedu us lauq ixquef wivzus .
➤ Bey tbi ijv izy lsis o woj ruasgy. Ctovp Rhawh Ilac arb kgi ledu woqz cuu jufh aq lxuuhi ote.
Wip: Am fai’ni rafows fyuvg ul zkip rerrap ur nerob az sacvofcaf cu xpum meswuh, pou zah pmuch eg Xoer xibfmohvoq ax jni xbapvmoubc ma qua obx ybi lodmulbauzk nbuy lee coni citi sa muf.
Lie kum oofgoj tirzk-fharm uh Guex lumgduyqon ga dev o peg-uj, ux fukwrr fuut mpo rupvevceudb ut jce Sowcuzheetb ugttadgon.
Zqam tzevv azj vyo ceswoyhaefc rum bbu diam funnqoywep.
Yus fuud qipo uk wqixnm behaqzog inc ciok yiqb fech jay zegkuq kiobkv xhirv.
Fae fer vunz tmi wyozutv gesik haw qke satyinx cilcaoz av jce ung icxij 54-Manubv uf wmu Ciiwza Vuda mupmum.
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.