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列表生成器的循环技巧分享
Mar 06 Python
给Python初学者的一些编程技巧
Apr 03 Python
Python批量按比例缩小图片脚本分享
May 21 Python
python实现二叉树的遍历
Dec 11 Python
用tensorflow实现弹性网络回归算法
Jan 09 Python
Python文件循环写入行时防止覆盖的解决方法
Nov 09 Python
Python生成MD5值的两种方法实例分析
Apr 26 Python
django之使用celery-把耗时程序放到celery里面执行的方法
Jul 12 Python
python列表返回重复数据的下标
Feb 10 Python
python如何求100以内的素数
May 27 Python
如何用Matlab和Python读取Netcdf文件
Feb 19 Python
Python中Numpy和Matplotlib的基本使用指南
Nov 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 采集书并合成txt格式的实现代码
2009/03/01 PHP
洪恩在线成语词典小偷程序php版
2012/04/20 PHP
使用PHP导出Word文档的原理和实例
2013/10/21 PHP
php的memcache类分享(memcache队列)
2014/03/26 PHP
php的ZipArchive类用法实例
2014/10/20 PHP
PHP中使用虚代理实现延迟加载技术
2014/11/05 PHP
利用404错误页面实现UrlRewrite的实现代码
2008/08/20 Javascript
JavaScript 在各个浏览器中执行的耐性
2009/04/06 Javascript
定义JavaScript二维数组采用定义数组的数组来实现
2012/12/09 Javascript
JavaScript实现将数组中所有元素连接成一个字符串的方法
2015/04/06 Javascript
老生常谈onBlur事件与onfocus事件(js)
2016/07/09 Javascript
React学习之事件绑定的几种方法对比
2017/09/24 Javascript
jQuery实现的鼠标响应缓冲动画效果示例
2018/02/13 jQuery
js中getter和setter用法实例分析
2018/08/14 Javascript
如何进行微信公众号开发的本地调试的方法
2019/06/16 Javascript
js实现录音上传功能
2019/11/22 Javascript
jQuery实现验证用户登录
2019/12/10 jQuery
原生js实现移动小球(碰撞检测)
2020/12/17 Javascript
python里将list中元素依次向前移动一位
2014/09/12 Python
PyTorch上实现卷积神经网络CNN的方法
2018/04/28 Python
Python selenium的基本使用方法分析
2019/12/21 Python
html5适合移动应用开发的12大特性
2014/03/19 HTML / CSS
乌克兰在线药房:Аптека24
2019/10/30 全球购物
什么是makefile? 如何编写makefile?
2013/01/02 面试题
社区庆八一活动方案
2014/02/02 职场文书
房产代理公证处委托书
2014/04/04 职场文书
电子商务系毕业生自荐信
2014/05/29 职场文书
党员领导干部民主生活会批评与自我批评发言
2014/09/28 职场文书
运动员入场前导词
2015/07/20 职场文书
2015双创工作总结
2015/07/24 职场文书
优秀共产党员主要事迹材料
2015/11/05 职场文书
2016年大学生暑假爱心支教活动策划书
2015/11/26 职场文书
2016高考寄语集锦
2015/12/04 职场文书
Html5获取用户当前位置的几种方式
2022/01/18 HTML / CSS
《王国之心》迎来了发售的20周年, 野村哲发布贺图
2022/04/11 其他游戏
详解MySQL的内连接和外连接
2023/05/08 MySQL