跳至正文
View Categories

3 min read

主要内容 #

    1. 因为玩家需要通过鼠标点击来操作卡片,这时候就涉及到一些碰撞检测。所以先定义一些必要的游戏精灵类,包括下面两种:
    1. 定义游戏卡片类
    2. 定义游戏按钮类
    3. 制作24点生成器

1.定义游戏卡片类 #

卡片类的定义也很简单,在屏幕上根据被赋予的属性值来显示自身即可。当然之后也需要根据用户的操作来改变这些属性值(内容、颜色、字体等)并在屏幕上根据属性的改变而改变显示状态即可。
具体代码实现如下:

class Card(pygame.sprite.Sprite):
    '''
    Function:
        卡片类
    Initial Args:
        --x,y: 左上角坐标
        --width: 宽
        --height: 高
        --text: 文本
        --font: [字体路径, 字体大小]
        --font_colors(list): 字体颜色
        --bg_colors(list): 背景色
    '''
    def __init__(self, x, y, width, height, text, font, font_colors, bg_colors, attribute, **kwargs): # 初始化成员属性
        pygame.sprite.Sprite.__init__(self)
        self.rect = pygame.Rect(x, y, width, height)
        self.text = text
        self.attribute = attribute
        self.font_info = font
        self.font = pygame.font.Font(font[0], font[1])
        self.font_colors = font_colors
        self.is_selected = False
        self.select_order = None
        self.bg_colors = bg_colors

    def draw(self, screen, mouse_pos):
        '''
        画到屏幕上
        '''
        pygame.draw.rect(screen, self.bg_colors[1], self.rect, 0)
        if self.rect.collidepoint(mouse_pos):  # 如果鼠标点击卡片,则改变背景颜色
            pygame.draw.rect(screen, self.bg_colors[0], self.rect, 0)
        font_color = self.font_colors[self.is_selected]
        text_render = self.font.render(self.text, True, font_color)
        font_size = self.font.size(self.text)
        screen.blit(text_render, (self.rect.x+(self.rect.width-font_size[0])/2, self.rect.y+(self.rect.height-font_size[1])/2))

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

2.定义游戏按钮类 #

按钮类和卡片类类似,唯一的不同点就是在用户点击按钮时需要根据该按钮的功能来响应用户的本次点击操作(即实现一次该功能)。因此只需要继承卡片类,然后再定义一个响应用户点击按钮事件的回调函数即可。
代码实现如下:

class Button(Card):
    '''
    按钮类,和卡片类似,初识参数都一致
    '''
    def __init__(self, x, y, width, height, text, font, font_colors, bg_colors, attribute, **kwargs):
        Card.__init__(self, x, y, width, height, text, font, font_colors, bg_colors, attribute)

    def do(self, game24_gen, func, sprites_group, objs):
        '''
        根据button function执行响应操作
        '''
        if self.attribute == 'NEXT': # “下一个”按钮,生成新的24点游戏
            for obj in objs:
                obj.font = pygame.font.Font(obj.font_info[0], obj.font_info[1])
                obj.text = obj.attribute
            self.font = pygame.font.Font(self.font_info[0], self.font_info[1])
            self.text = self.attribute
            game24_gen.generate()  # 生成新的24点游戏
            sprites_group = func(game24_gen.numbers_now)
        elif self.attribute == 'RESET':  # ”重置“按钮, 重新开始当前24点游戏
            for obj in objs:
                obj.font = pygame.font.Font(obj.font_info[0], obj.font_info[1])
                obj.text = obj.attribute
            game24_gen.numbers_now = game24_gen.numbers_ori # 数据变为原始数据
            game24_gen.answers_idx = 0  # 答案列表下标变为0
            sprites_group = func(game24_gen.numbers_now) # 重新开始本次游戏
        elif self.attribute == 'ANSWERS':  # ”答案“按钮,提示用户当前24点游戏答案的正解
            self.font = pygame.font.Font(self.font_info[0], 20)
            self.text = '[%d/%d]: ' % (game24_gen.answers_idx+1, len(game24_gen.answers)) + game24_gen.answers[game24_gen.answers_idx]
            game24_gen.answers_idx = (game24_gen.answers_idx+1) % len(game24_gen.answers)
        else:
            raise ValueError('Button.attribute unsupport <%s>, expect <%s>, <%s> or <%s>...' % (self.attribute, 'NEXT', 'RESET', 'ANSWERS'))
        return sprites_group

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

3.制作24点生成器 #

既然是24点小游戏,当然要先定义一个24点游戏类且构建一个生成函数。主要思路就是随机生成4个有解的数字,且范围在1~10之间,代码实现如下:

class Game24Generator():
    '''
    24点游戏生成器
    '''
    def __init__(self):
        self.info = 'game24Generator'

    def __reset(self):
        '''
        重置
        '''
        self.answers = []
        self.numbers_ori = []
        self.numbers_now = []
        self.target = 24.
        self.answers_idx = 0

    def generate(self):
        '''
        生成器
        '''
        self.__reset()
        while True:
            self.numbers_ori = [random.randint(1, 10) for i in range(4)]  # 原始数据
            self.numbers_now = copy.deepcopy(self.numbers_ori)     # 复制来的当前数据
            self.answers = True # 首先默认为True,这样会输出随机生成的结果
            # self.answers = self.__verify()  # 答案列表
            if self.answers:
                break

将以上所有代码加入到上一课创建的项目文件中(该代码请置放在main()函数和Button类之间)。

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

    # 在main()函数找到如下代码
	# 游戏主循环
    clock = pygame.time.Clock()

    # 在该代码的上方添加如下代码
    # 24点游戏生成器
    game24_gen = Game24Generator()
    game24_gen.generate()
    print(game24_gen.numbers_now)

全部修改完之后,运行代码,看整体效果,在shell端会输出随机生成的一组数据。

小结 #

  • 本节主要介绍了定义卡片类,按钮类的初始化属性和其中的成员函数、游戏类的初始化属性,后续的新增都在游戏类中添加。