前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >python 游戏(记忆拼图Memory

python 游戏(记忆拼图Memory

作者头像
py3study
发布2020-01-16 17:38:48
1.5K0
发布2020-01-16 17:38:48
举报
文章被收录于专栏:python3python3

1. 游戏功能和流程图

实现功能:翻开两个一样的牌子就显示,全部翻开游戏结束,设置5种图形,7种颜色,游戏开始提示随机8个牌子

游戏流程图

2. 游戏配置

配置游戏目录
配置游戏(game_conf.py)
代码语言:javascript
复制
FPS=30 #游戏帧数
WINDOW_WIDTH=640 #窗口大小
WINDOW_HEIGHT=480
REVEAL_SPEAD=3 #箱子显示的速度
BOX_SIZE=40 #箱子的大小宽高相等的正方形
GAP_SIZE=10 #箱子之间的间隔
BOARD_WIDTH=10 #图标的列数
BOARD_HEIGHT=7 #图标的行数
assert (BOARD_WIDTH*BOARD_HEIGHT)%2==0,'必须是偶数的棋盘' #检查语句
X_MARGIN=int((WINDOW_WIDTH-(BOARD_WIDTH*(BOX_SIZE+GAP_SIZE)))/2) #x轴 边缘空隙
Y_MARGIN=int((WINDOW_HEIGHT-(BOARD_HEIGHT*(BOX_SIZE+GAP_SIZE)))/2) #y轴 边缘空隙
配置颜色(color.py)
代码语言:javascript
复制
'''游戏颜色'''
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)
配置形状(shape.py)
代码语言:javascript
复制
DONUT='donut' #圆圈
SQUARE='square' #正方形
DIAMOND='diamond' #钻石
LINES='lines'#线条
OVAL='oval' #椭圆形

3. 游戏使用工具函数(views.py)

3.1 工具和绘画类使用模块和常量
代码语言:javascript
复制
import random
import pygame
from pygame.locals import *
from conf.color import *
from conf.game_conf import *
from conf.shape import *
代码语言:javascript
复制
LIGHTBG_COLOR=GRAY #灯光颜色
BOX_COLOR=WHITE #盒子颜色
HIGHLIGHT_COLOR=BLUE #强调颜色
BG_COLOR=NAVYBLUE #背景颜色
ALL_COLORS=(RED,GREEN,BLUE,YELLOW,ORANGE,PURPLE,CYAN) #颜色元组
ALL_SHAPES=(DONUT,SQUARE,DIAMOND,LINES,OVAL) #形状元组
3.2 生成游戏数据(游戏坐标,形状,颜色)
代码语言:javascript
复制
def get_randomized_board():
    '''生成所有盒子'''
    icons=[]
    #生成所有带颜色的图标,icons列表
    for color in ALL_COLORS:
        for shape in ALL_SHAPES:
            icons.append((shape,color))
    icon_use_number=int(BOARD_HEIGHT*BOARD_WIDTH/2) #所有图标使用的数量
    icons=icons[:icon_use_number]*2
    random.shuffle(icons)  # 打乱列表图标
    board=[]
    #生成坐标
    for x in range(BOARD_WIDTH):
        column=[] #生成列数
        for y in range(BOARD_HEIGHT):
            column.append(icons[0]) #给每列添加图标
            del icons[0]
        board.append(column)
    return board 
3.3 用户的游戏列表(游戏坐标,初始都是空坐标)
代码语言:javascript
复制
def generate_revealed_boxes_data(val):
    '''生成翻开盒子初始列表'''
    revealed_boxes = []
    for i in range(BOARD_WIDTH):
        revealed_boxes.append([val] * BOARD_HEIGHT)
    return revealed_boxes
3.4  将盒子列表坐标转化为实际的像素坐标
代码语言:javascript
复制
def left_top_coords_of_box(box_x, box_y):
    '''将盒子位置转化为像素坐标
    :param box_x 盒子x坐标
    :param box_y 盒子y坐标
    :return 返回屏幕坐标'''
    left = box_x * (BOX_SIZE + GAP_SIZE) + X_MARGIN
    top = box_y * (BOX_SIZE + GAP_SIZE) + Y_MARGIN
    return (left, top)
3.5  根据坐标返回对应的形状和颜色
代码语言:javascript
复制
def get_shape_and_color(board, box_x, box_y):
    '''获取对应坐标 形状和颜色
    :param board 游戏板块坐标列表
    :param box_x 盒子x坐标
    :param box_y 盒子y坐标
    :return 返回形状,颜色'''
    #board[box_x][box_y][0] 形状,board[box_x][box_y][1]颜色
    return board[box_x][box_y][0], board[box_x][box_y][1]
3.6  根据鼠标坐标找到矩形列表坐标
代码语言:javascript
复制
def get_box_at_pixel(x,y):
    '''根据鼠标坐标找到矩形列表坐标
    :param x 鼠标x坐标
    :param y 鼠标y坐标
    :return 返回列表坐标'''
    for box_x in range(BOARD_WIDTH):
        for box_y in range(BOARD_HEIGHT):
            left,top=left_top_coords_of_box(box_x,box_y)
            box_rect=pygame.Rect(left, top, BOX_SIZE, BOX_SIZE) #绘制所有坐标矩形
            if box_rect.collidepoint(x,y): #矩形碰撞,判断该鼠标坐标是否在矩形内
                return (box_x,box_y)
    return (None,None)
3.7  列表分组
代码语言:javascript
复制
def split_into_group_of(group_size, the_list):
    '''分组取值
    :param group_size 需要分组的数量 最后一个有多少取多少
    :param the_list 需要分组的列表'''
    result = []
    for i in range(0, len(the_list), group_size):
        result.append(the_list[i:i + group_size]) #每组取n个
    return result
3.8  检查牌子是否都开启了
代码语言:javascript
复制
def has_won(revealed_boxes):
    '''检查所有箱子是否都开启了
    :param revealed_boxes 反转箱子的坐标'''
    for i in revealed_boxes:
        if False in i:
            return False  # return False if any boxes are covered.
    return True

4  创建游戏绘画类(views.py)

4.1  创建类的初始化
代码语言:javascript
复制
class puzzle(object):
    def __init__(self,DISPLAY_SURF,FPS_CLOCK):
        self.DISPLAY_SURF=DISPLAY_SURF #surf对象
        self.FPS_CLOCK=FPS_CLOCK #fps锁对象
        self.main_board=get_randomized_board() #初始化盒子
        self.revealed_boxes=generate_revealed_boxes_data(False) #初始化翻开的盒子列表
4.2  绘制游戏盒子(类方法)
代码语言:javascript
复制
def draw_board(self,board,revealed):
    '''绘制游戏盒子
    :param board 盒子坐标列表
    :param revealed 被翻转盒子坐标列表'''
    for box_x in range(BOARD_WIDTH):
        for box_y in range(BOARD_HEIGHT):
            if not revealed[box_x][box_y]: #判断该坐标是否被反转
                #绘制没有翻开的盒子
                self.draw_lid(box_x,box_y)
            else:
                #绘制已翻开的盒子
                shape, color = get_shape_and_color(board, box_x, box_y)
                self.draw_icon(shape, color, box_x, box_y)
4.3  绘制没翻开的盒子
代码语言:javascript
复制
def draw_lid(self,box_x,box_y):
    '''绘制没翻开的盒子
    :param box_x,box_y 盒子坐标'''
    left, top = left_top_coords_of_box(box_x, box_y)
    pygame.draw.rect(self.DISPLAY_SURF, BOX_COLOR, (left, top, BOX_SIZE, BOX_SIZE))
4.4  绘制已经翻开的盒子
代码语言:javascript
复制
def draw_icon(self,shape,color,box_x,box_y):
    '''绘制翻开盒子的图案
    :param shape 形状
    :param color 形状的颜色
    :param box_x,box_y 盒子坐标'''
    quarter=int(BOX_SIZE*0.25) #
    half=int(BOX_SIZE*0.5) #
    left,top=left_top_coords_of_box(box_x,box_y) #通过盒子坐标找到像素坐标
    if shape==DONUT: #绘制甜甜圈形状
        pygame.draw.circle(self.DISPLAY_SURF,color,(left+half,top+half),half-5) #绘制 外圆 半径离框5个像素
        pygame.draw.circle(self.DISPLAY_SURF,BG_COLOR,(left+half,top+half),quarter-5) #绘制内圆 1/4之一个半径
    elif shape==SQUARE: #绘制正方形
        pygame.draw.rect(self.DISPLAY_SURF,color,(left+quarter,top+quarter,BOX_SIZE-half,BOX_SIZE-half))
    elif shape==DIAMOND: #绘制钻石形状
        pygame.draw.polygon(self.DISPLAY_SURF,color,((left+half ,top),(left+BOX_SIZE-1,top+half),(left+half,top+BOX_SIZE-1),(left,top+half)))
    elif shape==LINES: #绘制线条形
        for i in range(0,BOX_SIZE,6): #步长控制密度越小密度越大
            pygame.draw.line(self.DISPLAY_SURF,color,(left,top+i),(left+i,top)) #上往左边的斜角线N条 一半
            pygame.draw.line(self.DISPLAY_SURF,color,(left+i,top+BOX_SIZE-1),(left+BOX_SIZE-1,top+i)) #从下往右斜角线条N条 一半
    elif shape==OVAL: #绘制椭圆
        pygame.draw.ellipse(self.DISPLAY_SURF,color,(left,top+quarter,BOX_SIZE,half))
4.5  鼠标悬停高亮显示
代码语言:javascript
复制
def draw_hightlight_box(self,box_x, box_y):
    '''绘制鼠标悬停加亮显示
    :param box_x 盒子列表x坐标
    :param box_y 盒子列表y坐标'''
    left, top = left_top_coords_of_box(box_x, box_y)
    pygame.draw.rect(self.DISPLAY_SURF,HIGHLIGHT_COLOR,(left-5,top-5,BOX_SIZE+10,BOX_SIZE+10),4) #绘画外部高亮矩形
4.6  翻箱动画
代码语言:javascript
复制
def reveal_boxes_animation(self,boxes_to_reveal):
    '''翻箱子动画
    :param boxes_to_reveal 需要翻开的箱子坐标列表'''
    for coverage in range(BOX_SIZE, (-REVEAL_SPEAD) - 1, -REVEAL_SPEAD): #从大到小绘制盖板动画 开盖子
        self.draw_box_covers(boxes_to_reveal, coverage)
4.7  合箱动画
代码语言:javascript
复制
def cover_boxes_animation(self,boxes_to_cover):
    '''盖上箱子动画
    :param boxes_to_cover 需要盖上的箱子坐标列表'''
    for coverage in range(0, BOX_SIZE + REVEAL_SPEAD, REVEAL_SPEAD): #从小到大绘制盖板动画 关盖子
        self.draw_box_covers(boxes_to_cover, coverage)
4.8  动画遮罩层
代码语言:javascript
复制
def draw_box_covers(self, boxes, coverage):
    '''打印一次开/关 盖子
    :param boxes 需要操作的箱子列表
    :param coverage 遮罩层的宽度'''
    for box in boxes:
        left, top = left_top_coords_of_box(box[0], box[1])
        pygame.draw.rect(self.DISPLAY_SURF, BG_COLOR, (left, top, BOX_SIZE, BOX_SIZE)) #绘制背景
        shape, color = get_shape_and_color(self.main_board, box[0], box[1])
        self.draw_icon(shape, color, box[0], box[1]) #绘制形状
        if coverage > 0:  # 如果遮罩层的宽度小于0就不绘制遮罩层了
            pygame.draw.rect(self.DISPLAY_SURF, BOX_COLOR, (left, top, coverage, BOX_SIZE)) #绘制覆盖层
    pygame.display.update()
    self.FPS_CLOCK.tick(FPS)
4.9  玩家胜利动画
代码语言:javascript
复制
def game_won_animation(self):
    '''玩家胜利显示'''
    covered_boxes = generate_revealed_boxes_data(True)
    color1 = LIGHTBG_COLOR
    color2 = BG_COLOR

    for i in range(13):
        color1, color2 = color2, color1  # 交替背景色
        self.DISPLAY_SURF.fill(color1) #闪烁背景
        self.draw_board(self.main_board, covered_boxes) #绘制所有显示图案
        pygame.display.update()
        pygame.time.wait(300) #每次闪烁间隔300毫秒
4.10  游戏开始动画
代码语言:javascript
复制
def start_game_animation(self):
    '''随机展示8个盒子'''
    cover_boxes = generate_revealed_boxes_data(False) #制造随机翻开的盒子
    boxes = []
    for x in range(BOARD_WIDTH):
        for y in range(BOARD_HEIGHT):
            boxes.append((x, y))
    random.shuffle(boxes) #随机盒子坐标
    box_groups = split_into_group_of(8, boxes) #随机抽取8个盒子坐标

    self.draw_board(self.main_board,cover_boxes) #绘制没翻开板子的游戏界面
    for box_group in box_groups: #循环翻板
        self.reveal_boxes_animation(box_group)
        self.cover_boxes_animation(box_group)

 5. 游戏逻辑判断(游戏核心Memory_Puzzle.py) 

5.1 游戏使用模块和常量
代码语言:javascript
复制
import sys,pygame
from pygame.locals import *
from conf.color import *
from conf.game_conf import *
from core import views
from conf.shape import *
BG_COLOR=NAVYBLUE #背景色
5.2 游戏逻辑判断
代码语言:javascript
复制
def main():
    pygame.init()
    FPS_CLOCK=pygame.time.Clock()
    DISPLAY_SURF=pygame.display.set_mode((WINDOW_WIDTH,WINDOW_HEIGHT))
    Puzzle = views.puzzle(DISPLAY_SURF, FPS_CLOCK)
    pygame.display.set_caption('My Game')
    mouse_x=0 #鼠标x坐标
    mouse_y=0 #鼠标y坐标
    first_selection = None  # 存储第一个翻开的盒子
    DISPLAY_SURF.fill(BG_COLOR)#绘制背景色
    Puzzle.start_game_animation() #游戏开始提示
    while True:
        mouse_clicked=False #初始化鼠标点击
        DISPLAY_SURF.fill(BG_COLOR) #循环掩盖高亮显示
        Puzzle.draw_board(Puzzle.main_board,Puzzle.revealed_boxes)
        for event in pygame.event.get():
            if event.type==QUIT:
                pygame.quit()
                sys.exit()
            elif event.type==MOUSEMOTION: #获取鼠标悬停的像素坐标
                mouse_x,mouse_y=event.pos
            elif event.type==MOUSEBUTTONDOWN: #获取鼠标点击的像素坐标
                mouse_x,mouse_y=event.pos
                mouse_clicked=True
        box_x,box_y=views.get_box_at_pixel(mouse_x, mouse_y)
        if box_x!=None and box_y!=None: #当鼠标在一个框上的时候
            if not Puzzle.revealed_boxes[box_x][box_y]: #没有翻开的牌子高亮显示
                Puzzle.draw_hightlight_box(box_x,box_y)
            if not Puzzle.revealed_boxes[box_x][box_y] and mouse_clicked: #没有翻开牌子并且点击的盒子显示
                Puzzle.reveal_boxes_animation([(box_x,box_y)]) #掀开动画
                Puzzle.revealed_boxes[box_x][box_y]=True #设置翻开坐标
                if first_selection==None:  #检查是否第一次翻牌子
                    first_selection=(box_x,box_y)
                else:
                    icon1_shape,icon1_color=views.get_shape_and_color(Puzzle.main_board, first_selection[0], first_selection[1])
                    icon2_shape,icon2_color=views.get_shape_and_color(Puzzle.main_board, box_x, box_y)
                    if icon1_shape != icon2_shape or icon1_color!=icon2_color: #判断两个方块不相同
                        pygame.time.wait(1000)#等待一秒钟
                        Puzzle.cover_boxes_animation([(first_selection[0], first_selection[1]), (box_x, box_y)])
                        Puzzle.revealed_boxes[first_selection[0]][first_selection[1]] = False
                        Puzzle.revealed_boxes[box_x][box_y]=False
                    elif views.has_won(Puzzle.revealed_boxes): #判断游戏是否胜利
                        Puzzle.game_won_animation() #显示获胜界面
                        pygame.time.wait(200)
                        #初始化数据
                        Puzzle.main_board = views.get_randomized_board() #重置箱子
                        Puzzle.revealed_boxes = views.generate_revealed_boxes_data(False) #重置玩家翻开表
                        #显示游戏界面
                        Puzzle.draw_board(Puzzle.main_board,Puzzle.revealed_boxes)
                        pygame.display.update()
                        pygame.time.wait(1000)
                        #游戏开始前的动画
                        PURPLE.start_game_animation()
                    first_selection=None
        pygame.display.update()
        FPS_CLOCK.tick(FPS)
5.3  运行游戏
代码语言:javascript
复制
if __name__ == '__main__':
    main()
代码语言:javascript
复制
python学习途径

本游戏参考书本 <<Python和Pygame游戏开发>>

游戏源码下载 http://invpy.com/memorypuzzle.py

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2019-05-29 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1. 游戏功能和流程图
  • 2. 游戏配置
    • 配置游戏目录
      • 配置游戏(game_conf.py)
        • 配置颜色(color.py)
          • 配置形状(shape.py)
          • 3. 游戏使用工具函数(views.py)
            • 3.1 工具和绘画类使用模块和常量
              • 3.2 生成游戏数据(游戏坐标,形状,颜色)
                • 3.3 用户的游戏列表(游戏坐标,初始都是空坐标)
                  • 3.4  将盒子列表坐标转化为实际的像素坐标
                    • 3.5  根据坐标返回对应的形状和颜色
                      • 3.6  根据鼠标坐标找到矩形列表坐标
                        • 3.7  列表分组
                          • 3.8  检查牌子是否都开启了
                          • 4  创建游戏绘画类(views.py)
                            • 4.1  创建类的初始化
                              • 4.2  绘制游戏盒子(类方法)
                                • 4.3  绘制没翻开的盒子
                                  • 4.4  绘制已经翻开的盒子
                                    • 4.5  鼠标悬停高亮显示
                                      • 4.6  翻箱动画
                                        • 4.7  合箱动画
                                          • 4.8  动画遮罩层
                                            • 4.9  玩家胜利动画
                                              • 4.10  游戏开始动画
                                              •  5. 游戏逻辑判断(游戏核心Memory_Puzzle.py) 
                                                • 5.1 游戏使用模块和常量
                                                  • 5.2 游戏逻辑判断
                                                    • 5.3  运行游戏
                                                      • python学习途径
                                                      领券
                                                      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档