python制作小游戏——俄罗斯方块

图片[1]-python制作小游戏——俄罗斯方块-uusu优素-乐高,模型,3d打印,编程

实现

我们实现俄罗斯方块,主要用到的是 PyQt5 库,安装使用pip install PyQt5即可,游戏的组成比较简单,主要包括:主界面、各种方块和计分板,下面我们来看一下具体实现。

首先,我们来画一个主界面,主要实现代码如下:

classMainBoard(QFrame):
msg=pyqtSignal(str)
BoardWidth=10
BoardHeight=20
Speed=300
def__init__(self,parent):
super().__init__(parent)
self.initBoard()
definitBoard(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()

看一下效果:

01.jpg

分数的显示就是利用上面 msg 的 emit() 方法实现的。

我们接着画各种方块,方块的形状主要包括:T、Z、L、I、O 等,主要实现代码如下:

classShapeForm(object):
NoShape=0
ZShape=1
SShape=2
LineShape=3
TShape=4
SquareShape=5
LShape=6
MirroredLShape=7
classShape(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]foriinrange(4)]
self.pieceShape=ShapeForm.NoShape
self.setShape(ShapeForm.NoShape)
defshape(self):
returnself.pieceShape
defsetShape(self,shape):
table=Shape.coordsTable[shape]
foriinrange(4):
forjinrange(2):
self.coords[i][j]=table[i][j]
self.pieceShape=shape

看一下效果:

02.jpg

我们知道方块是不断自动下落的,因此需要一个计时器来控制,主要实现代码如下:

deftimerEvent(self,event):
ifevent.timerId()==self.timer.timerId():
ifself.isWaitingAfterLine:
self.isWaitingAfterLine=False
self.newPiece()
else:
self.oneLineDown()
else:
super(MainBoard,self).timerEvent(event)

在方块下落的过程中,我们需要通过键盘来控制方块的形状以及左右移动,因此,我们需要一个按键事件来控制它,主要实现代码如下:

defkeyPressEvent(self,event):
ifnotself.isStartedorself.curPiece.shape()==ShapeForm.NoShape:
super(MainBoard,self).keyPressEvent(event)
return
key=event.key()
ifkey==Qt.Key_P:
self.pause()
return
ifself.isPaused:
return
elifkey==Qt.Key_Left:
self.tryMove(self.curPiece,self.curX-1,self.curY)
elifkey==Qt.Key_Right:
self.tryMove(self.curPiece,self.curX+1,self.curY)
elifkey==Qt.Key_Down:
self.tryMove(self.curPiece.rotateRight(),self.curX,self.curY)
elifkey==Qt.Key_Up:
self.tryMove(self.curPiece.rotateLeft(),self.curX,self.curY)
elifkey==Qt.Key_Space:
self.dropDown()
elifkey==Qt.Key_D:
self.oneLineDown()
else:
super(MainBoard,self).keyPressEvent(event)

当方块落到底部后,需要来检测是否有构成一条直线的,因此我们需要有一个方法来找到所有能消除的行并且消除它们,主要实现代码如下:

defremoveFullLines(self):
numFullLines=0
rowsToRemove=[]
foriinrange(MainBoard.BoardHeight):
n=0
forjinrange(MainBoard.BoardWidth):
ifnotself.shapeAt(j,i)==ShapeForm.NoShape:
n=n+1
ifn==10:
rowsToRemove.append(i)
rowsToRemove.reverse()
forminrowsToRemove:
forkinrange(m,MainBoard.BoardHeight):
forlinrange(MainBoard.BoardWidth):
self.setShapeAt(l,k,self.shapeAt(l,k+1))
numFullLines=numFullLines+len(rowsToRemove)
ifnumFullLines>0:
self.numLinesRemoved=self.numLinesRemoved+numFullLines
self.msg.emit(str(self.numLinesRemoved))
self.isWaitingAfterLine=True
self.curPiece.setShape(ShapeForm.NoShape)
self.update()

我们来看一下最终实现效果:

03.jpg

是不是有内味了。

总结


更多python相关文章请关注python自学网。
原文来自:https://www.py.cn
© 版权声明
THE END
喜欢就支持一下吧
点赞5 分享
评论 抢沙发
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

取消
昵称表情代码图片

    暂无评论内容