小学生python游戏编程5----拼图游戏继

  • 前言
  • 应用知识点
  • 1、python知识点
  • 1.1 通过点击图块的次数,交换图块
  • 1.2 输赢确定
  • 1.3 对方块进行描边及选中的方块显红框
  • 1.4 读取文件及写入成绩
  • 2、pygamezero知识点
  • 2.1 点击图块,互换位置
  • 2.2 判断输赢
  • 2.3 改进,点击图片时进行划红框,每块显示绿框
  • 2.4 增加底框
  • 总结
  • 源码获取


前言

接前两篇文章,小学生python游戏编程3----拼图游戏-准备,小学生python游戏编程4----拼图游戏今天此主拼图游戏做完整 ,上次写到可以打乱图片,拼成游戏界面,今天主要写要如何通过点击图块互换位置,如何全局判断输赢,显示用时间及历史最高记录。

应用知识点

1、python知识点

1.1 通过点击图块的次数,交换图块

if clickTime % 2 == 0:  # 点击偶数次
    clickId1 = k  # 第一个要交换的小拼图块序号
    clickTime += 1  # 点击次数加1
elif clickTime % 2 == 1:  # 点击奇数次
    clickId2 = k  # 第二个要交换的小拼图块序号
    clickTime += 1  # 点击次数加1
    jiaohuanFk(clickId1, clickId2)  # 交换两个小拼图块位置

1.2 输赢确定

通过全局变量 allRight 进行设置,通过浏览每个小方块的位置与最初的方块集(打乱顺序前的)位置进行比对,如都一致则拼对了。
allRight = True # 假设全拼对了
for i in range(3):
for j in range(3):
tile = grid[i*3+j]
# 遍历,只要有一个小拼图的位置不对,就没有全拼对
# print(‘第’,i,j,tile.left,tile.top)
# print(tile.left,j * TILE_SIZE_w,‘后’,tile.top,i * TILE_SIZE_h)
if tile.left != j * TILE_SIZE_w or tile.top != i * TILE_SIZE_h:
allRight = False # 拼错了
break
# 如果上面的if语句都不执行,则表示全拼对了

1.3 对方块进行描边及选中的方块显红框

for i in range(x):  # 画两条横线、两条竖线
        screen.draw.line((0, i * TILE_SIZE_h), (WIDTH, i * TILE_SIZE_h), 'green')
        screen.draw.line((i * TILE_SIZE_w, 0), (i * TILE_SIZE_w, y * TILE_SIZE_h), 'green')
    if clickId1 != -1:  # 为选中的第一个小拼图块画一个红色框
        screen.draw.rect(Rect((grid[clickId1].left, grid[clickId1].top), (TILE_SIZE_w, TILE_SIZE_h)), 'red')

1.4 读取文件及写入成绩

读取文件,设置变量
txtFile = open(‘dangan.txt’, ‘r’) # 打开最佳时间记录存档文件
line = txtFile.readline() # 读取一行字符串
oldTime = int(line) # 将记录的秒数转换为整型存储
txtFile.close() # 关闭文件
start = datetime.datetime.now() # 程序运行开始计时
newTime = 0 # 这次游戏花了多长时间
游戏结束时,对比成绩,如有新战绩把新绩写入文档
if allRight:
if newTime < oldTime: # 看看是否更新最短时间记录
txtFile = open(‘rank.txt’, ‘w’)
txtFile.write(str(newTime))
txtFile.close()
具体细节多看下面的原码,想试试效果的可直接复制下来运行,还是希望你按自己的想法录一篇,会体会更深。

2、pygamezero知识点

2.1 点击图块,互换位置

效果:

小学生python项目 小学生python编程教程_游戏

代码:

import pgzrun  # 导入游戏库
from pgzero.actor import Actor
from pgzero.screen import Screen
screen: Screen  # 类型标注

TILE_SIZE_w = 132 # 根据小图块的宽设置
TILE_SIZE_h = 118  #  根据小图块的高设置
x = 5  # 横向方块数
y = 5  # 纵向方块数
WIDTH = x*TILE_SIZE_w  # 设置窗口的宽度
HEIGHT = y*TILE_SIZE_h  # 设置窗口的高度
TITLE = '拼图小游戏'

clickTime = 0  # 记录鼠标点击了多少次
clickId1 = clickId2 = -1 # 两次点击的小拼图块的序号

fk_list =[]
for i in range(1,x*y+1):
    fk_list.append(Actor('fenge\\df-'+str(i)))

grid = [] # 列表,用来存放最终所有拼图信息
for i in range(x): # 对行循环
    for j in range(y): # 对列循环
        # print(i*x+j)
        fangkuai = fk_list[i*x+j] # 导入拼图方块图片
        fangkuai.left = j * TILE_SIZE_w # 拼图方块图片最左边的x坐标
        fangkuai.top = i * TILE_SIZE_h  # 拼图方块图片最顶部的y坐标
        grid.append(fangkuai) # 将当前拼图加入到列表中

# 以下函数实现两个小拼图块位置的交换
def jiaohuanFk(a, b):
    # i,j为要交换的两个小拼图块的序号
    # 以下利用tempPos中间变量,实现两个小拼图块位置的交换
    tempPos = grid[a].pos
    grid[a].pos = grid[b].pos
    grid[b].pos = tempPos

import random
# 重复随机交换多次小拼图的位置
for k in range(x*y-1):
    i = random.randint(0, x*y-1)  # 第一个小拼图块的序号
    j = random.randint(0, x*y-1)  # 第二个小拼图块的序号
    jiaohuanFk(i, j) # 调用函数交换两个小拼图块的位置

print('ok')
def draw():  # 绘制模块,每帧重复执行
    screen.clear()  # 每帧清除屏幕,便于重新绘制
    for fk in grid:
        fk.draw()  # 绘制小拼图块


def on_mouse_down(pos, button): # 当鼠标按键时执行
    global clickTime, clickId1, clickId2
    for k in range(x*y): # 对所有grid中的小拼图块遍历
        if grid[k].collidepoint(pos): # 如果小拼图与鼠标位置碰撞
            print(k) # 输出拼图块序号
            break    # 跳出当前循环

    if clickTime % 2 == 0:  # 点击偶数次
        clickId1 = k  # 第一个要交换的小拼图块序号
        clickTime += 1  # 点击次数加1
    elif clickTime % 2 == 1:  # 点击奇数次
        clickId2 = k  # 第二个要交换的小拼图块序号
        clickTime += 1  # 点击次数加1
        jiaohuanFk(clickId1, clickId2)  # 交换两个小拼图块位置

pgzrun.go()  # 开始执行游戏

2.2 判断输赢

效果:

小学生python项目 小学生python编程教程_小学生python项目_02

代码:

import pgzrun  # 导入游戏库
from pgzero.actor import Actor
from pgzero.screen import Screen
screen: Screen  # 类型标注

TILE_SIZE_w = 132 # 根据小图块的宽设置
TILE_SIZE_h = 118  #  根据小图块的高设置
x = 5  # 横向方块数
y = 5  # 纵向方块数
WIDTH = x*TILE_SIZE_w  # 设置窗口的宽度
HEIGHT = y*TILE_SIZE_h  # 设置窗口的高度
TITLE = '拼图小游戏'

clickTime = 0  # 记录鼠标点击了多少次
clickId1 = clickId2 = -1 # 两次点击的小拼图块的序号
allRight = False  # 是否小拼图的位置全对了

fk_list =[]
for i in range(1,x*y+1):
    fk_list.append(Actor('fenge\\df-'+str(i)))

grid = [] # 列表,用来存放最终所有拼图信息
for i in range(x): # 对行循环
    for j in range(y): # 对列循环
        # print(i*x+j)
        fangkuai = fk_list[i*x+j] # 导入拼图方块图片
        fangkuai.left = j * TILE_SIZE_w # 拼图方块图片最左边的x坐标
        fangkuai.top = i * TILE_SIZE_h  # 拼图方块图片最顶部的y坐标
        grid.append(fangkuai) # 将当前拼图加入到列表中

# 以下函数实现两个小拼图块位置的交换
def jiaohuanFk(a, b):
    # i,j为要交换的两个小拼图块的序号
    # 以下利用tempPos中间变量,实现两个小拼图块位置的交换
    tempPos = grid[a].pos
    grid[a].pos = grid[b].pos
    grid[b].pos = tempPos

import random
# 重复随机交换多次小拼图的位置
for k in range(x*y-1):
    i = random.randint(0, x*y-1)  # 第一个小拼图块的序号
    j = random.randint(0, x*y-1)  # 第二个小拼图块的序号
    jiaohuanFk(i, j) # 调用函数交换两个小拼图块的位置

# print('ok')
def draw():  # 绘制模块,每帧重复执行
    screen.clear()  # 每帧清除屏幕,便于重新绘制
    for fk in grid:
        fk.draw()  # 绘制小拼图块


def on_mouse_down(pos, button): # 当鼠标按键时执行
    global clickTime, clickId1, clickId2, allright
    for k in range(x*y): # 对所有grid中的小拼图块遍历
        if grid[k].collidepoint(pos): # 如果小拼图与鼠标位置碰撞
            print(k) # 输出拼图块序号
            break    # 跳出当前循环

    if clickTime % 2 == 0:  # 点击偶数次
        clickId1 = k  # 第一个要交换的小拼图块序号
        clickTime += 1  # 点击次数加1
    elif clickTime % 2 == 1:  # 点击奇数次
        clickId2 = k  # 第二个要交换的小拼图块序号
        clickTime += 1  # 点击次数加1
        jiaohuanFk(clickId1, clickId2)  # 交换两个小拼图块位置

    allRight = True # 假设全拼对了
    for i in range(3):
        for j in range(3):
            tile = grid[i*3+j]
            # 遍历,只要有一个小拼图的位置不对,就没有全拼对
            # print('第',i,j,tile.left,tile.top)
            # print(tile.left,j * TILE_SIZE_w,'后',tile.top,i * TILE_SIZE_h)
            if tile.left != j * TILE_SIZE_w or tile.top != i * TILE_SIZE_h:
                allRight = False # 拼错了
                break
            # 如果上面的if语句都不执行,则表示全拼对了

pgzrun.go()  # 开始执行游戏

2.3 改进,点击图片时进行划红框,每块显示绿框

效果:

小学生python项目 小学生python编程教程_爬虫_03

代码:

import pgzrun  # 导入游戏库
from pgzero.actor import Actor
from pgzero.screen import Screen

import random
screen: Screen  # 类型标注

TILE_SIZE_w = 132 # 根据小图块的宽设置
TILE_SIZE_h = 118  #  根据小图块的高设置
x = 5  # 横向方块数
y = 5  # 纵向方块数
WIDTH = x*TILE_SIZE_w  # 设置窗口的宽度
HEIGHT = y*TILE_SIZE_h  # 设置窗口的高度
TITLE = '拼图小游戏'

clickTime = 0  # 记录鼠标点击了多少次
clickId1 = clickId2 = -1 # 两次点击的小拼图块的序号
allRight = False  # 是否小拼图的位置全对了

fk_list =[]
for i in range(1,x*y+1):
    fk_list.append(Actor('fenge\\df-'+str(i)))

grid = [] # 列表,用来存放最终所有拼图信息
for i in range(x): # 对行循环
    for j in range(y): # 对列循环
        # print(i*x+j)
        fangkuai = fk_list[i*x+j] # 导入拼图方块图片
        fangkuai.left = j * TILE_SIZE_w # 拼图方块图片最左边的x坐标
        fangkuai.top = i * TILE_SIZE_h  # 拼图方块图片最顶部的y坐标
        grid.append(fangkuai) # 将当前拼图加入到列表中

# 以下函数实现两个小拼图块位置的交换
def jiaohuanFk(a, b):
    # i,j为要交换的两个小拼图块的序号
    # 以下利用tempPos中间变量,实现两个小拼图块位置的交换
    tempPos = grid[a].pos
    grid[a].pos = grid[b].pos
    grid[b].pos = tempPos


# 重复随机交换多次小拼图的位置
for k in range(x*y-1):
    i = random.randint(0, x*y-1)  # 第一个小拼图块的序号
    j = random.randint(0, x*y-1)  # 第二个小拼图块的序号
    jiaohuanFk(i, j) # 调用函数交换两个小拼图块的位置

# print('ok')
def draw():  # 绘制模块,每帧重复执行
    screen.clear()  # 每帧清除屏幕,便于重新绘制
    for fk in grid:
        fk.draw()  # 绘制小拼图块

    if allRight:  # 输出游戏胜利信息
        screen.draw.text("游戏胜利!", (40, 10),
                         fontsize=50, fontname='simhei', color='blue')
    else:  # 如果没有成功,可以画几条提示线
        for i in range(x):  # 画两条横线、两条竖线
            screen.draw.line((0, i*TILE_SIZE_h), (WIDTH, i*TILE_SIZE_h), 'green')
            screen.draw.line((i*TILE_SIZE_w, 0), (i*TILE_SIZE_w, y*TILE_SIZE_h), 'green')
        if clickId1 != -1:  # 为选中的第一个小拼图块画一个红色框
            screen.draw.rect(Rect((grid[clickId1].left, grid[clickId1].top), (TILE_SIZE_w, TILE_SIZE_h)), 'red')

def on_mouse_down(pos, button): # 当鼠标按键时执行
    global clickTime, clickId1, clickId2, allRight
    for k in range(x*y): # 对所有grid中的小拼图块遍历
        if grid[k].collidepoint(pos): # 如果小拼图与鼠标位置碰撞
            print(k) # 输出拼图块序号
            break    # 跳出当前循环

    if clickTime % 2 == 0:  # 点击偶数次
        clickId1 = k  # 第一个要交换的小拼图块序号
        clickTime += 1  # 点击次数加1
    elif clickTime % 2 == 1:  # 点击奇数次
        clickId2 = k  # 第二个要交换的小拼图块序号
        clickTime += 1  # 点击次数加1
        jiaohuanFk(clickId1, clickId2)  # 交换两个小拼图块位置

    allRight = True # 假设全拼对了
    for i in range(x):
        for j in range(y):
            tile = grid[i*x+j]
            # 遍历,只要有一个小拼图的位置不对,就没有全拼对
            # print('第',i,j,tile.left,tile.top)
            # print(tile.left,j * TILE_SIZE_w,'后',tile.top,i * TILE_SIZE_h)
            if tile.left != j * TILE_SIZE_w or tile.top != i * TILE_SIZE_h:
                allRight = False # 拼错了
                break
            # 如果上面的if语句都不执行,则表示全拼对了


pgzrun.go()  # 开始执行游戏

2.4 增加底框

效果:

小学生python项目 小学生python编程教程_开发语言_04

代码:

import pgzrun  # 导入游戏库
from pgzero.actor import Actor
from pgzero.screen import Screen
import datetime  # 导入日期和时间库
from pgzero.rect import Rect  # Rect类引入
import random
screen:Screen  # 类型标注

TILE_SIZE_w = 132 # 根据小图块的宽设置
TILE_SIZE_h = 118  # 根据小图块的高设置
x = 5  # 横向方块数
y = 5  # 纵向方块数
WIDTH = x * TILE_SIZE_w  # 设置窗口的宽度
HEIGHT = y * TILE_SIZE_h + 60  # 设置窗口的高度,增加下框
TITLE = '拼图小游戏'

clickTime = 0  # 记录鼠标点击了多少次
clickId1 = clickId2 = -1  # 两次点击的小拼图块的序号
allRight = False  # 是否小拼图的位置全对了

txtFile = open('dangan.txt') # 打开最佳时间记录存档文件
line = txtFile.readline()  # 读取一行字符串
oldTime = int(line)  # 将记录的秒数转换为整型存储
txtFile.close()  # 关闭文件
start = datetime.datetime.now()  # 程序运行开始计时
newTime = 0  # 这次游戏花了多长时间

fk_list = []
for i in range(1, x * y + 1):
    fk_list.append(Actor('fenge\\df-' + str(i)))

grid = []  # 列表,用来存放最终所有拼图信息
for i in range(x):  # 对行循环
    for j in range(y):  # 对列循环
        # print(i*x+j)
        fangkuai = fk_list[i * x + j]  # 导入拼图方块图片
        fangkuai.left = j * TILE_SIZE_w  # 拼图方块图片最左边的x坐标
        fangkuai.top = i * TILE_SIZE_h  # 拼图方块图片最顶部的y坐标
        grid.append(fangkuai)  # 将当前拼图加入到列表中


# 以下函数实现两个小拼图块位置的交换
def jiaohuanFk(a, b):
    # i,j为要交换的两个小拼图块的序号
    # 以下利用tempPos中间变量,实现两个小拼图块位置的交换
    tempPos = grid[a].pos
    grid[a].pos = grid[b].pos
    grid[b].pos = tempPos


# 重复随机交换多次小拼图的位置
for k in range(x * y - 1):
    i = random.randint(0, x * y - 1)  # 第一个小拼图块的序号
    j = random.randint(0, x * y - 1)  # 第二个小拼图块的序号
    jiaohuanFk(i, j)  # 调用函数交换两个小拼图块的位置


# print('ok')
def draw():  # 绘制模块,每帧重复执行
    screen.clear()  # 每帧清除屏幕,便于重新绘制
    for fk in grid:
        fk.draw()  # 绘制小拼图块

    if allRight:  # 输出游戏胜利信息
        screen.draw.text("游戏胜利!", (WIDTH/3-60, HEIGHT - 60),
                         fontsize=50, fontname='simhei', color='blue')
    else:  # 如果没有成功,可以画几条提示线
        for i in range(x):  # 画两条横线、两条竖线
            screen.draw.line((0, i * TILE_SIZE_h), (WIDTH, i * TILE_SIZE_h), 'green')
            screen.draw.line((i * TILE_SIZE_w, 0), (i * TILE_SIZE_w, y * TILE_SIZE_h), 'green')
        if clickId1 != -1:  # 为选中的第一个小拼图块画一个红色框
            screen.draw.rect(Rect((grid[clickId1].left, grid[clickId1].top), (TILE_SIZE_w, TILE_SIZE_h)), 'red')
        screen.draw.text("最佳记录:" + str(oldTime) + '秒', (WIDTH/2-60, HEIGHT - 60), fontsize=25,
                         fontname='simhei', color='red')
        screen.draw.text("游戏运行:" + str(newTime) + '秒', (WIDTH/2-60, HEIGHT - 30), fontsize=25,
                         fontname='simhei', color='red')


def on_mouse_down(pos, button):  # 当鼠标按键时执行
    global clickTime, clickId1, clickId2, allRight
    for k in range(x * y):  # 对所有grid中的小拼图块遍历
        if grid[k].collidepoint(pos):  # 如果小拼图与鼠标位置碰撞
            # print(k)  # 输出拼图块序号
            break  # 跳出当前循环
    if clickTime % 2 == 0:  # 点击偶数次
        clickId1 = k  # 第一个要交换的小拼图块序号
        clickTime += 1  # 点击次数加1
    elif clickTime % 2 == 1:  # 点击奇数次
        clickId2 = k  # 第二个要交换的小拼图块序号
        clickTime += 1  # 点击次数加1
        jiaohuanFk(clickId1, clickId2)  # 交换两个小拼图块位置

    allRight = True  # 假设全拼对了
    for i in range(x):
        for j in range(y):
            tile = grid[i * x + j]
            # 遍历,只要有一个小拼图的位置不对,就没有全拼对
            # print('第',i,j,tile.left,tile.top)
            # print(tile.left,j * TILE_SIZE_w,'后',tile.top,i * TILE_SIZE_h)
            if tile.left != j * TILE_SIZE_w or tile.top != i * TILE_SIZE_h:
                allRight = False  # 拼错了
                break
            # 如果上面的if语句都不执行,则表示全拼对了
    if allRight:
        if newTime < oldTime:  # 看看是否更新最短时间记录
            txtFile = open('dangan.txt', 'w')
            txtFile.write(str(newTime))
            txtFile.close()


def update():  # 更新模块,每帧重复操作
    global newTime
    if not allRight:
        end = datetime.datetime.now()
        newTime = (end - start).seconds  # 程序运行了多少秒

pgzrun.go()  # 开始执行游戏

总结

通过此次的《拼图游戏》游戏三连发实现,让我对python的相关知识有了进一步的了解,对拼图游戏有了一些想法,如何更进一步的设计实现新功能,用于学习。