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实现simhash算法实例
Apr 25 Python
python删除指定类型(或非指定)的文件实例详解
Jul 06 Python
最近Python有点火? 给你7个学习它的理由!
Jun 26 Python
浅谈Scrapy网络爬虫框架的工作原理和数据采集
Feb 07 Python
Python合并同一个文件夹下所有PDF文件的方法
Mar 11 Python
深入解析Python小白学习【操作列表】
Mar 23 Python
Python爬虫实现验证码登录代码实例
May 10 Python
python 含子图的gif生成时内存溢出的方法
Jul 07 Python
python3 中的字符串(单引号、双引号、三引号)以及字符串与数字的运算
Jul 18 Python
python利用 keyboard 库记录键盘事件
Oct 16 Python
详解解决jupyter不能使用pytorch的问题
Feb 18 Python
python缺失值的解决方法总结
Jun 09 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
用户的详细注册和判断
2006/10/09 PHP
php数据结构 算法(PHP描述) 简单选择排序 simple selection sort
2011/08/09 PHP
PHP保留两位小数并且四舍五入及不四舍五入的方法
2013/09/22 PHP
简介WordPress中用于获取首页和站点链接的PHP函数
2015/12/17 PHP
PHP8.0新功能之Match表达式的使用
2020/07/19 PHP
图片连续滚动代码[兼容IE/firefox]
2009/06/11 Javascript
解决js中window.open弹出的是上次的缓存页面问题
2013/12/29 Javascript
node.js中的querystring.parse方法使用说明
2014/12/10 Javascript
JavaScript控制网页层收起和展开效果的方法
2015/04/15 Javascript
jquery对复选框(checkbox)的操作汇总
2016/01/13 Javascript
js表单登陆验证示例
2016/10/19 Javascript
Three.js基础部分学习
2017/01/08 Javascript
JavaScript实现省市联动效果
2019/11/22 Javascript
解决Ant Design Modal内嵌Form表单initialValue值不动态更新问题
2020/10/29 Javascript
uniapp微信小程序:key失效的解决方法
2021/01/20 Javascript
Python标准库与第三方库详解
2014/07/22 Python
python爬虫入门教程之点点美女图片爬虫代码分享
2014/09/02 Python
pygame学习笔记(3):运动速率、时间、事件、文字
2015/04/15 Python
Python读写ini文件的方法
2015/05/28 Python
python套接字流重定向实例汇总
2016/03/03 Python
Python pandas常用函数详解
2018/02/07 Python
PyTorch上搭建简单神经网络实现回归和分类的示例
2018/04/28 Python
python画柱状图--不同颜色并显示数值的方法
2018/12/13 Python
python数据库操作mysql:pymysql、sqlalchemy常见用法详解
2020/03/30 Python
ASP.NET Core中的配置详解
2021/02/05 Python
CSS3实现3D翻书效果
2016/06/20 HTML / CSS
美国最古老的精致书写工具制造商:A.T. Cross(高仕)
2018/01/30 全球购物
Linux上比较文件的命令都有哪些
2012/02/24 面试题
管理站站长岗位职责
2013/11/27 职场文书
有趣的广告词
2014/03/18 职场文书
学校安全工作汇报材料
2014/08/16 职场文书
元旦标语大全
2014/10/09 职场文书
五一劳动节活动总结
2015/02/09 职场文书
综合素质评价思想道德自我评价
2015/03/09 职场文书
女性健康知识讲座主持词
2015/07/04 职场文书
MySql子查询IN的执行和优化的实现
2021/08/02 MySQL