配置文件:
'''全局变量<集合>'''
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()