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共存的配置方法
May 22 Python
Python读取文件内容的三种常用方式及效率比较
Oct 07 Python
python实时监控cpu小工具
Jun 21 Python
python使用folium库绘制地图点击框
Sep 21 Python
Python 正则表达式匹配字符串中的http链接方法
Dec 25 Python
Python格式化字符串f-string概览(小结)
Jun 18 Python
Django shell调试models输出的SQL语句方法
Aug 29 Python
python实现WebSocket服务端过程解析
Oct 18 Python
Python中内建模块collections如何使用
May 27 Python
Python unittest装饰器实现原理及代码
Sep 08 Python
Python爬取某平台短视频的方法
Feb 08 Python
python爬取企查查企业信息之selenium自动模拟登录企查查
Apr 08 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根据身份证号码计算年龄的实例代码
2014/01/18 PHP
PHP中常用的输出函数总结
2014/09/22 PHP
PHP+shell脚本操作Memcached和Apache Status的实例分享
2016/03/11 PHP
PHP实现的随机IP函数【国内IP段】
2016/07/20 PHP
基于PHP实现短信验证码接口(容联运通讯)
2016/09/06 PHP
Thinkphp5.0框架的Db操作实例分析【连接、增删改查、链式操作等】
2019/10/11 PHP
javascript 装载iframe子页面,自适应高度
2009/03/20 Javascript
javascript常用的方法分享
2015/07/01 Javascript
初识Javascript小结
2015/07/16 Javascript
jQuery实现html元素拖拽
2015/07/21 Javascript
JS实现的另类手风琴效果网页内容切换代码
2015/09/08 Javascript
JS实现的表格操作类详解(添加,删除,排序,上移,下移)
2015/12/22 Javascript
ionic 自定义弹框效果
2017/06/27 Javascript
在小程序中使用Echart图表的示例代码
2018/08/02 Javascript
vue2.0 路由模式mode="history"的作用
2018/10/18 Javascript
vscode vue 文件模板的配置方法
2019/07/23 Javascript
js实现星星打分效果
2020/07/05 Javascript
使用scrapy实现爬网站例子和实现网络爬虫(蜘蛛)的步骤
2014/01/23 Python
Python实现远程调用MetaSploit的方法
2014/08/22 Python
Python执行时间的计算方法小结
2017/03/17 Python
python 二分查找和快速排序实例详解
2017/10/13 Python
PyQt5实现无边框窗口的标题拖动和窗口缩放
2018/04/19 Python
Python Django基础二之URL路由系统
2019/07/18 Python
解决Python对齐文本字符串问题
2019/08/28 Python
基于Python获取docx/doc文件内容代码解析
2020/02/17 Python
HTML5拖放功能_动力节点Java学院整理
2017/07/13 HTML / CSS
移动HTML5前端框架—MUI的使用
2017/12/18 HTML / CSS
英国卫浴商店:Ergonomic Design
2019/09/22 全球购物
英国奢侈品在线精品店:Hervia
2020/09/03 全球购物
大学生活学习的自我评价
2013/12/03 职场文书
高中军训感言400字
2014/02/24 职场文书
投标保密承诺书
2014/05/19 职场文书
助学感谢信范文
2015/01/21 职场文书
2015廉洁自律个人总结
2015/02/14 职场文书
关于HTML编码导致的乱码问题
2021/09/04 HTML / CSS
利用Python实现翻译HTML中的文本字符串
2022/06/21 Python