Dit artikel beskriuwt it proses fan it meitsjen fan in ienfâldich spultsje foar ûnthâldtraining dat ik echt leuk fyn. Neist it op himsels goed te wêzen, sille jo wat mear leare oer Swift-klassen en protokollen as jo gean. Mar foardat wy begjinne, litte wy it spultsje sels begripe.
Wy herinnerje:foar alle lêzers fan "Habr" - in koarting fan 10 roebel by it ynskriuwen fan in Skillbox-kursus mei de promoasjekoade "Habr".
It spul begjint mei in demonstraasje fan in set fan kaarten. Se lizze gesicht del (resp. ôfbylding del). As jo op ien klikke, iepenet de ôfbylding foar in pear sekonden.
De taak fan de spiler is om alle kaarten te finen mei deselde foto's. As jo, nei it iepenjen fan de earste kaart, de twadde omdraaie en de foto's oerienkomme, bliuwe beide kaarten iepen. As se net oerienkomme, wurde de kaarten wer sletten. It doel is om alles te iepenjen.
Projektstruktuer
Om in ienfâldige ferzje fan dit spultsje te meitsjen hawwe jo de folgjende komponinten nedich:
Ien Controller: GameController.swift.
Ien werjefte: CardCell.swift.
Twa modellen: MemoryGame.swift en Card.swift.
Main.storyboard om te soargjen dat de hiele set fan komponinten beskikber is.
Wy begjinne mei de ienfâldichste komponint fan it spul, de kaarten.
Card.swift
It kaartmodel sil trije eigenskippen hawwe: id om elk te identifisearjen, in Booleaanske fariabele werjûn om de status fan 'e kaart te spesifisearjen (ferburgen as iepen), en artworkURL foar de ôfbyldings op' e kaarten.
class Card {
var id: String
var shown: Bool = false
var artworkURL: UIImage!
}
Jo sille ek dizze metoaden nedich wêze om brûkersynteraksje mei kaarten te kontrolearjen:
Metoade foar it werjaan fan in ôfbylding op in kaart. Hjir sette wy alle eigenskippen werom nei standert. Foar id generearje wy in willekeurige id troch in oprop NSUUIS ().uuidString.
It twadde model is MemoryGame, hjir sette wy in 4 * 4 raster yn. It model sil eigenskippen hawwe lykas kaarten (in array fan kaarten op in raster), in cardsShown-array mei kaarten dy't al iepen binne, en in Booleaanske fariabele is Playing om de status fan it spul te folgjen.
class MemoryGame {
var cards:[Card] = [Card]()
var cardsShown:[Card] = [Card]()
var isPlaying: Bool = false
}
Wy moatte ek metoaden ûntwikkelje om ynteraksje fan brûkers mei it raster te kontrolearjen.
Metoade foar it meitsjen fan in nij spultsje. Hjir neame wy de earste metoade om de earste yndieling te begjinnen en de isPlaying-fariabele te initialisearjen nei wier.
Dizze metoade lêst it lêste elemint yn de ** cardsShown ** rige en jout de net-oerienkommende card.
func didSelectCard(_ card: Card?) {
guard let card = card else { return }
if unmatchedCardShown() {
let unmatched = unmatchedCard()!
if card.equals(unmatched) {
cardsShown.append(card)
} else {
let secondCard = cardsShown.removeLast()
}
} else {
cardsShown.append(card)
}
if cardsShown.count == cards.count {
endGame()
}
}
Main.storyboard en GameController.swift
Main.storyboard sjocht der sa út:
Yn it earstoan moatte jo it nije spultsje ynstelle as viewDidLoad yn 'e controller, ynklusyf de ôfbyldings foar it raster. Yn it spultsje sil dit alles wurde fertsjintwurdige troch 4 * 4 collectionView. As jo noch net bekend binne mei collectionView, hjir is it kinne jo krije de ynformaasje dy't jo nedich hawwe.
Wy sille de GameController konfigurearje as de root-controller fan 'e applikaasje. De GameController sil in samlingView hawwe dy't wy sille ferwize as in IBOutlet. In oare ferwizing is nei de IBAction onStartGame () knop, dit is in UIButton, kinne jo sjen it yn it storyboard neamd PLAY.
In bytsje oer de ymplemintaasje fan controllers:
Earst, wy inisjalisearje twa wichtichste objekten - it roaster: game = MemoryGame (), en in set fan kaarten: cards = [Card] ().
Wy sette de earste fariabelen as viewDidLoad, dit is de earste metoade dy't neamd wurdt wylst it spultsje rint.
collectionView is ynsteld op ferburgen omdat alle kaarten binne ferburgen oant de brûker drukt op PLAY.
Sadree't wy op PLAY drukke, begjint de onStartGame IBAction-seksje, en wy sette de collectionView isHidden-eigenskip op falsk, sadat de kaarten sichtber wurde kinne.
Elke kear as de brûker in kaart kiest, wurdt de metoade didSelectItemAt neamd. Yn 'e metoade dy't wy neame didSelectCard foar it útfieren fan de logika fan it haadspultsje.
Hjir is de lêste ymplemintaasje fan GameController:
Litte wy no in bytsje prate oer de wichtige protokollen.
Protokollen
Wurkje mei protokollen is de kearn fan Swift-programmearring. Protokollen jouwe de mooglikheid om regels te definiearjen foar in klasse, struktuer of opsomming. Dit prinsipe lit jo modulêre en útwreide koade skriuwe. Yn feite is dit in patroan dat wy al implementearje foar collectionView yn GameController. Litte wy no ús eigen ferzje meitsje. De syntaksis sil der sa útsjen:
protocol MemoryGameProtocol {
//protocol definition goes here
}
Wy witte dat in protokol ús regels of ynstruksjes kin definiearje foar it útfieren fan in klasse, dus litte wy tinke oer wat se moatte wêze. Jo moatte fjouwer yn totaal.
Game start: memoryGameDidStart.
Jo moatte keare de kaart face down: memoryGameShowCards.
Jo moatte keare de kaart face down: memoryGameHideCards.
Game ein: memoryGameDidEnd.
Alle fjouwer metoaden kinne wurde ymplemintearre foar de haadklasse, dat is GameController.
memoryGameDidStart
As dizze metoade wurdt útfierd, moat it spultsje begjinne (de brûker drukt op PLAY). Hjir sille wy gewoan opnij laden de ynhâld troch in oprop collectionView.reloadData (), dat sil skodzje de kaarten.
Wy neame dizze metoade út collectionSDViewSelectItemAt. Earst toant it de selektearre kaart. Dan kontrolearret om te sjen oft der in unmatched kaart yn de cardsShown array (as it oantal cardsShown is ûneven). As der ien is, wurdt de selektearre kaart dêrmei fergelike. As de foto's binne itselde, beide kaarten wurde tafoege oan cardsShown en bliuwe gesicht omheech. As oars, de kaart lit cardsShown en beide wurde draaid face down.
memoryGameHideCards
As de kaarten net oerienkomme, wurdt dizze metoade neamd en de kaartôfbyldings binne ferburgen.
werjûn = falsk.
memoryGameDidEnd
As dizze metoade wurdt neamd, betsjut dat alle kaarten binne al iepenbiere en binne yn de cardsShown list: cardsShown.count = cards.count, sadat it spul is foarby. De metoade wurdt neamd spesifyk neidat wy hawwe neamd endGame () foar in set de isPlaying var nei falsk, wêrnei't it spultsje ein berjocht wurdt werjûn. Ek alertController wurdt brûkt as in yndikator foar de controller. viewDidDisappear wurdt neamd en it spultsje is weromsette.
Hjir is hoe't it der allegear útsjocht yn GameController:
extension GameController: MemoryGameProtocol {
func memoryGameDidStart(_ game: MemoryGame) {
collectionView.reloadData()
}
func memoryGame(_ game: MemoryGame, showCards cards: [Card]) {
for card in cards {
guard let index = game.indexForCard(card)
else { continue
}
let cell = collectionView.cellForItem(
at: IndexPath(item: index, section:0)
) as! CardCell
cell.showCard(true, animted: true)
}
}
func memoryGame(_ game: MemoryGame, hideCards cards: [Card]) {
for card in cards {
guard let index = game.indexForCard(card)
else { continue
}
let cell = collectionView.cellForItem(
at: IndexPath(item: index, section:0)
) as! CardCell
cell.showCard(false, animted: true)
}
}
func memoryGameDidEnd(_ game: MemoryGame) {
let alertController = UIAlertController(
title: defaultAlertTitle,
message: defaultAlertMessage,
preferredStyle: .alert
)
let cancelAction = UIAlertAction(
title: "Nah", style: .cancel) {
[weak self] (action) in
self?.collectionView.isHidden = true
}
let playAgainAction = UIAlertAction(
title: "Dale!", style: .default) {
[weak self] (action) in
self?.collectionView.isHidden = true
self?.resetGame()
}
alertController.addAction(cancelAction)
alertController.addAction(playAgainAction)
self.present(alertController, animated: true) { }
resetGame()
}
}
Eins is dat alles. Jo kinne dit projekt brûke om jo eigen ferzje fan it spultsje te meitsjen.