前言
用python自帶的tkinter包寫一個記憶翻牌小游戲唄,讓我們愉快地開始吧~

開發工具
Python版本: 3.7.4
相關模塊:
pygame模塊;
tkinter模塊;
pillow模塊;
以及一些python自帶的模塊,
環境搭建
安裝Python并添加到環境變數,pip安裝需要的相關模塊即可,
原理簡介
ok,這里我們還是來簡單介紹一下游戲的實作原理吧,
首先,我們還是借助pygame來播放一首我們喜歡的背景音樂吧:
'''播放背景音樂'''
def playbgm(self):
pygame.init()
pygame.mixer.init()
pygame.mixer.music.load(cfg.AUDIOPATHS['bgm'])
pygame.mixer.music.play(-1, 0.0)
然后,我們初始化一下tkinter的主界面:
# 主界面句柄
self.root = Tk()
self.root.wm_title('Flip Card by Memory —— python工程獅')
并在主界面上顯示16張未被翻面的卡片:
# 游戲界面中的卡片字典
self.game_matrix = {}
# 背景影像
self.blank_image = PhotoImage(data=cfg.IMAGEPATHS['blank'])
# 卡片背面
self.cards_back_image = PhotoImage(data=cfg.IMAGEPATHS['cards_back'])
# 所有卡片的索引
cards_list = list(range(8)) + list(range(8))
random.shuffle(cards_list)
# 在界面上顯示所有卡片的背面
for r in range(4):
for c in range(4):
position = f'{r}_{c}'
self.game_matrix[position] = Label(self.root, image=self.cards_back_image)
self.game_matrix[position].back_image = self.cards_back_image
self.game_matrix[position].file = str(cards_list[r * 4 + c])
self.game_matrix[position].show = False
self.game_matrix[position].bind('<Button-1>', self.clickcallback)
self.game_matrix[position].grid(row=r, column=c)
這16張卡片共包含8張完全不同的影像,我們游戲的目標就是在有限的時間內,將16張卡片中包含相同的影像的卡片兩兩配對,匹配的規則是滑鼠連續地點擊兩張卡片,若卡片背面的影像相同,則匹對成功,否則配對失敗,游戲主要考察玩家的記憶力,因為游戲還規定游戲翻開的卡片數量至多有兩張,否則一開始被點擊而翻開的卡片將再次被蓋上(若該張卡片沒有匹對成功),
接著,我們來定義一些有用的變數:
# 已經顯示正面的卡片
self.shown_cards = []
# 場上存在的卡片數量
self.num_existing_cards = len(cards_list)
# 顯示游戲剩余時間
self.num_seconds = 30
self.time = Label(self.root, text=f'Time Left: {self.num_seconds}')
self.time.grid(row=6, column=3, columnspan=2)
并讓界面一開始可以出現在電腦螢屏的居中位置:
# 居中顯示
self.root.withdraw()
self.root.update_idletasks()
x = (self.root.winfo_screenwidth() - self.root.winfo_reqwidth()) / 2
y = (self.root.winfo_screenheight() - self.root.winfo_reqheight()) / 2
self.root.geometry('+%d+%d' % (x, y))
self.root.deiconify()
由于是在有限的時間內完成所有卡片的匹對,所以我們來寫一個定時函式,并實時等更新顯示當前游戲的剩余時間:
'''計時'''
def tick(self):
if self.num_existing_cards == 0: return
if self.num_seconds != 0:
self.num_seconds -= 1
self.time['text'] = f'Time Left: {self.num_seconds}'
self.time.after(1000, self.tick)
else:
is_restart = messagebox.askyesno('Game Over', 'You fail since time up, do you want to play again?')
if is_restart: self.restart()
else: self.root.destroy()
最后,我們在滑鼠左鍵點擊卡片時,用代碼定義一下游戲的回應規則,以實作我們想要的功能:
'''點擊回呼函式'''
def clickcallback(self, event):
card = event.widget
if card.show: return
# 之前沒有卡片被翻開
if len(self.shown_cards) == 0:
self.shown_cards.append(card)
image = ImageTk.PhotoImage(Image.open(os.path.join(self.card_dir, card.file+'.png')))
card.configure(image=image)
card.show_image = image
card.show = True
# 之前只有一張卡片被翻開
elif len(self.shown_cards) == 1:
# --之前翻開的卡片和現在的卡片一樣
if self.shown_cards[0].file == card.file:
def delaycallback():
self.shown_cards[0].configure(image=self.blank_image)
self.shown_cards[0].blank_image = self.blank_image
card.configure(image=self.blank_image)
card.blank_image = self.blank_image
self.shown_cards.pop(0)
self.score_sound.play()
self.num_existing_cards -= 2
image = ImageTk.PhotoImage(Image.open(os.path.join(self.card_dir, card.file+'.png')))
card.configure(image=image)
card.show_image = image
card.show = True
card.after(300, delaycallback)
# --之前翻開的卡片和現在的卡片不一樣
else:
self.shown_cards.append(card)
image = ImageTk.PhotoImage(Image.open(os.path.join(self.card_dir, card.file+'.png')))
card.configure(image=image)
card.show_image = image
card.show = True
# 之前有兩張卡片被翻開
elif len(self.shown_cards) == 2:
# --之前翻開的第一張卡片和現在的卡片一樣
if self.shown_cards[0].file == card.file:
def delaycallback():
self.shown_cards[0].configure(image=self.blank_image)
self.shown_cards[0].blank_image = self.blank_image
card.configure(image=self.blank_image)
card.blank_image = self.blank_image
self.shown_cards.pop(0)
self.score_sound.play()
self.num_existing_cards -= 2
image = ImageTk.PhotoImage(Image.open(os.path.join(self.card_dir, card.file+'.png')))
card.configure(image=image)
card.show_image = image
card.show = True
card.after(300, delaycallback)
# --之前翻開的第二張卡片和現在的卡片一樣
elif self.shown_cards[1].file == card.file:
def delaycallback():
self.shown_cards[1].configure(image=self.blank_image)
self.shown_cards[1].blank_image = self.blank_image
card.configure(image=self.blank_image)
card.blank_image = self.blank_image
self.shown_cards.pop(1)
self.score_sound.play()
self.num_existing_cards -= 2
image = ImageTk.PhotoImage(Image.open(os.path.join(self.card_dir, card.file+'.png')))
card.configure(image=image)
card.show_image = image
card.show = True
card.after(300, delaycallback)
# --之前翻開的卡片和現在的卡片都不一樣
else:
self.shown_cards.append(card)
self.shown_cards[0].configure(image=self.cards_back_image)
self.shown_cards[0].show = False
self.shown_cards.pop(0)
image = ImageTk.PhotoImage(Image.open(os.path.join(self.card_dir, card.file+'.png')))
self.shown_cards[-1].configure(image=image)
self.shown_cards[-1].show_image = image
self.shown_cards[-1].show = True
# 判斷游戲是否已經勝利
if self.num_existing_cards == 0:
is_restart = messagebox.askyesno('Game Over', 'Congratulations, you win, do you want to play again?')
if is_restart: self.restart()
else: self.root.destroy()
ok,大功告成,代碼邏輯比較簡單,就不展開講啦,小伙伴們簡單看下,肯定就能看懂啦,
完整源代碼詳見相關檔案~
文章到這里就結束了,感謝你的觀看,Python27個小游戲系列,下篇文章分享魔塔小游戲呀(1)
為了感謝讀者們,我想把我最近收藏的一些編程干貨分享給大家,回饋每一個讀者,希望能幫到你們,
完整源代碼私信獲取相關檔案~
往期回看
Python實作炸彈人小游戲
Python實作經典吃豆豆小游戲
Python實恐龍跳一跳小游戲現
Python實作簡易版飛機大戰小游戲
Python實作俄羅斯方塊小游戲
Python實作外星人入侵小游戲
Python實作“小兔子和Bun”游戲
Python實作經典90坦克大戰
Python實作塔防小游戲
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/333512.html
標籤:其他
