Python游戲開發,pygame模塊,Python實現拼圖小游戲


前言:

本期我們將制作一個拼圖小游戲。讓我們愉快地開始吧~~~

先來看看效果是這樣子的:

b18f78b6-45d3-452e-96db-bfcf0f9fa1c4.png

開發工具

Python版本:3.6.4

相關模塊:

pygame模塊;

以及一些Python自帶的模塊

環境搭建

安裝Python並添加到環境變量,pip安裝需要的相關模塊即可。

原理介紹

游戲簡介:

將圖像分為m×n個矩形塊,並將圖像右下角的矩形塊替換為空白塊后,將這些矩形塊隨機擺放成原圖像的形狀。游戲目標為通過移動非空白塊將隨機擺放獲得的圖像恢復成原圖像的模樣,且規定移動操作僅存在於非空白塊移動到空白塊。

例如下圖所示:

圖片

逐步實現:

Step1:游戲初始界面

既然是游戲,總得有個初始界面吧?

OK,我們先寫一個游戲初始界面:

'''顯示游戲開始界面'''
def ShowStartInterface(screen, width, height):
	screen.fill(cfg.BACKGROUNDCOLOR)
	tfont = pygame.font.Font(cfg.FONTPATH, width//4)
	cfont = pygame.font.Font(cfg.FONTPATH, width//20)
	title = tfont.render('拼圖游戲', True, cfg.RED)
	content1 = cfont.render('按H或M或L鍵開始游戲', True, cfg.BLUE)
	content2 = cfont.render('H為5*5模式, M為4*4模式, L為3*3模式', True, cfg.BLUE)
	trect = title.get_rect()
	trect.midtop = (width/2, height/10)
	crect1 = content1.get_rect()
	crect1.midtop = (width/2, height/2.2)
	crect2 = content2.get_rect()
	crect2.midtop = (width/2, height/1.8)
	screen.blit(title, trect)
	screen.blit(content1, crect1)
	screen.blit(content2, crect2)
	while True:
		for event in pygame.event.get():
			if (event.type == pygame.QUIT) or (event.type == pygame.KEYDOWN and event.key == pygame.K_ESCAPE):
				pygame.quit()
				sys.exit()
		elif event.type == pygame.KEYDOWN:
		if event.key == ord('l'): return 3
		elif event.key == ord('m'): return 4
		elif event.key == ord('h'): return 5
		pygame.display.update()

根據玩家自身水平,可以選擇不同難度的拼圖游戲。

Step2:定義移動操作

定義移動操作的目的是為了移動拼圖(好像是廢話T_T),具體實現起來十分簡單:

'''將空白Cell左邊的Cell右移到空白Cell位置'''
def moveR(board, blank_cell_idx, num_cols):
	if blank_cell_idx % num_cols == 0: return blank_cell_idx
	board[blank_cell_idx-1], board[blank_cell_idx] = board[blank_cell_idx], board[blank_cell_idx-1]
	return blank_cell_idx - 1


'''將空白Cell右邊的Cell左移到空白Cell位置'''
def moveL(board, blank_cell_idx, num_cols):
	if (blank_cell_idx+1) % num_cols == 0: return blank_cell_idx
	board[blank_cell_idx+1], board[blank_cell_idx] = board[blank_cell_idx], board[blank_cell_idx+1]
	return blank_cell_idx + 1


'''將空白Cell上邊的Cell下移到空白Cell位置'''
def moveD(board, blank_cell_idx, num_cols):
	if blank_cell_idx < num_cols: return blank_cell_idx
	board[blank_cell_idx-num_cols], board[blank_cell_idx] = board[blank_cell_idx], board[blank_cell_idx-num_cols]
	return blank_cell_idx - num_cols


'''將空白Cell下邊的Cell上移到空白Cell位置'''
def moveU(board, blank_cell_idx, num_rows, num_cols):
	if blank_cell_idx >= (num_rows-1) * num_cols: return blank_cell_idx
	board[blank_cell_idx+num_cols], board[blank_cell_idx] = board[blank_cell_idx], board[blank_cell_idx+num_cols]
	return blank_cell_idx + num_cols

Step3:游戲主界面

OK,有了前面的鋪墊,我們可以開始實現我們的游戲主界面了。

首先,我們需要打亂拼圖,但是隨機打亂很可能導致拼圖無解,因此我們通過隨機移動拼圖來實現打亂拼圖的效果,這也是我們先定義拼圖的移動操作的主要原因:

'''獲得打亂的拼圖'''
def CreateBoard(num_rows, num_cols, num_cells):
	board = []
	for i in range(num_cells): board.append(i)
	# 去掉右下角那塊
	blank_cell_idx = num_cells - 1
	board[blank_cell_idx] = -1
	for i in range(cfg.NUMRANDOM):
		# 0: left, 1: right, 2: up, 3: down
		direction = random.randint(0, 3)
		if direction == 0: blank_cell_idx = moveL(board, blank_cell_idx, num_cols)
		elif direction == 1: blank_cell_idx = moveR(board, blank_cell_idx, num_cols)
		elif direction == 2: blank_cell_idx = moveU(board, blank_cell_idx, num_rows, num_cols)
		elif direction == 3: blank_cell_idx = moveD(board, blank_cell_idx, num_cols)
	return board, blank_cell_idx

游戲主界面初始化:

image.png

最后實現主界面的顯示刷新以及事件響應等功能:

while True:
		game_board, blank_cell_idx = CreateBoard(num_rows, num_cols, num_cells)
		if not isGameOver(game_board, size):
			break
	# 游戲主循環
	is_running = True
	while is_running:
		# --事件捕獲
		for event in pygame.event.get():
			# ----退出游戲
			if (event.type == pygame.QUIT) or (event.type == pygame.KEYDOWN and event.key == pygame.K_ESCAPE):
				pygame.quit()
				sys.exit()
			# ----鍵盤操作
			elif event.type == pygame.KEYDOWN:
				if event.key == pygame.K_LEFT or event.key == ord('a'):
					blank_cell_idx = moveL(game_board, blank_cell_idx, num_cols)
				elif event.key == pygame.K_RIGHT or event.key == ord('d'):
					blank_cell_idx = moveR(game_board, blank_cell_idx, num_cols)
				elif event.key == pygame.K_UP or event.key == ord('w'):
					blank_cell_idx = moveU(game_board, blank_cell_idx, num_rows, num_cols)
				elif event.key == pygame.K_DOWN or event.key == ord('s'):
					blank_cell_idx = moveD(game_board, blank_cell_idx, num_cols)
			# ----鼠標操作
			elif event.type == pygame.MOUSEBUTTONDOWN and event.button == 1:
				x, y = pygame.mouse.get_pos()
				x_pos = x // cell_width
				y_pos = y // cell_height
				idx = x_pos + y_pos * num_cols
				if idx == blank_cell_idx-1:
					blank_cell_idx = moveR(game_board, blank_cell_idx, num_cols)
				elif idx == blank_cell_idx+1:
					blank_cell_idx = moveL(game_board, blank_cell_idx, num_cols)
				elif idx == blank_cell_idx+num_cols:
					blank_cell_idx = moveU(game_board, blank_cell_idx, num_rows, num_cols)
				elif idx == blank_cell_idx-num_cols:
					blank_cell_idx = moveD(game_board, blank_cell_idx, num_cols)
		# --判斷游戲是否結束
		if isGameOver(game_board, size):
			game_board[blank_cell_idx] = num_cells - 1
			is_running = False
		# --更新屏幕
		screen.fill(cfg.BACKGROUNDCOLOR)
		for i in range(num_cells):
			if game_board[i] == -1:
				continue
			x_pos = i // num_cols
			y_pos = i % num_cols
			rect = pygame.Rect(y_pos*cell_width, x_pos*cell_height, cell_width, cell_height)
			img_area = pygame.Rect((game_board[i]%num_cols)*cell_width, (game_board[i]//num_cols)*cell_height, cell_width, cell_height)
			screen.blit(game_img_used, rect, img_area)
		for i in range(num_cols+1):
			pygame.draw.line(screen, cfg.BLACK, (i*cell_width, 0), (i*cell_width, game_img_used_rect.height))
		for i in range(num_rows+1):
			pygame.draw.line(screen, cfg.BLACK, (0, i*cell_height), (game_img_used_rect.width, i*cell_height))
		pygame.display.update()
		clock.tick(cfg.FPS)

Step4:游戲結束界面

當玩家完成拼圖后,需要顯示游戲結束界面,和游戲初始界面類似,實現起來都比較簡單:

'''顯示游戲結束界面'''
def ShowEndInterface(screen, width, height):
	screen.fill(cfg.BACKGROUNDCOLOR)
	font = pygame.font.Font(cfg.FONTPATH, width//15)
	title = font.render('恭喜! 你成功完成了拼圖!', True, (233, 150, 122))
	rect = title.get_rect()
	rect.midtop = (width/2, height/2.5)
	screen.blit(title, rect)
	pygame.display.update()
	while True:
		for event in pygame.event.get():
			if (event.type == pygame.QUIT) or (event.type == pygame.KEYDOWN and event.key == pygame.K_ESCAPE):
				pygame.quit()
				sys.exit()
		pygame.display.update()

文章到這里就結束了,感謝你的觀看,Python24個小游戲系列,下篇文章分享滑雪小游戲
All done~點贊+評論~詳見個人簡介或者私信獲取完整源代碼。。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM