PyQt5制作俄罗斯方块的思路

         近来闲来无事在学习PyQt5,再看文档看到最后的俄罗斯方块的时候百思不得其解,把程序跑起来也看不到效果因为看不到图形,所以我就自己想做一个,以下是我要分享的思路。

一、先分析以下俄罗斯方块是要在界面上显示方块所以首先我们要先画方块,我就找了划方块的例子,来自PyQt5中文教程中的绘图章节。

 1 from PyQt5.QtWidgets import QWidget,QApplication
 2 from PyQt5.QtGui import QPainter,QColor,QBrush
 3 import sys
 4 
 5 class Example(QWidget):
 6     def __init__(self):
 7         super(Example, self).__init__()
 8         self.initUI()
 9 
10     def initUI(self):
11         self.setGeometry(300,300,350,100)
12         self.setWindowTitle('Colors')
13         self.show()
14 
15     def paintEvent(self, e):
16         qp = QPainter()
17         qp.begin(self)
18         self.drawRectangles(qp)
19         qp.end()
20 
21     def drawRectangles(self,qp):
22         col = QColor(0,0,0)
23         col.setNamedColor('#d4d4d4')
24         qp.setPen(col)
25         qp.setBrush(QColor(200,0,0))
26         qp.drawRect(10,15,90,60)
27         qp.setBrush(QColor(255,80,0,160))
28         qp.drawRect(130,15,90,60)
29         qp.setBrush(QColor(25,0,90,200))
30         qp.drawRect(250,15,90,60)
31 
32 if __name__ == '__main__':
33     app = QApplication(sys.argv)
34     ex = Example()
35     sys.exit(app.exec_())
View Code

这个例子是叫我们画矩形,之后照着书上俄罗斯方块的思路,是将图形定义在列表里面,里面存了坐标点。

 1 class Shape(object):
 2     coordsTable = (((0, -1), (0, 0),
 3                     (-1, 0), (-1, 1)),
 4 
 5                    ((0, -1), (0, 0),
 6                     (1, 0), (1, 1)),
 7 
 8                    ((0, -1), (0, 0),
 9                     (0, 1), (0, 2)),
10 
11                    ((-1, 0), (0, 0),
12                     (1, 0), (0, 1)),
13 
14                    ((0, 0), (1, 0),
15                     (0, 1), (1, 1)),
16 
17                    ((-1, -1), (0, -1),
18                     (0, 0), (0, 1)),
19 
20                    ((1, -1), (0, -1),
21                     (0, 0), (0, 1)))
22 
23     def __init__(self):
24         self.coords = [[0,0] for i in range(4)]
25         self.setRandomShape()
26 
27     def shape(self):
28         return self.pieceShape
29 
30     def setShape(self, shape):
31         table = Shape.coordsTable[shape]
32         for i in range(4):
33             for j in range(2):
34                 self.coords[i][j] = table[i][j]
35         self.pieceShape = shape
36 
37     def setRandomShape(self):
38         self.setShape(random.randint(1, 6))
View Code

这个书上的解释,我也是按照这个方法定义的方块,接下来我来说我的做法,这里涉及到一点算法,用这个坐标想要在自己定义的界面上显示20*20的方块必须让他的横坐标减去0.5再乘以20,让他的纵坐标加上0.5在乘以20,这样就可以使用画矩形的方法QPaint.drawRect()画出20*20的方块,代码如下:

1  def drawRectangles(self,qp):
2         col = QColor(0,0,0)
3         col.setNamedColor('#d4d4d4')
4         qp.setPen(col)
5         qp.setBrush(QColor(200,0,0))
6         for i in self.shape.coords:
7             qp.drawRect(self.Vline*20+(i[0]-0.5)*20,self.Hline*20+(i[1]+0.5)*20,20,20)
View Code

这样就能画出方块了,但是想要方块随机发生变化,书上的代码里已经写了setRandomShape(self)函数,只需要再将类中的self.coords拿出来就可以拿到要展示的方块,那就应该把注意力放在变化上,这个需要使用到QBasicTimer类,然后写timerevent,来让方块动起来。

1         self.Speed = 1000
2         self.timer = QBasicTimer()
3         self.timer.start(self.Speed,self)    
4 
5     def timerEvent(self,event):
6         self.shape.setRandomShape()
7         self.update()
View Code

这样方块就可以随机的出现在界面上,接下来就是下掉,这里我做了格子,因为我的方块是20*20的,界面是600*800的,所以左右有30列,上下有40行,所以方块出现的位置的计算方法应该是行数乘以20加上方块的显示的像素数

qp.drawRect(self.Vline*20+(i[0]-0.5)*20,self.Hline*20+(i[1]+0.5)*20,20,20)

,我将行列定义为全局变量,通过控制全局变量来控制左右,以及下掉。代码如下:

  1 from PyQt5.QtWidgets import QWidget,QApplication,QDesktopWidget
  2 from PyQt5.QtGui import QPainter,QColor,QBrush
  3 from PyQt5.QtCore import QBasicTimer,Qt
  4 import sys,random
  5 
  6 class Example(QWidget):
  7     def __init__(self):
  8         super(Example, self).__init__()
  9         self.initUI()
 10 
 11     def initUI(self):
 12         self.Hline = 1
 13         self.Vline =15
 14         self.Speed = 1000
 15         self.newPiece = False
 16         self.pause = False
 17         self.shape = Shape()
 18         self.setGeometry(300,300,600,800)
 19         screen = QDesktopWidget().screenGeometry()
 20         size = self.geometry()
 21         self.move(int((screen.width()-size.width())/2),int((screen.height()-size.height())/2))
 22         self.setWindowTitle('Colors')
 23         self.show()
 24         self.timer = QBasicTimer()
 25         self.timer.start(self.Speed,self)
 26 
 27 
 28     def keyPressEvent(self, event):
 29         key = event.key()
 30         if key == Qt.Key_P:
 31             if self.pause:
 32                 self.timer.stop()
 33             else:
 34                 self.timer.start(self.Speed,self)
 35         elif key == Qt.Key_Left:
 36             if self.Vline > 0:
 37                 self.Vline = self.Vline - 1
 38         elif key == Qt.Key_Right:
 39             if self.Vline < 29:
 40                 self.Vline = self.Vline + 1
 41         elif key == Qt.Key_Down:
 42             self.Speed = 100
 43         elif key == Qt.Key_Up:
 44             self.Speed = 100
 45         elif key == Qt.Key_Space:
 46             self.Speed = 10
 47             self.timer.stop()
 48             self.timer.start(self.Speed,self)
 49         elif key == Qt.Key_D:
 50             self.Speed = 100
 51         else:
 52             super(Example, self).keyPressEvent(event)
 53 
 54     def paintEvent(self, e):
 55         qp = QPainter()
 56         qp.begin(self)
 57         self.drawRectangles(qp)
 58         qp.end()
 59 
 60     def timerEvent(self,event):
 61         self.Hline = self.Hline + 1
 62         self.downCollisionDetection()
 63         if self.newPiece:
 64             self.shape.setRandomShape()
 65             self.newPiece = False
 66             self.Hline = 1
 67             self.Vline = 15
 68         self.update()
 69         # if event.timerId() == self.timer.timerId():
 70         #     if self.isWaitingAfterLine:
 71         #         self.isWaitingAfterLine = False
 72         #         self.newPiece()
 73         #     else:
 74         #         self.oneLineDown()
 75         # else:
 76         #     super(Board,self).timerEvent(event)
 77 
 78     def drawRectangles(self,qp):
 79         col = QColor(0,0,0)
 80         col.setNamedColor('#d4d4d4')
 81         qp.setPen(col)
 82         qp.setBrush(QColor(200,0,0))
 83         for i in self.shape.coords:
 84             qp.drawRect(self.Vline*20+(i[0]-0.5)*20,self.Hline*20+(i[1]+0.5)*20,20,20)
 85         # qp.setBrush(QColor(255,80,0,160))
 86         # qp.drawRect(130,15,90,60)
 87         # qp.setBrush(QColor(25,0,90,200))
 88         # qp.drawRect(250,15,90,60)
 89 
 90     def downCollisionDetection(self):
 91         if self.Hline > 39:
 92             self.newPiece = True
 93 
 94 
 95 
 96 class Tetrominoe(object):
 97     ZShape = 1
 98     SShape = 2
 99     LineShape = 3
100     TShape = 4
101     SquareShape = 5
102     LShape = 6
103     MirroredLShape = 7
104 class Shape(object):
105     coordsTable = (((0, -1), (0, 0),
106                     (-1, 0), (-1, 1)),
107 
108                    ((0, -1), (0, 0),
109                     (1, 0), (1, 1)),
110 
111                    ((0, -1), (0, 0),
112                     (0, 1), (0, 2)),
113 
114                    ((-1, 0), (0, 0),
115                     (1, 0), (0, 1)),
116 
117                    ((0, 0), (1, 0),
118                     (0, 1), (1, 1)),
119 
120                    ((-1, -1), (0, -1),
121                     (0, 0), (0, 1)),
122 
123                    ((1, -1), (0, -1),
124                     (0, 0), (0, 1)))
125 
126     def __init__(self):
127         self.coords = [[0,0] for i in range(4)]
128         self.setRandomShape()
129 
130     def shape(self):
131         return self.pieceShape
132 
133     def setShape(self, shape):
134         table = Shape.coordsTable[shape]
135         for i in range(4):
136             for j in range(2):
137                 self.coords[i][j] = table[i][j]
138         self.pieceShape = shape
139 
140     def setRandomShape(self):
141         self.setShape(random.randint(1, 6))
142 
143     def x(self, index):
144         return self.coords[index][0]
145 
146     def y(self, index):
147         return self.coords[index][1]
148 
149     def setX(self, index, x):
150         self.coords[index][0] = x
151 
152     def setY(self, index, y):
153         self.coords[index][1] = y
154 
155     def minX(self):
156         m = self.coords[0][0]
157         for i in range(4):
158             m = min(m, self.coords[i][0])
159         return m
160 
161     def maxX(self):
162         m = self.coords[0][0]
163         for i in range(4):
164             m = max(m, self.coords[i][0])
165         return m
166 
167     def minY(self):
168         m = self.coords[0][1]
169         for i in range(4):
170             m = min(m, self.coords[i][1])
171         return m
172 
173     def maxY(self):
174         m = self.coords[0][1]
175         for i in range(4):
176             m = max(m, self.coords[i][1])
177         return m
178 
179     def rotateLeft(self):
180         if self.pieceShape == Tetrominoe.SquareShape:
181             return self
182         result = Shape()
183         result.pieceShape = self.pieceShape
184         for i in range(4):
185             result.setX(i, self.y(i))
186             result.setY(i, -self.x(i))
187         return result
188 
189     def rotateRight(self):
190         if self.pieceShape == Tetrominoe.SquareShape:
191             return self
192         result = Shape()
193         result.pieceShape = self.pieceShape
194         for i in range(4):
195             result.setX(i, -self.y(i))
196             result.setY(i, self.x(i))
197         return result
198 
199 if __name__ == '__main__':
200     app = QApplication(sys.argv)
201     ex = Example()
202     sys.exit(app.exec_())
View Code

做到这里的效果展示:

 

二、接下来是根据上面的思路做出主体的俄罗斯方块。上面演示的将一个图形打印在上面,接下来我们就要涉及出整体方案,我的窗口是600*800,我规定格子是20*20的,每个格子在窗口上都可以用坐标表示,【40】【30】这样,格子的动作都是通过控制这个二维列表控制的。

  1 from PyQt5.QtWidgets import QWidget,QApplication,QDesktopWidget
  2 from PyQt5.QtGui import QPainter,QColor,QBrush
  3 from PyQt5.QtCore import QBasicTimer,Qt
  4 import sys,random
  5 import threading
  6 
  7 class Example(QWidget):
  8     def __init__(self):
  9         super(Example, self).__init__()
 10         self.initUI()
 11 
 12     def initUI(self):
 13         self.panal =[[0 for j in range(30)]for i in range(40)]
 14         self.hpoint = 0
 15         self.vpoint = 0
 16         self.Speed = 500
 17         self.pause = False
 18         self.downFlag = False
 19         self.shape = Shape()
 20         self.setGeometry(300,300,600,800)
 21         screen = QDesktopWidget().screenGeometry()
 22         size = self.geometry()
 23         self.move(int((screen.width()-size.width())/2),int((screen.height()-size.height())/2))
 24         self.setWindowTitle('Colors')
 25         self.show()
 26         self.timer = QBasicTimer()
 27         self.timer.start(self.Speed,self)
 28 
 29     def keyPressEvent(self, event):
 30         key = event.key()
 31         if key == Qt.Key_P:
 32             if self.pause:
 33                 self.timer.stop()
 34             else:
 35                 self.timer.start(self.Speed,self)
 36         elif key == Qt.Key_Left:
 37             if self.vpoint > 0:
 38                 self.leftMove()
 39         elif key == Qt.Key_Right:
 40             if self.vpoint < 29:
 41                 self.rightMove()
 42         elif key == Qt.Key_Down:
 43             self.rightFlip()
 44         elif key == Qt.Key_Up:
 45             self.leftFlip()
 46         elif key == Qt.Key_Space:
 47             self.spaceDown()
 48         elif key == Qt.Key_D:
 49             self.oneLineDown()
 50         else:
 51             super(Example, self).keyPressEvent(event)
 52 
 53     def paintEvent(self, e):
 54         qp = QPainter()
 55         qp.begin(self)
 56         self.drawRectangles(qp)
 57         qp.end()
 58 
 59     def timerEvent(self,event):
 60         if event.timerId() == self.timer.timerId():
 61             if self.downFlag == False:
 62                 if self.gameOver():
 63                     print('game over')
 64                 else:
 65                     self.downFlag = True
 66                     self.newPiece()
 67             else:
 68                 self.oneLineDown()
 69         else:
 70             super(Board,self).timerEvent(event)
 71         self.update()
 72 
 73     def gameOver(self):
 74         firstRow = 0
 75         flag = True
 76         for i in range(40):
 77             for j in range(30):
 78                 if self.panal[i][j] == 1:
 79                     flag = False
 80                     firstRow = i + 1
 81                     break
 82             if flag == False:
 83                 break
 84         if firstRow == 1:
 85             return True
 86 
 87     def spaceDown(self):
 88         initPoint = self.shape.getInitPoint()
 89         count = 0
 90         sFlag = True
 91         tempHPoint = self.hpoint
 92         while sFlag == True:
 93             for point in self.shape.getBottom():
 94                 if self.hpoint + count - (point[1] - initPoint[1]) > 39:
 95                     sFlag = False
 96                     break
 97                 else:
 98                     if self.panal[self.hpoint + count - (point[1] - initPoint[1])][self.vpoint + point[0] - initPoint[0]] == 1:
 99                         sFlag = False
100                         break
101             count = count + 1
102             if sFlag == False:
103                 self.hpoint = self.hpoint + count - 1
104                 break
105         for i in self.shape.coords:
106             self.panal[self.hpoint - 1 - (i[1] - initPoint[1])][self.vpoint + i[0] - initPoint[0]] = 1
107             self.panal[tempHPoint - 1 - (i[1] - initPoint[1])][self.vpoint + i[0] - initPoint[0]] = 0
108         self.finDownFlag = True
109         self.cancelRow()
110 
111     def cancelRow(self):
112         rowList = []
113         self.shape.getDataCharacteristics()
114         for i in range(self.shape.dataCharacteristics[0]):
115             cancelFlag = True
116             for j in range(30):
117                 if self.panal[self.hpoint - 1 - i][j] == 0:
118                     cancelFlag = False
119             if cancelFlag == True:
120                 rowList.append(self.hpoint - i)
121         for i in range(len(rowList)):
122             rowList[i] = rowList[i] + i
123         firstRow = 0
124         flag = True
125         for i in range(40):
126             for j in range(30):
127                 if self.panal[i][j] == 1:
128                     flag = False
129                     firstRow = i + 1
130                     break
131             if flag == False:
132                 break
133         for i in rowList:
134             for j in range(i - firstRow):
135                 for v in range(30):
136                     self.panal[i - 1 - j][v] = self.panal[i - 1 - j - 1][v]
137 
138 
139     def leftFlip(self):
140         flipFlag = True
141         self.shape.isLeftFlip()
142         initPoint = self.shape.leftFlipList[0]
143         for j in self.shape.leftFlipList:
144             nextFlag = False
145             for i in self.shape.coords:
146                 if (j[1] - self.shape.leftFlipList[0][1] == i[1] - self.shape.coords[0][1]) and (j[0] - self.shape.leftFlipList[0][0] == i[0] - self.shape.coords[0][0]):
147                     nextFlag = True
148             if nextFlag == True:
149                 continue
150             if (((self.vpoint + j[0] - initPoint[0]) > 29) or ((self.vpoint + j[0] - initPoint[0]) < 0)) or (((self.hpoint - 1 - (j[1] - initPoint[1])) > 39) or ((self.hpoint - 1 - (j[1] - initPoint[1])) < 0)):
151                 flipFlag = False
152             else:
153                 if self.panal[self.hpoint - 1 - (j[1] - initPoint[1])][self.vpoint + j[0] - initPoint[0]] == 1:
154                     flipFlag = False
155         if flipFlag == True:
156             initPoint = self.shape.getInitPoint()
157             for i in self.shape.coords:
158                 self.panal[self.hpoint - 1 - (i[1] - initPoint[1])][self.vpoint + i[0] - initPoint[0]] = 0
159             self.shape.leftFlip()
160             initPoint = self.shape.getInitPoint()
161             for j in self.shape.coords:
162                 self.panal[self.hpoint - 1 - (j[1] - initPoint[1])][self.vpoint + j[0] - initPoint[0]] = 1
163         self.update()
164 
165     def rightFlip(self):
166         flipFlag = True
167         self.shape.isRightFlip()
168         initPoint = self.shape.rightFlipList[0]
169         for j in self.shape.rightFlipList:
170             nextFlag = False
171             for i in self.shape.coords:
172                 if (j[1] - self.shape.rightFlipList[0][1] == i[1] - self.shape.coords[0][1]) and (j[0] - self.shape.rightFlipList[0][0] == i[0] - self.shape.coords[0][0]):
173                     nextFlag = True
174             if nextFlag == True:
175                 continue
176             if (((self.vpoint + j[0] - initPoint[0]) > 29) or ((self.vpoint + j[0] - initPoint[0]) < 0)) or (((self.hpoint - 1 - (j[1] - initPoint[1])) > 39) or ((self.hpoint - 1 - (j[1] - initPoint[1])) < 0)):
177                 flipFlag = False
178             else:
179                 if self.panal[self.hpoint - 1 - (j[1] - initPoint[1])][self.vpoint + j[0] - initPoint[0]] == 1:
180                     flipFlag = False
181         if flipFlag == True:
182             initPoint = self.shape.getInitPoint()
183             for i in self.shape.coords:
184                 self.panal[self.hpoint - 1 - (i[1] - initPoint[1])][self.vpoint + i[0] - initPoint[0]] = 0
185             self.shape.rightFlip()
186             initPoint = self.shape.getInitPoint()
187             for j in self.shape.coords:
188                 self.panal[self.hpoint - 1 - (j[1] - initPoint[1])][self.vpoint + j[0] - initPoint[0]] = 1
189         self.update()
190 
191     def leftMove(self):
192         leftFlag = True
193         initPoint = self.shape.getInitPoint()
194         for point in self.shape.getLeftSection():
195             if self.vpoint - 1 + point[0] - initPoint[0] == -1:
196                 leftFlag = False
197                 break
198             else:
199                 if self.panal[self.hpoint - 1 - (point[1] - initPoint[1])][self.vpoint - 1 + point[0] - initPoint[0]] == 1:
200                     leftFlag = False
201                     break
202         if leftFlag == True:
203              for i in self.shape.coords:
204                 self.panal[self.hpoint - 1 - (i[1] - initPoint[1])][self.vpoint - 1 + i[0] - initPoint[0]] = 1
205                 self.panal[self.hpoint - 1 - (i[1] - initPoint[1])][self.vpoint + i[0] - initPoint[0]] = 0
206              self.vpoint = self.vpoint - 1
207 
208     def rightMove(self):
209         rightFlag = True
210         initPoint = self.shape.getInitPoint()
211         for point in self.shape.getRightSection():
212             if self.vpoint + 1 + point[0] - initPoint[0] == 30:
213                 rightFlag = False
214                 break
215             else:
216                 if self.panal[self.hpoint - 1 - (point[1] - initPoint[1])][self.vpoint + 1 + point[0] - initPoint[0]] == 1:
217                     rightFlag = False
218                     break
219         if rightFlag == True:
220              for i in self.shape.coords:
221                 self.panal[self.hpoint - 1 - (i[1] - initPoint[1])][self.vpoint + 1 + i[0] - initPoint[0]] = 1
222                 self.panal[self.hpoint - 1 - (i[1] - initPoint[1])][self.vpoint + i[0] - initPoint[0]] = 0
223              self.vpoint = self.vpoint + 1
224 
225     def oneLineDown(self):
226         initPoint = self.shape.getInitPoint()
227         for point in self.shape.getBottom():
228             if self.hpoint - (point[1] - initPoint[1]) == 40:
229                 self.downFlag = False
230                 break
231             else:
232                 if self.panal[self.hpoint - (point[1] - initPoint[1])][self.vpoint + point[0] - initPoint[0]] == 1:
233                     self.downFlag = False
234                     break
235         if self.downFlag == False:
236             self.cancelRow()
237         if self.downFlag == True:
238              for i in self.shape.coords:
239                 self.panal[self.hpoint - (i[1] - initPoint[1])][self.vpoint + i[0] - initPoint[0]] = 1
240                 self.panal[self.hpoint - 1 - (i[1] - initPoint[1])][self.vpoint + i[0] - initPoint[0]] = 0
241              self.hpoint = self.hpoint + 1
242 
243     def newPiece(self):
244         self.shape.setRandomShape()
245         row = self.shape.dataCharacteristics[0]
246         list = self.shape.dataCharacteristics[1]
247         direction = self.shape.dataCharacteristics[2]
248         initPoint = self.shape.coords[0]
249         if direction == 0:
250             for i in range(row):
251                 self.panal[row - i - 1][15] = 1
252                 self.hpoint = row
253                 self.vpoint = 15
254         elif direction == 1:
255             self.panal[row - 1][15 + 1] = 1
256             self.hpoint = row
257             self.vpoint = 15 + 1
258             for i in self.shape.coords:
259                 if initPoint == i:
260                     continue
261                 else:
262                     self.panal[row - 1 - (i[1]-initPoint[1])][15 + 1 + i[0]-initPoint[0]] = 1
263         elif direction == 2:
264             self.panal[row - 1][15] = 1
265             self.hpoint = row
266             self.vpoint = 15
267             for i in self.shape.coords:
268                 if initPoint == i:
269                     continue
270                 else:
271                     self.panal[row - 1 - (i[1] - initPoint[1])][15 + i[0] - initPoint[0]] = 1
272 
273     def drawRectangles(self,qp):
274         col = QColor(0,0,0)
275         col.setNamedColor('#d4d4d4')
276         qp.setPen(col)
277         qp.setBrush(QColor(200,0,0))
278         for i in range(40):
279             for j in range(30):
280                 if self.panal[i][j] == 1:
281                     qp.drawRect(j*20+(-0.5)*20,i*20+0.5*20,20,20)
282         # qp.setBrush(QColor(255,80,0,160))
283         # qp.drawRect(130,15,90,60)
284         # qp.setBrush(QColor(25,0,90,200))
285         # qp.drawRect(250,15,90,60)
286 
287     def downCollisionDetection(self):
288         if self.Hline > 39:
289             self.newPiece = True
290 
291 
292 
293 class Tetrominoe(object):
294     ZShape = 1
295     SShape = 2
296     LineShape = 3
297     TShape = 4
298     SquareShape = 5
299     LShape = 6
300     MirroredLShape = 7
301 class Shape(object):
302     coordsTable = (((0, -1), (0, 0),
303                     (-1, 0), (-1, 1)),
304 
305                    ((0, -1), (0, 0),
306                     (1, 0), (1, 1)),
307 
308                    ((0, -1), (0, 0),
309                     (0, 1), (0, 2)),
310 
311                    ((-1, 0), (0, 0),
312                     (1, 0), (0, 1)),
313 
314                    ((0, 0), (1, 0),
315                     (0, 1), (1, 1)),
316 
317                    ((-1, -1), (0, -1),
318                     (0, 0), (0, 1)),
319 
320                    ((1, -1), (0, -1),
321                     (0, 0), (0, 1)))
322 
323     def __init__(self):
324         self.coords = [[0,0] for i in range(4)]
325         self.rightFlipList = [[0,0] for i in range(4)]
326         self.leftFlipList = [[0,0] for i in range(4)]
327         self.dataCharacteristics = [0,0,0]
328         self.setRandomShape()
329 
330     def getDataCharacteristics(self):
331         h = []
332         v = []
333         f = 0
334         for i in self.coords:
335             h.append(i[1])
336             v.append(i[0])
337         if self.coords[0][0] > self.coords[1][0]:
338             f = 1
339         elif self.coords[0][0] < self.coords[1][0]:
340             f = 2
341         else:
342             if self.coords[1][0] > self.coords[2][0]:
343                 f = 1
344             elif self.coords[1][0] < self.coords[2][0]:
345                 f = 2
346             else:
347                 if self.coords[2][0] > self.coords[3][0]:
348                     f = 1
349                 elif self.coords[2][0] < self.coords[3][0]:
350                     f = 2
351                 else:
352                     f = 0
353         self.dataCharacteristics = [len(set(h)),len(set(v)),f]
354 
355     def shape(self):
356         return self.pieceShape
357 
358     def setShape(self, shape):
359         table = Shape.coordsTable[shape]
360         self.coords = table
361         self.pieceShape = shape
362 
363     def setRandomShape(self):
364         self.setShape(random.randint(1, 6))
365         self.getDataCharacteristics()
366 
367     def getBottom(self):
368         xlist = []
369         bottomPointList = []
370         tempList = []
371         for i in self.coords:
372             xlist.append(i[0])
373         for j in set(xlist):
374             for v in self.coords:
375                 if v[0] == j:
376                     tempList.append(v)
377             if len(tempList) != 1:
378                 ymin = tempList[0][1]
379                 for i in tempList:
380                     if i[1] < ymin:
381                         ymin = i[1]
382                 bottomPointList.append([j,ymin])
383             else:
384                 bottomPointList.append(tempList[0])
385             tempList = []
386         return bottomPointList
387 
388     def getLeftSection(self):
389         ylist = []
390         leftPointList = []
391         tempList = []
392         for i in self.coords:
393             ylist.append(i[1])
394         for j in set(ylist):
395             for v in self.coords:
396                 if v[1] == j:
397                     tempList.append(v)
398             if len(tempList) != 1:
399                 xmin = tempList[0][0]
400                 for i in tempList:
401                     if i[0] < xmin:
402                         xmin = i[0]
403                 leftPointList.append([xmin, j])
404             else:
405                 leftPointList.append(tempList[0])
406             tempList = []
407         return leftPointList
408 
409     def getRightSection(self):
410         ylist = []
411         rightPointList = []
412         tempList = []
413         for i in self.coords:
414             ylist.append(i[1])
415         for j in set(ylist):
416             for v in self.coords:
417                 if v[1] == j:
418                     tempList.append(v)
419             if len(tempList) != 1:
420                 xmax = tempList[0][0]
421                 for i in tempList:
422                     if i[0] > xmax:
423                         xmax = i[0]
424                 rightPointList.append([xmax, j])
425             else:
426                 rightPointList.append(tempList[0])
427             tempList = []
428         return rightPointList
429 
430     def getInitPoint(self):
431         return self.coords[0]
432 
433     def isLeftFlip(self):
434         newPoint = []
435         initPoint = self.getInitPoint()
436         for i in self.coords:
437             if i[0] - initPoint[0] == 0 and i[1] - initPoint[1] == 0:
438                 newPoint.append([i[0], i[1]])
439                 continue
440             newPoint.append([initPoint[0] - (i[1] - initPoint[1]), initPoint[1] + i[0] - initPoint[0]])
441         list = []
442         for v in range(4):
443             list.append(newPoint[v][1])
444         ymin = min(set(list))
445         ymax = max(set(list))
446         firstPoint = []
447         tailPoint = []
448         tempList = []
449         for i in newPoint:
450             if i[1] == ymin:
451                 tempList.append(i[0])
452         tempList.sort()
453         if len(tempList) > 2:
454             firstPoint.append(tempList[1])
455         else:
456             firstPoint.append(tempList[0])
457         firstPoint.append(ymin)
458         tempList.clear()
459         for i in newPoint:
460             if i[1] == ymax:
461                 tempList.append(i[0])
462         tempList.sort()
463         tailPoint.append(tempList[len(tempList) - 1])
464         tailPoint.append(ymax)
465         tempList.clear()
466         tempList.append(firstPoint)
467         for j in newPoint:
468             if firstPoint != j and tailPoint != j:
469                 tempList.append(j)
470         tempList.append(tailPoint)
471         self.leftFlipList = tempList
472 
473     def leftFlip(self):
474         self.coords = self.leftFlipList
475 
476     def isRightFlip(self):
477         newPoint = []
478         initPoint = self.getInitPoint()
479         for i in self.coords:
480             if i[0] - initPoint[0] == 0 and i[1] - initPoint[1] == 0:
481                 newPoint.append([i[0],i[1]])
482                 continue
483             newPoint.append([initPoint[0] + i[1] - initPoint[1],initPoint[1] + initPoint[0] - i[0]])
484         list = []
485         for v in range(4):
486             list.append(newPoint[v][1])
487         ymin = min(set(list))
488         ymax = max(set(list))
489         firstPoint = []
490         tailPoint = []
491         tempList = []
492         for i in newPoint:
493             if i[1] == ymin:
494                 tempList.append(i[0])
495         tempList.sort()
496         if len(tempList) > 2:
497             firstPoint.append(tempList[1])
498         else:
499             firstPoint.append(tempList[0])
500         firstPoint.append(ymin)
501         tempList.clear()
502         for i in newPoint:
503             if i[1] == ymax:
504                 tempList.append(i[0])
505         tempList.sort()
506         tailPoint.append(tempList[len(tempList) - 1])
507         tailPoint.append(ymax)
508         tempList.clear()
509         tempList.append(firstPoint)
510         for j in newPoint:
511             if firstPoint != j and tailPoint != j:
512                 tempList.append(j)
513         tempList.append(tailPoint)
514         self.rightFlipList = tempList
515 
516     def rightFlip(self):
517         self.coords = self.rightFlipList
518 
519 
520 
521 
522 
523 if __name__ == '__main__':
524     app = QApplication(sys.argv)
525     ex = Example()
526     sys.exit(app.exec_())
View Code

图形的动作,将定义好点的图形放在二维列表里这些是根据点的坐标的特性做的。

三、我将做一个能够显示分数完整的俄罗斯方块,敬请期待。

 

posted on 2022-03-14 18:15  1548562170  阅读(210)  评论(0编辑  收藏  举报