0 項(xiàng)目簡(jiǎn)介
?? Hi,各位同學(xué)好呀,這里是L學(xué)長(zhǎng)!
??今天向大家分享一個(gè)今年(2022)最新完成的畢業(yè)設(shè)計(jì)項(xiàng)目作品
python小游戲畢設(shè) 走迷宮小游戲設(shè)計(jì)與實(shí)現(xiàn) (源碼)
?? 學(xué)長(zhǎng)根據(jù)實(shí)現(xiàn)的難度和等級(jí)對(duì)項(xiàng)目進(jìn)行評(píng)分(最低0分,滿分5分)
-
難度系數(shù):3分
-
工作量:3分
-
創(chuàng)新點(diǎn):4分
-
項(xiàng)目獲取:https://gitee.com/sinonfin/system-sharing
1 課題背景
人類建造迷宮已有5000年的歷史。在世界的不同文化發(fā)展時(shí)期,這些奇特的建筑物始終吸引人們沿著彎彎曲曲、困難重重的小路吃力地行走,尋找真相。迷宮類小游戲應(yīng)運(yùn)而生。
今天我們用pygame做一個(gè)走迷宮小游戲,游戲規(guī)則如下:
玩家通過↑↓←→鍵控制主角行動(dòng),使主角從出發(fā)點(diǎn)(左上角)繞出迷宮,到達(dá)終點(diǎn)(右下角)即為游戲勝利。
2 實(shí)現(xiàn)效果
3 Pygame介紹
簡(jiǎn)介
Pygame是一系列專門為編寫電子游戲而設(shè)計(jì)的Python模塊(modules)。Pygame在已經(jīng)非常優(yōu)秀的SDL庫的基礎(chǔ)上增加了許多功能。這讓你能夠用Python語言編寫出豐富多彩的游戲程序。
Pygame可移植性高,幾乎能在任何平臺(tái)和操作系統(tǒng)上運(yùn)行。
Pygame已經(jīng)被下載過數(shù)百萬次。
Pygame免費(fèi)開源。它在LGPL許可證(Lesser General Public License,GNU寬通用公共許可證)下發(fā)行。使用Pygame,你可以創(chuàng)造出免費(fèi)開源,可共享,或者商業(yè)化的游戲。詳情請(qǐng)見LGPL許可證。
優(yōu)點(diǎn)
-
能夠輕松使用多核CPU(multi core CPUs) :如今雙核CPU很常用,8核CPU在桌面系統(tǒng)中也很便宜,而利用好多核系統(tǒng),能讓你在你的游戲中實(shí)現(xiàn)更多東西。特定的pygame函數(shù)能夠釋放令人生畏的python GIL(全局解釋器鎖),這幾乎是你用C語言才能做的事。
-
核心函數(shù)用最優(yōu)化的C語言或匯編語言編寫:C語言代碼通常比Python代碼運(yùn)行速度快10-20倍。而匯編語言編寫的代碼(assembly code)比Python甚至快到100多倍。
-
安裝便捷:一般僅需包管理程序或二進(jìn)制系統(tǒng)程序便能安裝。
-
真正地可移植:支持Linux (主要發(fā)行版), Windows (95, 98, ME, 2000, XP, Vista, 64-bit Windows,), Windows CE, BeOS, MacOS, Mac OS X, FreeBSD, NetBSD, OpenBSD, BSD/OS, Solaris, IRIX, and QNX等操作系統(tǒng).也能支持AmigaOS, Dreamcast, Atari, AIX, OSF/Tru64, RISC OS, SymbianOS and OS/2,但是還沒有受到官方認(rèn)可。你也可以在手持設(shè)備,游戲控制臺(tái), One Laptop Per Child (OLPC) computer項(xiàng)目的電腦等設(shè)備中使用pygame.
-
用法簡(jiǎn)單:無論是小孩子還是大人都能學(xué)會(huì)用pygame來制作射擊類游戲。
-
很多Pygame游戲已發(fā)行:其中包括很多游戲大賽入圍作品、非常受歡迎的開源可分享的游戲。
-
由你來控制主循環(huán):由你來調(diào)用pygame的函數(shù),pygame的函數(shù)并不需要調(diào)用你的函數(shù)。當(dāng)你同時(shí)還在使用其他庫來編寫各種各種的程序時(shí),這能夠?yàn)槟闾峁O大的掌控權(quán)。
-
不需要GUI就能使用所有函數(shù):僅在命令行中,你就可以使用pygame的某些函數(shù)來處理圖片,獲取游戲桿輸入,播放音樂……
-
對(duì)bug反應(yīng)迅速:很多bug在被上報(bào)的1小時(shí)內(nèi)就能被我們修復(fù)。雖然有時(shí)候我們確實(shí)會(huì)卡在某一個(gè)bug上很久,但大多數(shù)時(shí)候我們都是很不錯(cuò)的bug修復(fù)者。如今bug的上報(bào)已經(jīng)很少了,因?yàn)樵S多bug早已被我們修復(fù)。
-
代碼量少:pygame并沒有數(shù)以萬計(jì)的也許你永遠(yuǎn)用不到的冗雜代碼。pygame的核心代碼一直保持著簡(jiǎn)潔特點(diǎn),其他附加物諸如GUI庫等,都是在核心代碼之外單獨(dú)設(shè)計(jì)研發(fā)的。
-
模塊化:你可以單獨(dú)使用pygame的某個(gè)模塊。想要換著使用一個(gè)別的聲音處理庫?沒問題。pygame的很多核心模塊支持獨(dú)立初始化與使用。
最小開發(fā)框架
import pygame,sys #sys是python的標(biāo)準(zhǔn)庫,提供Python運(yùn)行時(shí)環(huán)境變量的操控
pygame.init() #內(nèi)部各功能模塊進(jìn)行初始化創(chuàng)建及變量設(shè)置,默認(rèn)調(diào)用
size = width,height = 800,600 #設(shè)置游戲窗口大小,分別是寬度和高度
screen = pygame.display.set_mode(size) #初始化顯示窗口
pygame.display.set_caption("小游戲程序") #設(shè)置顯示窗口的標(biāo)題內(nèi)容,是一個(gè)字符串類型
while True: #無限循環(huán),直到Python運(yùn)行時(shí)退出結(jié)束
for event in pygame.event.get(): #從Pygame的事件隊(duì)列中取出事件,并從隊(duì)列中刪除該事件
if event.type == pygame.QUIT: #獲得事件類型,并逐類響應(yīng)
sys.exit() #用于退出結(jié)束游戲并退出
pygame.display.update() #對(duì)顯示窗口進(jìn)行更新,默認(rèn)窗口全部重繪
代碼執(zhí)行流程
4 具體實(shí)現(xiàn)
4.1 創(chuàng)建迷宮
首先,當(dāng)然是創(chuàng)建迷宮啦,為了方便,這里采用隨機(jī)生成迷宮的方式(人工設(shè)計(jì)真的費(fèi)眼睛,弄到一半不想弄了,有興趣的可以自行嘗試。)。思路其實(shí)很簡(jiǎn)單,就是把游戲界面劃分成多個(gè)cell,類似這樣子:
然后設(shè)計(jì)算法遍歷所有的cell,每個(gè)被遍歷到的cell在某幾個(gè)隨機(jī)的方向上打開一堵墻(就是去掉分割cell的線條)就ok啦~
算法如下:
'''隨機(jī)生成迷宮類'''
class RandomMaze():
def __init__(self, maze_size, block_size, border_size, **kwargs):
self.block_size = block_size
self.border_size = border_size
self.maze_size = maze_size
self.blocks_list = RandomMaze.createMaze(maze_size, block_size, border_size)
self.font = pygame.font.SysFont('Consolas', 15)
'''畫到屏幕上'''
def draw(self, screen):
for row in range(self.maze_size[0]):
for col in range(self.maze_size[1]):
self.blocks_list[row][col].draw(screen)
# 起點(diǎn)和終點(diǎn)標(biāo)志
showText(screen, self.font, 'S', (255, 0, 0), (self.border_size[0]-10, self.border_size[1]))
showText(screen, self.font, 'D', (255, 0, 0), (self.border_size[0]+(self.maze_size[1]-1)*self.block_size, self.border_size[1]+self.maze_size[0]*self.block_size+5))
'''創(chuàng)建迷宮'''
@staticmethod
def createMaze(maze_size, block_size, border_size):
def nextBlock(block_now, blocks_list):
directions = ['top', 'bottom', 'left', 'right']
blocks_around = dict(zip(directions, [None]*4))
block_next = None
count = 0
# 查看上邊block
if block_now.coordinate[1]-1 >= 0:
block_now_top = blocks_list[block_now.coordinate[1]-1][block_now.coordinate[0]]
if not block_now_top.is_visited:
blocks_around['top'] = block_now_top
count += 1
# 查看下邊block
if block_now.coordinate[1]+1 < maze_size[0]:
block_now_bottom = blocks_list[block_now.coordinate[1]+1][block_now.coordinate[0]]
if not block_now_bottom.is_visited:
blocks_around['bottom'] = block_now_bottom
count += 1
# 查看左邊block
if block_now.coordinate[0]-1 >= 0:
block_now_left = blocks_list[block_now.coordinate[1]][block_now.coordinate[0]-1]
if not block_now_left.is_visited:
blocks_around['left'] = block_now_left
count += 1
# 查看右邊block
if block_now.coordinate[0]+1 < maze_size[1]:
block_now_right = blocks_list[block_now.coordinate[1]][block_now.coordinate[0]+1]
if not block_now_right.is_visited:
blocks_around['right'] = block_now_right
count += 1
if count > 0:
while True:
direction = random.choice(directions)
if blocks_around.get(direction):
block_next = blocks_around.get(direction)
if direction == 'top':
block_next.has_walls[1] = False
block_now.has_walls[0] = False
elif direction == 'bottom':
block_next.has_walls[0] = False
block_now.has_walls[1] = False
elif direction == 'left':
block_next.has_walls[3] = False
block_now.has_walls[2] = False
elif direction == 'right':
block_next.has_walls[2] = False
block_now.has_walls[3] = False
break
return block_next
blocks_list = [[Block([col, row], block_size, border_size) for col in range(maze_size[1])] for row in range(maze_size[0])]
block_now = blocks_list[0][0]
records = []
while True:
if block_now:
if not block_now.is_visited:
block_now.is_visited = True
records.append(block_now)
block_now = nextBlock(block_now, blocks_list)
else:
block_now = records.pop()
if len(records) == 0:
break
return blocks_list
4.2 定義角色類
角色類需要根據(jù)用戶的操作進(jìn)行上下左右的移動(dòng),同時(shí),保證移動(dòng)是不能跨越墻的就OK了~具體而言,以下兩點(diǎn):
定義角色
'''定義hero'''
class Hero(pygame.sprite.Sprite):
def __init__(self, imagepath, coordinate, block_size, border_size, **kwargs):
pygame.sprite.Sprite.__init__(self)
self.image = pygame.image.load(imagepath)
self.image = pygame.transform.scale(self.image, (block_size, block_size))
self.rect = self.image.get_rect()
self.rect.left, self.rect.top = coordinate[0] * block_size + border_size[0], coordinate[1] * block_size + border_size[1]
self.coordinate = coordinate
self.block_size = block_size
self.border_size = border_size
移動(dòng)設(shè)置
'''移動(dòng)'''
def move(self, direction, maze):
blocks_list = maze.blocks_list
if direction == 'up':
if blocks_list[self.coordinate[1]][self.coordinate[0]].has_walls[0]:
return False
else:
self.coordinate[1] = self.coordinate[1] - 1
return True
elif direction == 'down':
if blocks_list[self.coordinate[1]][self.coordinate[0]].has_walls[1]:
return False
else:
self.coordinate[1] = self.coordinate[1] + 1
return True
elif direction == 'left':
if blocks_list[self.coordinate[1]][self.coordinate[0]].has_walls[2]:
return False
else:
self.coordinate[0] = self.coordinate[0] - 1
return True
elif direction == 'right':
if blocks_list[self.coordinate[1]][self.coordinate[0]].has_walls[3]:
return False
else:
self.coordinate[0] = self.coordinate[0] + 1
return True
else:
raise ValueError('Unsupport direction <%s> in Hero.move...' % direction)
'''綁定到屏幕'''
def draw(self, screen):
self.rect.left, self.rect.top = self.coordinate[0] * self.block_size + self.border_size[0], self.coordinate[1] * self.block_size + self.border_size[1]
screen.blit(self.image, self.rect)
綁定到屏幕
'''綁定到屏幕'''
def draw(self, screen):
self.rect.left, self.rect.top = self.coordinate[0] * self.block_size + self.border_size[0], self.coordinate[1] * self.block_size + self.border_size[1]
screen.blit(self.image, self.rect)
4.3 界面切換
最后要完成游戲主循環(huán),只要每次載入一個(gè)隨機(jī)生成的迷宮地圖和實(shí)例化一個(gè)主角,不斷進(jìn)行按鍵檢測(cè),并根據(jù)按鍵檢測(cè)的結(jié)果移動(dòng)主角,最后根據(jù)行動(dòng)結(jié)果更新界面數(shù)據(jù)就可以了
若主角到達(dá)了終點(diǎn),則進(jìn)入關(guān)卡切換界面。
具體而言,代碼實(shí)現(xiàn)如下:文章來源:http://www.zghlxwxcb.cn/news/detail-787253.html
'''主函數(shù)'''
def main(cfg):
# 初始化
pygame.init()
pygame.mixer.init()
pygame.font.init()
pygame.mixer.music.load(cfg.BGMPATH)
pygame.mixer.music.play(-1, 0.0)
screen = pygame.display.set_mode(cfg.SCREENSIZE)
pygame.display.set_caption('Maze - 微信公眾號(hào): Charles的皮卡丘')
font = pygame.font.SysFont('Consolas', 15)
# 開始界面
Interface(screen, cfg, 'game_start')
# 記錄關(guān)卡數(shù)
num_levels = 0
# 記錄最少用了多少步通關(guān)
best_scores = 'None'
# 關(guān)卡循環(huán)切換
while True:
num_levels += 1
clock = pygame.time.Clock()
screen = pygame.display.set_mode(cfg.SCREENSIZE)
# --隨機(jī)生成關(guān)卡地圖
maze_now = RandomMaze(cfg.MAZESIZE, cfg.BLOCKSIZE, cfg.BORDERSIZE)
# --生成hero
hero_now = Hero(cfg.HEROPICPATH, [0, 0], cfg.BLOCKSIZE, cfg.BORDERSIZE)
# --統(tǒng)計(jì)步數(shù)
num_steps = 0
# --關(guān)卡內(nèi)主循環(huán)
while True:
dt = clock.tick(cfg.FPS)
screen.fill((255, 255, 255))
is_move = False
# ----↑↓←→控制hero
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit(-1)
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_UP:
is_move = hero_now.move('up', maze_now)
elif event.key == pygame.K_DOWN:
is_move = hero_now.move('down', maze_now)
elif event.key == pygame.K_LEFT:
is_move = hero_now.move('left', maze_now)
elif event.key == pygame.K_RIGHT:
is_move = hero_now.move('right', maze_now)
num_steps += int(is_move)
hero_now.draw(screen)
maze_now.draw(screen)
# ----顯示一些信息
showText(screen, font, 'LEVELDONE: %d' % num_levels, (255, 0, 0), (10, 10))
showText(screen, font, 'BESTSCORE: %s' % best_scores, (255, 0, 0), (210, 10))
showText(screen, font, 'USEDSTEPS: %s' % num_steps, (255, 0, 0), (410, 10))
showText(screen, font, 'S: your starting point D: your destination', (255, 0, 0), (10, 600))
# ----判斷游戲是否勝利
if (hero_now.coordinate[0] == cfg.MAZESIZE[1] - 1) and (hero_now.coordinate[1] == cfg.MAZESIZE[0] - 1):
break
pygame.display.update()
# 更新最優(yōu)成績(jī)
if best_scores == 'None':
best_scores = num_steps
else:
if best_scores > num_steps:
best_scores = num_steps
# 關(guān)卡切換
Interface(screen, cfg, mode='game_switch')
5 最后
項(xiàng)目獲?。?/strong>https://gitee.com/sinonfin/system-sharing文章來源地址http://www.zghlxwxcb.cn/news/detail-787253.html
到了這里,關(guān)于python項(xiàng)目分享 - python走迷宮小游戲的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!