游戏截图
![0927-1](https://i-blog.csdnimg.cn/blog_migrate/ec1a008ad8e6bb0228f499ef85284862.png)
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/2919c360c324338c172a8a5f03c630a1.jpeg#pic_center)
![0927-3](https://i-blog.csdnimg.cn/blog_migrate/d7661b1c4f37abd47bd976cf2dab68da.png)
配置类
'''配置类'''
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)