Python和tkinter实现的字母记忆配对游戏
因为这个小游戏用到了tkinter,先简要介绍一下它。tkinter是Python的标准GUI(图形用户界面)库,它提供了一种简单而强大的方式来创建图形界面应用程序。它提供了创建基本图形界面所需的所有工具,同时保持了相对简单的学习曲线。tkinter是Python的内置库,无需额外安装。
messagebox是tkinter中用于创建各种类型的消息对话框的模块,需要注意的是messagebox是tkinter的一个子模块。为了正确使用messagebox,你需要从tkinter中单独导入它。
这个小游戏具有重新开始和难度设置功能。
“游戏”菜单,包含“新游戏”选项,点击它或完成一局游戏后,会自动开始新游戏。
“难度”菜单,难度设置,包含简单、中等和困难三个选项。
简单难度: 4x2 网格,8个方块
中等难度: 4x3 网格,12个方块
困难难度: 4x4 网格,16个方块
运行界面:
现在Python和tkinter实现字母记忆配对游戏源码,先看使用面向过程风格的版本源码:
import tkinter as tk
import tkinter.messagebox
import random
def setup_menu(root, difficulty, new_game_func):
"""设置游戏菜单"""
menubar = tk.Menu(root)
root.config(menu=menubar)
# 创建"游戏"菜单
game_menu = tk.Menu(menubar, tearoff=0)
menubar.add_cascade(label="游戏", menu=game_menu)
game_menu.add_command(label="新游戏", command=new_game_func)
# 创建"难度"菜单
difficulty_menu = tk.Menu(menubar, tearoff=0)
menubar.add_cascade(label="难度", menu=difficulty_menu)
difficulty_menu.add_radiobutton(label="简单", variable=difficulty, value="简单", command=new_game_func)
difficulty_menu.add_radiobutton(label="中等", variable=difficulty, value="中等", command=new_game_func)
difficulty_menu.add_radiobutton(label="困难", variable=difficulty, value="困难", command=new_game_func)
def create_button(frame, row, col, on_click_func):
"""创建游戏按钮"""
button = tk.Button(frame, text='', width=10, height=5,
command=lambda: on_click_func(row, col))
button.grid(row=row, column=col, padx=5, pady=5)
return button
def new_game():
"""开始新游戏"""
global matches_found, first_click, buttons, symbols
matches_found = 0
first_click = None
# 清除旧的游戏布局
for widget in frame.winfo_children():
widget.destroy()
buttons = []
# 根据难度设置游戏布局和符号
if difficulty.get() == "简单":
rows, cols = 4, 2
symbols = ['A', 'B', 'C', 'D'] * 2
elif difficulty.get() == "中等":
rows, cols = 4, 3
symbols = ['A', 'B', 'C', 'D', 'E', 'F'] * 2
else: # 困难
rows, cols = 4, 4
symbols = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H'] * 2
random.shuffle(symbols)
# 创建游戏按钮
for i in range(rows):
for j in range(cols):
button = create_button(frame, i, j, on_click)
buttons.append(button)
def on_click(row, col):
"""处理按钮点击事件"""
global first_click, matches_found
index = row * len(frame.grid_slaves()) // 4 + col
button = buttons[index]
if button['text'] == '':
button['text'] = symbols[index]
if first_click is None:
first_click = (index, button)
else:
if symbols[index] == first_click[1]['text']:
matches_found += 1
if matches_found == len(symbols) // 2:
tk.messagebox.showinfo("恭喜", "你赢了!")
new_game()
else:
# 如果不匹配,0.5秒后隐藏按钮
root.after(500, hide_buttons, index, first_click[0])
first_click = None
def hide_buttons(index1, index2):
"""隐藏不匹配的按钮"""
buttons[index1]['text'] = ''
buttons[index2]['text'] = ''
# 主程序
root = tk.Tk()
root.title("字母记忆配对游戏")
root.geometry("400x450") # 设置窗口的宽度为400像素,高度为450像素
difficulty = tk.StringVar()
difficulty.set("简单") # 默认难度为简单
frame = tk.Frame(root)
frame.pack()
setup_menu(root, difficulty, new_game)
# 初始化游戏变量
matches_found = 0
first_click = None
buttons = []
symbols = []
new_game() # 开始第一局游戏
root.mainloop() # 启动主事件循环
上面是使用面向过程风格的版本,下面改写为使用面向对象风格的版本,源码如下:
import tkinter as tk
import tkinter.messagebox
import random
class MemoryGame:
def __init__(self, master):
self.master = master
self.master.title("字母记忆配对游戏")
self.master.geometry("400x450") #设置了窗体的宽度为400像素,高度为450像素
self.buttons = []
self.first_click = None
self.matches_found = 0
self.difficulty = tk.StringVar()
self.difficulty.set("简单")
self.setup_menu()
self.setup_game()
def setup_menu(self):
menubar = tk.Menu(self.master)
self.master.config(menu=menubar)
game_menu = tk.Menu(menubar, tearoff=0)
menubar.add_cascade(label="游戏", menu=game_menu)
game_menu.add_command(label="新游戏", command=self.new_game)
difficulty_menu = tk.Menu(menubar, tearoff=0)
menubar.add_cascade(label="难度", menu=difficulty_menu)
difficulty_menu.add_radiobutton(label="简单", variable=self.difficulty, value="简单", command=self.new_game)
difficulty_menu.add_radiobutton(label="中等", variable=self.difficulty, value="中等", command=self.new_game)
difficulty_menu.add_radiobutton(label="困难", variable=self.difficulty, value="困难", command=self.new_game)
def setup_game(self):
self.frame = tk.Frame(self.master)
self.frame.pack()
self.new_game()
def new_game(self):
self.matches_found = 0
self.first_click = None
for widget in self.frame.winfo_children():
widget.destroy()
self.buttons = []
if self.difficulty.get() == "简单":
rows, cols = 4, 2
symbols = ['A', 'B', 'C', 'D'] * 2
elif self.difficulty.get() == "中等":
rows, cols = 4, 3
symbols = ['A', 'B', 'C', 'D', 'E', 'F'] * 2
else: # 困难
rows, cols = 4, 4
symbols = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H'] * 2
random.shuffle(symbols)
for i in range(rows):
for j in range(cols):
button = tk.Button(self.frame, text='', width=10, height=5,
command=lambda x=i, y=j: self.on_click(x, y))
button.grid(row=i, column=j, padx=5, pady=5)
self.buttons.append(button)
self.symbols = symbols
def on_click(self, row, col):
index = row * len(self.frame.grid_slaves()) // 4 + col
button = self.buttons[index]
if button['text'] == '':
button['text'] = self.symbols[index]
if self.first_click is None:
self.first_click = (index, button)
else:
if self.symbols[index] == self.first_click[1]['text']:
self.matches_found += 1
if self.matches_found == len(self.symbols) // 2:
tk.messagebox.showinfo("恭喜", "你赢了!")
self.new_game()
else:
# 如果不匹配,0.5秒后隐藏按钮
self.master.after(500, self.hide_buttons, index, self.first_click[0])
self.first_click = None
def hide_buttons(self, index1, index2):
self.buttons[index1]['text'] = ''
self.buttons[index2]['text'] = ''
root = tk.Tk()
game = MemoryGame(root)
root.mainloop()