python实现拼图小游戏


Posted in Python onFebruary 22, 2020

Python小白一只,正在成长,程序自己设计,很多不足,算法很多地方能优化。欢迎大佬来指教。

游戏效果

python实现拼图小游戏

创建设置类,储存游戏基础数据

可以不使用这个类,在程序中直接使用相应的数据。但是使用这个类更便于程序阅读和修改基础数据。

class Settings:
 def __init__(self):
 self.picture_num = 4 # 每行图片数
 self.screen_width = 408 # 窗口宽度
 self.screen_length = 809 # 窗口长度
 self.picture_length = 100 # 每个正方形图片的长
 self.screen_bgcol = (96, 127, 255) # 背景颜色
 self.picture_bian = 1 # 每个图片的边缘宽度 ,便于分清每个照片
 self.picture_distance = 102 # 两个图片之间的距离

创建图片类,储存游戏需要的图片

这样可以在游戏的开始把游戏用到的图片一起读到内存,显示照片时直接使用创建的图像对象列表即可。
类的构造函数要接收一个数字,按着这个数字读生成相应图片的路径和名称 picture_name。在按照这个打开相应的照片。
pygame相应方法可以简单学习一下。

class Picture:
 def __init__(self, num):
 self.picture_name = 'images/p{}.gif'.format(num)
 self.picture = pygame.image.load(self.picture_name) # 打开照片
 self.picture_rect = self.picture.get_rect() # 获得照片属性类
 def display_picture(self, screen, x, y): # 在屏幕上显示图片方法
 self.picture_rect.x = x
 self.picture_rect.y = y
 screen.blit(self.picture, self.picture_rect)

生成初始数据,创建窗口

游戏数据用两个4*4二维列表存储,一个存储图片位置,一个存储图片对象。
游戏开始,图片的顺序的应该是乱的。
先要对数据进行打乱,打乱时要按照原有的顺序打乱,不然可能会出现图片不可能复原的情况。

数据打乱函数

def data_begin(caozuoshu, p0, data):
 for i in caozuoshu:
 move(i, p0, data)

def move(i, p0, data):
 if i == 3 and p0[1] > 0:
 t = data[p0[0]][p0[1]]
 data[p0[0]][p0[1]] = data[p0[0]][p0[1]-1]
 data[p0[0]][p0[1]-1] = t
 p0[1] -= 1
 elif i == 4 and p0[1] < 3:
 t = data[p0[0]][p0[1]]
 data[p0[0]][p0[1]] = data[p0[0]][p0[1]+1]
 data[p0[0]][p0[1]+1] = t
 p0[1] += 1
 elif i == 1 and p0[0] > 0:
 t = data[p0[0]][p0[1]]
 data[p0[0]][p0[1]] = data[p0[0]-1][p0[1]]
 data[p0[0]-1][p0[1]] = t
 p0[0] -= 1
 elif i == 2 and p0[0] < 3:
 t = data[p0[0]][p0[1]]
 data[p0[0]][p0[1]] = data[p0[0]+1][p0[1]]
 data[p0[0]+1][p0[1]] = t
 p0[0] += 1

def create_caozuoshu():
 n = 30
 caozuo = [1, 2, 3, 4]
 caozuoshu = []
 for i in range(n):
 caozuoshu.append(random.choice(caozuo))
 return caozuoshu

这样之后,把data列表打乱

在按照data生成picture列表

def create_pictures(picture, data, set):
 for i in range(set.picture_num):
 for j in range(set.picture_num):
  p = Picture(data[i][j])
  picture[i][j] = p

创建窗口函数

def screen_create(set):
 pygame.init()
 screen = pygame.display.set_mode((set.screen_length, set.screen_width))
 pygame.display.set_caption("拼图")
 return screen

主函数

if __name__ == '__main__':
 set = Settings()
 # 初始数据
 data = [[9, 1, 3, 4],
  [2, 16, 14, 8],
  [6, 10, 5, 12],
  [13, 7, 11, 15]]
 p0 = [1, 1]
 caozuoshu = create_caozuoshu()
 data_begin(caozuoshu, p0, data)
 bushu = [0]
 # 创建图片
 picture = [[None, None, None, None],
  [None, None, None, None],
  [None, None, None, None],
  [None, None, None, None]]
 yuantu = Picture(17)
 create_pictures(picture, data, set) # 按照data生成相应顺序的picture列表
 # 创建窗口
 screen = screen_create(set)

 # 游戏主循环
 while True:
 check_events(picture, p0, data, bushu)
 screen_updata(picture, screen, set, yuantu)

响应按键控制

响应按键是,picture和data列表都要同步改变,data用来判断是否拼图完成。

响应按键,产生相应的控制

def check_events(picture, p0, data, bushu):
 for event in pygame.event.get():
 if event.type == pygame.QUIT:
  sys.exit()
 elif event.type == pygame.KEYDOWN and game_over(data, set, bushu):
  if event.key == pygame.K_DOWN and p0[0] > 0:
  xinhao = 1
  bushu[0] += 1
  updata(xinhao, picture, p0, data)
  elif event.key == pygame.K_UP and p0[0] < 3:
  xinhao = 2
  bushu[0] += 1
  updata(xinhao, picture, p0, data)
  elif event.key == pygame.K_RIGHT and p0[1] > 0:
  xinhao = 3
  bushu[0] += 1
  updata(xinhao, picture, p0, data)
  elif event.key == pygame.K_LEFT and p0[1] < 3:
  xinhao = 4
  bushu[0] += 1
  updata(xinhao, picture, p0, data)

按照控制数,更新picture和data

def updata(xinhao, picture, p0, data):
 if xinhao == 3:
 tmp = picture[p0[0]][p0[1]]
 picture[p0[0]][p0[1]] = picture[p0[0]][p0[1]-1]
 picture[p0[0]][p0[1]-1] = tmp

 t = data[p0[0]][p0[1]]
 data[p0[0]][p0[1]] = data[p0[0]][p0[1]-1]
 data[p0[0]][p0[1]-1] = t
 p0[1] -= 1

 elif xinhao == 4:
 tmp = picture[p0[0]][p0[1]]
 picture[p0[0]][p0[1]] = picture[p0[0]][p0[1] + 1]
 picture[p0[0]][p0[1] + 1] = tmp

 t = data[p0[0]][p0[1]]
 data[p0[0]][p0[1]] = data[p0[0]][p0[1]+1]
 data[p0[0]][p0[1]+1] = t
 p0[1] += 1
 elif xinhao == 1:
 tmp = picture[p0[0]][p0[1]]
 picture[p0[0]][p0[1]] = picture[p0[0] - 1][p0[1]]
 picture[p0[0] - 1][p0[1]] = tmp

 t = data[p0[0]][p0[1]]
 data[p0[0]][p0[1]] = data[p0[0]-1][p0[1]]
 data[p0[0]-1][p0[1]] = t
 p0[0] -= 1
 elif xinhao == 2:
 tmp = picture[p0[0]][p0[1]]
 picture[p0[0]][p0[1]] = picture[p0[0] + 1][p0[1]]
 picture[p0[0] + 1][p0[1]] = tmp

 t = data[p0[0]][p0[1]]
 data[p0[0]][p0[1]] = data[p0[0] + 1][p0[1]]
 data[p0[0] +1][p0[1]] = t
 p0[0] += 1

判断是否拼图完成

def game_over(data, set,bushu):
 datao = [[1, 2, 3, 4],
  [5, 6, 7, 8],
  [9, 10, 11, 12],
  [13, 14, 15, 16]]
 for i in range(set.picture_num):
 for j in range(set.picture_num):
  if datao[i][j] != data[i][j]:
  return True
 print("牛逼!\n 游戏结束!\n 步数:{}".format(bushu[0]))
 return False

此函数要在响应按键函数中实时使用,监测是否完成拼图。

完整程序

import pygame
import random
import sys

class Settings:
 def __init__(self):
 self.picture_num = 4
 self.screen_width = 408
 self.screen_length = 809
 self.picture_length = 100
 self.screen_bgcol = (96, 127, 255)
 self.picture_speed = 5
 self.picture_bian = 1
 self.picture_distance = 102

class Picture:
 def __init__(self, num):
 self.picture_name = 'images/p{}.gif'.format(num)
 self.picture = pygame.image.load(self.picture_name)
 self.picture_rect = self.picture.get_rect()
 def display_picture(self, screen, x, y):
 self.picture_rect.x = x
 self.picture_rect.y = y
 screen.blit(self.picture, self.picture_rect)
'''def data_begin(data,p0):
 n = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]
 ns = 16
 for i in range(4):
 for j in range(4):
  num = random.randint(0, ns-1)
  ns -= 1
  data[i][j] = n.pop(num)
  if data[i][j] == 16:
  p0[0] = i
  p0[1] = j'''
def data_begin(caozuoshu, p0, data):
 for i in caozuoshu:
 move(i, p0, data)

def move(i, p0, data):
 if i == 3 and p0[1] > 0:
 t = data[p0[0]][p0[1]]
 data[p0[0]][p0[1]] = data[p0[0]][p0[1]-1]
 data[p0[0]][p0[1]-1] = t
 p0[1] -= 1
 elif i == 4 and p0[1] < 3:
 t = data[p0[0]][p0[1]]
 data[p0[0]][p0[1]] = data[p0[0]][p0[1]+1]
 data[p0[0]][p0[1]+1] = t
 p0[1] += 1
 elif i == 1 and p0[0] > 0:
 t = data[p0[0]][p0[1]]
 data[p0[0]][p0[1]] = data[p0[0]-1][p0[1]]
 data[p0[0]-1][p0[1]] = t
 p0[0] -= 1
 elif i == 2 and p0[0] < 3:
 t = data[p0[0]][p0[1]]
 data[p0[0]][p0[1]] = data[p0[0]+1][p0[1]]
 data[p0[0]+1][p0[1]] = t
 p0[0] += 1

def create_caozuoshu():
 n = 30
 caozuo = [1, 2, 3, 4]
 caozuoshu = []
 for i in range(n):
 caozuoshu.append(random.choice(caozuo))
 return caozuoshu

def create_pictures(picture, data, set):
 for i in range(set.picture_num):
 for j in range(set.picture_num):
  p = Picture(data[i][j])
  picture[i][j] = p

def screen_updata(picture, screen, set, yuantu):
 screen.fill(set.screen_bgcol)
 x, y = 402, set.picture_bian
 for i in range(set.picture_num):
 for j in range(set.picture_num):
  picture[i][j].display_picture(screen, x, y)
  x += set.picture_distance
 x = 402
 y += set.picture_distance
 yuantu.display_picture(screen, 1, 4)
 pygame.display.flip()

def screen_create(set):
 pygame.init()
 screen = pygame.display.set_mode((set.screen_length, set.screen_width))
 pygame.display.set_caption("拼图")
 return screen

def game_over(data, set,bushu):
 datao = [[1, 2, 3, 4],
  [5, 6, 7, 8],
  [9, 10, 11, 12],
  [13, 14, 15, 16]]
 for i in range(set.picture_num):
 for j in range(set.picture_num):
  if datao[i][j] != data[i][j]:
  return True
 print("牛逼!\n 游戏结束!\n 步数:{}".format(bushu[0]))
 return False

def updata(xinhao, picture, p0, data):
 if xinhao == 3:
 tmp = picture[p0[0]][p0[1]]
 picture[p0[0]][p0[1]] = picture[p0[0]][p0[1]-1]
 picture[p0[0]][p0[1]-1] = tmp

 t = data[p0[0]][p0[1]]
 data[p0[0]][p0[1]] = data[p0[0]][p0[1]-1]
 data[p0[0]][p0[1]-1] = t
 p0[1] -= 1

 elif xinhao == 4:
 tmp = picture[p0[0]][p0[1]]
 picture[p0[0]][p0[1]] = picture[p0[0]][p0[1] + 1]
 picture[p0[0]][p0[1] + 1] = tmp

 t = data[p0[0]][p0[1]]
 data[p0[0]][p0[1]] = data[p0[0]][p0[1]+1]
 data[p0[0]][p0[1]+1] = t
 p0[1] += 1
 elif xinhao == 1:
 tmp = picture[p0[0]][p0[1]]
 picture[p0[0]][p0[1]] = picture[p0[0] - 1][p0[1]]
 picture[p0[0] - 1][p0[1]] = tmp

 t = data[p0[0]][p0[1]]
 data[p0[0]][p0[1]] = data[p0[0]-1][p0[1]]
 data[p0[0]-1][p0[1]] = t
 p0[0] -= 1
 elif xinhao == 2:
 tmp = picture[p0[0]][p0[1]]
 picture[p0[0]][p0[1]] = picture[p0[0] + 1][p0[1]]
 picture[p0[0] + 1][p0[1]] = tmp

 t = data[p0[0]][p0[1]]
 data[p0[0]][p0[1]] = data[p0[0] + 1][p0[1]]
 data[p0[0] +1][p0[1]] = t
 p0[0] += 1
 #print(data)

def check_events(picture, p0, data, bushu):
 for event in pygame.event.get():
 if event.type == pygame.QUIT:
  sys.exit()
 elif event.type == pygame.KEYDOWN and game_over(data, set, bushu):
  if event.key == pygame.K_DOWN and p0[0] > 0:
  xinhao = 1
  bushu[0] += 1
  updata(xinhao, picture, p0, data)
  elif event.key == pygame.K_UP and p0[0] < 3:
  xinhao = 2
  bushu[0] += 1
  updata(xinhao, picture, p0, data)
  elif event.key == pygame.K_RIGHT and p0[1] > 0:
  xinhao = 3
  bushu[0] += 1
  updata(xinhao, picture, p0, data)
  elif event.key == pygame.K_LEFT and p0[1] < 3:
  xinhao = 4
  bushu[0] += 1
  updata(xinhao, picture, p0, data)

if __name__ == '__main__':
 set = Settings()
 # 初始数据
 data = [[9, 1, 3, 4],
  [2, 16, 14, 8],
  [6, 10, 5, 12],
  [13, 7, 11, 15]]
 p0 = [1, 1]
 caozuoshu = create_caozuoshu()
 data_begin(caozuoshu, p0, data)
 bushu = [0]
 # 创建图片
 picture = [[None, None, None, None],
  [None, None, None, None],
  [None, None, None, None],
  [None, None, None, None]]
 yuantu = Picture(17)
 create_pictures(picture, data, set)
 # 创建窗口
 screen = screen_create(set)

 # 游戏主循环
 while True:
 check_events(picture, p0, data, bushu)
 screen_updata(picture, screen, set, yuantu)

游戏用到的图片,图片位置和文件名要和程序中的一致

python实现拼图小游戏

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
Python的设计模式编程入门指南
Apr 02 Python
python单元测试unittest实例详解
May 11 Python
python pandas dataframe 行列选择,切片操作方法
Apr 10 Python
Python3中关于cookie的创建与保存
Oct 21 Python
对Python实现累加函数的方法详解
Jan 23 Python
Python threading的使用方法解析
Aug 28 Python
在Python中使用turtle绘制多个同心圆示例
Nov 23 Python
Python3和pyqt5实现控件数据动态显示方式
Dec 13 Python
django在保存图像的同时压缩图像示例代码详解
Feb 11 Python
利用pyecharts读取csv并进行数据统计可视化的实现
Apr 17 Python
Python API 操作Hadoop hdfs详解
Jun 06 Python
tensorflow中的梯度求解及梯度裁剪操作
May 26 Python
Python双链表原理与实现方法详解
Feb 22 #Python
Python单链表原理与实现方法详解
Feb 22 #Python
python函数enumerate,operator和Counter使用技巧实例小结
Feb 22 #Python
python通过文本在一个图中画多条线的实例
Feb 21 #Python
python使用html2text库实现从HTML转markdown的方法详解
Feb 21 #Python
python-sys.stdout作为默认函数参数的实现
Feb 21 #Python
pycharm运行程序时看不到任何结果显示的解决
Feb 21 #Python
You might like
Javascript 兼容firefox的一些问题
2009/05/21 Javascript
JavaScript初学者应注意的七个细节详细介绍
2012/12/27 Javascript
3种Jquery限制文本框只能输入数字字母的方法
2014/12/03 Javascript
jQuery+HTML5实现手机摇一摇换衣特效
2015/06/05 Javascript
卸载安装Node.js与npm过程详解
2016/08/15 Javascript
jQuery鼠标事件总结
2016/10/13 Javascript
Jquery Easyui进度条组件Progress使用详解(8)
2020/03/26 Javascript
JS实现仿百度文库评分功能
2017/01/12 Javascript
windows下vue.js开发环境搭建教程
2017/03/20 Javascript
angularjs下拉框空白的解决办法
2017/06/20 Javascript
JavaScript仿微信(电话)联系人列表滑动字母索引实例讲解(推荐)
2017/08/16 Javascript
H5+C3+JS实现五子棋游戏(AI篇)
2020/05/28 Javascript
35个最好用的Vue开源库(史上最全)
2019/01/03 Javascript
js prototype深入理解及应用实例分析
2019/11/25 Javascript
解决vue项目运行提示Warnings while compiling.警告的问题
2020/09/18 Javascript
Python字符串处理之count()方法的使用
2015/05/18 Python
Python数字图像处理之霍夫线变换实现详解
2018/01/12 Python
django 开发忘记密码通过邮箱找回功能示例
2018/04/17 Python
Django model序列化为json的方法示例
2018/10/16 Python
python游戏开发之视频转彩色字符动画
2019/04/26 Python
Python3 实现串口两进程同时读写
2019/06/12 Python
pycharm双击无响应(打不开问题解决办法)
2020/01/10 Python
Python按照list dict key进行排序过程解析
2020/04/04 Python
Python计算信息熵实例
2020/06/18 Python
python 生成正态分布数据,并绘图和解析
2020/12/21 Python
Python3+SQLAlchemy+Sqlite3实现ORM教程
2021/02/16 Python
全球速卖通西班牙站:AliExpress西班牙
2017/10/30 全球购物
运动会入场解说词
2014/02/07 职场文书
中国文明网向国旗敬礼寄语大全
2014/09/27 职场文书
2014年采购工作总结
2014/11/20 职场文书
2015年超市收银员工作总结
2015/04/25 职场文书
审查起诉阶段律师意见书
2015/05/19 职场文书
运动会加油稿50字
2015/07/21 职场文书
《植物妈妈有办法》教学反思
2016/02/23 职场文书
导游词之张家界
2019/10/31 职场文书
nginx 添加http_stub_status_module模块
2022/05/25 Servers