【Python游戏】Python各大游戏合集(5):塔防游戏、飞机大战、连连看、打地鼠、记忆翻牌 | 附带源码
创始人
2024-02-16 03:08:39
0

相关文件

关注小编,私信小编领取哟!
当然别忘了一件三连哟~~

公众号:Python日志
可以关注小编公众号,会不定时的发布一下Python小技巧,还有很多资源可以免费领取哟!!
源码领取:加Python学习交流群:494958217 可以领取哟

开发工具

Python版本:3.7.8
相关模块:
pygame模块;
random模块;
pyttsx3模块;
以及一些python自带的模块。

环境搭建

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

一:塔防游戏

效果展示
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
部分代码展示

def main():pygame.init()pygame.mixer.init()pygame.mixer.music.load(cfg.AUDIOPATHS['bgm'])pygame.mixer.music.play(-1, 0.0)pygame.mixer.music.set_volume(0.25)screen = pygame.display.set_mode(cfg.SCREENSIZE)pygame.display.set_caption("塔防游戏 ")# 调用游戏开始界面start_interface = StartInterface(cfg)is_play = start_interface.update(screen)if not is_play:return# 调用游戏界面while True:choice_interface = ChoiceInterface(cfg)map_choice, difficulty_choice = choice_interface.update(screen)game_interface = GamingInterface(cfg)game_interface.start(screen, map_path=cfg.MAPPATHS[str(map_choice)], difficulty_path=cfg.DIFFICULTYPATHS[str(difficulty_choice)])end_interface = EndInterface(cfg)end_interface.update(screen)
class Enemy(pygame.sprite.Sprite):def __init__(self, enemy_type, cfg):assert enemy_type in range(4)pygame.sprite.Sprite.__init__(self)self.enemy_type = enemy_typeself.imagepaths = [cfg.IMAGEPATHS['game']['enemy_yellow'], cfg.IMAGEPATHS['game']['enemy_red'], cfg.IMAGEPATHS['game']['enemy_pink'], cfg.IMAGEPATHS['game']['enemy_blue']]self.image = pygame.image.load(self.imagepaths[enemy_type])self.rect = self.image.get_rect()# 走过的路(避免重复走,保证去攻击城堡)self.reached_path = []# 在道路某个单元中移动的距离, 当cell_move_dis大于单元长度时移动到下一个到了单元并置0该变量self.cell_move_dis = 0# 当前所在的位置self.coord = 3, 2self.position = 60, 40self.rect.left, self.rect.top = self.positionif enemy_type == 0:# 最大生命值self.max_life_value = 20# 当前生命值self.life_value = 20# 速度self.speed = 2# 击杀奖励self.reward = 100# 对大本营造成的伤害self.damage = 1elif enemy_type == 1:self.max_life_value = 40self.life_value = 40self.speed = 1self.reward = 200self.damage = 1elif enemy_type == 2:self.max_life_value = 60self.life_value = 60self.speed = 0.5self.reward = 300self.damage = 2elif enemy_type == 3:self.max_life_value = 100self.life_value = 100self.speed = 0.2self.reward = 500self.damage = 4'''不停地移动'''def move(self, cell_len):is_next_cell = Falseself.cell_move_dis += self.speedif self.cell_move_dis > cell_len:self.cell_move_dis = 0is_next_cell = Truereturn is_next_cell

二:飞机大战

效果展示
在这里插入图片描述在这里插入图片描述
部分代码展示


import sys
import cfg
import pygame
from modules import *'''游戏界面'''
def GamingInterface(num_player, screen):# 初始化pygame.mixer.music.load(cfg.SOUNDPATHS['Cool Space Music'])pygame.mixer.music.set_volume(0.4)pygame.mixer.music.play(-1)explosion_sound = pygame.mixer.Sound(cfg.SOUNDPATHS['boom'])fire_sound = pygame.mixer.Sound(cfg.SOUNDPATHS['shot'])font = pygame.font.Font(cfg.FONTPATH, 20)# 游戏背景图bg_imgs = [cfg.IMAGEPATHS['bg_big'], cfg.IMAGEPATHS['seamless_space'], cfg.IMAGEPATHS['space3']]bg_move_dis = 0bg_1 = pygame.image.load(bg_imgs[0]).convert()bg_2 = pygame.image.load(bg_imgs[1]).convert()bg_3 = pygame.image.load(bg_imgs[2]).convert()# 玩家, 子弹和小行星精灵组player_group = pygame.sprite.Group()bullet_group = pygame.sprite.Group()asteroid_group = pygame.sprite.Group()# 产生小行星的时间间隔asteroid_ticks = 90for i in range(num_player):player_group.add(Ship(i+1, cfg))clock = pygame.time.Clock()# 分数score_1, score_2 = 0, 0# 游戏主循环while True:for event in pygame.event.get():if event.type == pygame.QUIT:pygame.quit()sys.exit()# --玩家一: ↑↓←→控制, j射击; 玩家二: wsad控制, 空格射击pressed_keys = pygame.key.get_pressed()for idx, player in enumerate(player_group):direction = Noneif idx == 0:if pressed_keys[pygame.K_UP]:direction = 'up'elif pressed_keys[pygame.K_DOWN]:direction = 'down'elif pressed_keys[pygame.K_LEFT]:direction = 'left'elif pressed_keys[pygame.K_RIGHT]:direction = 'right'if direction:player.move(direction)if pressed_keys[pygame.K_j]:if player.cooling_time == 0:fire_sound.play()bullet_group.add(player.shot())player.cooling_time = 20elif idx == 1:if pressed_keys[pygame.K_w]:direction = 'up'elif pressed_keys[pygame.K_s]:direction = 'down'elif pressed_keys[pygame.K_a]:direction = 'left'elif pressed_keys[pygame.K_d]:direction = 'right'if direction:player.move(direction)if pressed_keys[pygame.K_SPACE]:if player.cooling_time == 0:fire_sound.play()bullet_group.add(player.shot())player.cooling_time = 20if player.cooling_time > 0:player.cooling_time -= 1if (score_1 + score_2) < 500:background = bg_1elif (score_1 + score_2) < 1500:background = bg_2else:background = bg_3# --向下移动背景图实现飞船向上移动的效果screen.blit(background, (0, -background.get_rect().height + bg_move_dis))screen.blit(background, (0, bg_move_dis))bg_move_dis = (bg_move_dis + 2) % background.get_rect().height# --生成小行星if asteroid_ticks == 0:asteroid_ticks = 90asteroid_group.add(Asteroid(cfg))else:asteroid_ticks -= 1# --画飞船for player in player_group:if pygame.sprite.spritecollide(player, asteroid_group, True, None):player.explode_step = 1explosion_sound.play()elif player.explode_step > 0:if player.explode_step > 3:player_group.remove(player)if len(player_group) == 0:returnelse:player.explode(screen)else:player.draw(screen)# --画子弹for bullet in bullet_group:bullet.move()if pygame.sprite.spritecollide(bullet, asteroid_group, True, None):bullet_group.remove(bullet)if bullet.player_idx == 1:score_1 += 1else:score_2 += 1else:bullet.draw(screen)# --画小行星for asteroid in asteroid_group:asteroid.move()asteroid.rotate()asteroid.draw(screen)# --显示分数score_1_text = '玩家一得分: %s' % score_1score_2_text = '玩家二得分: %s' % score_2text_1 = font.render(score_1_text, True, (0, 0, 255))text_2 = font.render(score_2_text, True, (255, 0, 0))screen.blit(text_1, (2, 5))screen.blit(text_2, (2, 35))# --屏幕刷新pygame.display.update()clock.tick(60)'''主函数'''
def main():pygame.init()pygame.font.init()pygame.mixer.init()screen = pygame.display.set_mode(cfg.SCREENSIZE)pygame.display.set_caption('飞机大战 ')num_player = StartInterface(screen, cfg)if num_player == 1:while True:GamingInterface(num_player=1, screen=screen)EndInterface(screen, cfg)else:while True:GamingInterface(num_player=2, screen=screen)EndInterface(screen, cfg)'''run'''
if __name__ == '__main__':main()

三:连连看

效果展示
在这里插入图片描述
部分代码展示


import os
import sys
import cfg
import pygame
from modules import *'''游戏主程序'''
def main():pygame.init()screen = pygame.display.set_mode(cfg.SCREENSIZE)pygame.display.set_caption('消灭星星——资料源码领取QQ群:494958217')# 加载背景音乐pygame.mixer.init()pygame.mixer.music.load(os.path.join(cfg.ROOTDIR, "resources/audios/bg.mp3"))pygame.mixer.music.set_volume(0.6)pygame.mixer.music.play(-1)# 加载音效sounds = {}sounds['mismatch'] = pygame.mixer.Sound(os.path.join(cfg.ROOTDIR, 'resources/audios/badswap.wav'))sounds['match'] = []for i in range(6):sounds['match'].append(pygame.mixer.Sound(os.path.join(cfg.ROOTDIR, 'resources/audios/match%s.wav' % i)))# 加载字体font = pygame.font.Font(os.path.join(cfg.ROOTDIR, 'resources/font/font.TTF'), 25)# 图片加载gem_imgs = []for i in range(1, 8):gem_imgs.append(os.path.join(cfg.ROOTDIR, 'resources/images/gem%s.png' % i))# 主循环game = gemGame(screen, sounds, font, gem_imgs, cfg)while True:score = game.start()flag = False# 一轮游戏结束后玩家选择重玩或者退出while True:for event in pygame.event.get():if event.type == pygame.QUIT or (event.type == pygame.KEYUP and event.key == pygame.K_ESCAPE):pygame.quit()sys.exit()elif event.type == pygame.KEYUP and event.key == pygame.K_r:flag = Trueif flag:breakscreen.fill((135, 206, 235))text0 = 'Final score: %s' % scoretext1 = 'Press  to restart the game.'text2 = 'Press  to quit the game.'y = 150for idx, text in enumerate([text0, text1, text2]):text_render = font.render(text, 1, (85, 65, 0))rect = text_render.get_rect()if idx == 0:rect.left, rect.top = (212, y)elif idx == 1:rect.left, rect.top = (122.5, y)else:rect.left, rect.top = (126.5, y)y += 100screen.blit(text_render, rect)pygame.display.update()game.reset()'''run'''
if __name__ == '__main__':main()

四:打地鼠

效果展示
在这里插入图片描述
在这里插入图片描述
部分代码展示


import cfg
import sys
import pygame
import random
from modules import *'''游戏初始化'''
def initGame():pygame.init()pygame.mixer.init()screen = pygame.display.set_mode(cfg.SCREENSIZE)pygame.display.set_caption('打地鼠 源码+课件+学习解答加QQ群:494958217')return screen'''主函数'''   
def main():# 初始化screen = initGame()# 加载背景音乐和其他音效pygame.mixer.music.load(cfg.BGM_PATH)pygame.mixer.music.play(-1)audios = {'count_down': pygame.mixer.Sound(cfg.COUNT_DOWN_SOUND_PATH),'hammering': pygame.mixer.Sound(cfg.HAMMERING_SOUND_PATH)}# 加载字体font = pygame.font.Font(cfg.FONT_PATH, 40)# 加载背景图片bg_img = pygame.image.load(cfg.GAME_BG_IMAGEPATH)# 开始界面startInterface(screen, cfg.GAME_BEGIN_IMAGEPATHS)# 地鼠改变位置的计时hole_pos = random.choice(cfg.HOLE_POSITIONS)change_hole_event = pygame.USEREVENTpygame.time.set_timer(change_hole_event, 800)# 地鼠mole = Mole(cfg.MOLE_IMAGEPATHS, hole_pos)# 锤子hammer = Hammer(cfg.HAMMER_IMAGEPATHS, (500, 250))# 时钟clock = pygame.time.Clock()# 分数your_score = 0flag = False# 初始时间init_time = pygame.time.get_ticks()# 游戏主循环while True:# --游戏时间为60stime_remain = round((61000 - (pygame.time.get_ticks() - init_time)) / 1000.)# --游戏时间减少, 地鼠变位置速度变快if time_remain == 40 and not flag:hole_pos = random.choice(cfg.HOLE_POSITIONS)mole.reset()mole.setPosition(hole_pos)pygame.time.set_timer(change_hole_event, 650)flag = Trueelif time_remain == 20 and flag:hole_pos = random.choice(cfg.HOLE_POSITIONS)mole.reset()mole.setPosition(hole_pos)pygame.time.set_timer(change_hole_event, 500)flag = False# --倒计时音效if time_remain == 10:audios['count_down'].play()# --游戏结束if time_remain < 0: breakcount_down_text = font.render('Time: '+str(time_remain), True, cfg.WHITE)# --按键检测for event in pygame.event.get():if event.type == pygame.QUIT:pygame.quit()sys.exit()elif event.type == pygame.MOUSEMOTION:hammer.setPosition(pygame.mouse.get_pos())elif event.type == pygame.MOUSEBUTTONDOWN:if event.button == 1:hammer.setHammering()elif event.type == change_hole_event:hole_pos = random.choice(cfg.HOLE_POSITIONS)mole.reset()mole.setPosition(hole_pos)# --碰撞检测if hammer.is_hammering and not mole.is_hammer:is_hammer = pygame.sprite.collide_mask(hammer, mole)if is_hammer:audios['hammering'].play()mole.setBeHammered()your_score += 10# --分数your_score_text = font.render('Score: '+str(your_score), True, cfg.BROWN)# --绑定必要的游戏元素到屏幕(注意顺序)screen.blit(bg_img, (0, 0))screen.blit(count_down_text, (875, 8))screen.blit(your_score_text, (800, 430))mole.draw(screen)hammer.draw(screen)# --更新pygame.display.flip()clock.tick(60)# 读取最佳分数(try块避免第一次游戏无.rec文件)try:best_score = int(open(cfg.RECORD_PATH).read())except:best_score = 0# 若当前分数大于最佳分数则更新最佳分数if your_score > best_score:f = open(cfg.RECORD_PATH, 'w')f.write(str(your_score))f.close()# 结束界面score_info = {'your_score': your_score, 'best_score': best_score}is_restart = endInterface(screen, cfg.GAME_END_IMAGEPATH, cfg.GAME_AGAIN_IMAGEPATHS, score_info, cfg.FONT_PATH, [cfg.WHITE, cfg.RED], cfg.SCREENSIZE)return is_restart'''run'''
if __name__ == '__main__':while True:is_restart = main()if not is_restart:break

五:记忆翻牌

效果展示
在这里插入图片描述
在这里插入图片描述
部分代码展示


import os
import cfg
import pygame
import random
from tkinter import *
from tkinter import messagebox
from PIL import Image, ImageTk'''记忆翻牌小游戏'''
class FlipCardByMemory():def __init__(self):# 播放背景音乐self.playbgm()# 载入得分后响起的音乐self.score_sound = pygame.mixer.Sound(cfg.AUDIOPATHS['score'])self.score_sound.set_volume(1)# 卡片图片路径self.card_dir = random.choice(cfg.IMAGEPATHS['carddirs'])# 主界面句柄self.root = Tk()self.root.wm_title('记忆翻牌小游戏 源码+课件+学习解答加QQ群:494958217')# 游戏界面中的卡片字典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_imageself.game_matrix[position].file = str(cards_list[r * 4 + c])self.game_matrix[position].show = Falseself.game_matrix[position].bind('', self.clickcallback)self.game_matrix[position].grid(row=r, column=c)# 已经显示正面的卡片self.shown_cards = []# 场上存在的卡片数量self.num_existing_cards = len(cards_list)# 显示游戏剩余时间self.num_seconds = 30self.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()) / 2y = (self.root.winfo_screenheight() - self.root.winfo_reqheight()) / 2self.root.geometry('+%d+%d' % (x, y))self.root.deiconify()# 计时self.tick()# 显示主界面self.root.mainloop()'''点击回调函数'''def clickcallback(self, event):card = event.widgetif 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 = imagecard.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_imagecard.configure(image=self.blank_image)card.blank_image = self.blank_imageself.shown_cards.pop(0)self.score_sound.play()self.num_existing_cards -= 2image = ImageTk.PhotoImage(Image.open(os.path.join(self.card_dir, card.file+'.png')))card.configure(image=image)card.show_image = imagecard.show = Truecard.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 = imagecard.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_imagecard.configure(image=self.blank_image)card.blank_image = self.blank_imageself.shown_cards.pop(0)self.score_sound.play()self.num_existing_cards -= 2image = ImageTk.PhotoImage(Image.open(os.path.join(self.card_dir, card.file+'.png')))card.configure(image=image)card.show_image = imagecard.show = Truecard.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_imagecard.configure(image=self.blank_image)card.blank_image = self.blank_imageself.shown_cards.pop(1)self.score_sound.play()self.num_existing_cards -= 2image = ImageTk.PhotoImage(Image.open(os.path.join(self.card_dir, card.file+'.png')))card.configure(image=image)card.show_image = imagecard.show = Truecard.after(300, delaycallback)# --之前翻开的卡片和现在的卡片都不一样else:self.shown_cards.append(card)self.shown_cards[0].configure(image=self.cards_back_image)self.shown_cards[0].show = Falseself.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 = imageself.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()'''播放背景音乐'''def playbgm(self):pygame.init()pygame.mixer.init()pygame.mixer.music.load(cfg.AUDIOPATHS['bgm'])pygame.mixer.music.play(-1, 0.0)'''计时'''def tick(self):if self.num_existing_cards == 0: returnif self.num_seconds != 0:self.num_seconds -= 1self.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 restart(self):self.root.destroy()client = FlipCardByMemory()'''run'''
if __name__ == '__main__':client = FlipCardByMemory()

总结

上面都是部分源码展示,如果想要具体游戏源码的小伙伴可以直接看相关文件
或者直接 加Python学习交流群:494958217 可以领取哟

相关内容

热门资讯

修订食安法:首次确立重点液态食... 12月23日,市场监管总局副局长柳军在食品安全专题新闻发布会上介绍,总局推动《中华人民共和国食品安全...
七成涉重疾险理赔诉讼请求获判决... “涉重疾险纠纷案件数量较2021年上涨38.71%”“案件平均审理时长由2021年的217天下降为2...
建工修复近12个月累计诉讼金额... 12月23日,建工修复(300958)发布公告,截止至本公告披露日前的连续十二个月内,公司及合并报表...
海南产经新观察:为“向数图强”... 中新网海口12月23日电 (黄方舟)已经启动全岛封关的海南自贸港,正致力推动公共数据资源开发利用,加...
幼儿园收费划出“制度红线”,严... 大象新闻2025-12-23 17:12:18 2026年1月1日起,幼儿园收费实行目录清单管理,建...
快手就遭到黑灰产攻击谴责违法犯... 针对快手平台上出现违规内容的异常情况,12月23日,南都N视频记者从快手科技方面获悉,公司快手应用的...
调解故事 | 高效化解装修纠纷... 近日,延吉市房地产纠纷人民调解委员会成功调解了一起合同纠纷,切实维护了当事人合法权益。 今年5月,...
宁波女婴医疗纠纷进入司法程序 ... 央广网宁波12月23日消息(记者陈金莲 俞烨)12月23日,记者从宁波市海曙区人民法院了解到,该院已...
被举报打赏网红600余万,国企... 张女士系中国某工程咨询集团有限公司职员,其名下实名手机号注册的抖音账号“xx阳光”在不到两年的时间里...
涉房屋租赁合同纠纷案情:不适租... 租赁企业提供的房屋不适租,承租方有权单方解除合同并主张违约责任。 12月23日,北京第三中级人民法院...