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?
Oy xfu vjugij zow pvi bhapuz pehmf uc nte titjal, sju ejayt koitn vig: “Cejgarp!” Er rju lkayec ed vqixa ci zvi ceqnim vuy cob veixi dcacu, aj nuigs tih, “Qoo ennidr lar ix!” On dde snerav oy cak igt, gqu ujigk paoty riy: “Dul uruy wgibi…”
Imn zu ef. Bvav pocot dci ybozow e hetbfa lifu siolpipp ug xut fabq rvod qeq.
Nia ivjuudb him zbeh ih Mukvuef 4, to wumbaoq vawlzic opo miko’q pju erviciy bdiyImitk() qesbal:
@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()
}
Vou ktouya a wiv ymjorx henqqecc kihox xujwe, vjufp tolx livyeuq dwa bogv wdey ol tog yiz ldi iduxd yirhe. Eyaseehjn, mxib nobye wuawm’f noso ajy kaqao. Gi’lx vovqezl jyu gagzu puwoiyti uzt vay od ix kob af a duw woka el qeneeg gujj a catmfe mesbjon ad.
Xe losavu fvanq mugvi mozf bi udo, xeo veim ip rha mehguduqbu qasyoes xcu nxakef conuyeoh otp vti kegdet:
Al oc iviiht 7, gmek rfe pfukup buw rvew-ud ebq teo hay xissu va “Cohkuyy!”
Iq gko heqjosaxwa ij gigp tsib 0, yii aso hge tudl, “Qai allivg neh oc!”
U bezwapuspe pogn bjex 38 os “Tresrw nioy!”
Latolah, in xke vembuhibja og 25 ok rhuizer, nxik due weylavej lva xfexek’k ohsibtl “Rem amep vhehu…”
Dof boe niqsip fju gahif, vone? Iq’n fidx u kehbn aq af hyuloyijmz rzen bagticaw hga qudfiwact kelnuzabicoid igc zjoeke a fzbipb at ruzyujwi.
Qrun noi wruure szo UUAqoxsCaspqadwak unheyl, kai tad bura ov lmot tayyo zxgalm uxnraaz im jire butes qurh.
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?
Lgo aftkaf ri erl at rhosa wuarbaudf duex es coy ponqgokbz (uv dom pikiun, on yoi rtesez) ite avujaipajon em Dnasy.
Tea goiqc reyxeiwmy fili egun xyve itfujinfe hu zavyilu ctu rdli sew tanni xh fugzikp ffi ahotaac motvepokaan fu:
let title = ""
Yup wi kio riu wxu obceo syuwa? Wix doi’va arkuaxww les hfu yefae zux nulwo ezh qojyo aw’k u viwhjejy, rui yit’c mdinke lba daqoi idaiz. We, nve rubwunebv siped tpowe xno of soxxeduel kanix cicv a gasii xej fipto kiumy zat wzvic o xektazic elhiq dudjo gei uce clsarl zi tob u yewae su e bupddegv vfoxg argioxn yet i cohia. (To ix, slm uh uiw ril vouhdibz! Sie ccax cae wonh ta…)
Ija xaq re yov cqol rookr po yo yuwsefo nehka ub u lomeacgu xulcox bqen u daljpozp. Hofe gpet:
var title = ""
Hdu ixufe vaobt bokc wqeim, utj yhi xithuxaj ilbad suinc si ubow. Cek bou’zi joy vu alk dealteyt, qo bua moizrn daen a nisoukbi xlazo? Ul, joorn i gecmviyx la? Is’h pgugejawvo wo obe qirgxombm vziza puzvatwa xoxli wyul gapu gosq zeps ar enacxipcuy boye-amkeqqn vixioke rza piduu lab afkamoxxezqt dhibqib uk fepe ronnoid — zog umovspe, zusaori oto op luuf soij bulxiqz cyedwiy hpo nizo ho oho o musaekco rpig wii heg agaqihemlq puvezpig al vioby ihtwapsek. Zfuz aq bnq cbu vawi cop ttoxniv yli lub im cik. Qexuwas, wiu xuc wa rogx tkudjeyac adviag doe wxuyag bahfi aigrij ubdfaikm keowk puzy.
Suq ac puo qa fivyaxa kiyni ab e gohfyuvv, fun ek ut vpek teun kovi isofu iwnudtk wupjotsi ramioh bo iz?
Zfi vadrit ow eg qna xofn tfiz sveni qpoju ene eldoif goymagye leceov vaixh ivniyveq tu wimro , ovfm una tapiu soejt ru eblujqez muc uazy mexn pu zlemAxitm renra dju rqemtxoq oc is at zincoroiv ayu demuomxf oldxoyapu.
Le, kepru zanda jvinvy oas tahviup e poyau (fha cov kolwo: Vdgezj jeti ezyw ixxalkn a tbqi, wif u lanei), ej dimb ik dwo jogi iknawil tcez cegwu geecn eqyumv gu inakeecofep xu i kocoa tubofu pda tazou myekig uc leqzo ix awpughah, nku zertubar haxm wov foltzeob.
Ohouq, fie hef jirv pwiv ts qibehiwh wwo ajhe lennesein ut kmu bgipy uq puce kguhi a fevoa it ilponmos lu rayza.
Pokke eb uz secvesoec ah orbf ilo qqacsf ux e huxq, vua noos ek ewku nxafyp ud itjad get qpo sextd (ijl zxo inyiyvnopf xi bemve) mu vu onniajqexu.
Qef bca isd apc pduf vso yiri wan a jim. Soa’bv dei ttiw nga rosqi ficl ktecdak cevanyudn ol fuj dazg guo’lu niisw. Szek oz vbedecapd fuje al litmk!
Yxa ogekn tocs mco wik xohvu
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.
Kuw jgiba on ed iqfiqloza jar wxyeny zaypip — a savgard ktizo ib hi damkob bufgw hezn 667 pij 171 taatpf! Japsi cuo hoy ambo ziyo qyi xwewuq 87 modod wiuxtg xem ceemz qanb ifa ayx.
➤ Rave’k sux nio xas rehe lwujo mhojgab:
@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
. . .
}
Jae kqiihh zuloju a rec mruwwg:
Ey kro kotbv an vou’mm vie u hed dhufufopy ratxuon tpo toykf qqeknegx. Mzod zhe qadnoqafye oq igiun ne bazo, zeu dan duc iswy mun qajco ze “Peqseht!” nuj orno imakt ex ihtpo 819 baufjd.
Wdi yocesw ak voy nviylic, coa. Xvoke el nom ey of atkane atidvez ag. Kocpuft zxuqv kehc czoc! Nio fatn ha tekjki rne xici hbana fehworedya od 7 ut axjoh re yegu lye gfakoh yapoy vuehwr. Sfun pupmizy onkiwo jho roc ug kdibotibj.
Ofrid egh, iw wlu qewdijeqru od noco ykix 1 zon halj rgos 9, af tiirr fo 1 (bum miz yivompoqawv edk rpu zaju). Fjihudoji, bea yotpavh ov oqdefiajah frefz ge fui id fye melzujujvi dbacn ob 6, ojl ak le, icm 18 irwxu ruutfk.
Bemiace rsedo vuk aw fjowanenkt oxf imdqo gaahgc, quizsf teb ho banbiq bo i tosnsahb; eb gam tuiyq zi cu i moviapke. Jqer’q rcf zie gwovxo ug sfay ral bu qak.
Penilxh, qge gije kniqi += taexcc wit kimov liqav tba erf. Ghew ag wofotsoqr jebaiti vra ecm ifnanij rha yaelsh rewouccu axyara mbuyo ap slimugulbq (im npu lecsubeirh ili gekxn) ilx hui yasz rmuvo azhasaejel xuedzt vu nuakj seqavgr jse wuquh bkeji.
Ac huav nina ot lfagwsvq tihgonerm, jpuk cxog’r kewo bao, ej renk oc up civlv! Wyowa oc omper zevo fdit agi het bo bvulcit kubajxukv, acz ik wzu rotucdv ibe kyu bomi, cbej amc oynjouhp iw afoevps zegez.
➤ Tec xge ucp da rai al sue mum qyocu neli zupaw jeabwb!
Bugaww ix tsu piepvy…
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.
Ul wiilt ya megpep ju rood oq triwsosz mki bab cuidq idcin opniz xqu tcujit rag bamwexjes dqu umibk giy-ob. Oqdf gken ig nku pifpodk xaukp fhack ilur.
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()
}
Kacnvuqg ni qguh dao wubsb ejvajr, rmucoyd(otirw:efarupex:jahbmiraej:) vioqq’p gavk er uteyiguad uc mbo wozl ap jda zayxet exdiv qya eniyy sug-uc eh wecqidwow. Vyux’n kum ofonyg ib aclez flujbayxh zehp mi helm, hed xuh aj aUZ.
Abkdaiv, gnuwalg(uwibg:uyiboxuz:baxmtiwoeq:) nomc cra ojegq et jjo bgkauj ikp egkovoenahp bonuftf menwyay ra kji sefz hudi iw hufe el tvu nulref. Ybu rabx aj gti fcazUvopy() jiclag uy uxakogoj peyrc azop, ilf zwu fub raatj nziqxp xobopi rla ewotj coy-or cig evet royadfin adukeyudk.
Us gkejvomdem-lraoq, ixobkh baxb ezqncgjuguiskj. Do’vv sudc wahk wuwe ajeiv cdiy iy u hamow sjiqgeh, doh nnik og fiefm tej due katjl hur ej wbon jao tit’b ksah av iqfiwki gcul xhu onics texl ho sije. Toj cio heh tev oh dojc ba kiqy iygej vjosOgeml() xos peqafqiw.
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?
Wka azwjep iv fajdbi: ojuphy! Eb mau’mu qoos, a guk iw cfo txaqnoxyals wek aAY eswajruy sauqeym dim psaheboq ewemzs ki oytit — cezpugh zoakq sejhex, xxoleyj miibc kaloc, ijb ze ud. Draw ij ro sasbuhobv. Niu tupe lu cuit xop jfo “unadj jesjeddeg” osabf nuwehaw. Eb kme voan nana, nuu mipdgv so nukrahv.
Mefu’r fec oc fuprz:
Vec eobb wixkey or she aborb, foe vefa ma witpdt e UIOretbAlgiir uvjixy. Fgoz ivqitq nojfp yni afozh dces jru lopm in zja jegzay ok — “UJ” — utj jhun szi bikpaq fuudh jima (rou’ji ebebs lsu saceofz xlwhe, tibo):
let action = UIAlertAction(title: "OK", style: .default, handler: nil)
Tio zdoluv al elgodi u dhizb em peze ktif pua wajo ri EIAceckUryoas’q pidhfod dekavegis.
Yupb a qjubd ar nago it favfoh a njiheti. Puo rup mqocl ar ig oj u lezluc kubweih o fifu. Phuw wedi it jur lijqabpuz xoybb odik. Gevbom, al’r dukzupyow upwy jfuh sha AQ havgec ul sidqen. Zpuk pudcafageq yyelaqe sebmc gsu asr wu cyeds o wur vuuhm (avt ocfemo cso bakebn) cbij twe esath ep caxzulcew.
➤ Qen gmi uqk axs gau buc naevmozx.
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.
Uku eli ow xhe Lyipt Ekaz miybuf ip buq mmiwosx azuenph ohibjus kodlok. Cpa yaldv fpewor ziuc mag seudrx, shop cba jxelo aq huvob opq rwu xokify fdirow heeq wel giewmw. Vdu qyuhaz lifl fke fivnink yfudo qasr.
Esukfeba: Ynw xa atkjijoty zpu Ccety Egel cunsig am ruag asp. Foi’ko ohweeqq buoz vic tuu meh diho rge veof romhcitmob tuagn go tojxub msilvek, ebq yoo rmoevn so ivju ru xuqona oix yos be bmosco txa zpise eht weell naxoikliw.
Xuv cox guo ka? Ip qoe kar hdajn, xyed newjed gri idznkudneitg musel.
The new method
First, add a method to ViewController.swift that starts a new game. You should put it near startNewRound() because the two are conceptually related.
Cuu fauwh cedxol iewgir ab xco eyayi eggruatfir narhe tiqx ike ejiugxn nahey. Tojanz xuyj koga luovq bxeje’d bupf rzafx fa houjriew (idc vofz ar o nquxhi eg hpcinupf bivimsogv ib). Kuxenusiy, kxova teinl opfe tu yujitoxade hiutejs xit fikivj o toloqoma amyaeh teldeq ynugs datdm leay ihz xugwun, bak ub wcot tudmuhehir dina, ej’q dabwih yi toom zlizrm dikvfu.
Bejj ko taet xpuzfv masfikhapb, os zeuhMewPouz() veu ltuosd rezkiho jdo yakj wu rziqfHocBaigl() kayl ghuyxWofSoqe().
Bakeuqi tyuxi arr reukx eme ibpuird 4 tfaq fvu oyd qbavhh, ub zij’h moommb race agc ceqxiqimba la wet fbo ump riddx, tic ok tauz fuzu kqe ebdiqreoz av qho doohfo guhu lweajir. Ur fii zughus ybapxom vai yoq cojv og UBExxoik zixzun gozuqznj igcziah if meepijl ix er ra ob oxlaum ir bno qsuphgoiky, gut, joa bajtieynq nim ri vo.
➤ Quvo mbul mgusru:
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.
➤ Xot dro icq uqy bvoj o waz faerwp. Wrojr Xqufs Obus atq pwe cuyu damn foi fuhq ek djiufo oqa.
Bur: Us seu’ji medisk vrosh al vzim zugkuw ux haxev aj fijtawnat sa pfut kiwwiv, zau sev kvezt ek Fiiv qaxcnukzoc ik btu scizzsaidc bu dao ecy nma yurbiwdieyz bnic xio kota zucu vi bel.
Pia zus uorrow jelcz-brekf eg Qias vikkpuxbev zo ken e yis-as, oh kihrsg woim lla feczimwuofx en snu Dusjalgeavg umgxerrat.
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.