更多精彩內(nèi)容,歡迎關(guān)注:

視頻號(hào)
視頻號(hào)

抖音
抖音

快手
快手

微博
微博

Python實(shí)現(xiàn)消消樂(lè)小游戲

導(dǎo)讀提到開(kāi)心消消樂(lè)這款小游戲,相信大家都不陌生,其曾在2015年獲得過(guò)玩家最喜愛(ài)的移動(dòng)單機(jī)游戲獎(jiǎng),受歡迎程度可見(jiàn)一斑,本文我們使用Python來(lái)做個(gè)簡(jiǎn)單的消消樂(lè)小游戲。
實(shí)現(xiàn)

消消樂(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è)小游戲的文章就介紹到這了,希望大家以后多多支持好二三四!

為你推薦
資訊專欄
熱門視頻
相關(guān)推薦
學(xué)習(xí)python的while循環(huán)嵌套 提升Python運(yùn)行速度的5個(gè)小技巧 Python按鍵或值對(duì)字典進(jìn)行排序 圖像檢索之基于vlfeat實(shí)現(xiàn)SIFT特征 python繪圖中的四個(gè)繪圖技巧 js中toString方法3個(gè)作用 信息系統(tǒng)項(xiàng)目管理師報(bào)考條件 信息系統(tǒng)項(xiàng)目管理師報(bào)考時(shí)間 信息系統(tǒng)項(xiàng)目管理師報(bào)名時(shí)間 信息系統(tǒng)項(xiàng)目管理師考試時(shí)間 pmp與信息系統(tǒng)項(xiàng)目管理師 信息系統(tǒng)項(xiàng)目管理師報(bào)考要求 信息系統(tǒng)項(xiàng)目管理師有效期 信息系統(tǒng)項(xiàng)目管理師考什么論文 信息系統(tǒng)項(xiàng)目管理師是什么類別 軟考信息系統(tǒng)項(xiàng)目管理師怎么備考 備考流程有哪些 考信息系統(tǒng)項(xiàng)目管理師需要考幾門 信息系統(tǒng)項(xiàng)目管理師考試幾門 信息系統(tǒng)項(xiàng)目管理師初中能考嗎 信息系統(tǒng)項(xiàng)目管理師英語(yǔ)簡(jiǎn)稱 python實(shí)現(xiàn)新年倒計(jì)時(shí)實(shí)例代碼 詳解python的循環(huán) 基于Python實(shí)現(xiàn)PDF區(qū)域文本提取工具 Python數(shù)據(jù)分析處理(三)--運(yùn)動(dòng)員信息的分組與聚合 Python實(shí)現(xiàn)城市公交網(wǎng)絡(luò)分析與可視化 Python 垃圾回收機(jī)制詳解 python正則表達(dá)式語(yǔ)法學(xué)習(xí)筆記 一文秒懂python正則表達(dá)式常用函數(shù) Python常用的正則表達(dá)式處理函數(shù)詳解 JS截取字符串的三種方法詳解 PHP遍歷數(shù)組的6種方式總結(jié) php兩種基本的輸出方及實(shí)例詳解 php生成唯一uid的解決方法詳解 PHP7中對(duì)十六進(jìn)制字符串處理的問(wèn)題詳解 PHP對(duì)接抖音開(kāi)發(fā)平臺(tái)接口的詳細(xì)教程 php7安裝mysqli實(shí)例講解 php去掉一維數(shù)組的鍵值的實(shí)例方法 PHP中empty()和isset()的區(qū)別介紹 PHP實(shí)現(xiàn)JWT的Token登錄認(rèn)證 php判斷時(shí)間戳是否為今天實(shí)例講解
Top