این مقاله روند ایجاد یک بازی آموزش حافظه ساده را شرح می دهد که من واقعاً از آن لذت می برم. علاوه بر این که به خودی خود خوب است، در حین حرکت کمی بیشتر در مورد کلاس ها و پروتکل های سوئیفت خواهید آموخت. اما قبل از شروع، بیایید خود بازی را درک کنیم.
یادآوری می کنیم:برای همه خوانندگان "Habr" - تخفیف 10 روبل هنگام ثبت نام در هر دوره Skillbox با استفاده از کد تبلیغاتی "Habr".
بازی با نمایش مجموعه ای از کارت ها آغاز می شود. آنها رو به پایین دراز می کشند (به ترتیب، تصویر پایین). وقتی روی هر کدام کلیک می کنید، تصویر برای چند ثانیه باز می شود.
وظیفه بازیکن این است که همه کارت ها را با تصاویر مشابه پیدا کند. اگر پس از باز کردن کارت اول، کارت دوم را برگردانید و تصاویر مطابقت داشتند، هر دو کارت باز می مانند. اگر مطابقت نداشتند، کارت ها دوباره بسته می شوند. هدف باز کردن همه چیز است.
ساختار پروژه
برای ایجاد یک نسخه ساده از این بازی به اجزای زیر نیاز دارید:
یک کنترلر: GameController.swift.
One View: CardCell.swift.
دو مدل: MemoryGame.swift و Card.swift.
Main.storyboard برای اطمینان از در دسترس بودن کل مجموعه اجزا.
ما با ساده ترین جزء بازی، کارت ها شروع می کنیم.
کارت.سوئیفت
مدل کارت دارای سه ویژگی است: id برای شناسایی هر یک، یک متغیر بولی نشان داده شده برای مشخص کردن وضعیت کارت (مخفی یا باز)، و artworkURL برای تصاویر روی کارتها.
class Card {
var id: String
var shown: Bool = false
var artworkURL: UIImage!
}
همچنین برای کنترل تعامل کاربر با نقشه ها به این روش ها نیاز دارید:
روش نمایش تصویر روی کارت در اینجا همه ویژگی ها را به حالت پیش فرض بازنشانی می کنیم. برای شناسه، با فراخوانی NSUUIS().uuidString یک شناسه تصادفی تولید می کنیم.
مدل دوم MemoryGame است، در اینجا ما یک شبکه 4*4 تنظیم می کنیم. این مدل دارای ویژگیهایی مانند کارتها (آرایهای از کارتها در یک شبکه)، آرایه کارتهای نشان داده شده با کارتهایی که قبلاً باز شدهاند، و یک متغیر بولی isPlaying برای ردیابی وضعیت بازی خواهد داشت.
class MemoryGame {
var cards:[Card] = [Card]()
var cardsShown:[Card] = [Card]()
var isPlaying: Bool = false
}
ما همچنین نیاز به توسعه روش هایی برای کنترل تعامل کاربر با شبکه داریم.
این متد آخرین عنصر را در آرایه **cardsShown** می خواند و کارت غیر منطبق را برمی گرداند.
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 و GameController.swift
Main.storyboard چیزی شبیه به این است:
در ابتدا، باید بازی جدید را به عنوان viewDidLoad در کنترلر تنظیم کنید، از جمله تصاویر شبکه. در بازی، همه اینها با 4*4 collectionView نشان داده می شود. اگر هنوز با collectionView آشنا نیستید، اینجاست می توانید اطلاعات مورد نیاز خود را دریافت کنید.
ما GameController را به عنوان کنترلر اصلی برنامه پیکربندی می کنیم. GameController یک collectionView خواهد داشت که به عنوان یک IBOutlet به آن ارجاع می دهیم. مرجع دیگر دکمه IBAction onStartGame () است، این یک دکمه UIB است، می توانید آن را در استوری بورد به نام PLAY ببینید.
کمی در مورد پیاده سازی کنترلرها:
ابتدا، دو شی اصلی را مقداردهی می کنیم - شبکه: game = MemoryGame()، و مجموعه ای از کارت ها: cards = [Card]().
ما متغیرهای اولیه را viewDidLoad قرار می دهیم، این اولین روشی است که در حین اجرای بازی فراخوانی می شود.
collectionView روی مخفی تنظیم شده است زیرا همه کارتها تا زمانی که کاربر PLAY را فشار دهد پنهان میشوند.
به محض فشار دادن PLAY، قسمت onStartGame IBAction شروع می شود و ویژگی collectionView isHidden را روی false قرار می دهیم تا کارت ها قابل مشاهده باشند.
هر بار که کاربر کارتی را انتخاب می کند، متد didSelectItemAt فراخوانی می شود. در متدی که برای پیاده سازی منطق اصلی بازی، didSelectCard را فراخوانی می کنیم.
کار با پروتکل ها هسته اصلی برنامه نویسی سوئیفت است. پروتکل ها توانایی تعریف قوانین برای یک کلاس، ساختار یا شمارش را فراهم می کنند. این اصل به شما امکان می دهد کدهای ماژولار و قابل توسعه بنویسید. در واقع این الگویی است که ما در حال پیاده سازی آن برای collectionView در GameController هستیم. حالا بیایید نسخه خودمان را بسازیم. سینتکس به شکل زیر خواهد بود:
protocol MemoryGameProtocol {
//protocol definition goes here
}
ما می دانیم که یک پروتکل به ما اجازه می دهد تا قوانین یا دستورالعمل هایی را برای پیاده سازی یک کلاس تعریف کنیم، بنابراین بیایید در مورد آنها فکر کنیم. در کل به چهار مورد نیاز دارید.
شروع بازی: memoryGameDidStart.
باید کارت را رو به پایین بچرخانید: memoryGameShowCards.
باید کارت را رو به پایین بچرخانید: memoryGameHideCards.
پایان بازی: memoryGameDidEnd.
هر چهار متد را می توان برای کلاس اصلی که GameController است پیاده سازی کرد.
memoryGameDidStart
هنگامی که این روش اجرا می شود، بازی باید شروع شود (کاربر PLAY را فشار می دهد). در اینجا ما به سادگی محتوا را با فراخوانی () collectionView.reloadData بارگیری می کنیم، که کارت ها را به هم می زند.
ما این متد را از collectionSDViewSelectItemAt می نامیم. ابتدا کارت انتخاب شده را نشان می دهد. سپس بررسی می کند که آیا کارت بی همتا در آرایه cardsShown وجود دارد (اگر تعداد کارت های نمایش داده شده فرد باشد). در صورت وجود، کارت انتخاب شده با آن مقایسه می شود. اگر تصاویر یکسان باشند، هر دو کارت به cardsShown اضافه می شوند و رو به بالا باقی می مانند. اگر متفاوت باشد، کارت cardsShown را میگذارد و هر دو رو به پایین میچرخند.
MemoryGameHideCards
اگر کارت ها مطابقت نداشته باشند، این روش فراخوانی می شود و تصاویر کارت پنهان می شوند.
نشان داده شده = نادرست
memoryGameDidEnd
هنگامی که این روش فراخوانی می شود، به این معنی است که همه کارت ها قبلاً آشکار شده اند و در لیست cardsShown قرار دارند: cardsShown.count = cards.count، بنابراین بازی تمام شده است. متد به طور خاص پس از فراخوانی endGame() فراخوانی می شود تا isPlaying var را روی false قرار دهیم و پس از آن پیام پایان بازی نشان داده می شود. همچنین alertController به عنوان نشانگر کنترلر استفاده می شود. viewDidDisappear فراخوانی می شود و بازی ریست می شود.
در اینجا همه چیز در 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()
}
}
در واقع، این همه است. شما می توانید از این پروژه برای ساخت نسخه خود از بازی استفاده کنید.