使用Pygame库编写拼图游戏01

使用Pygame库编写拼图游戏01

代码举例

# -*- coding:utf-8 -*-
from sys import exit  # 使用sys模块的exit函数来退出游戏
import pygame
from pygame.locals import *  # 导入一些常用的函数和常量

# Sta 参数赋值
SCREEN_WIDTH = 600
SCREEN_HEIGHT = 600
srcImgFilename = 'src.jpg'
# End 参数赋值

# Sta 资源初始化
pygame.init()  # 初始化pygame
screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))  # 创建一个指定大小的窗口
srcSurface = pygame.image.load(srcImgFilename).convert()  # 加载背景图
# End 资源初始化

# Sta 主逻辑
while True:
    for event in pygame.event.get():
        if event.type == QUIT:
            exit()  # 接收到退出事件后退出程序

    screen.blit(srcSurface, (0, 0))
    pygame.display.update()  # 刷新一下画面
# End 主逻辑

完整代码

import random
import time
import copy
import operator
from sys import exit  # 使用sys模块的exit函数来退出游戏

import pygame
from pygame.locals import *  # 导入一些常用的函数和常量

SCREEN_WIDTH = 600
SCREEN_HEIGHT = 600
ROW = 3
COL = 3
CELL_WIDTH = SCREEN_WIDTH / ROW
CELL_HEIGHT = SCREEN_HEIGHT / COL

firstClickCell = None
successFlag = False


class Cell:
    def __init__(self, cellImg, x, y, id):
        self.cellImg = cellImg
        self.x = x
        self.y = y
        self.id = id

    def isOver(self):
        w, h = self.cellImg.get_size()
        point_x, point_y = pygame.mouse.get_pos()  # 返回鼠标当前坐标
        in_x = self.x < point_x < self.x + w
        in_y = self.y < point_y < self.y + h
        # print('id,x,y', self.id,':' ,self.getX(), ',',self.getY())
        # print('id', self.id, in_x, in_y)
        return in_x and in_y

    def isPressed(self):
        # print('is_pressed')
        if self.isOver():
            b1, b2, b3 = pygame.mouse.get_pressed()
            if b1 == 1:
                global firstClickCell
                global successFlag

                if firstClickCell is None:
                    firstClickCell = self
                    print('id为{}的块被点击'.format(firstClickCell.getId()))
                else:
                    print('交换{}与{}的坐标'.format(firstClickCell.getId(), self.getId()))
                    cellSwitch(firstClickCell, self)
                    if isFinish(cellList):
                        print('成功!')
                        successFlag = True
                    else:
                        successFlag = False
                    firstClickCell = None
                return True
        return False

    def render(self, screen):
        screen.blit(self.cellImg, (self.x, self.y))

    def setXY(self, x, y):
        self.x = x
        self.y = y

    def getX(self):
        return self.x

    def getY(self):
        return self.y

    def getId(self):
        return self.id


def chop(imgSrc):
    '''切割原图,其中imgSrc为pygame.Surface类型'''
    cellList = []
    id = 0
    # 从左往右 从上到下
    for i in range(ROW):
        for j in range(COL):
            # print(j * CELL_WIDTH, i * CELL_HEIGHT)
            cellImg = imgSrc.subsurface(j * CELL_WIDTH, i * CELL_HEIGHT, CELL_WIDTH, CELL_HEIGHT)
            tempCell = Cell(cellImg, j * CELL_WIDTH, i * CELL_HEIGHT, id)
            cellList.append(tempCell)
            id = id + 1
    return cellList


def cellSwitch(cell1, cell2):
    tempX = cell1.getX()
    tempY = cell1.getY()
    cell1.setXY(cell2.getX(), cell2.getY())
    cell2.setXY(tempX, tempY)


def isFinish(cellList):
    for cell in cellList:
        quo = cell.getId() // ROW  # 商
        rem = cell.getId() % COL  # 余数
        if quo * 200 != cell.getY() or rem * 200 != cell.getX():
            return False
    return True


def shuffle(cellList):
    random.shuffle(cellList)
    i = 0
    while i < len(cellList) - 1:
        cellSwitch(cellList[i], cellList[i + 1])
        i += 2


pygame.init()  # 初始化pygame
screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))  # 创建了一个窗口
pygame.display.set_caption('交换式拼图')  # 设置窗口标题
imgSrc = pygame.image.load('src.jpg').convert()  # 原图
cellList = chop(imgSrc)

# 随机化数组
while isFinish(cellList):
    shuffle(cellList)
# 随机化数组

while True:  # 游戏主循环
    for event in pygame.event.get():
        if event.type == QUIT:
            exit()  # 接收到退出事件后退出程序
        elif event.type == MOUSEBUTTONDOWN:
            for cell in cellList:
                if cell.isPressed():
                    break

    for cell in cellList:
        cell.render(screen)

    if not successFlag:
        # Sta 绘制分割线
        pygame.draw.line(screen, (0, 0, 0), (200, 0), (200, 600))
        pygame.draw.line(screen, (0, 0, 0), (400, 0), (400, 600))
        pygame.draw.line(screen, (0, 0, 0), (0, 200), (600, 200))
        pygame.draw.line(screen, (0, 0, 0), (0, 400), (600, 400))
        # End 绘制分割线

    pygame.display.update()  # 刷新一下画面

src.jpg

使用Pygame库编写拼图游戏01

B站视频传送门