Dësen Artikel beschreift de Prozess fir en einfacht Memory Training Spill ze kreéieren dat ech wierklech gär hunn. Nieft gutt u sech selwer, léiert Dir e bësse méi iwwer Swift Klassen a Protokoller wéi Dir gitt. Awer ier mer ufänken, loosst eis d'Spill selwer verstoen.
Mir erënneren Iech:fir all Habr Lieser - eng Remise vun 10 Rubel wann Dir Iech an all Skillbox Cours aschreift mat dem Habr Promo Code.
D'Spill fänkt mat enger Demonstratioun vun enger Rei vu Kaarten un. Si leien Gesiicht erof (respektiv Bild erof). Wann Dir op eng klickt, mécht d'Bild fir e puer Sekonnen op.
D'Aufgab vum Spiller ass all Kaarte mat de selwechte Biller ze fannen. Wann Dir, nodeems Dir déi éischt Kaart opgemaach hutt, déi zweet ëmdréit an d'Biller passen, bleiwen déi zwou Kaarten op. Wann se net Match, d'Kaarte sinn zougemaach erëm. D'Zil ass alles opzemaachen.
Projet Struktur
Fir eng einfach Versioun vun dësem Spill ze kreéieren braucht Dir déi folgend Komponenten:
One Controller: GameController.swift.
One View: CardCell.swift.
Zwee Modeller: MemoryGame.swift an Card.swift.
Main.storyboard fir sécherzestellen datt de ganze Set vu Komponenten verfügbar ass.
Mir fänken mat der einfachst Komponent vum Spill, d'Kaarte.
Card.swift
De Kaartemodell wäert dräi Eegeschaften hunn: ID fir all eenzel z'identifizéieren, eng boolesch Variabel gewisen fir de Status vun der Kaart ze spezifizéieren (verstoppt oder oppen), an ArtworkURL fir d'Biller op de Kaarten.
class Card {
var id: String
var shown: Bool = false
var artworkURL: UIImage!
}
Dir braucht och dës Methoden fir d'Benotzerinteraktioun mat Kaarten ze kontrolléieren:
Method fir e Bild op enger Kaart ze weisen. Hei setzen mir all Properties op Standard zréck. Fir ID Generéiere mir eng zoufälleg ID vun engem Opruff NSUUIS ().uuidString.
Den zweete Modell ass MemoryGame, hei setzen mir e 4 * 4 Gitter. De Modell wäert Eegeschafte wéi Kaarten hunn (eng Array vu Kaarten op engem Gitter), e CardsShown Array mat Kaarte scho op, an eng boolesch Variabel ass Playing fir de Status vum Spill ze verfolgen.
class MemoryGame {
var cards:[Card] = [Card]()
var cardsShown:[Card] = [Card]()
var isPlaying: Bool = false
}
Mir mussen och Methoden entwéckelen fir d'Benotzerinteraktioun mam Gitter ze kontrolléieren.
Method fir eng nei Spill schafen. Hei nenne mir déi éischt Method fir den initialen Layout unzefänken an d'isPlaying Variabel op richteg ze initialiséieren.
Dës Method liest de leschten Element an der **cardsShown** Array a gëtt déi net passende Kaart zréck.
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 an GameController.swift
Main.storyboard gesäit sou eppes aus:
Am Ufank musst Dir dat neit Spill als viewDidLoad am Controller setzen, och d'Biller fir d'Gitter. Am Spill gëtt all dëst duerch 4 * 4 CollectionView vertruede ginn. Wann Dir nach net mat CollectionView vertraut sidd, hei ass et Dir kënnt d'Informatioun kréien déi Dir braucht.
Mir konfiguréieren de GameController als Root Controller vun der Applikatioun. De GameController wäert eng CollectionView hunn déi mir als IBOutlet referenzéieren. Eng aner Referenz ass op den IBAction onStartGame () Knäppchen, dëst ass en UIButton, Dir kënnt et am Storyboard gesinn PLAY genannt.
E bëssen iwwer d'Ëmsetzung vu Controller:
Als éischt initialiséieren mir zwee Haaptobjekter - d'Gitter: Spill = MemoryGame (), an eng Rei vu Kaarten: Kaarten = [Card] ().
Mir setzen déi initial Variabelen als viewDidLoad, dëst ass déi éischt Method déi genannt gëtt wärend d'Spill leeft.
collectionView ass op verstoppt gesat well all Kaarte verstoppt sinn bis de Benotzer PLAY dréckt.
Soubal mir op PLAY drécken, fänkt d'onStartGame IBAction Sektioun un, a mir setzen d'CollectionView isHidden Propriétéit op falsch sou datt d'Kaarte siichtbar kënne ginn.
All Kéier wann de Benotzer eng Kaart wielt, gëtt d'didSelectItemAt Method genannt. An der Method mir ruffen didSelectCard der Haaptrei Logik ëmsetzen.
Hei ass déi lescht GameController Implementatioun:
Loosst eis elo e bëssen iwwer déi wichteg Protokoller schwätzen.
Protokoller
Mat Protokoller schaffen ass de Kär vun der Swift Programméierung. Protokoller bidden d'Fäegkeet Regele fir eng Klass, Struktur oder Opzielung ze definéieren. Dëse Prinzip erlaabt Iech modulare an erweiterbare Code ze schreiwen. Tatsächlech ass dëst e Muster dat mir scho fir CollectionView am GameController implementéieren. Loosst eis elo eis eege Versioun maachen. D'Syntax wäert esou ausgesinn:
protocol MemoryGameProtocol {
//protocol definition goes here
}
Mir wëssen datt e Protokoll eis erlaabt Reegelen oder Instruktioune fir d'Ëmsetzung vun enger Klass ze definéieren, also loosst eis nodenken wat se solle sinn. Dir braucht véier am Ganzen.
Spillstart: memoryGameDidStart.
Dir musst d'Kaart ëmdréinen: MemoryGameShowCards.
Dir musst d'Kaart Gesiicht erof: MemoryGameHideCards.
Spill Enn: memoryGameDidEnd.
All véier Methode kënne fir d'Haaptklass ëmgesat ginn, dat ass GameController.
memoryGameDidStart
Wann dës Method leeft, soll d'Spill ufänken (de Benotzer dréckt op PLAY). Hei wäerte mir den Inhalt einfach nei lueden andeems Dir collectionView.reloadData () rufft, wat d'Kaarte gemëscht.
Mir ruffen dës Method aus collectionSDViewSelectItemAt. Éischt weist et déi gewielte Kaart. Dann iwwerpréift fir ze kucken ob et eng oniwwertraff Kaart am CardsShown Array ass (wann d'Zuel vun de CardsShown komesch ass). Wann et een ass, gëtt déi gewielte Kaart domat verglach. Wann d'Biller déi selwecht sinn, ginn zwou Kaarten op d'Kaarte bäigefüügt a bleiwen Gesiicht erop. Wann anescht, verléisst d'Kaart d'KaarteShown a béid ginn d'Gesiicht erof.
memoryGameHideCards
Wann d'Kaarte net passen, gëtt dës Method genannt an d'Kaart Biller sinn verstoppt.
ugewisen = falsch.
memoryGameDidEnd
Wann dës Method genannt gëtt, heescht et, datt all Kaarte schonn opgedeckt sinn an an der CardsShown Lëscht sinn: cardsShown.count = cards.count, sou datt d'Spill eriwwer ass. D'Method gëtt speziell genannt nodeems mir endGame genannt hunn () fir den isPlaying var op falsch ze setzen, duerno gëtt de Spill Enn Message gewisen. Och alertController gëtt als Indikator fir de Controller benotzt. viewDidDisappear gëtt genannt an d'Spill gëtt zréckgesat.
Hei ass wéi et alles am GameController ausgesäit:
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()
}
}
Eigentlech ass dat alles. Dir kënnt dëse Projet benotze fir Är eege Versioun vum Spill ze kreéieren.