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 19 Python
python查找指定具有相同内容文件的方法
Jun 28 Python
Python进阶篇之字典操作总结
Nov 16 Python
用TensorFlow实现lasso回归和岭回归算法的示例
May 02 Python
python如何生成网页验证码
Jul 28 Python
python 利用pywifi模块实现连接网络破解wifi密码实时监控网络
Sep 16 Python
基于python监控程序是否关闭
Jan 14 Python
python关于变量名的基础知识点
Mar 03 Python
Python根据指定文件生成XML的方法
Jun 29 Python
python操作toml文件的示例代码
Nov 27 Python
python文件路径操作方法总结
Dec 21 Python
python gui开发——制作抖音无水印视频下载工具(附源码)
Feb 07 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调用API接口实现天气查询功能的示例
2017/09/21 PHP
JQuery跨Iframe选择实现代码
2010/08/19 Javascript
validator验证控件使用代码
2010/11/23 Javascript
javascript之querySelector和querySelectorAll使用说明
2011/10/09 Javascript
IE下window.onresize 多次调用与死循环bug处理方法介绍
2013/11/12 Javascript
jQuery 常见小例汇总
2016/12/14 Javascript
JavaScript Ajax实现异步通信
2016/12/14 Javascript
vuejs绑定class和style样式
2017/04/11 Javascript
详解webpack的proxyTable无效的解决方案
2018/06/15 Javascript
JS可断点续传文件上传实现代码解析
2020/07/30 Javascript
小程序实现上传视频功能
2020/08/18 Javascript
举例讲解Python中装饰器的用法
2015/04/27 Python
python魔法方法-属性访问控制详解
2016/07/25 Python
python清除字符串前后空格函数的方法
2018/10/21 Python
使用python实现简单五子棋游戏
2019/06/18 Python
对Django中static(静态)文件详解以及{% static %}标签的使用方法
2019/07/28 Python
Python urlopen()和urlretrieve()用法解析
2020/01/07 Python
Python对Tornado请求与响应的数据处理
2020/02/12 Python
Python写捕鱼达人的游戏实现
2020/03/31 Python
Python matplotlib实时画图案例
2020/04/23 Python
python框架flask入门之路由及简单实现方法
2020/06/07 Python
python爬虫调度器用法及实例代码
2020/11/30 Python
Python调用高德API实现批量地址转经纬度并写入表格的功能
2021/01/12 Python
意大利在线大学图书馆:Libreria universitaria
2019/07/16 全球购物
屈臣氏俄罗斯在线商店:Watsons俄罗斯
2020/08/03 全球购物
怎样建立和理解非常复杂的声明?例如定义一个包含N 个指向返回 指向字符的指针的函数的指针的数组?
2013/03/19 面试题
J2EE面试题
2016/03/14 面试题
怎么样写好简历中的自我评价
2013/10/25 职场文书
自我鉴定200字
2013/10/28 职场文书
社区庆八一活动方案
2014/02/02 职场文书
初中教师个人总结
2015/02/10 职场文书
党校毕业个人总结
2015/02/28 职场文书
matlab xlabel位置的设置方式
2021/05/21 Python
Python函数式编程中itertools模块详解
2021/09/15 Python
javascript函数式编程基础
2021/09/15 Javascript
Python可视化学习之seaborn调色盘
2022/02/24 Python