python如何写个俄罗斯方块


Posted in Python onNovember 06, 2020

俄罗斯方块是俄罗斯人发明的一款休闲类的小游戏,这款小游戏可以说是很多人童年的主打电子游戏了,本文我们使用 Python 来实现这款小游戏。

游戏的基本规则是:移动、旋转和摆放游戏自动输出的各种方块,使之排列成完整的一行或多行并且消除得分。

实现

我们实现俄罗斯方块,主要用到的是 PyQt5 库,安装使用 pip install PyQt5 即可,游戏的组成比较简单,主要包括:主界面、各种方块和计分板,下面我们来看一下具体实现。

首先,我们来画一个主界面,主要实现代码如下:

class MainBoard(QFrame):
 msg = pyqtSignal(str)
 BoardWidth = 10
 BoardHeight = 20
 Speed = 300

 def __init__(self, parent):
  super().__init__(parent)
  self.initBoard()

 def initBoard(self):
  self.timer = QBasicTimer()
  self.isWaitingAfterLine = False
  self.curX = 0
  self.curY = 0
  self.numLinesRemoved = 0
  self.board = []
  self.setFocusPolicy(Qt.StrongFocus)
  self.isStarted = False
  self.isPaused = False
  self.clearBoard()

看一下效果:

python如何写个俄罗斯方块

分数的显示就是利用上面 msg 的 emit() 方法实现的。

我们接着画各种方块,方块的形状主要包括:T、Z、L、I、O 等,主要实现代码如下:

class ShapeForm(object):
 NoShape = 0
 ZShape = 1
 SShape = 2
 LineShape = 3
 TShape = 4
 SquareShape = 5
 LShape = 6
 MirroredLShape = 7

class Shape(object):
 coordsTable = (
  ((0, 0),  (0, 0),  (0, 0),  (0, 0)),
  ((0, -1), (0, 0),  (-1, 0), (-1, 1)),
  ((0, -1), (0, 0),  (1, 0),  (1, 1)),
  ((0, -1), (0, 0),  (0, 1),  (0, 2)),
  ((-1, 0), (0, 0),  (1, 0),  (0, 1)),
  ((0, 0),  (1, 0),  (0, 1),  (1, 1)),
  ((-1, -1), (0, -1), (0, 0),  (0, 1)),
  ((1, -1), (0, -1), (0, 0),  (0, 1))
 )

 def __init__(self):
  self.coords = [[0,0] for i in range(4)]
  self.pieceShape = ShapeForm.NoShape
  self.setShape(ShapeForm.NoShape)

 def shape(self):
  return self.pieceShape

 def setShape(self, shape):
  table = Shape.coordsTable[shape]
  for i in range(4):
   for j in range(2):
    self.coords[i][j] = table[i][j]
  self.pieceShape = shape

python如何写个俄罗斯方块

我们知道方块是不断自动下落的,因此需要一个计时器来控制,主要实现代码如下:

def timerEvent(self, event):
	if event.timerId() == self.timer.timerId():
		if self.isWaitingAfterLine:
			self.isWaitingAfterLine = False
			self.newPiece()
		else:
			self.oneLineDown()
	else:
		super(MainBoard, self).timerEvent(event)

在方块下落的过程中,我们需要通过键盘来控制方块的形状以及左右移动,因此,我们需要一个按键事件来控制它,主要实现代码如下:

def keyPressEvent(self, event):
	if not self.isStarted or self.curPiece.shape() == ShapeForm.NoShape:
		super(MainBoard, self).keyPressEvent(event)
		return
	key = event.key()
	if key == Qt.Key_P:
		self.pause()
		return
	if self.isPaused:
		return
	elif key == Qt.Key_Left:
		self.tryMove(self.curPiece, self.curX - 1, self.curY)
	elif key == Qt.Key_Right:
		self.tryMove(self.curPiece, self.curX + 1, self.curY)
	elif key == Qt.Key_Down:
		self.tryMove(self.curPiece.rotateRight(), self.curX, self.curY)
	elif key == Qt.Key_Up:
		self.tryMove(self.curPiece.rotateLeft(), self.curX, self.curY)
	elif key == Qt.Key_Space:
		self.dropDown()
	elif key == Qt.Key_D:
		self.oneLineDown()
	else:
		super(MainBoard, self).keyPressEvent(event)

当方块落到底部后,需要来检测是否有构成一条直线的,因此我们需要有一个方法来找到所有能消除的行并且消除它们,主要实现代码如下:

def removeFullLines(self):
	numFullLines = 0
	rowsToRemove = []
	for i in range(MainBoard.BoardHeight):
		n = 0
		for j in range(MainBoard.BoardWidth):
			if not self.shapeAt(j, i) == ShapeForm.NoShape:
				n = n + 1
		if n == 10:
			rowsToRemove.append(i)
	rowsToRemove.reverse()
	for m in rowsToRemove:
		for k in range(m, MainBoard.BoardHeight):
			for l in range(MainBoard.BoardWidth):
					self.setShapeAt(l, k, self.shapeAt(l, k + 1))
	numFullLines = numFullLines + len(rowsToRemove)
	if numFullLines > 0:
		self.numLinesRemoved = self.numLinesRemoved + numFullLines
		self.msg.emit(str(self.numLinesRemoved))
		self.isWaitingAfterLine = True
		self.curPiece.setShape(ShapeForm.NoShape)
		self.update()

我们来看一下最终实现效果:

python如何写个俄罗斯方块

是不是有内味了。

总结

本文我们使用 PyQt5 库写了一个俄罗斯方块小游戏,如果你对 PyQt5 库感兴趣的话,可以尝试使用一下。

示例代码:py-tetris

以上就是python写个俄罗斯方块的详细内容,更多关于python 俄罗斯方块的资料请关注三水点靠木其它相关文章!

Python 相关文章推荐
Python基于pygame实现图片代替鼠标移动效果
Nov 11 Python
Python闭包的两个注意事项(推荐)
Mar 20 Python
浅谈python内置变量-reversed(seq)
Jun 21 Python
Python2.7下安装Scrapy框架步骤教程
Dec 22 Python
Python中出现IndentationError:unindent does not match any outer indentation level错误的解决方法
Apr 18 Python
对python调用RPC接口的实例详解
Jan 03 Python
使用python求解二次规划的问题
Feb 29 Python
python实现ftp文件传输功能
Mar 20 Python
Pycharm快捷键配置详细整理
Oct 13 Python
Python+OpenCV图像处理—— 色彩空间转换
Oct 22 Python
4款Python 类型检查工具,你选择哪个呢?
Oct 30 Python
python中的列表和元组区别分析
Dec 30 Python
基于Python实现全自动下载抖音视频
Nov 06 #Python
Python3读写ini配置文件的示例
Nov 06 #Python
Python Serial串口基本操作(收发数据)
Nov 06 #Python
python基于exchange函数发送邮件过程详解
Nov 06 #Python
Python Unittest原理及基本使用方法
Nov 06 #Python
python中的yield from语法快速学习
Nov 06 #Python
Python通过字典映射函数实现switch
Nov 06 #Python
You might like
php中文件上传的安全问题
2006/10/09 PHP
新手配置 PHP 调试环境(IIS+PHP+MYSQL)
2007/01/10 PHP
php下实现在指定目录搜索指定类型文件的函数
2008/10/03 PHP
mysql5的sql文件导入到mysql4的方法
2008/10/19 PHP
Yii2中cookie用法示例分析
2016/07/18 PHP
关于Laravel参数验证的一些疑与惑
2019/11/19 PHP
基于jquery.Jcrop的头像编辑器
2010/03/01 Javascript
基于jquery的cookie的用法
2011/01/10 Javascript
JQuery 选择器、过滤器介绍
2011/02/14 Javascript
jquery动态调整div大小使其宽度始终为浏览器宽度
2014/06/06 Javascript
jquery简单倒计时实现方法
2015/12/18 Javascript
javascript滚轮控制模拟滚动条
2016/10/19 Javascript
百度地图API之百度地图退拽标记点获取经纬度的实现代码
2017/01/12 Javascript
JavaScript中in和hasOwnProperty区别详解
2017/08/04 Javascript
Angularjs自定义指令实现分页插件(DEMO)
2017/09/16 Javascript
使用vue的v-for生成table并给table加上序号的实例代码
2017/10/27 Javascript
vue打包使用Nginx代理解决跨域问题
2018/08/27 Javascript
JS浮点数运算结果不精确的Bug解决
2019/08/01 Javascript
JavaScript实现图片上传并预览并提交ajax
2019/09/30 Javascript
Python标准库06之子进程 (subprocess包) 详解
2016/12/07 Python
Python编程实现微信企业号文本消息推送功能示例
2017/08/21 Python
详解python上传文件和字符到PHP服务器
2017/11/24 Python
Python即时网络爬虫项目启动说明详解
2018/02/23 Python
Python实现的本地文件搜索功能示例【测试可用】
2018/05/30 Python
中东地区最大的奢侈品市场:The Luxury Closet
2019/04/09 全球购物
在校生汽车维修实习自我鉴定
2013/09/19 职场文书
管理学专业个人求职信范文
2013/09/21 职场文书
《夏夜多美》教学反思
2014/02/17 职场文书
行政部工作岗位职责范本
2014/03/05 职场文书
最美孝心少年事迹材料
2014/08/15 职场文书
《我爱祖国》演讲稿1000字
2014/09/26 职场文书
学校感恩节活动策划方案
2014/10/06 职场文书
2014年党建工作汇报材料
2014/10/27 职场文书
初中生毕业评语
2014/12/29 职场文书
Python机器学习之逻辑回归
2021/05/11 Python
端午节将至,用Python爬取粽子数据并可视化,看看网友喜欢哪种粽子吧!
2021/06/11 Python