PyQt5制作俄罗斯方块的思路
近来闲来无事在学习PyQt5,再看文档看到最后的俄罗斯方块的时候百思不得其解,把程序跑起来也看不到效果因为看不到图形,所以我就自己想做一个,以下是我要分享的思路。
一、先分析以下俄罗斯方块是要在界面上显示方块所以首先我们要先画方块,我就找了划方块的例子,来自PyQt5中文教程中的绘图章节。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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_())
这个例子是叫我们画矩形,之后照着书上俄罗斯方块的思路,是将图形定义在列表里面,里面存了坐标点。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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))
这个书上的解释,我也是按照这个方法定义的方块,接下来我来说我的做法,这里涉及到一点算法,用这个坐标想要在自己定义的界面上显示20*20的方块必须让他的横坐标减去0.5再乘以20,让他的纵坐标加上0.5在乘以20,这样就可以使用画矩形的方法QPaint.drawRect()画出20*20的方块,代码如下:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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)
这样就能画出方块了,但是想要方块随机发生变化,书上的代码里已经写了setRandomShape(self)函数,只需要再将类中的self.coords拿出来就可以拿到要展示的方块,那就应该把注意力放在变化上,这个需要使用到QBasicTimer类,然后写timerevent,来让方块动起来。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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()
这样方块就可以随机的出现在界面上,接下来就是下掉,这里我做了格子,因为我的方块是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)
,我将行列定义为全局变量,通过控制全局变量来控制左右,以及下掉。代码如下:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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_())
做到这里的效果展示:
二、接下来是根据上面的思路做出主体的俄罗斯方块。上面演示的将一个图形打印在上面,接下来我们就要涉及出整体方案,我的窗口是600*800,我规定格子是20*20的,每个格子在窗口上都可以用坐标表示,【40】【30】这样,格子的动作都是通过控制这个二维列表控制的。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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_())
图形的动作,将定义好点的图形放在二维列表里这些是根据点的坐标的特性做的。
三、我将做一个能够显示分数完整的俄罗斯方块,敬请期待。