
Artikel ini menjelaskan proses membuat game pelatihan memori sederhana yang sangat saya sukai. Selain bagus dan dengan sendirinya, Anda akan belajar sedikit lebih banyak tentang kelas dan protokol Swift selama bekerja. Tapi sebelum Anda mulai, mari kita cari tahu permainannya sendiri.
Kami mengingatkan Anda: untuk semua pembaca "Habr" - diskon 10.000 rubel saat mendaftar untuk kursus Skillbox apa pun menggunakan kode promo "Habr".
Skillbox merekomendasikan: Kursus pendidikan online "Pengembang Java Profesi" .
Cara memainkan Kartu Memori
Permainan dimulai dengan demonstrasi serangkaian kartu. Mereka berbaring "baju" ke atas (masing-masing, menghadap ke bawah). Ketika Anda mengklik salah satu, gambar terbuka selama beberapa detik.
Tugas pemain adalah menemukan semua kartu dengan gambar yang sama. Jika setelah membuka kartu pertama Anda membalik kartu kedua dan gambar-gambarnya cocok, kedua kartu tetap terbuka. Jika tidak cocok, kartu ditutup kembali. Tugasnya adalah membuka segalanya.
Struktur proyek
Untuk membuat versi sederhana dari gim ini, Anda memerlukan komponen berikut:
- One Controller: GameController.swift.
- Satu Tampilan: CardCell.swift.
- Dua Model: MemoryGame.swift dan Card.swift.
- Main.storyboard sehingga seluruh set komponen tersedia.
Kami mulai dengan komponen permainan yang paling sederhana, kartu.
Card.swiftModel kartu akan memiliki tiga properti: id untuk mengidentifikasi masing-masing, variabel logis ditunjukkan untuk memperjelas status kartu (tersembunyi atau terbuka) dan artworkURL untuk gambar pada kartu.
class Card { var id: String var shown: Bool = false var artworkURL: UIImage! }
Anda juga akan memerlukan metode ini untuk mengontrol interaksi pengguna dengan kartu:
Metode untuk menampilkan gambar pada kartu. Di sini kita mengatur ulang semua properti ke default. Untuk id, buat id acak dengan memanggil NSUUIS (). UuidString.
init(image: UIImage) { self.id = NSUUID().uuidString self.shown = false self.artworkURL = image }
Metode untuk membandingkan kartu id. func equals(_ card: Card) -> Bool { return (card.id == id) }
Metode untuk membuat salinan dari setiap kartu adalah untuk mendapatkan jumlah yang lebih besar dari
kartu yang identik. Metode ini akan mengembalikan kartu dengan nilai yang sama.
func copy() -> Card { return Card(card: self) } init(card: Card) { self.id = card.id self.shown = card.shown self.artworkURL = card.artworkURL }
Dan metode lain diperlukan untuk mencampur kartu di awal. Kami akan membuatnya menjadi perpanjangan dari kelas Array.
extension Array { mutating func shuffle() { for _ in 0...self.count { sort { (_,_) in arc4random() < arc4random() } } } }
Dan di sini adalah implementasi kode untuk model Kartu dengan semua properti dan metode.
class Card { var id: String var shown: Bool = false var artworkURL: UIImage! static var allCards = [Card]() init(card: Card) { self.id = card.id self.shown = card.shown self.artworkURL = card.artworkURL } init(image: UIImage) { self.id = NSUUID().uuidString self.shown = false self.artworkURL = image } func equals(_ card: Card) -> Bool { return (card.id == id) } func copy() -> Card { return Card(card: self) } } extension Array { mutating func shuffle() { for _ in 0...self.count { sort { (_,_) in arc4random() < arc4random() } } } }
Silakan.
Model kedua adalah MemoryGame, di sini kita mengatur kisi 4 * 4. Model akan memiliki properti seperti kartu (array kartu di grid), array cardsShown dengan kartu yang sudah terbuka, dan boolean isPlaying untuk melacak status permainan.
class MemoryGame { var cards:[Card] = [Card]() var cardsShown:[Card] = [Card]() var isPlaying: Bool = false }
Kita juga perlu mengembangkan metode untuk mengontrol interaksi pengguna dengan kisi.
Metode yang mengocok kartu dalam kotak. func shuffleCards(cards:[Card]) -> [Card] { var randomCards = cards randomCards.shuffle() return randomCards }
Metode untuk membuat game baru. Di sini kita memanggil metode pertama untuk memulai tata letak awal dan menginisialisasi variabel isPlaying sebagai true.
func newGame(cardsArray:[Card]) -> [Card] { cards = shuffleCards(cards: cardsArray) isPlaying = true return cards }
Jika kami ingin memulai kembali gim, kami mengatur variabel isPlaying menjadi false dan menghapus tata letak awal kartu.
func restartGame() { isPlaying = false cards.removeAll() cardsShown.removeAll() }
Metode untuk verifikasi kartu yang ditekan. Lebih banyak tentang itu nanti.
func cardAtIndex(_ index: Int) -> Card? { if cards.count > index { return cards[index] } else { return nil } }
Metode yang mengembalikan posisi kartu tertentu. func indexForCard(_ card: Card) -> Int? { for index in 0...cards.count-1 { if card === cards[index] { return index } } return nil }
Memeriksa kepatuhan kartu yang dipilih dengan standar.
func unmatchedCardShown() -> Bool { return cardsShown.count % 2 != 0 }
Metode ini membaca elemen terakhir dalam array ** cardsShown ** dan mengembalikan kartu yang tidak pantas.
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 dan GameController.swift
Main.storyboard terlihat seperti ini:

Awalnya, di controller Anda perlu menginstal game baru sebagai viewDidLoad, termasuk gambar untuk grid. Dalam game, semua ini akan diwakili oleh 4 * 4 collectionView. Jika Anda tidak terbiasa dengan collectionView, di sini
Anda bisa mendapatkan informasi yang diperlukan .
Kami akan mengonfigurasi GameController sebagai pengontrol root aplikasi. Akan ada collectionView di GameController, yang akan kami rujuk sebagai IBOutlet. Tautan lain adalah ke tombol IBAction onStartGame (), ini adalah UIButton, Anda dapat melihatnya di storyboard yang disebut PLAY.
Sedikit tentang implementasi pengendali:
- Pertama, kita menginisialisasi dua objek utama - kisi (permainan): game = MemoryGame (), dan pada set kartu: kartu = [Kartu] ().
- Tetapkan variabel awal sebagai viewDidLoad, ini adalah metode pertama yang disebut selama permainan.
- atur collectionView sebagai tersembunyi, karena semua peta disembunyikan hingga pengguna menekan MAINKAN.
- Segera setelah kami menekan PLAY, bagian IBAction onStartGame dimulai, dan kami mengatur properti collectionView isHidden menjadi false sehingga kartu dapat menjadi terlihat.
- Setiap kali pengguna memilih kartu, metode didSelectItemAt dipanggil. Dalam metode ini, kami memanggil didSelectCard untuk menerapkan logika dasar permainan.
Inilah implementasi akhir dari GameController:
class GameController: UIViewController { @IBOutlet weak var collectionView: UICollectionView! let game = MemoryGame() var cards = [Card]() override func viewDidLoad() { super.viewDidLoad() game.delegate = self collectionView.dataSource = self collectionView.delegate = self collectionView.isHidden = true APIClient.shared.getCardImages { (cardsArray, error) in if let _ = error {
Sekarang mari kita membahas beberapa protokol penting.
Protokol
Bekerja dengan protokol adalah dasar dari pemrograman Swift. Protokol menyediakan kemampuan untuk menetapkan aturan untuk kelas, struktur, atau enumerasi. Prinsip ini memungkinkan Anda untuk menulis kode modular dan extensible. Ini sebenarnya sebuah template yang sudah kami terapkan untuk collectionView di GameController. Sekarang mari kita buat versi kita sendiri. Sintaksnya akan terlihat seperti ini:
protocol MemoryGameProtocol {
Kami tahu bahwa protokol memungkinkan Anda untuk mendefinisikan aturan atau instruksi untuk mengimplementasikan kelas, jadi mari kita pikirkan tentang apa yang seharusnya. Hanya empat yang dibutuhkan.
- Mulai dari gim: memoryGameDidStart.
- Perlu membalik kartu ke bawah: memoryGameShowCards.
- Perlu membalik kartu ke bawah: memoryGameHideCards.
- Penyelesaian game: memoryGameDidEnd.
Kami menerapkan keempat metode untuk kelas utama, dan ini adalah GameController.
memoryGameDidStart
Ketika metode ini diluncurkan, game harus dimulai (pengguna menekan MAINKAN). Di sini, kita cukup memuat ulang konten dengan memanggil collectionView.reloadData (), yang akan menyebabkan peta menjadi acak.
func memoryGameDidStart(_ game: MemoryGame) { collectionView.reloadData() }
memoryGameShowCard
Panggil metode ini dari collectionSDViewSelectItemAt. Pertama, ini menunjukkan peta yang dipilih. Kemudian memeriksa untuk melihat apakah ada kartu yang tidak cocok dalam array cardsShown (jika jumlah cardsShown ganjil). Jika ada, kartu yang dipilih dibandingkan dengannya. Jika gambarnya sama, kedua kartu ditambahkan ke cardsShown dan tetap terbuka. Jika berbeda, kartu tersebut meninggalkan cardShown, dan keduanya terbalik.
memoryGameHideCards
Jika kartu tidak cocok, metode ini disebut, dan gambar kartu disembunyikan.
ditampilkan = salah.
memoryGameDidEnd
Ketika metode ini dipanggil, itu berarti bahwa semua kartu sudah terbuka dan berada di daftar cardsShown: cardsShown.count = cards.count, sehingga permainan selesai. Metode ini dipanggil secara khusus setelah kami memanggil endGame () untuk mengatur isPlaying var ke false, setelah itu pesan tentang penyelesaian permainan ditampilkan. AlertController juga digunakan sebagai indikator untuk pengontrol. ViewDidDisappear dipanggil dan permainan diatur ulang.
Begini tampilannya di 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() } }

Itu saja. Anda dapat menggunakan proyek ini untuk membuat versi gim Anda sendiri.
Pengodean yang bagus!
Skillbox merekomendasikan: