Hierdie artikel beskryf die proses om 'n eenvoudige geheue-opleidingspeletjie te skep waarvan ek baie hou. Behalwe dat dit op sigself goed is, sal jy 'n bietjie meer leer oor Swift-klasse en -protokolle soos jy gaan. Maar voor ons begin, laat ons die spel self verstaan.
Ons herinner:vir alle lesers van "Habr" - 'n afslag van 10 000 roebels wanneer u inskryf vir enige Skillbox-kursus met behulp van die "Habr"-promosiekode.
Die speletjie begin met 'n demonstrasie van 'n stel kaarte. Hulle lê met die gesig na onder (onderskeidelik, beeld af). Wanneer jy op enige een klik, maak die prent vir 'n paar sekondes oop.
Die speler se taak is om alle kaarte met dieselfde prente te vind. As jy, nadat jy die eerste kaart oopgemaak het, die tweede omdraai en die prente pas, bly albei kaarte oop. As hulle nie ooreenstem nie, word die kaarte weer toegemaak. Die doel is om alles oop te maak.
Projekstruktuur
Om 'n eenvoudige weergawe van hierdie speletjie te skep, benodig jy die volgende komponente:
Een beheerder: GameController.swift.
Een aansig: CardCell.swift.
Twee modelle: MemoryGame.swift en Card.swift.
Main.storyboard om te verseker dat die hele stel komponente beskikbaar is.
Ons begin met die eenvoudigste komponent van die spel, die kaarte.
Card.swift
Die kaartmodel sal drie eienskappe hê: ID om elkeen te identifiseer, 'n Boolese veranderlike wat gewys word om die status van die kaart (versteek of oop) te spesifiseer, en kunswerkURL vir die beelde op die kaarte.
class Card {
var id: String
var shown: Bool = false
var artworkURL: UIImage!
}
Jy sal ook hierdie metodes nodig hê om gebruikersinteraksie met kaarte te beheer:
Metode om 'n prent op 'n kaart te vertoon. Hier stel ons alle eienskappe terug na verstek. Vir id genereer ons 'n ewekansige id deur NSUUIS().uuidString te roep.
Die tweede model is MemoryGame, hier stel ons 'n 4*4-rooster in. Die model sal eienskappe hê soos kaarte ('n verskeidenheid kaarte op 'n rooster), 'n kaarte-getoon-skikking met kaarte wat reeds oop is, en 'n Boolese veranderlike is Speel om die status van die speletjie na te spoor.
class MemoryGame {
var cards:[Card] = [Card]()
var cardsShown:[Card] = [Card]()
var isPlaying: Bool = false
}
Ons moet ook metodes ontwikkel om gebruikersinteraksie met die rooster te beheer.
Metode om 'n nuwe speletjie te skep. Hier noem ons die eerste metode om die aanvanklike uitleg te begin en die isPlaying-veranderlike inisialiseer na waar.
Hierdie metode lees die laaste element in die **cardsShown**-skikking en gee die nie-ooreenstemmende kaart terug.
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 lyk so iets:
Aanvanklik moet jy die nuwe speletjie as viewDidLoad in die beheerder stel, insluitend die beelde vir die rooster. In die speletjie sal dit alles verteenwoordig word deur 'n 4*4-versamelingView. As jy nog nie vertroud is met collectionView nie, hier is dit jy kan die inligting kry wat jy nodig het.
Ons sal die GameController opstel as die toepassing se wortelbeheerder. Die GameController sal 'n versamelingView hê wat ons as 'n IBOoutlet sal verwys. Nog 'n verwysing is na die IBAction onStartGame() knoppie, dit is 'n UIButton, jy kan dit sien in die storiebord genaamd PLAY.
'n Bietjie oor die implementering van beheerders:
Eerstens inisialiseer ons twee hoofobjekte - die rooster: spel = MemoryGame(), en 'n stel kaarte: kaarte = [Card]().
Ons stel die aanvanklike veranderlikes as viewDidLoad, dit is die eerste metode wat genoem word terwyl die speletjie aan die gang is.
collectionView is op versteek gestel omdat alle kaarte versteek is totdat die gebruiker PLAY druk.
Sodra ons PLAY druk, begin die onStartGame IBAction-afdeling, en ons stel die collectionView isHidden-eienskap op vals sodat die kaarte sigbaar kan word.
Elke keer as die gebruiker 'n kaart kies, word die didSelectItemAt-metode genoem. In die metode wat ons didSelectCard noem om die hoofspellogika te implementeer.
Kom ons praat nou bietjie oor die belangrike protokolle.
protokolle
Werk met protokolle is die kern van Swift-programmering. Protokolle bied die vermoë om reëls vir 'n klas, struktuur of opsomming te definieer. Hierdie beginsel laat jou toe om modulêre en uitbreidbare kode te skryf. Trouens, dit is 'n patroon wat ons reeds vir collectionView in GameController implementeer. Kom ons maak nou ons eie weergawe. Die sintaksis sal soos volg lyk:
protocol MemoryGameProtocol {
//protocol definition goes here
}
Ons weet dat 'n protokol ons toelaat om reëls of instruksies vir die implementering van 'n klas te definieer, so kom ons dink oor wat dit moet wees. Jy benodig altesaam vier.
Speletjie begin: memoryGameDidStart.
Jy moet die kaart met die gesig na onder draai: memoryGameShowCards.
Jy moet die kaart met die gesig na onder draai: memoryGameHideCards.
Speleinde: memoryGameDidEnd.
Al vier metodes kan geïmplementeer word vir die hoofklas, wat GameController is.
memoryGameHetStart
Wanneer hierdie metode uitgevoer word, moet die speletjie begin (die gebruiker druk PLAY). Hier sal ons eenvoudig die inhoud herlaai deur collectionView.reloadData() te skakel, wat die kaarte sal skommel.
Ons noem hierdie metode vanaf collectionSDViewSelectItemAt. Eerstens wys dit die gekose kaart. Kontroleer dan of daar 'n ongeëwenaarde kaart in die kaarte-getoon-skikking is (as die aantal kaarte wat gewys word, vreemd is). As daar een is, word die gekose kaart daarmee vergelyk. As die prente dieselfde is, word albei kaarte by kaarte gevoeg wat gewys word en bly gesig na bo. Indien anders, laat die kaart kaarte wat gewys word en albei word met die gesig na onder gedraai.
memoryGameHideCards
As die kaarte nie ooreenstem nie, word hierdie metode genoem en die kaartbeelde word versteek.
getoon = onwaar.
memoryGameDidEnd
Wanneer hierdie metode genoem word, beteken dit dat alle kaarte reeds geopenbaar is en in die kaarteGetoonde lys is: cardsShown.count = cards.count, so die speletjie is verby. Die metode word spesifiek genoem nadat ons endGame() geroep het om die isPlaying var op vals te stel, waarna die speletjie-eindboodskap gewys word. AlertController word ook gebruik as 'n aanwyser vir die kontroleerder. viewDidDisappear word geroep en die speletjie word teruggestel.
Hier is hoe dit alles lyk 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()
}
}
Eintlik is dit al. Jy kan hierdie projek gebruik om jou eie weergawe van die speletjie te skep.