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使用time模块实现指定时间触发器示例
May 18 Python
Python实现字符串的逆序 C++字符串逆序算法
May 28 Python
浅谈利用numpy对矩阵进行归一化处理的方法
Jul 11 Python
Django csrf 验证问题的实现
Oct 09 Python
解决python Markdown模块乱码的问题
Feb 14 Python
在python中实现调用可执行文件.exe的3种方法
Jul 07 Python
Python二次规划和线性规划使用实例
Dec 09 Python
python程序需要编译吗
Jun 19 Python
Python实现迪杰斯特拉算法并生成最短路径的示例代码
Dec 01 Python
python 写一个文件分发小程序
Dec 05 Python
python用opencv 图像傅里叶变换
Jan 04 Python
Python实现制作销售数据可视化看板详解
Nov 27 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
谈谈新手如何学习PHP
2006/12/23 PHP
PHP 创建标签云函数代码
2010/05/26 PHP
Yii使用ajax验证显示错误messagebox的解决方法
2014/12/03 PHP
PHP MVC框架路由学习笔记
2016/03/02 PHP
PHP实现网页内容html标签补全和过滤的方法小结【2种方法】
2017/04/27 PHP
Yii2框架操作数据库的方法分析【以mysql为例】
2019/05/27 PHP
js 实现复制到粘贴板的功能代码
2010/05/13 Javascript
19个很有用的 JavaScript库推荐
2011/06/27 Javascript
JavaScript高级程序设计(第3版)学习笔记3 js简单数据类型
2012/10/11 Javascript
Javascript实现页面跳转的几种方式分享
2013/10/26 Javascript
parentElement,srcElement的使用小结
2014/01/13 Javascript
javascript实现别踩白块儿小游戏程序
2015/11/22 Javascript
jQuery插件之jQuery.Form.js用法实例分析(附demo示例源码)
2016/01/04 Javascript
jQuery调用Webservice传递json数组的方法
2016/08/06 Javascript
jquery层级选择器(匹配父元素下的子元素实现代码)
2016/09/05 Javascript
angularjs中回车键触发某一事件的方法
2017/04/24 Javascript
基于vue 实现token验证的实例代码
2017/12/14 Javascript
Angular数据绑定机制原理
2018/04/17 Javascript
vue基于viewer实现的图片查看器功能
2019/04/12 Javascript
微信小程序实现发送模板消息功能示例【通过openid推送消息给用户】
2019/05/05 Javascript
koa2+vue实现登陆及登录状态判断
2019/08/15 Javascript
vue组件创建的三种方式小结
2020/02/03 Javascript
简单了解JavaScript弹窗实现代码
2020/05/07 Javascript
Python中用于返回绝对值的abs()方法
2015/05/14 Python
Python学习小技巧总结
2018/06/10 Python
深入理解Python异常处理的哲学
2019/02/01 Python
美国知名日用品连锁超市:Dollar General(多来店)
2017/01/14 全球购物
美国名表在线商城:Ashford(支持中文)
2019/09/24 全球购物
Michael Kors英国官网:美国奢侈品品牌
2019/11/13 全球购物
《再见了,亲人》教学反思
2014/02/26 职场文书
实习评语大全
2014/04/26 职场文书
活动总结怎么写啊
2014/05/07 职场文书
团拜会主持词
2015/07/04 职场文书
2016党员干部廉政准则学习心得体会
2016/01/20 职场文书
Python import模块的缓存问题解决方案
2021/06/02 Python
利用Matlab绘制各类特殊图形的实例代码
2021/07/16 Python