配置文件:

'''全局变量<集合>'''
window_width = 700  # 窗口宽
window_height = 700  # 窗口高

box_size = 100  # 盒子大小
gap_size = 10  # 盒子间距

fps = 30  # 动画帧频
display_second = 3  # 开始游戏前展示多少秒
# 形状
DONUT = 'donut'  # 甜甜圈
SQUARE = 'square'  # 方形
DIAMOND = 'diamond'  # 钻石
LINES = 'lines'  # 多条线
OVAL = 'oval'  # 椭圆
SHAPES = (DONUT, SQUARE, DIAMOND, LINES, OVAL)

# 颜色   R    G    B
GRAY = (100, 100, 100)
NAVYBLUE = (60, 60, 100)  # 背景颜色
WHITE = (255, 255, 255)
RED = (255, 0, 0)
GREEN = (0, 255, 0)
BLUE = (0, 0, 255)
YELLOW = (255, 255, 0)
ORANGE = (255, 128, 0)
PURPLE = (255, 0, 255)
CYAN = (0, 255, 255)
CAP_COLOR = (200, 200, 200)  # 盒盖颜色
COLORS = (GRAY, RED, GREEN, BLUE, YELLOW, ORANGE, PURPLE, CYAN)

类文件:

import pygame, time, random, properties, sys
from properties import *
from pygame.locals import *

'''对象<集合>'''


class Game(object):
    # 画布
    surf = None
    # 时钟
    fps_clock = None
    # 盒子集
    boxs = None
    # 临时盒子
    temp_box = None

    # 初始化
    def __init__(self, win_width, win_height, caption, background=(255, 255, 255)):
        pygame.init()
        self.surf = pygame.display.set_mode((win_width, win_height))
        self.surf.fill(background)
        self.fps_clock = pygame.time.Clock()
        pygame.display.set_caption(caption)

    # 准备
    def ready(self):
        self.boxs = Game.create_boxs()  # 初始化所有盒子
        Box.opens(self.boxs)  # 打开所有盒子
        for box in self.boxs:
            Box.draw_box(self.surf, box)
        pygame.display.update()  # 刷上窗口
        time.sleep(display_second)  # 展示3秒
        self.fps_clock.tick(fps)
        Box.closes(self.boxs)  # 关闭所有盒子
        # 关闭动画
        for x in range(int(box_size / 5)):
            for box in self.boxs:
                pygame.draw.rect(self.surf, CAP_COLOR, (box.x, box.y, x * 2, box.height))
            pygame.display.update()
            self.fps_clock.tick(10)

    # 开始
    def begin(self):
        while True:
            self.__event_handle()  # 处理事件
            # 将事件后的对象画到画布上
            for box in self.boxs:
                Box.draw_box(self.surf, box)
                if not box.state:
                    Box.draw_cap(self.surf, box)
            pygame.display.update()
            self.fps_clock.tick(30)

    # 结束
    def over(self):
        sys_font = pygame.font.SysFont("宋体", 100)
        text = sys_font.render("You Are Win !", 1, (255, 255, 255))
        self.surf.blit(text, (window_width / 4, window_height / 2))
        pygame.display.update()
        time.sleep(3)
        pygame.quit()
        sys.exit()

        # 事件处理

    def __event_handle(self):
        for event in pygame.event.get():
            # 监听退出事件
            if event.type == QUIT:  # 退出事件
                pygame.quit()
                sys.exit()
            if event.type == MOUSEBUTTONUP:  # 点击事件
                pos = pygame.mouse.get_pos()
                click_box = Game.find_box_by_pos(self.boxs, pos)
                if click_box and not click_box.state:  # 点击的地方有盒子且盒子是关闭则打开盒子
                    click_box.open(self.surf, self.fps_clock)
                    if not self.temp_box:  # 首次点击
                        self.temp_box = click_box
                    elif not (
                            click_box.color == self.temp_box.color and click_box.shape == self.temp_box.shape):  # 如果临时盒子不是空的,且与点击的盒子属性不相等,则紧接着合上盒子
                        click_box.close(self.surf, self.fps_clock)
                        self.temp_box.close(self.surf, self.fps_clock)
                        self.temp_box = None
                    else:
                        self.temp_box = None
                        # 检测是否所有boxs都被打开
                        win = True
                        for box in self.boxs:
                            if not box.state:
                                win = box.state
                        if win:
                            self.over()  # 胜利动画!!!

    # 根据坐标找出所在盒子
    @staticmethod
    def find_box_by_pos(boxs, pos):
        click_box = None
        for index, box in enumerate(boxs):
            if box.left <= pos[0] <= box.right and box.top <= pos[1] <= box.bottom:
                click_box = boxs[index]
        return click_box

    # 创建版面初始盒子
    @staticmethod
    def create_boxs():
        # 列数
        xcount = int(window_width / (box_size + gap_size))
        # 行数
        ycount = int(window_height / (box_size + gap_size))
        # 总数(去掉收尾行列)
        icons_num = (xcount - 2) * (ycount - 2)
        icons = []
        for x in range(int(icons_num / 2)):
            icons.append((random.choice(SHAPES), random.choice(COLORS)))
        icons *= 2
        random.shuffle(icons)  # 乱序
        boxs = []
        for x in range(1, xcount - 1):
            for y in range(1, ycount - 1):
                box = Box(((box_size + gap_size) * x, (box_size + gap_size) * y, 40, 40), icons[0][1],
                          icons[0][0])
                del icons[0]
                boxs.append(box)
        return boxs


# 盒子
class Box(pygame.Rect):
    # 形状
    shape = None
    # 颜色
    color = None
    # 状态
    state = False

    def __init__(self, rect, color, shape):
        super().__init__(rect)
        self.color = color
        self.shape = shape

    # 打开盒子的动画
    def open(self, surf, fps_clock):
        self.state = True
        for x in reversed(range(int(self.width / 5))):
            self.draw_box(surf, self)
            pygame.draw.rect(surf, CAP_COLOR, (self.x, self.y, x * 2, self.height))
            pygame.display.update()
            fps_clock.tick(30)

    # 关闭盒子的动画
    def close(self, surf, fps_clock):
        self.state = False
        for x in range(int(box_size / 5)):
            pygame.draw.rect(surf, CAP_COLOR, (self.x, self.y, x * 2, self.height))
            pygame.display.update()
            fps_clock.tick(fps)

    # 打开所有盒子
    @staticmethod
    def opens(boxs):
        for box in boxs:
            box.state = True
        return boxs

    # 关闭所有盒子
    @staticmethod
    def closes(boxs):
        for box in boxs:
            box.state = False
        return boxs

    # 画盒子背面
    @staticmethod
    def draw_cap(surf, box):
        pygame.draw.rect(surf, CAP_COLOR, box)

    # 画盒子
    @staticmethod
    def draw_box(surf, box):
        # 甜甜圈
        if box.shape == DONUT:
            pygame.draw.circle(surf, box.color, box.center, int(box.width / 2))
            pygame.draw.circle(surf, (255, 255, 255), box.center, int(box.width / 4))
        # 方形
        if box.shape == SQUARE:
            pygame.draw.rect(surf, box.color, box)
        # 钻石
        if box.shape == DIAMOND:
            pygame.draw.polygon(surf, box.color, ((box.x + box.width / 4, box.y + box.height / 2),
                                                  (box.x + box.width / 2, box.y),
                                                  (box.x + box.width * 0.75, box.y + box.width / 2),
                                                  (box.x + box.width / 2, box.y + box.width)))
        # 椭圆
        if box.shape == OVAL:
            pygame.draw.ellipse(surf, box.color, (box.x + box.width / 4, box.y, box.width / 2, box.height))  # 椭圆
        # 斜线
        if box.shape == LINES:
            # 上半区
            xp1 = []
            yp1 = []
            for i in range(int(box.width / 10)):
                xp1.append((box.x + i * 10, box.y))
            for i in range(int(box.height / 10)):
                yp1.append((box.x, box.y + i * 10))
            for z in range(xp1.__len__()):
                pygame.draw.line(surf, box.color, xp1[z], yp1[z])

            # 下半区
            xp2 = []
            yp2 = []
            for i in range(int(box.width / 10)):
                xp2.append((box.x + i * 10, box.y + box.height))
            for i in range(int(box.height / 10)):
                yp2.append((box.x + box.width, box.y + i * 10))
            for z in range(xp2.__len__()):
                pygame.draw.line(surf, box.color, xp2[z], yp2[z])

启动:

import properties, clazz


def main():
    # 创建游戏对象
    game = clazz.Game(properties.window_width, properties.window_height, "记忆游戏", properties.NAVYBLUE)
    game.ready()
    game.begin()


if __name__ == '__main__':
    main()

面向对象的方式用pygame写记忆游戏_Game

面向对象的方式用pygame写记忆游戏_ci_02