跳至正文
View Categories

3 min read

主要内容 #

    1. 定义宝石精灵类
    2. 定义游戏类
    3. 主函数完善

1.定义宝石精灵类 #

消消乐游戏中需要用到鼠标与拼图块之间的碰撞检测,从而操作拼图块移动,因此我们可以定义一个拼图块游戏精灵类以方便实现这些功能。
宝石精灵类包括的成员函数有拼图块移动、获取坐标、设置坐标。

class gemSprite(pygame.sprite.Sprite):
    '''
    初始化函数:img_path=图片文件所在路径,size=整个界面大小,position=拼图块位置,downlen=消除拼图块后下降格数
    '''
    def __init__(self, img_path, size, position, downlen, **kwargs):
        pygame.sprite.Sprite.__init__(self)
        self.image = pygame.image.load(img_path)
        self.image = pygame.transform.smoothscale(self.image, size)  # 改变加载的图片大小
        self.rect = self.image.get_rect()
        self.rect.left, self.rect.top = position
        self.downlen = downlen
        self.target_x = position[0]
        self.target_y = position[1] + downlen
        self.type = img_path.split('/')[-1].split('.')[0]
        self.fixed = False
        self.speed_x = 10
        self.speed_y = 10
        self.direction = 'down'

    def move(self):
        '''
        拼图块移动函数:主要通过鼠标控制拼图块交换方向,有上下左右四个方向
        '''
        if self.direction == 'down':
            self.rect.top = min(self.target_y, self.rect.top+self.speed_y)
            if self.target_y == self.rect.top:
                self.fixed = True
        elif self.direction == 'up':
            self.rect.top = max(self.target_y, self.rect.top-self.speed_y)
            if self.target_y == self.rect.top:
                self.fixed = True
        elif self.direction == 'left':
            self.rect.left = max(self.target_x, self.rect.left-self.speed_x)
            if self.target_x == self.rect.left:
                self.fixed = True
        elif self.direction == 'right':
            self.rect.left = min(self.target_x, self.rect.left+self.speed_x)
            if self.target_x == self.rect.left:
                self.fixed = True

    def getPosition(self):
        '''
        获取坐标函数:获取当前拼图块坐标,主要通过左(left)和上(top)两个方向定义坐标距离
        '''
        return self.rect.left, self.rect.top

    def setPosition(self, position):
        '''
        设置坐标函数:设置拼图块坐标
        '''
        self.rect.left, self.rect.top = position

将以上所有代码加入到上一课创建的项目文件中(该代码请置放在main()函数上面),运行,发现无任何变化,因为该部分只是定义了宝石类,还未去调用该类,主要在游戏类中进行调用。

2.定义游戏类 #

游戏类包含的成员函数有开始游戏(游戏主循环)、初始化(随机生成各个块,即初始化游戏地图各个元素、得分、拼出一个的奖励、时间)、显示剩余时间、显示得分、显示加分、生成新的拼图块、移除匹配的gem宝石、游戏界面的网格绘制、画矩形block框、下落特效、检查是否每个位置都有拼图块了、检查有无拼图块被选中、检查是否有连续一样的三个块、根据坐标获取对应位置的拼图对象、交换拼图等。

此处只介绍一下游戏类的初始属性:

class gemGame():
	def __init__(self, screen, sounds, font, gem_imgs, **kwargs):  # 初始化游戏类
		self.info = '大师码'
		self.screen = screen # 游戏窗口
		self.sounds = sounds # 音乐
		self.font = font # 字体
		self.gem_imgs = gem_imgs # 宝石图片

将以上所有代码加入到上一课创建的项目文件中(该代码请置放在main()函数和gemSprite类之间),运行,发现无任何变化,因为该部分只是定义了游戏类,还未去调用该类。

再下一节将介绍游戏类中一些重要的成员函数。

3.主函数完善 #

现在我们已经定义好了宝石类和游戏类,后续所有的操作都在游戏类中设定,因此提前将主函数模块完善,具体代码如下:

def main():

    # 加载背景音乐
    pygame.mixer.init()
    pygame.mixer.music.load(os.path.join(ROOTDIR, "resources/audios/bg.mp3"))
    pygame.mixer.music.set_volume(0.6)
    pygame.mixer.music.play(-1)

    # 加载音效,分别匹配成功和匹配失败
    sounds = {}
    sounds['mismatch'] = pygame.mixer.Sound(os.path.join(ROOTDIR, 'resources/audios/badswap.wav'))
    sounds['match'] = []
    for i in range(6):  # 匹配成功一共有六个音效
        sounds['match'].append(pygame.mixer.Sound(os.path.join(ROOTDIR, 'resources/audios/match%s.wav' % i)))
    # 加载字体
    font = pygame.font.Font(os.path.join(ROOTDIR, 'resources/font.TTF'), 25)
    # 图片加载
    gem_imgs = []
    for i in range(1, 8):  # 一共七种宝石
        gem_imgs.append(os.path.join(ROOTDIR, 'resources/images/gem%s.png' % i))

    game = gemGame(screen, sounds, font, gem_imgs)
    while True:
        score = 0
        # score = game.start() # 后续打开该函数
        flag = False
        # 一轮游戏结束后玩家选择重玩或者退出
        while True:
            for event in pygame.event.get():
                if event.type == pygame.QUIT or (event.type == pygame.KEYUP and event.key == pygame.K_ESCAPE):
                    pygame.quit()
                    sys.exit()
                elif event.type == pygame.KEYUP and event.key == pygame.K_r: # r或者keyup则按住就重新开始游戏
                    flag = True
            if flag:
                break
            screen.fill((135, 206, 235))
            text0 = 'Final score: %s' % score
            text1 = 'Press r to restart the game.'
            text2 = 'Press esc to quit the game.'
            y = 150
            # enumerate() 函数用于将一个可遍历的数据对象(如列表、元组或字符串)组合为一个索引序列,同时列出数据和数据下标
            for idx, text in enumerate([text0, text1, text2]): # 该模块是针对三组文本置放在对应位置
                text_render = font.render(text, 1, (85, 65, 0))
                rect = text_render.get_rect()
                if idx == 0:
                    rect.left, rect.top = (212, y)
                elif idx == 1:
                    rect.left, rect.top = (122.5, y)
                else:
                    rect.left, rect.top = (126.5, y)
                y += 100
                screen.blit(text_render, rect)  # 绘出文本框
            pygame.display.update() # 这部分就是每次循环都要更新屏幕,这样能保持一直状态最新
        # game.reset() # 后续打开该函数


if __name__ == '__main__':
    main()

将以上所有代码加入到上一课创建的项目文件中(该代码覆盖原有的main函数),运行,查看已有的效果。

小结 #

  • 本节主要介绍了定义宝石精灵类的初始化属性和其中的成员函数、游戏类的初始化属性,并且完善了main函数的功能,后续的新增都在游戏类中添加。