【拼图游戏】自选图片拼图--基于pygame实现

游戏截图

0927-1

在这里插入图片描述

0927-3

配置类

'''配置类'''
class CFG:
    def __init__(self):
        self.SCREENSIZE = (640, 640)
        self.PICTURE_ROOT_DIR = os.path.join(os.getcwd(), '你的图片文件夹')
        self.FONTPATH = os.path.join(os.getcwd(), '你的字体文件') # 例如simsun.ttc
        self.BACKGROUNDCOLOR = (255, 255, 255)
        self.FPS = 30
        self.NUMRANDOM = 50    # 随机打乱拼图次数

cfg=CFG()

打乱拼图

def newGameBoard(num_rows, num_cols, num_cells):
    board = [i for i in range(num_cells)]
    # 去掉右下角的一块作为空白
    blank_cell_idx = num_cells - 1
    board[blank_cell_idx] = -1
    for i in range(cfg.NUMRANDOM*num_rows): # n*n的拼图,打乱次数为50*n
        direction = random.randint(0, 3)
        if direction == 0:
            blank_cell_idx = moveLeft(board, blank_cell_idx, num_cols)
        elif direction == 1:
            blank_cell_idx = moveRight(board, blank_cell_idx, num_cols)
        elif direction == 2:
            blank_cell_idx = moveUp(board, blank_cell_idx, num_rows, num_cols)
        elif direction == 3:
            blank_cell_idx = moveDown(board, blank_cell_idx, num_cols)
    return board, blank_cell_idx

开始界面

'''游戏开始界面'''
def gameStart(screen, width, height):
    screen.fill(cfg.BACKGROUNDCOLOR)

    tfont = pygame.font.Font(cfg.FONTPATH, width // 4)
    title = tfont.render('Jigsaw', True, (255, 0, 0))
    trect = title.get_rect()
    trect.midtop = (width / 2, height / 10)
    screen.blit(title, trect)

    cfont = pygame.font.Font(cfg.FONTPATH, width // 20)
    content1 = cfont.render('Press number key to start', True, (0, 0, 255))
    content2 = cfont.render('Alternatives:3*3 4*4 …… 9*9', True, (0, 0, 0))
    crect1 = content1.get_rect()
    crect1.midtop = (width / 2, height / 2.2)
    crect2 = content2.get_rect()
    crect2.midtop = (width / 2, height / 1.8)
    screen.blit(content1, crect1)
    screen.blit(content2, crect2)

    while True:
        for event in pygame.event.get():
            if (event.type == pygame.QUIT) or (event.type == pygame.KEYDOWN and event.key == pygame.K_ESCAPE):
                pygame.quit()
                sys.exit()
            elif event.type == pygame.KEYDOWN:
                for i in range(2,10):
                    if event.key == ord(str(i)):
                        return i
        pygame.display.update()

移动方块

def moveRight(board, blank_cell_idx, num_cols):
    if blank_cell_idx % num_cols == 0: return blank_cell_idx
    board[blank_cell_idx - 1], board[blank_cell_idx] = board[blank_cell_idx], board[blank_cell_idx - 1]
    return blank_cell_idx - 1
    
def moveLeft(board, blank_cell_idx, num_cols):
    if (blank_cell_idx + 1) % num_cols == 0: return blank_cell_idx
    board[blank_cell_idx + 1], board[blank_cell_idx] = board[blank_cell_idx], board[blank_cell_idx + 1]
    return blank_cell_idx + 1
    
def moveDown(board, blank_cell_idx, num_cols):
    if blank_cell_idx < num_cols: return blank_cell_idx
    board[blank_cell_idx - num_cols], board[blank_cell_idx] = board[blank_cell_idx], board[blank_cell_idx - num_cols]
    return blank_cell_idx - num_cols
    
def moveUp(board, blank_cell_idx, num_rows, num_cols):
    if blank_cell_idx >= (num_rows - 1) * num_cols: return blank_cell_idx
    board[blank_cell_idx + num_cols], board[blank_cell_idx] = board[blank_cell_idx], board[blank_cell_idx + num_cols]
    return blank_cell_idx + num_cols

判断游戏是否结束

def isGameOver(board, size):
    assert isinstance(size, int)
    num_cells = size * size
    for i in range(num_cells - 1):
        if board[i] != i: return False
    return True

结束界面

def gameOver(screen, width, height):
    screen.fill(cfg.BACKGROUNDCOLOR)

    tfont = pygame.font.Font(cfg.FONTPATH, width // 8)
    title = tfont.render('Success!', True, (255, 0, 0))
    trect = title.get_rect()
    trect.midtop = (width / 2, height / 3.5)
    screen.blit(title, trect)

    cfont = pygame.font.Font(cfg.FONTPATH, width // 25)
    content = cfont.render('press space to try again', False, (0,0,0))
    crect = content.get_rect()
    crect.midtop = (width / 2, height / 2)
    screen.blit(content, crect)

    pygame.display.update()
    while True:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                sys.exit()
            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_ESCAPE:
                    pygame.quit()
                    sys.exit()
                if event.key == pygame.K_SPACE: # 按空格重新开始游戏
                    main()
        pygame.display.update()

主函数

def main():
    pygame.init()
    clock = pygame.time.Clock()
    # 加载图片
    img = pygame.image.load(GetImage(cfg.PICTURE_ROOT_DIR))
    img = pygame.transform.scale(img, cfg.SCREENSIZE)
    img_rect = img.get_rect()
    # 设置窗口
    screen = pygame.display.set_mode(cfg.SCREENSIZE)
    pygame.display.set_caption('Jigsaw')
    # 游戏开始界面
    size = gameStart(screen, img_rect.width, img_rect.height)
    assert isinstance(size, int)
    num_rows, num_cols = size, size
    num_cells = size * size
    # 计算Cell大小
    cell_width = img_rect.width // num_cols
    cell_height = img_rect.height // num_rows
    # 避免初始化为原图
    while True:
        game_board, blank_cell_idx = newGameBoard(num_rows, num_cols, num_cells)
        if not isGameOver(game_board, size):
            break
    # 主循环
    is_running = True
    while is_running:
        for event in pygame.event.get():
            if (event.type == pygame.QUIT) or (event.type == pygame.KEYDOWN and event.key == pygame.K_ESCAPE):
                pygame.quit()
                sys.exit()
            elif event.type == pygame.KEYDOWN:  # wsad操作
                if event.key == pygame.K_UP or event.key == ord('w'):
                    blank_cell_idx = moveUp(game_board, blank_cell_idx, num_rows, num_cols)
                elif event.key == pygame.K_DOWN or event.key == ord('s'):
                    blank_cell_idx = moveDown(game_board, blank_cell_idx, num_cols)
                elif event.key == pygame.K_LEFT or event.key == ord('a'):
                    blank_cell_idx = moveLeft(game_board, blank_cell_idx, num_cols)
                elif event.key == pygame.K_RIGHT or event.key == ord('d'):
                    blank_cell_idx = moveRight(game_board, blank_cell_idx, num_cols)
            elif event.type == pygame.MOUSEBUTTONDOWN and event.button == 1:
                x, y = pygame.mouse.get_pos()  # 鼠标点击
                x_pos = x // cell_width
                y_pos = y // cell_height
                idx = x_pos + y_pos * num_cols
                if idx == blank_cell_idx - 1:
                    blank_cell_idx = moveRight(game_board, blank_cell_idx, num_cols)
                elif idx == blank_cell_idx + 1:
                    blank_cell_idx = moveLeft(game_board, blank_cell_idx, num_cols)
                elif idx == blank_cell_idx + num_cols:
                    blank_cell_idx = moveUp(game_board, blank_cell_idx, num_rows, num_cols)
                elif idx == blank_cell_idx - num_cols:
                    blank_cell_idx = moveDown(game_board, blank_cell_idx, num_cols)
        # 判断游戏是否结束
        if isGameOver(game_board, size):
            game_board[blank_cell_idx] = num_cells - 1
            is_running = False

        screen.fill(cfg.BACKGROUNDCOLOR)
        for i in range(num_cells):
            if game_board[i] == -1:
                continue
            x_pos = i // num_cols
            y_pos = i % num_cols
            rect = pygame.Rect(y_pos * cell_width, x_pos * cell_height, cell_width, cell_height)
            img_area = pygame.Rect((game_board[i] % num_cols) * cell_width, (game_board[i] // num_cols) * cell_height,
                                   cell_width, cell_height)
            screen.blit(img, rect, img_area)
        for i in range(num_cols + 1):
            pygame.draw.line(screen, (0,0,0), (i * cell_width, 0), (i * cell_width, img_rect.height))
        for i in range(num_rows + 1):
            pygame.draw.line(screen, (0,0,0), (0, i * cell_height), (img_rect.width, i * cell_height))
        pygame.display.update()
        clock.tick(cfg.FPS)
    # 游戏结束界面
    gameOver(screen, img_rect.width, img_rect.height)
  • 20
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 21
    评论
基于Pygame的游戏设计是使用Python编程语言和Pygame模块来进行游戏开发的一种方式。Pygame是一个专为电子游戏设计的Python模块,它提供了丰富的功能和工具,可以帮助开发者轻松地创建2D游戏。通过Pygame,开发者可以处理图形、音效、输入设备和游戏逻辑等方面的功能。 在Python游戏设计中,使用Pygame可以轻松创建各种类型的游戏,包括贪吃蛇、飞机大战等。通过Pygame提供的功能,开发者可以实现游戏的界面设计、用户交互、游戏逻辑和音效等方面的功能。同时,Pygame还提供了一些实用的工具和函数,方便开发者进行游戏开发和调试。 如果你对Python游戏设计感兴趣,可以参考以下步骤: 1. 安装Pygame模块:在官方网站https://www.pygame.org/上下载Pygame模块,并按照官方文档的说明进行安装。 2. 导入Pygame模块:在Python代码中导入Pygame模块,以便可以使用它提供的功能和工具。 3. 创建游戏窗口:使用Pygame创建一个游戏窗口,设置窗口的大小和标题等属性。 4. 处理用户输入:使用Pygame监听用户的键盘和鼠标输入,并根据用户的操作进行相应的响应和处理。 5. 绘制游戏元素:使用Pygame提供的绘图函数和工具,在游戏窗口中绘制游戏元素,如精灵、背景和特效等。 6. 更新游戏逻辑:在游戏循环中,根据游戏的逻辑进行状态更新和处理,包括碰撞检测、计分和游戏结束等。 7. 播放音效和音乐:使用Pygame提供的音效和音乐功能,为游戏添加声音效果和背景音乐。 8. 调试和优化:在开发过程中,通过调试和优化,确保游戏的正常运行和流畅性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 21
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

可可卷

不要看到我~~

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值