基于Python制作的记忆翻牌小游戏

基于 Python 制作的记忆翻牌小游戏 导语 昨天看到有留言竟然说我是月更博主,我明明更新地这么勤快(心虚,jpg),看吧,昨天刚更新过,今天又来更新了

本文包含相关资料包-----> 点击直达获取<-------

基于 Python 制作的记忆翻牌小游戏

导语

昨天看到有留言竟然说我是月更博主,我明明更新地这么勤快(心虚.jpg)。看吧,昨天刚更新过,今天又来更新了。今天还是带大家写个小游戏吧,不过老是用 pygame 也没啥意思,这次我们换点新花样,用 python 自带的 tkinter 包写一个记忆翻牌小游戏呗。

废话不多说,让我们愉快地开始吧~

开发工具

Python 版本: 3.7.4

相关模块:

pygame 模块;

tkinter 模块;

pillow 模块;

以及一些 python 自带的模块。

环境搭建

安装 Python 并添加到环境变量,pip 安装需要的相关模块即可。

先睹为快

在终端运行如下命令即可:

python Game27.py

效果如下:

原理简介

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 —— Charles的皮卡丘') ```

并在主界面上显示 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(' ', 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() ```

最后,我们在鼠标左键点击卡片时,用代码定义一下游戏的响应规则,以实现我们想要的功能:

python '''点击回调函数''' 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,大功告成。代码逻辑比较简单,就不展开讲啦,小伙伴们简单看下,肯定就能看懂啦。

完整源代码详见相关文件~

参考文献

  • 豆玩手机游戏平台的设计与实现(吉林大学·李天明)
  • 网络游戏虚拟物品交易系统设计与实现(吉林大学·李云峰)
  • 基于B/S架构的酷跑社区系统的设计与实现(内蒙古大学·张晓乐)
  • 网络游戏虚拟物品交易系统设计与实现(吉林大学·李云峰)
  • 基于轻量级J2EE的网络游戏虚拟物品交易系统的设计与实现(北京邮电大学·曹鹃)
  • 商务活动开发平台的设计与实现(华中科技大学·罗洋)
  • 成语电子词典系统的设计与实现(电子科技大学·刘健)
  • 基于Web的竞赛软件的设计与实现(河北科技大学·马丽红)
  • 教育类游戏《成语天地》的设计与开发(华中师范大学·龙艳)
  • 基于web的旅游服务平台的设计与实现(内蒙古大学·张凡)
  • 面向人物简介的主题爬虫设计与实现(吉林大学·蒋超)
  • 教育类游戏《成语天地》的设计与开发(华中师范大学·龙艳)
  • 基于B/S架构的酷跑社区系统的设计与实现(内蒙古大学·张晓乐)
  • 基于Web的竞赛软件的设计与实现(河北科技大学·马丽红)
  • 基于SSH架构的个人空间交友网站的设计与实现(北京邮电大学·隋昕航)

本文内容包括但不限于文字、数据、图表及超链接等)均来源于该信息及资料的相关主题。发布者:源码客栈 ,原文地址:https://bishedaima.com/yuanma/36069.html

相关推荐

发表回复

登录后才能评论