【Python游戏开发】拼图小游戏demo

使用mu编辑器 + pgzero编写拼图小游戏

python 复制代码
import random

SIZE = 96           # 设置每张图块的大小
WIDTH = SIZE * 3    # 根据土块大小设置窗口
HEIGHT = SIZE * 3
pics = []           # 存放图块
finished  = False   # 游戏结束标识

# 将前八张图块存放在pics列表中
for i in range(8):
    # 使用Actor()方法创建图块
    pic = Actor("puzzle_pic" + str(i))
    # 给每张图块设置索引值
    pic.index = i
    pics.append(pic)

# 将图块列表pics的顺序打乱
random.shuffle(pics)

# 设立每块图块的初始位置
for i in range(8):
    # 使用余数确认x坐标,如0、3、6余数为0,所以都在第一列
    pics[i].left = i % 3 * SIZE
    # 使用除数确认y坐标,如0、1、2除以3整数部分都为0,所以在第一行
    pics[i].top = i // 3 * SIZE
# 创建最后一张图块,固定放置在最后一个位置
lastpic = Actor("puzzle_pic8")
lastpic.left = 2 * SIZE
lastpic.top = 2 * SIZE

def draw():
    # 设置游戏背景色
    screen.fill((255,255,255))
    # 绘制图块
    for pic in pics:
        pic.draw()
    # 如果游戏结束,则将最后一张图块绘制进游戏中
    if finished:
        lastpic.draw()
        # 显示结束语
        screen.draw.text("victory!",center = (WIDTH // 2, HEIGHT // 2),
                            fontsize = 50, color = "red")

# 鼠标点击处理
def on_mouse_down(pos):
    if finished:
        return
    # 获取被点击位置的坐标
    grid_x = pos[0] // SIZE
    grid_y = pos[1] // SIZE
    # 检测是否存在图块
    thispic = get_pic(grid_x,grid_y)
    # 不存在,则return,不执行任何存在
    if thispic == None:
        return
    # 存在,则判断其相邻位置是否为空,如为空,则移动图块至空位
    if grid_y> 0 and get_pic(grid_x,grid_y - 1) == None:
        thispic.y -= SIZE
        return
    if grid_y< 2 and get_pic(grid_x,grid_y + 1 ) == None:
        thispic.y += SIZE
        return
    if grid_x> 0 and get_pic(grid_x - 1,grid_y) == None:
        thispic.x -= SIZE
        return
    if grid_x< 2 and get_pic(grid_x + 1,grid_y) == None:
        thispic.x += SIZE
        return

# 通过坐标获取图块信息
def get_pic(grid_x,grid_y):
    # 循环遍历图块判断是否有图块在对应坐标中
    for pic in pics:
        if pic.x // SIZE == grid_x and pic.y // SIZE == grid_y:
           return pic
    return None

def update():
    global finished
    if finished:
        return
    # 遍历前八个坐标位置,判断位置上的图块是否符合需求
    for i in range(8):
        # 获取坐标位置上的图块信息
        pic = get_pic(i % 3 ,i// 3)
        # 如果不存在图块或者图块索引值不对,则return
        if (pic == None or pic.index != i):
            return
    # 游戏结束
    finished = True
    # 设置胜利
    sounds.win.play()

代码执行,便会生成3x3拼图小游戏

完成拼图后

但是,因为是使用随机数Random无规则的打乱顺序,所以会导致游戏存在无解的情况

所以放弃采用random.shuffle(pics)打乱图块的方法,改为程序多次自动随机点击空图块相邻的图块,实现打乱图块效果

python 复制代码
# 将图块列表pics的顺序打乱
# random.shuffle(pics)
blank_pic = [2,2]   # 初始空白图块的坐标
# 逆向打乱拼图顺序
def init_pics():
    global blank_pic
    move_list = []
    # 将空白图块相邻的图块位置插入列表中
    if blank_pic[0] > 0:
        move_list.append([blank_pic[0] - 1,blank_pic[1]])
    if blank_pic[0] < 2:
        move_list.append([blank_pic[0] + 1,blank_pic[1]])
    if blank_pic[1] > 0:
        move_list.append([blank_pic[0],blank_pic[1] - 1])
    if blank_pic[1] < 2:
        move_list.append([blank_pic[0],blank_pic[1] + 1])
    # 从列表中随机一个图块进行点击
    blank_pic = random.choice(move_list)
    on_mouse_down([blank_pic[0] * SIZE,blank_pic[1] * SIZE])

最后,根据自己的设定,循环调用init_pics方法,实现打乱效果

python 复制代码
for i in range(50):
    init_pics()

运行结果如图,也是实现了随机打乱图块的效果,且不会出现无解的情况

调整优化:

  1. SUM_XSUM_Y:可设置拼图难度,生成m*n拼图
  2. random_num:设置系统打乱方块的步数
python 复制代码
# 在这里写上你的代码
import random
SUM_X = 4               # 设置每行存放图块的数量
SUM_Y = 3               # 设置每列存放图块的数量
random_num = 100        # 打乱方块次数
SIZE = 96               # 设置每张图块的大小

SUM_I = SUM_X * SUM_Y   # 图块总数
WIDTH = SIZE * SUM_X    # 根据土块大小设置窗口
HEIGHT = SIZE * SUM_Y
pics = []               # 存放图块
finished  = False       # 游戏结束标识

blank_pic = [SUM_X - 1,SUM_Y - 1]   # 空白图块坐标

# 将显示图块存放在pics列表中
for i in range(SUM_I - 1):
    # 使用Actor()方法创建图块
    pic = Actor("puzzle_pic" + str(i))
    # 给每张图块设置索引值
    pic.index = i
    pics.append(pic)

# 设立每块图块的初始位置
for i in range(SUM_I - 1):
    # 使用余数确认x坐标
    pics[i].left = i % SUM_Y * SIZE
    # 使用除数确认y坐标
    pics[i].top = i // SUM_X * SIZE
    
# 创建最后一张图块,固定放置在最后一个位置
lastpic = Actor("puzzle_pic8")
lastpic.left = SUM_X * SIZE
lastpic.top = SUM_Y * SIZE

def draw():
    # 设置游戏背景色
    screen.fill((255,255,255))
    # 绘制图块
    for pic in pics:
        pic.draw()
    # 如果游戏结束,则将最后一张图块绘制进游戏中
    if finished:
        lastpic.draw()
        # 显示结束语
        screen.draw.text("victory!",center = (WIDTH // 2, HEIGHT // 2),
                            fontsize = 50, color = "red")

# 鼠标点击处理
def on_mouse_down(pos):
    if finished:
        return
    # 获取被点击位置的坐标
    grid_x = pos[0] // SIZE
    grid_y = pos[1] // SIZE
    # 检测是否存在图块
    thispic = get_pic(grid_x,grid_y)
    # 不存在,则return,不执行任何存在
    if thispic == None:
        return
    # 存在,则判断其相邻位置是否为空,如为空,则移动图块至空位
    if grid_y> 0 and get_pic(grid_x,grid_y - 1) == None:
        thispic.y -= SIZE
        return
    if grid_y< (SUM_Y - 1) and get_pic(grid_x,grid_y + 1 ) == None:
        thispic.y += SIZE
        return
    if grid_x> 0 and get_pic(grid_x - 1,grid_y) == None:
        thispic.x -= SIZE
        return
    if grid_x< (SUM_X - 1) and get_pic(grid_x + 1,grid_y) == None:
        thispic.x += SIZE
        return

# 通过坐标获取图块信息
def get_pic(grid_x,grid_y):
    # 循环遍历图块判断是否有图块在对应坐标中
    for pic in pics:
        if pic.x // SIZE == grid_x and pic.y // SIZE == grid_y:
           return pic
    return None

def update():
    global finished
    if finished:
        return
    # 遍历前八个坐标位置,判断位置上的图块是否符合需求
    for i in range(SUM_I - 1):
        # 获取坐标位置上的图块信息
        pic = get_pic(i % SUM_X ,i// SUM_Y)
        # 如果不存在图块或者图块索引值不对,则return
        if (pic == None or pic.index != i):
            return
    # 游戏结束
    finished = True
    # 设置胜利
    sounds.win.play()
    
# 逆向打乱拼图顺序
def init_pics():
    global blank_pic
    move_list = []
    if blank_pic[0] > 0:
        move_list.append([blank_pic[0] - 1,blank_pic[1]])
    if blank_pic[0] < SUM_X - 1:
        move_list.append([blank_pic[0] + 1,blank_pic[1]])
    if blank_pic[1] > 0:
        move_list.append([blank_pic[0],blank_pic[1] - 1])
    if blank_pic[1] < SUM_Y - 1:
        move_list.append([blank_pic[0],blank_pic[1] + 1])
    # 从列表中随机一个移动方法
    blank_pic = random.choice(move_list)
    on_mouse_down([blank_pic[0] * SIZE,blank_pic[1] * SIZE])
    
for i in range(random_num):
    init_pics()

因为图块是随机打乱的,我们无法确认随机出来的图块会不会跟没打乱的图块一致,出现一进游戏就获胜的情况,但这我们可以加代码去判定,比较简单,所以就不阐述了

相关推荐
数云界29 分钟前
使用 VSCode 在 Python 中创建项目环境
ide·vscode·python
m0_6085709831 分钟前
vscode对python进行多卡调试
ide·vscode·python
zhang-ge44 分钟前
python提取pdf表格到excel:拆分、提取、合并
python·pdf·excel
计算机学姐44 分钟前
基于python+django+vue的在线学习资源推送系统
开发语言·vue.js·python·学习·django·pip·web3.py
吃什么芹菜卷1 小时前
2024.9最新:CUDA安装,pytorch库安装
人工智能·pytorch·笔记·python·深度学习
鬼圣1 小时前
【软件测试】--xswitch将请求代理到测试桩
软件测试·python·flask·测试桩·xswitch插件
快快小毛毛1 小时前
CC攻击防御策略要怎么调整?使用游戏盾有效解决
运维·服务器·网络·tcp/ip·游戏·udp
王大傻09281 小时前
python selenium 显示等待 + EC
开发语言·python·selenium·自动化
闲人编程1 小时前
Python实现 Socket.IO 的在线游戏场景
开发语言·python·游戏·网络编程·io·socket·异步
雪小妮1 小时前
python 使用seleniumwire获取响应数据以及请求参数
python