最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • python制作小游戏——俄罗斯方块

    正文概述    2020-06-08   327

    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 库感兴趣的话,可以尝试使用一下。


    更多python相关文章请关注python自学网。

    起源地下载网 » python制作小游戏——俄罗斯方块

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元