俄罗斯方块游戏(修改为无敌版)
1 #coding=utf-8 2 from tkinter import * 3 from random import * 4 import threading 5 from tkinter.messagebox import showinfo 6 from tkinter.messagebox import askquestion 7 import threading 8 from time import sleep 9 10 11 class BrickGame(object): 12 13 #是否开始 14 start = True 15 #是否到达底部 16 isDown = True 17 isPause = False 18 #窗体 19 window = None 20 #frame 21 frame1 = None 22 frame2 = None 23 24 #按钮 25 btnStart = None 26 27 #绘图类 28 canvas = None 29 canvas1 = None 30 31 #标题 32 title = "俄罗斯方块(无敌版)" 33 #宽和高 34 width = 450 35 height = 670 36 37 #行和列 38 rows = 20 39 cols = 10 40 41 #下降方块的线程 42 downThread = None 43 44 #几种方块 45 brick = [ 46 [ 47 [ 48 [0, 1, 1], 49 [1, 1, 0], 50 [0, 0, 0] 51 ], 52 [ 53 [1, 0, 0], 54 [1, 1, 0], 55 [0, 1, 0] 56 ], 57 [ 58 [0, 1, 1], 59 [1, 1, 0], 60 [0, 0, 0] 61 ], 62 [ 63 [1, 0, 0], 64 [1, 1, 0], 65 [0, 1, 0] 66 ] 67 ], 68 [ 69 [ 70 [1, 1, 1], 71 [1, 0, 0], 72 [0, 0, 0] 73 ], 74 [ 75 [0, 1, 1], 76 [0, 0, 1], 77 [0, 0, 1] 78 ], 79 [ 80 [0, 0, 0], 81 [0, 0, 1], 82 [1, 1, 1] 83 ], 84 [ 85 [1, 0, 0], 86 [1, 0, 0], 87 [1, 1, 0] 88 ] 89 ], 90 [ 91 [ 92 [1, 1, 1], 93 [0, 0, 1], 94 [0, 0, 0] 95 ], 96 [ 97 [0, 0, 1], 98 [0, 0, 1], 99 [0, 1, 1] 100 ], 101 [ 102 [0, 0, 0], 103 [1, 0, 0], 104 [1, 1, 1] 105 ], 106 [ 107 [1, 1, 0], 108 [1, 0, 0], 109 [1, 0, 0] 110 ] 111 ], 112 [ 113 [ 114 [0, 0, 0], 115 [0, 1, 1], 116 [0, 1, 1] 117 ], 118 [ 119 [0, 0, 0], 120 [0, 1, 1], 121 [0, 1, 1] 122 ], 123 [ 124 [0, 0, 0], 125 [0, 1, 1], 126 [0, 1, 1] 127 ], 128 [ 129 [0, 0, 0], 130 [0, 1, 1], 131 [0, 1, 1] 132 ] 133 ], 134 [ 135 [ 136 [1, 1, 1], 137 [0, 1, 0], 138 [0, 0, 0] 139 ], 140 [ 141 [0, 0, 1], 142 [0, 1, 1], 143 [0, 0, 1] 144 ], 145 [ 146 [0, 0, 0], 147 [0, 1, 0], 148 [1, 1, 1] 149 ], 150 [ 151 [1, 0, 0], 152 [1, 1, 0], 153 [1, 0, 0] 154 ] 155 ], 156 [ 157 [ 158 [0, 1, 0], 159 [0, 1, 0], 160 [0, 1, 0] 161 162 ], 163 [ 164 [0, 0, 0], 165 [1, 1, 1], 166 [0, 0, 0] 167 168 ], 169 [ 170 [0, 1, 0], 171 [0, 1, 0], 172 [0, 1, 0] 173 ], 174 [ 175 [0, 0, 0], 176 [1, 1, 1], 177 [0, 0, 0] 178 ] 179 ], 180 [ 181 [ 182 [1, 1, 0], 183 [0, 1, 1], 184 [0, 0, 0] 185 ], 186 [ 187 [0, 0, 1], 188 [0, 1, 1], 189 [0, 1, 0] 190 ], 191 [ 192 [0, 0, 0], 193 [1, 1, 0], 194 [0, 1, 1] 195 ], 196 [ 197 [0, 1, 0], 198 [1, 1, 0], 199 [1, 0, 0] 200 ] 201 ] 202 203 204 ] 205 206 #当前的方块 207 curBrick = None 208 #当前方块数组 209 arr = None 210 arr1 = None 211 #当前方块形状 212 shape = -1 213 #当前方块的行和列(最左上角) 214 curRow = -10 215 curCol = -10 216 217 #背景 218 back = list() 219 #格子 220 gridBack = list() 221 preBack = list() 222 223 #初始化 224 def init(self): 225 226 for i in range(0, self.rows): 227 228 self.back.insert(i, list()) 229 self.gridBack.insert(i, list()) 230 231 for i in range(0, self.rows): 232 233 for j in range(0, self.cols): 234 235 self.back[i].insert(j, 0) 236 self.gridBack[i].insert(j, self.canvas.create_rectangle( 237 30*j, 30*i, 30*(j+1), 30*(i+1), fill="black")) 238 239 for i in range(0, 3): 240 241 self.preBack.insert(i, list()) 242 243 for i in range(0, 3): 244 245 for j in range(0, 3): 246 247 self.preBack[i].insert(j, self.canvas1.create_rectangle( 248 30*j, 30*i, 30*(j+1), 30*(i+1), fill="black")) 249 250 #绘制游戏的格子 251 def drawRect(self): 252 for i in range(0, self.rows): 253 254 for j in range(0, self.cols): 255 256 if self.back[i][j] == 1: 257 258 self.canvas.itemconfig( 259 self.gridBack[i][j], fill="blue", outline="white") 260 261 elif self.back[i][j] == 0: 262 263 self.canvas.itemconfig( 264 self.gridBack[i][j], fill="black", outline="white") 265 266 #绘制预览方块 267 for i in range(0, len(self.arr1)): 268 269 for j in range(0, len(self.arr1[i])): 270 271 if self.arr1[i][j] == 0: 272 273 self.canvas1.itemconfig( 274 self.preBack[i][j], fill="black", outline="white") 275 276 elif self.arr1[i][j] == 1: 277 278 self.canvas1.itemconfig( 279 self.preBack[i][j], fill="orange", outline="white") 280 281 #绘制当前正在运动的方块 282 if self.curRow != -10 and self.curCol != -10: 283 284 for i in range(0, len(self.arr)): 285 286 for j in range(0, len(self.arr[i])): 287 288 if self.arr[i][j] == 1: 289 290 self.canvas.itemconfig( 291 self.gridBack[self.curRow+i][self.curCol+j], fill="blue", outline="white") 292 293 #判断方块是否已经运动到达底部 294 if self.isDown: 295 296 for i in range(0, 3): 297 298 for j in range(0, 3): 299 300 if self.arr[i][j] != 0: 301 302 self.back[self.curRow+i][self.curCol+j] = self.arr[i][j] 303 304 #判断整行消除 305 self.removeRow() 306 307 #获得下一个方块 308 self.getCurBrick() 309 310 #判断是否有整行需要消除 311 def removeRow(self): 312 count = 0 313 for i in range(0, self.rows): 314 315 tag1 = True 316 for j in range(0, self.cols): 317 318 if self.back[i][j] == 0: 319 320 tag1 = False 321 break 322 323 if tag1 == True: 324 325 #从上向下挪动 326 count = count+1 327 for m in range(i-1, 0, -1): 328 329 for n in range(0, self.cols): 330 331 self.back[m+1][n] = self.back[m][n] 332 333 scoreValue = eval(self.scoreLabel2['text']) 334 scoreValue += 5*count*(count+3) 335 self.scoreLabel2.config(text=str(scoreValue)) 336 337 #获得当前的方块 338 def getCurBrick(self): 339 340 self.curBrick = randint(0, len(self.brick)-1) 341 self.shape = 0 342 #当前方块数组 343 self.arr = self.brick[self.curBrick][self.shape] 344 self.arr1 = self.arr 345 346 self.curRow = 0 347 self.curCol = 1 348 349 #是否到底部为False 350 self.isDown = False 351 352 #监听键盘输入 353 def onKeyboardEvent(self, event): 354 355 #未开始,不必监听键盘输入 356 if self.start == False: 357 358 return 359 360 if self.isPause == True: 361 return 362 363 #记录原来的值 364 tempCurCol = self.curCol 365 tempCurRow = self.curRow 366 tempShape = self.shape 367 tempArr = self.arr 368 direction = -1 369 370 if event.keycode == 37: 371 372 #左移 373 self.curCol -= 1 374 direction = 1 375 elif event.keycode == 38: 376 #变化方块的形状 377 self.shape += 1 378 direction = 2 379 380 if self.shape >= 4: 381 382 self.shape = 0 383 self.arr = self.brick[self.curBrick][self.shape] 384 elif event.keycode == 39: 385 386 direction = 3 387 #右移 388 self.curCol += 1 389 elif event.keycode == 40: 390 391 direction = 4 392 #下移 393 self.curRow += 1 394 395 if self.isEdge(direction) == False: 396 397 self.curCol = tempCurCol 398 self.curRow = tempCurRow 399 self.shape = tempShape 400 self.arr = tempArr 401 402 self.drawRect() 403 404 return True 405 406 #判断当前方块是否到达边界 407 def isEdge(self, direction): 408 409 tag = True 410 411 #向左,判断边界 412 if direction == 1: 413 414 for i in range(0, 3): 415 416 for j in range(0, 3): 417 418 if self.arr[j][i] != 0 and (self.curCol+i < 0 or self.back[self.curRow+j][self.curCol+i] != 0): 419 420 tag = False 421 break 422 #向右,判断边界 423 elif direction == 3: 424 425 for i in range(0, 3): 426 427 for j in range(0, 3): 428 429 if self.arr[j][i] != 0 and (self.curCol+i >= self.cols or self.back[self.curRow+j][self.curCol+i] != 0): 430 431 tag = False 432 break 433 #向下,判断底部 434 elif direction == 4: 435 436 for i in range(0, 3): 437 438 for j in range(0, 3): 439 440 if self.arr[i][j] != 0 and (self.curRow+i >= self.rows or self.back[self.curRow+i][self.curCol+j] != 0): 441 442 tag = False 443 self.isDown = True 444 break 445 #进行变形,判断边界 446 elif direction == 2: 447 448 if self.curCol < 0: 449 450 self.curCol = 0 451 452 if self.curCol+2 >= self.cols: 453 454 self.curCol = self.cols-3 455 456 if self.curRow+2 >= self.rows: 457 458 self.curRow = self.curRow-3 459 460 return tag 461 462 #方块向下移动 463 def brickDown(self): 464 465 while True: 466 467 if self.start == False: 468 469 print("exit thread") 470 break 471 if self.isPause == False: 472 tempRow = self.curRow 473 self.curRow += 1 474 475 if self.isEdge(4) == False: 476 477 self.curRow = tempRow 478 479 self.drawRect() 480 481 #每一秒下降一格 482 sleep(1) 483 484 #点击开始 485 def clickStart(self): 486 487 self.start = True 488 489 for i in range(0, self.rows): 490 491 for j in range(0, self.cols): 492 493 self.back[i][j] = 0 494 self.canvas.itemconfig( 495 self.gridBack[i][j], fill="black", outline="white") 496 497 for i in range(0, len(self.arr)): 498 499 for j in range(0, len(self.arr[i])): 500 501 self.canvas1.itemconfig( 502 self.preBack[i][j], fill="black", outline="white") 503 504 self.getCurBrick() 505 self.drawRect() 506 507 self.downThread = threading.Thread(target=self.brickDown, args=()) 508 self.downThread.start() 509 510 def clickPause(self): 511 self.isPause = not self.isPause 512 print(self.isPause) 513 if not self.isPause: 514 self.btnPause["text"] = "暂停" 515 else: 516 self.btnPause["text"] = "恢复" 517 518 def clickReStart(self): 519 ackRestart = askquestion("重新开始", "你确定要重新开始吗?") 520 if ackRestart == 'yes': 521 self.clickStart() 522 else: 523 return 524 525 def clickQuit(self): 526 ackQuit = askquestion("退出", "你确定要退出吗?") 527 if ackQuit == 'yes': 528 self.window.destroy() 529 exit() 530 531 #运行 532 def __init__(self): 533 534 self.window = Tk() 535 self.window.title(self.title) 536 self.window.minsize(self.width, self.height) 537 self.window.maxsize(self.width, self.height) 538 539 self.frame1 = Frame(self.window, width=300, height=600, bg="black") 540 self.frame1.place(x=20, y=30) 541 542 self.scoreLabel1 = Label(self.window, text="Score:", font=(30)) 543 self.scoreLabel1.place(x=340, y=60) 544 self.scoreLabel2 = Label(self.window, text="0", fg='red', font=(30)) 545 self.scoreLabel2.place(x=410, y=60) 546 547 self.frame2 = Frame(self.window, width=90, height=90, bg="black") 548 self.frame2.place(x=340, y=120) 549 550 self.canvas = Canvas(self.frame1, width=300, height=600, bg="black") 551 self.canvas1 = Canvas(self.frame2, width=90, height=90, bg="black") 552 553 self.btnStart = Button(self.window, text="开始", command=self.clickStart) 554 self.btnStart.place(x=340, y=400, width=80, height=25) 555 556 self.btnPause = Button(self.window, text="暂停", command=self.clickPause) 557 self.btnPause.place(x=340, y=450, width=80, height=25) 558 559 self.btnReStart = Button(self.window, text="重新开始", 560 command=self.clickReStart) 561 self.btnReStart.place(x=340, y=500, width=80, height=25) 562 563 self.btnQuit = Button(self.window, text="退出", command=self.clickQuit) 564 self.btnQuit.place(x=340, y=550, width=80, height=25) 565 566 self.init() 567 568 #获得当前的方块 569 self.getCurBrick() 570 571 #按照数组,绘制格子 572 573 self.drawRect() 574 575 self.canvas.pack() 576 577 self.canvas1.pack() 578 579 #监听键盘事件 580 self.window.bind("<KeyPress>", self.onKeyboardEvent) 581 582 #启动方块下落线程 583 self.downThread = threading.Thread(target=self.brickDown, args=()) 584 self.downThread.start() 585 586 self.window.mainloop() 587 588 self.start = False 589 590 pass 591 592 593 if __name__ == '__main__': 594 595 brickGame = BrickGame()
参考:python 实现俄罗斯方块(一)https://blog.csdn.net/ITxiaoangzai/article/details/81489136
删除了代码:
1 #判断是否死了 2 self.isDead() 3 #判断是否死了 4 5 def isDead(self): 6 7 for j in range(0, len(self.back[0])): 8 9 if self.back[0][j] != 0: 10 11 showinfo("提示", "你挂了,再来一盘吧!") 12 self.start = False 13 break
插入前:
插入后:
初始状态: