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 22 Python
python使用urllib2提交http post请求的方法
May 26 Python
Linux中Python 环境软件包安装步骤
Mar 31 Python
Python实现ssh批量登录并执行命令
Oct 25 Python
Python3学习urllib的使用方法示例
Nov 29 Python
python2.7到3.x迁移指南
Feb 01 Python
python读写LMDB文件的方法
Jul 02 Python
python定时按日期备份MySQL数据并压缩
Apr 19 Python
简单了解Python3里的一些新特性
Jul 13 Python
浅谈Python中os模块及shutil模块的常规操作
Apr 03 Python
Python下载的11种姿势(小结)
Nov 18 Python
Python使用tkinter实现小时钟效果
Feb 22 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
PHPMYADMIN 简明安装教程 推荐
2010/03/07 PHP
新手学习PHP的一些基础知识分享
2011/07/27 PHP
比较好用的PHP防注入漏洞过滤函数代码
2012/04/11 PHP
php生成局部唯一识别码LUID的代码
2012/10/06 PHP
PHP 观察者模式的实现代码
2013/05/10 PHP
PHP删除目录及目录下所有文件的方法详解
2013/06/06 PHP
PHP6 中可能会出现的新特性预览
2014/04/04 PHP
PHP+Ajax异步带进度条上传文件实例
2016/11/01 PHP
IE6与IE7中,innerHTML获取param的区别
2009/03/15 Javascript
限制文本框输入N个字符的js代码
2010/05/13 Javascript
js中实现多态采用和继承类似的方法
2014/08/22 Javascript
jquery实现弹出层登录和全屏层注册特效
2015/08/28 Javascript
详解javascript函数的参数
2015/11/10 Javascript
JavaScript算法系列之快速排序(Quicksort)算法实例详解
2016/09/04 Javascript
node.js缺少mysql模块运行报错的解决方法
2016/11/13 Javascript
bootstrap datetimepicker2.3.11时间插件使用
2016/11/19 Javascript
详解用vue.js和laravel实现微信支付
2017/06/23 Javascript
微信小程序录音与播放录音功能
2017/12/25 Javascript
vue和小程序项目中使用iconfont的方法
2020/05/19 Javascript
javascript实现前端分页功能
2020/11/26 Javascript
python益智游戏计算汉诺塔问题示例
2014/03/05 Python
python里大整数相乘相关技巧指南
2014/09/12 Python
使用优化器来提升Python程序的执行效率的教程
2015/04/02 Python
简介二分查找算法与相关的Python实现示例
2015/08/26 Python
Ubuntu下安装PyV8
2016/03/13 Python
Python实现k-means算法
2018/02/23 Python
Python实现获取nginx服务器ip及流量统计信息功能示例
2018/05/18 Python
Python基础教程之异常详解
2019/01/10 Python
Python 实现还原已撤回的微信消息
2019/06/18 Python
pytorch进行上采样的种类实例
2020/02/18 Python
Champion官网:美国冠军运动服装
2017/01/25 全球购物
在Java开发中如何选择使用哪种集合类
2016/08/09 面试题
经典人生语录分享:不畏将来,不念过去,笑对当下
2019/12/12 职场文书
nginx实现发布静态资源的方法
2021/03/31 Servers
JAVA长虹键法之建造者Builder模式实现
2022/04/10 Java/Android
postgresql之greenplum字符串去重拼接方式
2023/05/08 PostgreSQL