Bu makale, gerçekten sevdiğim basit bir hafıza eğitimi oyunu oluşturma sürecini anlatıyor. Kendi içinde iyi olmanın yanı sıra, ilerledikçe Swift sınıfları ve protokolleri hakkında biraz daha fazlasını öğreneceksiniz. Ancak başlamadan önce oyunun kendisini anlayalım.
Hatırlatıyoruz:tüm "Habr" okuyucuları için - "Habr" promosyon kodunu kullanarak herhangi bir Skillbox kursuna kayıt olurken 10 ruble indirim.
Oyun bir dizi kartın gösterilmesiyle başlar. Yüzüstü uzanırlar (sırasıyla görüntü aşağı doğru). Herhangi birine tıkladığınızda resim birkaç saniyeliğine açılır.
Oyuncunun görevi aynı resimlere sahip tüm kartları bulmaktır. İlk kartı açtıktan sonra ikinciyi açarsanız ve resimler eşleşirse her iki kart da açık kalır. Eşleşmiyorlarsa kartlar tekrar kapatılır. Amaç her şeyi açmaktır.
Proje yapısı
Bu oyunun basit bir versiyonunu oluşturmak için aşağıdaki bileşenlere ihtiyacınız var:
Bir Denetleyici: GameController.swift.
Tek Görünüm: CardCell.swift.
İki Model: MemoryGame.swift ve Card.swift.
Main.storyboard, tüm bileşen setinin mevcut olduğundan emin olmak için.
Oyunun en basit bileşeni olan kartlarla başlıyoruz.
Kart.hızlı
Kart modelinin üç özelliği olacaktır: her birini tanımlayan kimlik, kartın durumunu (gizli veya açık) belirtmek için gösterilen bir boole değişkeni ve kartlardaki resimler için resim URL'si.
class Card {
var id: String
var shown: Bool = false
var artworkURL: UIImage!
}
Haritalarla kullanıcı etkileşimini kontrol etmek için şu yöntemlere de ihtiyacınız olacak:
Bir görüntüyü kartta görüntüleme yöntemi. Burada tüm özellikleri varsayılana sıfırlıyoruz. Kimlik için NSUUIS().uuidString'i çağırarak rastgele bir kimlik oluştururuz.
İkinci model ise MemoryGame, burada 4*4'lük bir grid ayarladık. Model, kartlar (bir ızgara üzerinde kart dizisi), zaten açık olan kartların bulunduğu birwardsShown dizisi ve oyunun durumunu izlemek için bir boolean isPlaying değişkeni gibi özelliklere sahip olacaktır.
class MemoryGame {
var cards:[Card] = [Card]()
var cardsShown:[Card] = [Card]()
var isPlaying: Bool = false
}
Ayrıca kullanıcının grid ile etkileşimini kontrol edecek yöntemler geliştirmemiz gerekiyor.
Bu yöntem **cardsShown** dizisindeki son öğeyi okur ve eşleşmeyen kartı döndürür.
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 ve GameController.swift
Main.storyboard şuna benzer:
Başlangıçta, yeni oyunu, ızgara görüntüleri de dahil olmak üzere denetleyicide viewDidLoad olarak ayarlamanız gerekir. Oyunda tüm bunlar 4*4 koleksiyon Görünümü ile temsil edilecek. CollectionView'a henüz aşina değilseniz, işte burada ihtiyacınız olan bilgiyi alabilirsiniz.
GameController'ı uygulamanın kök denetleyicisi olarak yapılandıracağız. GameController, IBOutlet olarak başvuracağımız bir koleksiyon Görünümüne sahip olacaktır. Başka bir referans IBAction onStartGame() düğmesidir, bu bir UIButton'dur, bunu PLAY adlı storyboard'da görebilirsiniz.
Denetleyicilerin uygulanması hakkında biraz:
Öncelikle iki ana nesneyi başlatıyoruz: ızgara: oyun = MemoryGame() ve bir kart seti: kartlar = [Card]().
Başlangıç değişkenlerini viewDidLoad olarak ayarladık, oyun çalışırken çağrılan ilk yöntem budur.
CollectionView gizli olarak ayarlanmıştır çünkü kullanıcı PLAY'e basana kadar tüm kartlar gizlidir.
PLAY tuşuna bastığımız anda onStartGame IBAction bölümü başlıyor ve kartların görünür olabilmesi için CollectionView isHidden özelliğini false olarak ayarlıyoruz.
Kullanıcı her kart seçtiğinde didSelectItemAt yöntemi çağrılır. Ana oyun mantığını uygulamak için didSelectCard dediğimiz yöntemde.
Protokollerle çalışmak Swift programlamanın temelidir. Protokoller bir sınıf, yapı veya numaralandırma için kuralları tanımlama yeteneği sağlar. Bu prensip modüler ve genişletilebilir kod yazmanıza olanak tanır. Aslında bu, GameController'da CollectionView için zaten uyguladığımız bir kalıptır. Şimdi kendi versiyonumuzu yapalım. Sözdizimi şöyle görünecek:
protocol MemoryGameProtocol {
//protocol definition goes here
}
Bir protokolün, bir sınıfı uygulamaya yönelik kuralları veya talimatları tanımlamamıza izin verdiğini biliyoruz, o halde bunların ne olması gerektiğini düşünelim. Toplamda dörde ihtiyacınız var.
Oyunun başlangıcı: MemoryGameDidStart.
Kartı ters çevirmeniz gerekiyor: MemoryGameShowCards.
Kartı ters çevirmeniz gerekiyor: MemoryGameHideCards.
Oyunun sonu: MemoryGameDidEnd.
Dört yöntemin tümü GameController olan ana sınıf için uygulanabilir.
hafızaOyunDidBaşlat
Bu yöntem çalıştırıldığında oyun başlamalıdır (kullanıcı PLAY'e basar). Burada, kartları karıştıracak olan CollectionView.reloadData()'yı çağırarak içeriği yeniden yükleyeceğiz.
Bu yöntemi CollectionSDViewSelectItemAt'tan çağırıyoruz. İlk önce seçilen kartı gösterir. Daha sonra,wardsShown dizisinde eşleşmeyen bir kart olup olmadığını kontrol eder (eğercardShown sayısı tek ise). Varsa seçilen kart onunla karşılaştırılır. Resimler aynıysa, her iki kart da gösterilen kartlara eklenir ve açık olarak kalır. Farklıysa, kartta kartlar gösterilir ve her ikisi de ters çevrilir.
hafızaOyunGizleKartlar
Kartların eşleşmemesi durumunda bu yöntem çağrılır ve kart görselleri gizlenir.
gösterilen = yanlış.
hafızaOyunDidEnd
Bu yöntem çağrıldığında, tüm kartların zaten açık olduğu ve kartların Gösterildiği listede olduğu anlamına gelir: kartlarShown.count = kartlar.sayısı, yani oyun biter. Bu yöntem özellikle isPlaying var'ı false olarak ayarlamak için endGame() çağrıldıktan sonra çağrılır ve ardından oyun sonu mesajı gösterilir. Ayrıca warningController denetleyici için bir gösterge olarak kullanılır. viewDidDisappear çağrılır ve oyun sıfırlanır.
GameController'da her şey şöyle görünüyor:
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()
}
}
Aslında hepsi bu. Oyunun kendi versiyonunu oluşturmak için bu projeyi kullanabilirsiniz.