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编程中的文件操作攻略
Oct 16 Python
python实现下载整个ftp目录的方法
Jan 17 Python
详解Python判定IP地址合法性的三种方法
Mar 06 Python
Python 函数基础知识汇总
Mar 09 Python
python实现NB-IoT模块远程控制
Jun 20 Python
Python爬虫实现抓取京东店铺信息及下载图片功能示例
Aug 07 Python
Python正则表达式匹配数字和小数的方法
Jul 03 Python
python基于celery实现异步任务周期任务定时任务
Dec 30 Python
Python Numpy库常见用法入门教程
Jan 16 Python
基于python3生成标签云代码解析
Feb 18 Python
python3美化表格数据输出结果的实现代码
Apr 14 Python
Matlab如何实现矩阵复制扩充
Jun 02 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 skymvc 一款轻量、简单的php
2011/06/28 PHP
PHP常用的缓存技术汇总
2014/05/05 PHP
使用YUI+Ant 实现JS CSS压缩
2014/09/02 PHP
PHP链接MySQL的常用扩展函数
2014/10/23 PHP
php基本函数汇总
2015/07/09 PHP
php制作圆形用户头像的实例_自定义封装类源代码
2017/09/18 PHP
ThinkPHP 在阿里云上的nginx.config配置实例详解
2017/10/11 PHP
tp5(thinkPHP5)框架实现多数据库查询的方法
2019/01/10 PHP
showModalDialog在谷歌浏览器下会返回Null的解决方法
2013/11/27 Javascript
javascript上下方向键控制表格行选中并高亮显示的方法
2015/02/13 Javascript
jQuery实现表格展开与折叠的方法
2015/05/04 Javascript
超级给力的JavaScript的React框架入门教程
2015/07/02 Javascript
微信JS接口大全
2016/08/25 Javascript
超全面的javascript中变量命名规则
2017/02/09 Javascript
JavaScript中值类型和引用类型的区别
2017/02/23 Javascript
JS 验证密码 不能为空,必须含有数字、字母、特殊字符,长度在8-12位
2017/06/21 Javascript
vue 父组件调用子组件方法及事件
2018/03/29 Javascript
区别JavaScript函数声明与变量声明
2018/09/12 Javascript
vue项目引入Iconfont图标库的教程图解
2018/10/24 Javascript
如何优雅地在Node应用中进行错误异常处理
2019/11/25 Javascript
[57:12]完美世界DOTA2联赛循环赛 Inki vs Matador BO2第一场 10.31
2020/11/02 DOTA
python登录WeChat 实现自动回复实例详解
2019/05/28 Python
详解pandas使用drop_duplicates去除DataFrame重复项参数
2019/08/01 Python
Python 限定函数参数的类型及默认值方式
2019/12/24 Python
在python中list作函数形参,防止被实参修改的实现方法
2020/06/05 Python
Python如何测试stdout输出
2020/08/10 Python
会计岗位职责
2013/11/08 职场文书
计算机应用专业推荐信
2013/11/13 职场文书
客服主管岗位职责
2013/12/13 职场文书
化验室技术员岗位职责
2013/12/24 职场文书
高三上学期学习自我评价
2014/04/23 职场文书
绿色环保口号
2014/06/12 职场文书
学习雷锋标语
2014/06/25 职场文书
2015年学生会纪检部工作总结
2015/03/31 职场文书
MySQL表锁、行锁、排它锁及共享锁的使用详解
2022/04/02 MySQL
请求模块urllib之PYTHON爬虫的基本使用
2022/04/08 Python