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迭代器的使用方法实例
Nov 21 Python
Python的Tornado框架异步编程入门实例
Apr 24 Python
Python 绘图和可视化详细介绍
Feb 11 Python
名片管理系统python版
Jan 11 Python
Python常见工厂函数用法示例
Mar 21 Python
Python 200行代码实现一个滑动验证码过程详解
Jul 11 Python
python opencv实现证件照换底功能
Aug 19 Python
python实现全排列代码(回溯、深度优先搜索)
Feb 26 Python
Pycharm连接远程服务器过程图解
Apr 30 Python
Python不支持 i ++ 语法的原因解析
Jul 22 Python
解决pytorch 的state_dict()拷贝问题
Mar 03 Python
python实现简单的三子棋游戏
Apr 28 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
DC动画电影《黑暗正义联盟》曝预告 5月5日上线数字平台
2020/04/09 欧美动漫
中国第一家无线电行
2021/03/01 无线电
PHP在线生成二维码代码(google api)
2013/06/03 PHP
PHP获取真实客户端的真实IP
2017/03/07 PHP
PHP简单实现二维数组赋值与遍历功能示例
2017/10/19 PHP
实例分析PHP中PHPMailer发邮件
2017/12/13 PHP
PHP如何使用JWT做Api接口身份认证的实现
2020/02/03 PHP
jquery 指南/入门基础
2007/11/30 Javascript
jQuery学习笔记 获取jQuery对象
2012/09/19 Javascript
按下回车键指向下一个位置的一个函数代码
2014/03/10 Javascript
jquery实现拖动效果(代码分享)
2017/01/25 Javascript
webpack3之loader全解析
2017/10/26 Javascript
vue基于mint-ui实现城市选择三级联动
2020/06/30 Javascript
JavaScript函数的特性与应用实践深入详解
2018/12/30 Javascript
深入Node TCP模块的理解
2019/03/13 Javascript
Node.JS在命令行中检查Chrome浏览器是否安装并打开指定网址
2019/05/21 Javascript
BootstrapValidator实现表单验证功能
2019/11/08 Javascript
原生js+css实现tab切换功能
2020/09/17 Javascript
详解template标签用法(含vue中的用法总结)
2021/01/12 Vue.js
[01:22:29]真视界:2019年国际邀请赛总决赛
2020/01/29 DOTA
Python深入学习之特殊方法与多范式
2014/08/31 Python
Python中解析JSON并同时进行自定义编码处理实例
2015/02/08 Python
Python面向对象编程中的类和对象学习教程
2015/03/30 Python
Python中的pygal安装和绘制直方图代码分享
2017/12/08 Python
详解python中自定义超时异常的几种方法
2019/07/29 Python
Django media static外部访问Django中的图片设置教程
2020/04/07 Python
Python 存取npy格式数据实例
2020/07/01 Python
keras 简单 lstm实例(基于one-hot编码)
2020/07/02 Python
HTML5实现页面切换激活的PageVisibility API使用初探
2016/05/13 HTML / CSS
国际领先的学术出版商:Springer
2017/01/11 全球购物
美国顶级防滑鞋:Shoes For Crews
2017/03/27 全球购物
Easy Spirit官网:美国休闲鞋履中的代表品牌
2019/04/12 全球购物
升职自荐信范文
2013/10/05 职场文书
物业公司采购员岗位职责
2013/12/31 职场文书
社区端午节活动方案
2014/01/28 职场文书
国际贸易专业求职信
2014/06/04 职场文书