跳至正文
View Categories

3 min read

主要内容 #

    1. 游戏类中遍历整个界面函数
    2. 游戏类中检查有无拼图块被选中函数
    3. 游戏类中的交换拼图函数

1.游戏类中遍历整个界面函数 #

该模块实现的功能为:遍历整个界面,将宝石置放满整个矩形框。
该部分代码如下:


	def removeMatched(self, res_match):
        '''
        消除匹配成功的拼图块:行或列三个一样的拼图块出现即消除
        '''
        if res_match[0] > 0:  # 大于0说明出现行或列有三个一样的块
            # self.generateNewGems(res_match)  # 将res_match列表信息传给生成函数
            self.score += self.reward  # 匹配成功增加得分
            return self.reward
        return 0

    def dropGems(self, x, y):
        '''
        新的拼图块出现下落特效
        '''
        if not self.getGemByPos(x, y).fixed:
            self.getGemByPos(x, y).move()
        if x < NUMGRID-1:
            x += 1
            return self.dropGems(x, y)
        elif y < NUMGRID-1:
            x = 0
            y += 1
            return self.dropGems(x, y)
        else:
            return self.isFull()

    def isFull(self):
        '''
        是否每个位置都有拼图块了
        '''
        for x in range(NUMGRID):
            for y in range(NUMGRID):
                if not self.getGemByPos(x, y).fixed:
                    return False
        return True

将以上所有代码加入到游戏类代码中,作为成员函数。

接下来需要在各个模块中添加和修改代码,具体如下。

    # 在gemGame类中的start()函数中找到如下代码
	self.screen.fill((135, 206, 235))
	self.drawGrids()  # 绘出游戏网格

    # 在该句代码前增加如下代码
	if overall_moving: # 遍历整个游戏界面更新位置
		overall_moving = not self.dropGems(0, 0)
		# 移动一次可能可以拼出多个3连块
		if not overall_moving:
			res_match = self.isMatch()
			add_score = self.removeMatched(res_match)
			if add_score > 0:
				overall_moving = True

全部修改完之后,运行整体代码,看整体效果,可以看出宝石已经满格置放在矩形框中。

2.游戏类中检查有无拼图块被选中函数 #

我们通过鼠标来操纵拼图块,因此程序需要检查有无拼图块被选中,代码实现如下:


	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

3.游戏类中的交换拼图函数 #

我们需要将鼠标连续选择的拼图块进行位置交换。该函数完成的功能是交换两个宝石位置:
具体实现代码如下:


	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:  # 宝石1在宝石2的右边,则交换时宝石1需要往左,宝石2需要往右
			gem1.direction = 'left'
			gem2.direction = 'right'
		elif gem1_pos[0] - gem2_pos[0] == -1:  # 宝石1在宝石2的左边,则交换时宝石1需要往右,宝石2需要往左
			gem2.direction = 'left'
			gem1.direction = 'right'
		elif gem1_pos[1] - gem2_pos[1] == 1:  # 宝石1在宝石2的下边,则交换时宝石1需要往上,宝石2需要往下
			gem1.direction = 'up'
			gem2.direction = 'down'
		elif gem1_pos[1] - gem2_pos[1] == -1:  # 宝石1在宝石2的上边,则交换时宝石1需要往下,宝石2需要往上
			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  # 将宝石1交换到原本宝石2的位置
		self.all_gems[gem1_pos[0]][gem1_pos[1]] = gem2  # 将宝石2交换到原本宝石1的位置
		return True

将2部分和3部分中的所有代码加入到游戏类代码中,作为成员函数。

接下来需要在各个模块中添加和修改代码,具体如下。

    # 在gemGame类中的start()函数中找到如下代码
		if event.type == pygame.QUIT or (event.type == pygame.KEYUP and event.key == pygame.K_ESCAPE):
			pygame.quit()
			sys.exit()

    # 在该句代码后增加如下代码
		elif event.type == pygame.MOUSEBUTTONUP:
			if (not overall_moving) and (not individual_moving) and (not add_score):
				position = pygame.mouse.get_pos()  # 获取当前鼠标的位置
				if gem_selected_xy is None: # 没有选中
					gem_selected_xy = self.checkSelected(position)
				else:  # 选中了第一个宝石,则继续选择第二个宝石
					gem_selected_xy2 = self.checkSelected(position)
					if gem_selected_xy2:  # 选中第二个宝石
						if self.swapGem(gem_selected_xy, gem_selected_xy2):   # 交换两个被选中的宝石
							individual_moving = True
							swap_again = False
						else:
							gem_selected_xy = None
    # 在gemGame类中的start()函数中找到如下代码
	self.screen.fill((135, 206, 235))
	self.drawGrids()  # 绘出游戏网格

    # 在该句代码前增加如下代码
	if individual_moving: # 更新特定指定的宝石位置
		gem1 = self.getGemByPos(*gem_selected_xy)
		gem2 = self.getGemByPos(*gem_selected_xy2)
		gem1.move()
		gem2.move()
		if gem1.fixed and gem2.fixed:
			res_match = self.isMatch()
			if res_match[0] == 0 and not swap_again:
				swap_again = True
				self.swapGem(gem_selected_xy, gem_selected_xy2)
				self.sounds['mismatch'].play()  # 播放匹配失败音效
			else:
				add_score = self.removeMatched(res_match) # 增加得分
				overall_moving = True
				individual_moving = False
				gem_selected_xy = None
				gem_selected_xy2 = None

全部修改完之后,运行整体代码,看整体效果,可以看出宝石可以交换。

小结 #

本节主要介绍了消消乐游戏中检查有无拼图块被选中函数,游戏类中的交换拼图函数和游戏类中遍历整个界面函数,并且加到游戏类中作为成员函数。