拼图游戏(puzzle)是一种常见的益智游戏,玩家通过拖动图块来正确拼接成完整的图片。
由一张原图,分割成图块,拼图块的大小将会根据行列数自动调整,然后随机打乱,玩家通过拖拽图块,最后复原原图。
🐛图片分割
将原图分割成 piece1~9
from PIL import Image
def split_image(image_path):
img = Image.open(image_path)
width, height = img.size
piece_width = width // 3
piece_height = height // 3
count = 1
for i in range(3):
for j in range(3):
box = (j * piece_width, i * piece_height, (j + 1) * piece_width, (i + 1) * piece_height)
piece = img.crop(box)
piece.save(f'piece{count}.png')
count += 1
if __name__ == '__main__':
split_image('test.jpg')
🐛图片乱拼
将分割的图片乱拼起来,合成一张新的图
from PIL import Image
import random
def split_image(image_path):
img = Image.open(image_path)
width, height = img.size
piece_width = width // 3
piece_height = height // 3
count = 1
pieces = []
for i in range(3):
for j in range(3):
box = (j * piece_width, i * piece_height, (j + 1) * piece_width, (i + 1) * piece_height)
piece = img.crop(box)
pieces.append(piece)
random.shuffle(pieces)
new_img = Image.new('RGB', (width, height))
count = 0
for i in range(3):
for j in range(3):
new_img.paste(pieces[count], (j * piece_width, i * piece_height))
count += 1
new_img.save('new_image.jpg')
if __name__ == '__main__':
split_image('test.jpg')
🐛九宫格拼图
# 拖拽拼图
import pygame
import random
import sys
# 设置屏幕尺寸和信息框高度
WINDOW_WIDTH, WINDOW_HEIGHT = 600, 640
WIDTH, HEIGHT = 600, 600
INFO_BOX_HEIGHT = 40
TILE_SIZE = 200 # 每个拼图块的大小
ROWS, COLS = 3, 3 # 拼图的行数和列数
# 随机打乱拼图
def shuffle_image(image):
pieces = [image.subsurface((x * TILE_SIZE, y * TILE_SIZE, TILE_SIZE, TILE_SIZE))
for y in range(ROWS) for x in range(COLS)]
pieces = random.sample(pieces, len(pieces))
return pieces
# 主函数
def main():
pygame.init()
screen = pygame.display.set_mode((WINDOW_WIDTH, WINDOW_HEIGHT))
pygame.display.set_caption("Sliding Puzzle Game")
clock = pygame.time.Clock()
start_time = pygame.time.get_ticks() # 记录开始时间
finished = False
#game_over = False # 游戏结束标志
#original_image = pygame.image.load("new_image.jpg")
original_image = pygame.image.load("test.jpg")
original_image = pygame.transform.scale(original_image, (WIDTH, HEIGHT))
pieces = shuffle_image(original_image)
empty_tile = len(pieces) - 1 # 空白拼图块的索引
selected_tile = None # 当前选中的拼图块索引
#drag_offset = (0, 0) # 拖拽时的偏移量
while not finished:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
if event.type == pygame.MOUSEBUTTONDOWN:
if event.button == 1:
x, y = pygame.mouse.get_pos()
selected_tile = (y // TILE_SIZE) * COLS + (x // TILE_SIZE)
#if selected_tile != empty_tile:
#drag_offset = (x - (selected_tile % COLS) * TILE_SIZE, y - (selected_tile // COLS) * TILE_SIZE)
if event.type == pygame.MOUSEBUTTONUP:
if event.button == 1 and selected_tile is not None:
x, y = pygame.mouse.get_pos()
target_tile = (y // TILE_SIZE) * COLS + (x // TILE_SIZE)
if target_tile != empty_tile and target_tile != selected_tile:
pieces[selected_tile], pieces[target_tile] = pieces[target_tile], pieces[selected_tile]
selected_tile = None
screen.fill((0, 0, 0))
# 绘制拼图部分
for i, piece in enumerate(pieces):
x = (i % COLS) * TILE_SIZE
y = (i // COLS) * TILE_SIZE
screen.blit(piece, (x, y))
# 绘制信息框
pygame.draw.rect(screen, (255, 255, 224), (0, WINDOW_HEIGHT - INFO_BOX_HEIGHT, WINDOW_WIDTH, INFO_BOX_HEIGHT))
# 绘制计时信息
current_time = (pygame.time.get_ticks() - start_time) // 1000 # 计算当前用时(秒)
font = pygame.font.Font(None, 24)
time_text = font.render("Time: {} seconds".format(current_time), True, (60, 179, 113))
screen.blit(time_text, (10, WINDOW_HEIGHT - INFO_BOX_HEIGHT + 10))
pygame.display.flip()
clock.tick(60)
if __name__ == "__main__":
main()
🐛拼图小游戏
行列数更大,图块分得更小,难度更大
"""
description: 拼图小游戏(拖拽拼图)@2024-05-25
written by yjan.10:16
remark:
- 原图: test.jpg
"""
import pygame
import random
import sys
# 基本设置
WINDOW_WIDTH, WINDOW_HEIGHT = 600, 640 # 设置屏幕尺寸
WIDTH, HEIGHT = 600, 600 # 拼图区域大小
INFO_BOX_HEIGHT = 40 # 信息框高度
#TILE_SIZE = 100 # 每个拼图块的大小
#ROWS, COLS = 6, 6 # 拼图的行数和列数
ROWS, COLS = 6, 6 # 拼图的行数和列数
TILE_SIZE = WIDTH // COLS # 图块的大小
# 随机打乱拼图
def shuffle_image(image):
pieces = [image.subsurface((x * TILE_SIZE, y * TILE_SIZE, TILE_SIZE, TILE_SIZE))
for y in range(ROWS) for x in range(COLS)]
pieces = random.sample(pieces, len(pieces))
return pieces
# 主函数
def main():
pygame.init()
screen = pygame.display.set_mode((WINDOW_WIDTH, WINDOW_HEIGHT))
pygame.display.set_caption("Sliding Puzzle Game")
clock = pygame.time.Clock()
start_time = pygame.time.get_ticks() # 记录开始时间
finished = False
#game_over = False # 游戏结束标志
#original_image = pygame.image.load("new_image.jpg")
original_image = pygame.image.load("test.jpg")
original_image = pygame.transform.scale(original_image, (WIDTH, HEIGHT))
pieces = shuffle_image(original_image)
empty_tile = len(pieces) - 1 # 空白拼图块的索引
selected_tile = None # 当前选中的拼图块索引
#drag_offset = (0, 0) # 拖拽时的偏移量
while not finished:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
if event.type == pygame.MOUSEBUTTONDOWN:
if event.button == 1:
x, y = pygame.mouse.get_pos()
selected_tile = (y // TILE_SIZE) * COLS + (x // TILE_SIZE)
#if selected_tile != empty_tile:
#drag_offset = (x - (selected_tile % COLS) * TILE_SIZE, y - (selected_tile // COLS) * TILE_SIZE)
if event.type == pygame.MOUSEBUTTONUP:
if event.button == 1 and selected_tile is not None:
x, y = pygame.mouse.get_pos()
target_tile = (y // TILE_SIZE) * COLS + (x // TILE_SIZE)
if target_tile != empty_tile and target_tile != selected_tile:
pieces[selected_tile], pieces[target_tile] = pieces[target_tile], pieces[selected_tile]
selected_tile = None
screen.fill((0, 0, 0))
# 绘制拼图部分
for i, piece in enumerate(pieces):
x = (i % COLS) * TILE_SIZE
y = (i // COLS) * TILE_SIZE
screen.blit(piece, (x, y))
# 绘制信息框
pygame.draw.rect(screen, (255, 255, 224), (0, WINDOW_HEIGHT - INFO_BOX_HEIGHT, WINDOW_WIDTH, INFO_BOX_HEIGHT))
# 绘制计时信息
current_time = (pygame.time.get_ticks() - start_time) // 1000 # 计算当前用时(秒)
font = pygame.font.Font(None, 24)
time_text = font.render("Time: {} seconds".format(current_time), True, (60, 179, 113))
screen.blit(time_text, (10, WINDOW_HEIGHT - INFO_BOX_HEIGHT + 10))
pygame.display.flip()
clock.tick(60)
if __name__ == "__main__":
main()