如何自制游戏(手把手教你Python制作拼图类益智游戏)

前言:

本期我们将制作一个拼图小游戏。让我们愉快地开始吧~~~

先来看看效果是这样子的:

Python制作游戏原来这么简单,手把手教你制作拼图类益智游戏

 

开发工具

**Python版本:**3.6.4

私信小编01即可获取大量python学习资源

相关模块:

pygame模块;

以及一些Python自带的模块

环境搭建

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

原理介绍

游戏简介:

将图像分为m×n个矩形块,并将图像右下角的矩形块替换为空白块后,将这些矩形块随机摆放成原图像的形状。游戏目标为通过移动非空白块将随机摆放获得的图像恢复成原图像的模样,且规定移动操作仅存在于非空白块移动到空白块。

例如下图所示:

Python制作游戏原来这么简单,手把手教你制作拼图类益智游戏

 

逐步实现:

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
复制代码

游戏主界面初始化:

Python制作游戏原来这么简单,手把手教你制作拼图类益智游戏

 

最后实现主界面的显示刷新以及事件响应等功能:

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:游戏结束界面

%E

站长微信:yqq8233(长安复制)公众号:vzyun222