用 Python 写个俄罗斯方块小游戏

ゝ一世哀愁。 2023-02-13 11:09 90阅读 0赞

前言

本文的文字及图片来源于网络,仅供学习、交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理。

作者:python技术

PS:如有需要Python学习资料的小伙伴可以加点击下方链接自行获取

python免费学习资料以及群交流解答点击即可加入


俄罗斯方块是俄罗斯人发明的一款休闲类的小游戏,这款小游戏可以说是很多人童年的主打电子游戏了,本文我们使用 Python 来实现这款小游戏。

游戏的基本规则是:移动、旋转和摆放游戏自动输出的各种方块,使之排列成完整的一行或多行并且消除得分。

实现

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

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

  1. class MainBoard(QFrame):
  2. msg = pyqtSignal(str)
  3. BoardWidth = 10
  4. BoardHeight = 20
  5. Speed = 300
  6. def __init__(self, parent):
  7. super().__init__(parent)
  8. self.initBoard()
  9. def initBoard(self):
  10. self.timer = QBasicTimer()
  11. self.isWaitingAfterLine = False
  12. self.curX = 0
  13. self.curY = 0
  14. self.numLinesRemoved = 0
  15. self.board = []
  16. self.setFocusPolicy(Qt.StrongFocus)
  17. self.isStarted = False
  18. self.isPaused = False
  19. self.clearBoard()

看一下效果:
在这里插入图片描述
分数的显示就是利用上面 msg 的 emit() 方法实现的。

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

  1. class ShapeForm(object):
  2. NoShape = 0
  3. ZShape = 1
  4. SShape = 2
  5. LineShape = 3
  6. TShape = 4
  7. SquareShape = 5
  8. LShape = 6
  9. MirroredLShape = 7
  10. class Shape(object):
  11. coordsTable = (
  12. ((0, 0), (0, 0), (0, 0), (0, 0)),
  13. ((0, -1), (0, 0), (-1, 0), (-1, 1)),
  14. ((0, -1), (0, 0), (1, 0), (1, 1)),
  15. ((0, -1), (0, 0), (0, 1), (0, 2)),
  16. ((-1, 0), (0, 0), (1, 0), (0, 1)),
  17. ((0, 0), (1, 0), (0, 1), (1, 1)),
  18. ((-1, -1), (0, -1), (0, 0), (0, 1)),
  19. ((1, -1), (0, -1), (0, 0), (0, 1))
  20. )
  21. def __init__(self):
  22. self.coords = [[0,0] for i in range(4)]
  23. self.pieceShape = ShapeForm.NoShape
  24. self.setShape(ShapeForm.NoShape)
  25. def shape(self):
  26. return self.pieceShape
  27. def setShape(self, shape):
  28. table = Shape.coordsTable[shape]
  29. for i in range(4):
  30. for j in range(2):
  31. self.coords[i][j] = table[i][j]
  32. self.pieceShape = shape

看一下效果:
在这里插入图片描述
我们知道方块是不断自动下落的,因此需要一个计时器来控制,主要实现代码如下:

  1. def timerEvent(self, event):
  2. if event.timerId() == self.timer.timerId():
  3. if self.isWaitingAfterLine:
  4. self.isWaitingAfterLine = False
  5. self.newPiece()
  6. else:
  7. self.oneLineDown()
  8. else:
  9. super(MainBoard, self).timerEvent(event)

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

  1. def keyPressEvent(self, event):
  2. if not self.isStarted or self.curPiece.shape() == ShapeForm.NoShape:
  3. super(MainBoard, self).keyPressEvent(event)
  4. return
  5. key = event.key()
  6. if key == Qt.Key_P:
  7. self.pause()
  8. return
  9. if self.isPaused:
  10. return
  11. elif key == Qt.Key_Left:
  12. self.tryMove(self.curPiece, self.curX - 1, self.curY)
  13. elif key == Qt.Key_Right:
  14. self.tryMove(self.curPiece, self.curX + 1, self.curY)
  15. elif key == Qt.Key_Down:
  16. self.tryMove(self.curPiece.rotateRight(), self.curX, self.curY)
  17. elif key == Qt.Key_Up:
  18. self.tryMove(self.curPiece.rotateLeft(), self.curX, self.curY)
  19. elif key == Qt.Key_Space:
  20. self.dropDown()
  21. elif key == Qt.Key_D:
  22. self.oneLineDown()
  23. else:
  24. super(MainBoard, self).keyPressEvent(event)

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

  1. def removeFullLines(self):
  2. numFullLines = 0
  3. rowsToRemove = []
  4. for i in range(MainBoard.BoardHeight):
  5. n = 0
  6. for j in range(MainBoard.BoardWidth):
  7. if not self.shapeAt(j, i) == ShapeForm.NoShape:
  8. n = n + 1
  9. if n == 10:
  10. rowsToRemove.append(i)
  11. rowsToRemove.reverse()
  12. for m in rowsToRemove:
  13. for k in range(m, MainBoard.BoardHeight):
  14. for l in range(MainBoard.BoardWidth):
  15. self.setShapeAt(l, k, self.shapeAt(l, k + 1))
  16. numFullLines = numFullLines + len(rowsToRemove)
  17. if numFullLines > 0:
  18. self.numLinesRemoved = self.numLinesRemoved + numFullLines
  19. self.msg.emit(str(self.numLinesRemoved))
  20. self.isWaitingAfterLine = True
  21. self.curPiece.setShape(ShapeForm.NoShape)
  22. self.update()

我们来看一下最终实现效果:
在这里插入图片描述
是不是有内味了。

发表评论

表情:
评论列表 (有 0 条评论,90人围观)

还没有评论,来说两句吧...

相关阅读

    相关 C语言俄罗斯方块

    在开始写俄罗斯方块的游戏之前,你需要了解一些基本的 C 语言知识。 下面是一些步骤,帮助你在 C 语言中编写俄罗斯方块的游戏: 1. 首先,你需要准备一些头文件,这些头文

    相关 JAVA俄罗斯方块

    用JAVA写的俄罗斯方块,刚学,参考了CSDN里的代码,写的很乱。一共2类。N键开始,P暂停,R重新开始,空格变形。7个方块随机。一次消除4行可以打开提示功能,简化版。 ![

    相关 JAVA俄罗斯方块

    本文实例为大家分享了java实现俄罗斯方块的具体代码,供大家参考,具体内容如下 俄罗斯方块设计思想 俄罗斯方块都从小玩到大吧,什么规则大家都知道了吧,以前感觉那玩意贼好玩,