消消樂(lè)的構(gòu)成主要包括三部分:游戲主體、計(jì)分器、計(jì)時(shí)器,下面來(lái)看一下具體實(shí)現(xiàn)。
先來(lái)看一下游戲所需 Python 庫(kù)。
import?os import?sys import?time import?pygame import?random
定義一些常量,比如:窗口寬高、網(wǎng)格行列數(shù)等,代碼如下:
WIDTH?=?400 HEIGHT?=?400 NUMGRID?=?8 GRIDSIZE?=?36 XMARGIN?=?(WIDTH?-?GRIDSIZE?*?NUMGRID)?//?2 YMARGIN?=?(HEIGHT?-?GRIDSIZE?*?NUMGRID)?//?2 ROOTDIR?=?os.getcwd() FPS?=?30
接著創(chuàng)建一個(gè)主窗口,代碼如下:
pygame.init() screen?=?pygame.display.set_mode((WIDTH,?HEIGHT)) pygame.display.set_caption('消消樂(lè)')
看一下效果:
再接著在窗口中畫(huà)一個(gè) 8 x 8 的網(wǎng)格,代碼如下:
screen.fill((255,?255,?220)) #?游戲界面的網(wǎng)格繪制 def?drawGrids(self): for?x?in?range(NUMGRID): for?y?in?range(NUMGRID): rect?=?pygame.Rect((XMARGIN+x*GRIDSIZE,?YMARGIN+y*GRIDSIZE,?GRIDSIZE,?GRIDSIZE)) self.drawBlock(rect,?color=(255,?165,?0),?size=1 #?畫(huà)矩形?block?框 def?drawBlock(self,?block,?color=(255,?0,?0),?size=2): pygame.draw.rect(self.screen,?color,?block,?size)
看一下效果:
再接著在網(wǎng)格中隨機(jī)放入各種拼圖塊,代碼如下:
while?True: self.all_gems?=?[] self.gems_group?=?pygame.sprite.Group() for?x?in?range(NUMGRID): self.all_gems.append([]) for?y?in?range(NUMGRID): gem?=?Puzzle(img_path=random.choice(self.gem_imgs),?size=(GRIDSIZE,?GRIDSIZE),?position=[XMARGIN+x*GRIDSIZE,?YMARGIN+y*GRIDSIZE-NUMGRID*GRIDSIZE],?downlen=NUMGRID*GRIDSIZE) self.all_gems[x].append(gem) self.gems_group.add(gem) if?self.isMatch()[0]?==?0: break
看一下效果:
再接著加入計(jì)分器和計(jì)時(shí)器,代碼如下:
#?顯示得分 def?drawScore(self): score_render?=?self.font.render('分?jǐn)?shù):'+str(self.score),?1,?(85,?65,?0)) rect?=?score_render.get_rect() rect.left,?rect.top?=?(55,?15) self.screen.blit(score_render,?rect) #?顯示加分 def?drawAddScore(self,?add_score): score_render?=?self.font.render('+'+str(add_score),?1,?(255,?100,?100)) rect?=?score_render.get_rect() rect.left,?rect.top?=?(250,?250) self.screen.blit(score_render,?rect) #?顯示剩余時(shí)間 def?showRemainingTime(self): remaining_time_render?=?self.font.render('倒計(jì)時(shí):?%ss'?%?str(self.remaining_time),?1,?(85,?65,?0)) rect?=?remaining_time_render.get_rect() rect.left,?rect.top?=?(WIDTH-190,?15) self.screen.blit(remaining_time_render,?rect)
看一下效果:
當(dāng)設(shè)置的游戲時(shí)間用盡時(shí),我們可以生成一些提示信息,代碼如下:
while?True: for?event?in?pygame.event.get(): if?event.type?==?pygame.QUIT: pygame.quit() sys.exit() if?event.type?==?pygame.KEYUP?and?event.key?==?pygame.K_r: flag?=?True if?flag: break screen.fill((255,?255,?220)) text0?=?'最終得分:?%s'?%?score text1?=?'按?R?鍵重新開(kāi)始' y?=?140 for?idx,?text?in?enumerate([text0,?text1]): text_render?=?font.render(text,?1,?(85,?65,?0)) rect?=?text_render.get_rect() if?idx?==?0: rect.left,?rect.top?=?(100,?y) elif?idx?==?1: rect.left,?rect.top?=?(100,?y) y?+=?60 screen.blit(text_render,?rect) pygame.display.update()
看一下效果:
說(shuō)完了游戲圖形化界面相關(guān)的部分,我們?cè)倏匆幌掠螒虻闹饕幚磉壿嫛?/p>
我們通過(guò)鼠標(biāo)來(lái)操縱拼圖塊,因此程序需要檢查有無(wú)拼圖塊被選中,代碼實(shí)現(xiàn)如下:
def?checkSelected(self,?position): for?x?in?range(NUMGRID): for?y?in?range(NUMGRID): if?self.getGemByPos(x,?y).rect.collidepoint(*position): return?[x,?y] return?None
我們需要將鼠標(biāo)連續(xù)選擇的拼圖塊進(jìn)行位置交換,代碼實(shí)現(xiàn)如下:
def?swapGem(self,?gem1_pos,?gem2_pos): margin?=?gem1_pos[0]?-?gem2_pos[0]?+?gem1_pos[1]?-?gem2_pos[1] if?abs(margin)?!=?1: return?False gem1?=?self.getGemByPos(*gem1_pos) gem2?=?self.getGemByPos(*gem2_pos) if?gem1_pos[0]?-?gem2_pos[0]?==?1: gem1.direction?=?'left' gem2.direction?=?'right' elif?gem1_pos[0]?-?gem2_pos[0]?==?-1: gem2.direction?=?'left' gem1.direction?=?'right' elif?gem1_pos[1]?-?gem2_pos[1]?==?1: gem1.direction?=?'up' gem2.direction?=?'down' elif?gem1_pos[1]?-?gem2_pos[1]?==?-1: gem2.direction?=?'up' gem1.direction?=?'down' gem1.target_x?=?gem2.rect.left gem1.target_y?=?gem2.rect.top gem1.fixed?=?False gem2.target_x?=?gem1.rect.left gem2.target_y?=?gem1.rect.top gem2.fixed?=?False self.all_gems[gem2_pos[0]][gem2_pos[1]]?=?gem1 self.all_gems[gem1_pos[0]][gem1_pos[1]]?=?gem2 return?True
每一次交換拼圖塊時(shí),我們需要判斷是否有連續(xù)一樣的三個(gè)及以上拼圖塊,代碼實(shí)現(xiàn)如下:
def?isMatch(self): for?x?in?range(NUMGRID): for?y?in?range(NUMGRID): if?x?+?2?當(dāng)出現(xiàn)三個(gè)及以上拼圖塊時(shí),需要將這些拼圖塊消除,代碼實(shí)現(xiàn)如下:
def?removeMatched(self,?res_match): if?res_match[0]?>?0: self.generateNewGems(res_match) self.score?+=?self.reward return?self.reward return?0將匹配的拼圖塊消除之后,我們還需要隨機(jī)生成新的拼圖塊,代碼實(shí)現(xiàn)如下:
def?generateNewGems(self,?res_match): if?res_match[0]?==?1: start?=?res_match[2] while?start?>?-2: for?each?in?[res_match[1],?res_match[1]+1,?res_match[1]+2]: gem?=?self.getGemByPos(*[each,?start]) if?start?==?res_match[2]: self.gems_group.remove(gem) self.all_gems[each][start]?=?None elif?start?>=?0: gem.target_y?+=?GRIDSIZE gem.fixed?=?False gem.direction?=?'down' self.all_gems[each][start+1]?=?gem else: gem?=?Puzzle(img_path=random.choice(self.gem_imgs),?size=(GRIDSIZE,?GRIDSIZE),?position=[XMARGIN+each*GRIDSIZE,?YMARGIN-GRIDSIZE],?downlen=GRIDSIZE) self.gems_group.add(gem) self.all_gems[each][start+1]?=?gem start?-=?1 elif?res_match[0]?==?2: start?=?res_match[2] while?start?>?-4: if?start?==?res_match[2]: for?each?in?range(0,?3): gem?=?self.getGemByPos(*[res_match[1],?start+each]) self.gems_group.remove(gem) self.all_gems[res_match[1]][start+each]?=?None elif?start?>=?0: gem?=?self.getGemByPos(*[res_match[1],?start]) gem.target_y?+=?GRIDSIZE?*?3 gem.fixed?=?False gem.direction?=?'down' self.all_gems[res_match[1]][start+3]?=?gem else: gem?=?Puzzle(img_path=random.choice(self.gem_imgs),?size=(GRIDSIZE,?GRIDSIZE),?position=[XMARGIN+res_match[1]*GRIDSIZE,?YMARGIN+start*GRIDSIZE],?downlen=GRIDSIZE*3) self.gems_group.add(gem) self.all_gems[res_match[1]][start+3]?=?gem start?-=?1之后反復(fù)執(zhí)行這個(gè)過(guò)程,直至耗盡游戲時(shí)間,游戲結(jié)束。
最后,我們動(dòng)態(tài)看一下游戲效果。
總結(jié)本文我們使用 Python 實(shí)現(xiàn)了一個(gè)簡(jiǎn)單的消消樂(lè)游戲,有興趣的可以對(duì)游戲做進(jìn)一步擴(kuò)展,比如增加關(guān)卡等。
到此這篇關(guān)于Python實(shí)現(xiàn)消消樂(lè)小游戲的文章就介紹到這了,希望大家以后多多支持好二三四!