Ĉi tiu artikolo priskribas la procezon krei simplan memortrejnadludon, kiun mi tre ĝuas. Krom esti bona en si mem, vi lernos iom pli pri Swift-klasoj kaj protokoloj dum vi iros. Sed antaŭ ol komenci, ni komprenu la ludon mem.
Ni memorigas vin:por ĉiuj legantoj de "Habr" - rabato de 10 000 rubloj kiam oni enskribas en iu ajn Skillbox-kurso per la reklamkodo "Habr".
La ludo komenciĝas per pruvo de aro de kartoj. Ili kuŝas vizaĝe malsupren (respektive, bildo malsupren). Kiam vi alklakas iun ajn, la bildo malfermiĝas dum kelkaj sekundoj.
La tasko de la ludanto estas trovi ĉiujn kartojn kun la samaj bildoj. Se, post malfermi la unuan karton, vi turnas la duan kaj la bildoj kongruas, ambaŭ kartoj restas malfermitaj. Se ili ne kongruas, la kartoj denove estas fermitaj. La celo estas malfermi ĉion.
Projekta strukturo
Por krei simplan version de ĉi tiu ludo vi bezonas la jenajn komponantojn:
Unu Regilo: GameController.swift.
Unu Vido: CardCell.swift.
Du Modeloj: MemoryGame.swift kaj Card.swift.
Main.storyboard por certigi ke la tuta aro de komponantoj estas disponebla.
Ni komencas kun la plej simpla komponanto de la ludo, la kartoj.
Karto.rapida
La karto-modelo havos tri trajtojn: id por identigi ĉiun, bulean variablon montritan por specifi la staton de la karto (kaŝita aŭ malfermita), kaj artworkURL por la bildoj sur la kartoj.
class Card {
var id: String
var shown: Bool = false
var artworkURL: UIImage!
}
Vi ankaŭ bezonos ĉi tiujn metodojn por kontroli uzantinteragon kun mapoj:
Metodo por montri bildon sur karto. Ĉi tie ni restarigas ĉiujn proprietojn al defaŭlta. Por id, ni generas hazardan id per vokado de NSUUIS().uuidString.
La dua modelo estas MemoryGame, ĉi tie ni starigas 4 * 4 kradon. La modelo havos ecojn kiel ekzemple kartoj (aro da kartoj sur krado), kartoj Montritaj tabelo kun kartoj jam malfermitaj, kaj bulea variablo Ludas por spuri la staton de la ludo.
class MemoryGame {
var cards:[Card] = [Card]()
var cardsShown:[Card] = [Card]()
var isPlaying: Bool = false
}
Ni ankaŭ devas evoluigi metodojn por kontroli uzantinteragon kun la krado.
Ĉi tiu metodo legas la lastan elementon en la tabelo **cardsShown** kaj resendas la nekongruan karton.
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()
}
}
Ĉefa.storyboard kaj GameController.swift
Main.storyboard aspektas kiel ĉi tio:
Komence, vi devas agordi la novan ludon kiel viewDidLoad en la regilo, inkluzive de la bildoj por la krado. En la ludo, ĉio ĉi estos reprezentita per 4*4 kolektoVido. Se vi ankoraŭ ne konas collectionView, jen ĝi vi povas ricevi la informojn, kiujn vi bezonas.
Ni agordos la GameController kiel la radikan regilon de la aplikaĵo. La GameController havos kolekton, kiun ni referencos kiel IBOutlet. Alia referenco estas al la butono IBAction onStartGame(), ĉi tiu estas UIButton, vi povas vidi ĝin en la storyboard nomita PLAY.
Iom pri la efektivigo de regiloj:
Unue, ni pravigigas du ĉefajn objektojn - la krado: ludo = MemoryGame(), kaj aro da kartoj: kartoj = [Karto]().
Ni fiksas la komencajn variablojn kiel viewDidLoad, ĉi tiu estas la unua metodo vokita dum la ludo funkcias.
collectionView estas agordita kiel kaŝita ĉar ĉiuj kartoj estas kaŝitaj ĝis la uzanto premas PLAY.
Tuj kiam ni premas PLAY, la sekcio onStartGame IBAction komenciĝas, kaj ni agordas la collectionView isHidden-posedaĵon al falsa por ke la kartoj fariĝu videblaj.
Ĉiufoje kiam la uzanto elektas karton, la metodo didSelectItemAt estas vokita. En la metodo ni nomas didSelectCard por efektivigi la ĉefan ludlogikon.
Labori kun protokoloj estas la kerno de Swift-programado. Protokoloj disponigas la kapablon difini regulojn por klaso, strukturo aŭ listigo. Ĉi tiu principo permesas vin skribi modulan kaj etendeblan kodon. Fakte, ĉi tio estas ŝablono, kiun ni jam efektivigas por kolektoView en GameController. Nun ni faru nian propran version. La sintakso aspektos jene:
protocol MemoryGameProtocol {
//protocol definition goes here
}
Ni scias, ke protokolo permesas al ni difini regulojn aŭ instrukciojn por efektivigi klason, do ni pensu pri kio ili devus esti. Vi bezonas kvar entute.
Ludkomenco: memoryGameDidStart.
Vi devas turni la karton vizaĝo malsupren: memoryGameShowCards.
Vi devas turni la karton vizaĝe malsupren: memoryGameHideCards.
Ludfino: memoryGameDidEnd.
Ĉiuj kvar metodoj povas esti efektivigitaj por la ĉefklaso, kiu estas GameController.
memoryGameDidStart
Kiam ĉi tiu metodo estas rulita, la ludo devus komenciĝi (la uzanto premas PLAY). Ĉi tie ni simple reŝargos la enhavon nomante collectionView.reloadData(), kiu miksos la kartojn.
Ni nomas ĉi tiun metodon de collectionSDViewSelectItemAt. Unue ĝi montras la elektitan karton. Poste kontrolas ĉu estas nekomparebla karto en la tabelo cardsShown (se la nombro da kartoj Montritaj estas nepara). Se ekzistas unu, la elektita karto estas komparata kun ĝi. Se la bildoj estas samaj, ambaŭ kartoj estas aldonitaj al kartoj Montritaj kaj restas vizaĝo supre. Se malsama, la karto lasas kartojn Montritaj kaj ambaŭ estas turnitaj vizaĝo malsupren.
memorludoKaŝkartoj
Se la kartoj ne kongruas, ĉi tiu metodo estas vokita kaj la kartobildoj estas kaŝitaj.
montrata = malvera.
memoryGameDidEnd
Kiam ĉi tiu metodo estas vokita, tio signifas, ke ĉiuj kartoj estas jam malkaŝitaj kaj estas en la kartojShown listo: cardsShown.count = cards.count, do la ludo finiĝis. La metodo estas vokita specife post kiam ni vokis endGame() por agordi la isPlaying var al false, post kio la ludfina mesaĝo montriĝas. Ankaŭ alertController estas uzata kiel indikilo por la regilo. viewDidDisappear estas vokita kaj la ludo estas rekomencigita.
Jen kiel ĉio aspektas en 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()
}
}
Fakte, jen ĉio. Vi povas uzi ĉi tiun projekton por krei vian propran version de la ludo.