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实现简单socket程序在两台电脑之间传输消息的方法
Mar 13 Python
详解JavaScript编程中的window与window.screen对象
Oct 26 Python
Python 实现 贪吃蛇大作战 代码分享
Sep 07 Python
详解Python进程间通信之命名管道
Aug 28 Python
Python tkinter事件高级用法实例
Jan 31 Python
Python函数参数匹配模型通用规则keyword-only参数详解
Jun 10 Python
django实现用户注册实例讲解
Oct 30 Python
详解Django3中直接添加Websockets方式
Feb 12 Python
python 工具 字符串转numpy浮点数组的实现
Mar 14 Python
Python matplotlib可视化实例解析
Jun 01 Python
python为什么要安装到c盘
Jul 20 Python
通用的Django注册功能模块实现方法
Feb 05 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数组函数序列之in_array() 查找数组值是否存在
2011/10/29 PHP
PHP下通过QRCode类库创建中间带网站LOGO的二维码
2014/07/12 PHP
JS.findElementById()使用介绍
2013/09/21 Javascript
extjs表格文本启用选择复制功能具体实现
2013/10/11 Javascript
php读取sqlite数据库入门实例代码
2014/06/25 Javascript
js实现class样式的修改、添加及删除的方法
2015/01/20 Javascript
关于Jquery中的bind(),on()绑定事件方式总结
2016/10/26 Javascript
js实现鼠标左右移动,图片也跟着移动效果
2017/01/25 Javascript
使用JS和canvas实现gif动图的停止和播放代码
2017/09/01 Javascript
React-Native使用Mobx实现购物车功能
2017/09/14 Javascript
vue中如何实现pdf文件预览的方法
2018/07/12 Javascript
JS+HTML5本地存储Localstorage实现注册登录及验证功能示例
2020/02/10 Javascript
Python中请使用isinstance()判断变量类型
2014/08/25 Python
解决python删除文件的权限错误问题
2018/04/24 Python
python3.6+selenium实现操作Frame中的页面元素
2019/07/16 Python
python中使用while循环的实例
2019/08/05 Python
python代码实现TSNE降维数据可视化教程
2020/02/28 Python
pymysql 插入数据 转义处理方式
2020/03/02 Python
解决Django Haystack全文检索为空的问题
2020/05/19 Python
python中前缀运算符 *和 **的用法示例详解
2020/05/28 Python
免费获得微软MCSD证书赶快行动吧!
2012/11/13 HTML / CSS
HTML5中如何显示视频呢 HTML5视频播放demo
2013/06/08 HTML / CSS
会议邀请书范文
2014/02/02 职场文书
黄河的主人教学反思
2014/02/07 职场文书
社区班子个人对照检查材料思想汇报
2014/10/07 职场文书
武夷山导游词
2015/02/03 职场文书
父亲节感言
2015/08/03 职场文书
大学体育课感想
2015/08/10 职场文书
小学六年级班主任工作经验交流材料
2015/11/02 职场文书
Nginx实现高可用集群构建(Keepalived+Haproxy+Nginx)
2021/05/27 Servers
Mysql数据库索引面试题(程序员基础技能)
2021/05/31 MySQL
一次项目中Thinkphp绕过禁用函数的实战记录
2021/11/17 PHP
PostgreSQL13基于流复制搭建后备服务器的方法
2022/01/18 PostgreSQL
Kubernetes关键组件与结构组成介绍
2022/03/31 Servers
《极主夫道》真人电影正式预告 定档6月3日上映
2022/04/05 日漫
JS函数式编程实现XDM一
2022/06/16 Javascript