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 相关文章推荐
django通过ajax发起请求返回JSON格式数据的方法
Jun 04 Python
Python聊天室实例程序分享
Jan 05 Python
Python中http请求方法库汇总
Jan 06 Python
Python实现的递归神经网络简单示例
Aug 11 Python
python实现pdf转换成word/txt纯文本文件
Jun 07 Python
Python IDLE清空窗口的实例
Jun 25 Python
python 对txt中每行内容进行批量替换的方法
Jul 11 Python
python看某个模块的版本方法
Oct 16 Python
关于Python3 lambda函数的深入浅出
Nov 27 Python
解决PyCharm不在run输出运行结果而不是再Console里输出的问题
Sep 21 Python
利用python调用摄像头的实例分析
Jun 07 Python
Python 操作pdf pdfplumber读取PDF写入Exce
Aug 14 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伪静态的实现详细介绍
2013/04/28 PHP
IIS+fastcgi下PHP运行超时问题的解决办法详解
2013/06/20 PHP
PHP输出当前进程所有变量/常量/模块/函数/类的示例
2013/11/07 PHP
浅析PHP程序设计中的MVC编程思想
2014/07/28 PHP
PHP图像处理之imagecreate、imagedestroy函数介绍
2014/11/19 PHP
[原创]PHP正则匹配中英文、数字及下划线的方法【用户名验证】
2017/08/01 PHP
Laravel Validator自定义错误返回提示消息并在前端展示
2019/05/09 PHP
js中split函数的使用方法说明
2013/12/26 Javascript
jQuery实现手机号码输入提示功能实例
2015/04/30 Javascript
自己编写的支持Ajax验证的JS表单验证插件
2015/05/15 Javascript
jquery实现图片上传之前预览的方法
2015/07/11 Javascript
jquery实现鼠标滑过后动态图片提示效果实例
2015/08/10 Javascript
jqGrid用法汇总(全经典)
2016/06/28 Javascript
js转换对象为xml
2017/02/17 Javascript
canvas雪花效果核心代码分享
2017/02/19 Javascript
es6学习笔记之Async函数基本教程
2017/05/11 Javascript
js中json对象和字符串的理解及相互转化操作实现方法
2017/09/22 Javascript
SVG实现时钟效果
2018/07/17 Javascript
分享vue里swiper的一些坑
2018/08/30 Javascript
Webpack按需加载打包chunk命名的方法
2019/09/22 Javascript
解决js中的setInterval清空定时器不管用问题
2020/11/17 Javascript
python3.4.3下逐行读入txt文本并去重的方法
2018/04/29 Python
Python中pandas模块DataFrame创建方法示例
2018/06/20 Python
python 输出所有大小写字母的方法
2019/01/02 Python
pyhton中__pycache__文件夹的产生与作用详解
2019/11/24 Python
Python drop方法删除列之inplace参数实例
2020/06/27 Python
python pymysql库的常用操作
2020/10/16 Python
Python-split()函数实例用法讲解
2020/12/18 Python
Matplotlib配色之Colormap详解
2021/01/05 Python
CSS3 简写animation
2012/05/10 HTML / CSS
Maisons du Monde德国:法国家具和装饰的市场领导者
2019/07/26 全球购物
英国羊皮鞋类领先品牌:Just Sheepskin
2019/12/12 全球购物
Tuckernuck官网:经典的美国品质服装、鞋子和配饰
2021/01/11 全球购物
String这个类型的class为何定义成final?
2012/11/13 面试题
集体备课反思
2014/02/12 职场文书
汽车销售助理岗位职责
2015/04/14 职场文书