Questu articulu descrive u prucessu di creà un ghjocu simplice di furmazione di memoria chì mi piace assai. Oltre à esse bonu in sè stessu, amparate un pocu di più nantu à e classi è i protokolli Swift mentre andate. Ma prima di principià, capiscemu u ghjocu stessu.
Ramintemu:per tutti i lettori di "Habr" - un scontu di 10 000 rubles quandu si iscrizzione in ogni cursu Skillbox cù u codice promozionale "Habr".
U ghjocu principia cù una dimostrazione di un set di carte. Si trovanu a faccia in giru (rispettivamente, l'imaghjini). Quandu cliccate nant'à qualcunu, l'imaghjini si apre per uni pochi seconde.
U compitu di u ghjucatore hè di truvà tutte e carte cù i stessi ritratti. Se, dopu avè apertu a prima carta, turnate a seconda è e foto currispondenu, e duie carte restanu aperte. S'ellu ùn currispondenu micca, i carte sò chjusi di novu. U scopu hè di apre tuttu.
Struttura di u prugettu
Per creà una versione simplice di stu ghjocu avete bisognu di i seguenti cumpunenti:
Un Controller: GameController.swift.
Una vista: CardCell.swift.
Dui mudelli: MemoryGame.swift è Card.swift.
Main.storyboard per assicurà chì tuttu u settore di cumpunenti hè dispunibule.
Cuminciamu cù u cumpunente più simplice di u ghjocu, i carte.
Card.swift
U mudellu di carta averà trè proprietà: id per identificà ognunu, una variabile booleana mostrata per specificà u statutu di a carta (oculata o aperta), è artworkURL per l'imaghjini nantu à e carte.
class Card {
var id: String
var shown: Bool = false
var artworkURL: UIImage!
}
Averete ancu bisognu di sti metudi per cuntrullà l'interazzione di l'utilizatori cù e carte:
Metudu per vede una maghjina nantu à una carta. Quì avemu resettatu tutte e pruprietà per difettu. Per id, generemu un id aleatoriu chjamendu NSUUIS().uuidString.
U sicondu mudellu hè MemoryGame, quì avemu stabilitu una griglia 4 * 4. U mudellu avarà pruprietà cum'è carte (un array di carte nantu à una griglia), un array cardsShown cù carte digià aperte, è una variabile booleana in Playing per seguità u statutu di u ghjocu.
class MemoryGame {
var cards:[Card] = [Card]()
var cardsShown:[Card] = [Card]()
var isPlaying: Bool = false
}
Avemu ancu bisognu di sviluppà metudi per cuntrullà l'interazzione di l'utilizatori cù a griglia.
Stu metudu leghje l'ultimu elementu in l'array **cardsShown** è torna a carta chì ùn currisponde.
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 è GameController.swift
Main.storyboard s'assumiglia à questu:
Inizialmente, avete bisognu di stabilisce u novu ghjocu cum'è viewDidLoad in u controller, cumprese l'imaghjini per a griglia. In u ghjocu, tuttu questu serà rapprisintatu da 4 * 4 collectionView. Se ùn site micca ancu familiarizatu cù collectionView, quì hè quì pudete uttene l'infurmazioni chì avete bisognu.
Cunfiguremu u GameController cum'è u controller root di l'applicazione. U GameController avarà una cullizzioniView chì faremu riferimentu cum'è un IBOutlet. Un altru riferimentu hè à u buttone IBAction onStartGame (), questu hè un UIButton, pudete vede in u storyboard chjamatu PLAY.
Un pocu nantu à l'implementazione di i cuntrolli:
Prima, avemu inizializatu dui ogetti principali - a griglia: ghjocu = MemoryGame(), è un set di carte: cards = [Card]().
Avemu stabilitu e variabili iniziali cum'è viewDidLoad, questu hè u primu metudu chì hè chjamatu mentre u ghjocu hè in esecuzione.
collectionView hè pusatu per ammucciatu perchè tutte e carte sò ammucciate finu à chì l'utilizatore preme PLAY.
Appena pressu PLAY, a sezione onStartGame IBAction principia, è avemu stabilitu a pruprietà collectionView isHidden à false per chì e carte ponu esse visibili.
Ogni volta chì l'utilizatore sceglie una carta, u metudu didSelectItemAt hè chjamatu. In u metudu chjamemu didSelectCard per implementà a logica di u ghjocu principale.
U travagliu cù protokolli hè u core di a prugrammazione Swift. I protokolli furniscenu l'abilità di definisce e regule per una classa, struttura o enumerazione. Stu principiu permette di scrive codice modulare è extensible. In fatti, questu hè un mudellu chì avemu digià implementatu per a cullezzioneView in GameController. Avà facemu a nostra propria versione. A sintassi sarà cusì:
protocol MemoryGameProtocol {
//protocol definition goes here
}
Sapemu chì un protokollu ci permette di definisce e regule o struzzioni per implementà una classa, allora pensemu ciò chì deve esse. Avete bisognu di quattru in totale.
U principiu di u ghjocu: memoryGameDidStart.
Avete bisognu di vultà a carta a faccia in giù: memoryGameShowCards.
Avete bisognu di turnà a carta a faccia in giù: memoryGameHideCards.
Finu di u ghjocu: memoryGameDidEnd.
Tutti i quattru metudi ponu esse implementati per a classa principale, chì hè GameController.
memoryGameDidStart
Quandu stu metudu hè eseguitu, u ghjocu deve principià (l'utilizatore pressu PLAY). Quì avemu da solu ricaricà u cuntenutu chjamendu collectionView.reloadData (), chì mischiarà e carte.
Chjamemu stu metudu da collectionSDViewSelectItemAt. Prima mostra a carta scelta. Allora cuntrolla per vede s'ellu ci hè una carta ineguagliata in l'array cardsShown (se u numeru di cardsShown hè stranu). Se ci hè unu, a carta scelta hè paragunata cun ella. Se l'imaghjini sò listessi, e duie carte sò aghjuntu à e carte Mostrate è restanu a faccia in sopra. S'ellu hè differente, a carta lasci cartesShown è i dui sò girati a faccia in giru.
memoryGameHideCards
Se e carte ùn currispondenu micca, stu metudu hè chjamatu è l'imaghjini di carte sò oculati.
mostratu = falsu.
memoriaGameDidEnd
Quandu stu metudu hè chjamatu, significa chì tutte e carte sò digià revelate è sò in a lista di carteShown: cardsShown.count = cards.count, cusì u ghjocu hè finitu. U metudu hè chjamatu specificamente dopu chì avemu chjamatu endGame () per stabilisce a var isPlaying à false, dopu chì u messagiu di u ghjocu hè mostratu. Ancu alertController hè utilizatu com'è un indicatore per u controller. viewDidDisappear hè chjamatu è u ghjocu hè resettatu.
Eccu ciò chì pare tuttu in 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()
}
}
In fatti, hè tuttu. Pudete aduprà stu prughjettu per creà a vostra propria versione di u ghjocu.