当前位置:   article > 正文

python写俄罗斯方块

python写俄罗斯方块
  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. class BrickGame(object):
  10. #是否开始
  11. start = True;
  12. #是否到达底部
  13. isDown = True;
  14. isPause = False;
  15. #窗体
  16. window = None;
  17. #frame
  18. frame1 = None;
  19. frame2 = None;
  20. #按钮
  21. btnStart = None;
  22. #绘图类
  23. canvas = None;
  24. canvas1 = None;
  25. #标题
  26. title = "BrickGame";
  27. #宽和高
  28. width = 450;
  29. height = 670;
  30. #行和列
  31. rows = 20;
  32. cols = 10;
  33. #下降方块的线程
  34. downThread = None;
  35. #几种方块
  36. brick = [
  37. [
  38. [
  39. [0,1,1],
  40. [1,1,0],
  41. [0,0,0]
  42. ],
  43. [
  44. [1,0,0],
  45. [1,1,0],
  46. [0,1,0]
  47. ],
  48. [
  49. [0,1,1],
  50. [1,1,0],
  51. [0,0,0]
  52. ],
  53. [
  54. [1,0,0],
  55. [1,1,0],
  56. [0,1,0]
  57. ]
  58. ],
  59. [
  60. [
  61. [1,1,1],
  62. [1,0,0],
  63. [0,0,0]
  64. ],
  65. [
  66. [0,1,1],
  67. [0,0,1],
  68. [0,0,1]
  69. ],
  70. [
  71. [0,0,0],
  72. [0,0,1],
  73. [1,1,1]
  74. ],
  75. [
  76. [1,0,0],
  77. [1,0,0],
  78. [1,1,0]
  79. ]
  80. ],
  81. [
  82. [
  83. [1,1,1],
  84. [0,0,1],
  85. [0,0,0]
  86. ],
  87. [
  88. [0,0,1],
  89. [0,0,1],
  90. [0,1,1]
  91. ],
  92. [
  93. [0,0,0],
  94. [1,0,0],
  95. [1,1,1]
  96. ],
  97. [
  98. [1,1,0],
  99. [1,0,0],
  100. [1,0,0]
  101. ]
  102. ],
  103. [
  104. [
  105. [0,0,0],
  106. [0,1,1],
  107. [0,1,1]
  108. ],
  109. [
  110. [0,0,0],
  111. [0,1,1],
  112. [0,1,1]
  113. ],
  114. [
  115. [0,0,0],
  116. [0,1,1],
  117. [0,1,1]
  118. ],
  119. [
  120. [0,0,0],
  121. [0,1,1],
  122. [0,1,1]
  123. ]
  124. ],
  125. [
  126. [
  127. [1,1,1],
  128. [0,1,0],
  129. [0,0,0]
  130. ],
  131. [
  132. [0,0,1],
  133. [0,1,1],
  134. [0,0,1]
  135. ],
  136. [
  137. [0,0,0],
  138. [0,1,0],
  139. [1,1,1]
  140. ],
  141. [
  142. [1,0,0],
  143. [1,1,0],
  144. [1,0,0]
  145. ]
  146. ],
  147. [
  148. [
  149. [0,1,0],
  150. [0,1,0],
  151. [0,1,0]
  152. ],
  153. [
  154. [0,0,0],
  155. [1,1,1],
  156. [0,0,0]
  157. ],
  158. [
  159. [0,1,0],
  160. [0,1,0],
  161. [0,1,0]
  162. ],
  163. [
  164. [0,0,0],
  165. [1,1,1],
  166. [0,0,0]
  167. ]
  168. ],
  169. [
  170. [
  171. [1,1,0],
  172. [0,1,1],
  173. [0,0,0]
  174. ],
  175. [
  176. [0,0,1],
  177. [0,1,1],
  178. [0,1,0]
  179. ],
  180. [
  181. [0,0,0],
  182. [1,1,0],
  183. [0,1,1]
  184. ],
  185. [
  186. [0,1,0],
  187. [1,1,0],
  188. [1,0,0]
  189. ]
  190. ]
  191. ];
  192. #当前的方块
  193. curBrick = None;
  194. #当前方块数组
  195. arr = None;
  196. arr1 = None;
  197. #当前方块形状
  198. shape = -1;
  199. #当前方块的行和列(最左上角)
  200. curRow = -10;
  201. curCol = -10;
  202. #背景
  203. back = list();
  204. #格子
  205. gridBack = list();
  206. preBack = list();
  207. #初始化
  208. def init(self):
  209. for i in range(0,self.rows):
  210. self.back.insert(i,list());
  211. self.gridBack.insert(i,list());
  212. for i in range(0,self.rows):
  213. for j in range(0,self.cols):
  214. self.back[i].insert(j,0);
  215. self.gridBack[i].insert(j,self.canvas.create_rectangle(30*j,30*i,30*(j+1),30*(i+1),fill="black"));
  216. for i in range(0,3):
  217. self.preBack.insert(i,list());
  218. for i in range(0,3):
  219. for j in range(0,3):
  220. self.preBack[i].insert(j,self.canvas1.create_rectangle(30*j,30*i,30*(j+1),30*(i+1),fill="black"));
  221. #绘制游戏的格子
  222. def drawRect(self):
  223. for i in range(0,self.rows):
  224. for j in range(0,self.cols):
  225. if self.back[i][j]==1:
  226. self.canvas.itemconfig(self.gridBack[i][j],fill="blue",outline="white");
  227. elif self.back[i][j]==0:
  228. self.canvas.itemconfig(self.gridBack[i][j],fill="black",outline="white");
  229. #绘制预览方块
  230. for i in range(0,len(self.arr1)):
  231. for j in range(0,len(self.arr1[i])):
  232. if self.arr1[i][j]==0:
  233. self.canvas1.itemconfig(self.preBack[i][j],fill="black",outline="white");
  234. elif self.arr1[i][j]==1:
  235. self.canvas1.itemconfig(self.preBack[i][j],fill="orange",outline="white");
  236. #绘制当前正在运动的方块
  237. if self.curRow!=-10 and self.curCol!=-10:
  238. for i in range(0,len(self.arr)):
  239. for j in range(0,len(self.arr[i])):
  240. if self.arr[i][j]==1:
  241. self.canvas.itemconfig(self.gridBack[self.curRow+i][self.curCol+j],fill="blue",outline="white");
  242. #判断方块是否已经运动到达底部
  243. if self.isDown:
  244. for i in range(0,3):
  245. for j in range(0,3):
  246. if self.arr[i][j]!=0:
  247. self.back[self.curRow+i][self.curCol+j] = self.arr[i][j];
  248. #判断整行消除
  249. self.removeRow();
  250. #判断是否死了
  251. self.isDead();
  252. #获得下一个方块
  253. self.getCurBrick();
  254. #判断是否有整行需要消除
  255. def removeRow(self):
  256. count=0
  257. for i in range(0,self.rows):
  258. tag1 = True;
  259. for j in range(0,self.cols):
  260. if self.back[i][j]==0:
  261. tag1 = False;
  262. break;
  263. if tag1==True:
  264. #从上向下挪动
  265. count=count+1
  266. for m in range(i-1,0,-1):
  267. for n in range(0,self.cols):
  268. self.back[m+1][n] = self.back[m][n];
  269. scoreValue = eval(self.scoreLabel2['text'])
  270. scoreValue += 5*count*(count+3)
  271. self.scoreLabel2.config(text=str(scoreValue))
  272. #获得当前的方块
  273. def getCurBrick(self):
  274. self.curBrick = randint(0,len(self.brick)-1);
  275. self.shape = 0;
  276. #当前方块数组
  277. self.arr = self.brick[self.curBrick][self.shape];
  278. self.arr1 = self.arr;
  279. self.curRow = 0;
  280. self.curCol = 1;
  281. #是否到底部为False
  282. self.isDown = False;
  283. #监听键盘输入
  284. def onKeyboardEvent(self,event):
  285. #未开始,不必监听键盘输入
  286. if self.start == False:
  287. return;
  288. if self.isPause == True:
  289. return;
  290. #记录原来的值
  291. tempCurCol = self.curCol;
  292. tempCurRow = self.curRow;
  293. tempShape = self.shape;
  294. tempArr = self.arr;
  295. direction = -1;
  296. if event.keycode==37:
  297. #左移
  298. self.curCol-=1;
  299. direction = 1;
  300. elif event.keycode==38:
  301. #变化方块的形状
  302. self.shape+=1;
  303. direction = 2;
  304. if self.shape>=4:
  305. self.shape=0;
  306. self.arr = self.brick[self.curBrick][self.shape];
  307. elif event.keycode==39:
  308. direction = 3;
  309. #右移
  310. self.curCol+=1;
  311. elif event.keycode==40:
  312. direction = 4;
  313. #下移
  314. self.curRow+=1;
  315. if self.isEdge(direction)==False:
  316. self.curCol = tempCurCol;
  317. self.curRow = tempCurRow;
  318. self.shape = tempShape;
  319. self.arr = tempArr;
  320. self.drawRect();
  321. return True;
  322. #判断当前方块是否到达边界
  323. def isEdge(self,direction):
  324. tag = True;
  325. #向左,判断边界
  326. if direction==1:
  327. for i in range(0,3):
  328. for j in range(0,3):
  329. if self.arr[j][i]!=0 and (self.curCol+i<0 or self.back[self.curRow+j][self.curCol+i]!=0):
  330. tag = False;
  331. break;
  332. #向右,判断边界
  333. elif direction==3:
  334. for i in range(0,3):
  335. for j in range(0,3):
  336. if self.arr[j][i]!=0 and (self.curCol+i>=self.cols or self.back[self.curRow+j][self.curCol+i]!=0):
  337. tag = False;
  338. break;
  339. #向下,判断底部
  340. elif direction==4:
  341. for i in range(0,3):
  342. for j in range(0,3):
  343. if self.arr[i][j]!=0 and (self.curRow+i>=self.rows or self.back[self.curRow+i][self.curCol+j]!=0):
  344. tag = False;
  345. self.isDown = True;
  346. break;
  347. #进行变形,判断边界
  348. elif direction==2:
  349. if self.curCol<0:
  350. self.curCol=0;
  351. if self.curCol+2>=self.cols:
  352. self.curCol = self.cols-3;
  353. if self.curRow+2>=self.rows:
  354. self.curRow = self.curRow-3;
  355. return tag;
  356. #方块向下移动
  357. def brickDown(self):
  358. while True:
  359. if self.start==False:
  360. print("exit thread");
  361. break;
  362. if self.isPause==False:
  363. tempRow = self.curRow;
  364. self.curRow+=1;
  365. if self.isEdge(4)==False:
  366. self.curRow = tempRow;
  367. self.drawRect();
  368. #每一秒下降一格
  369. sleep(1);
  370. #点击开始
  371. def clickStart(self):
  372. self.start = True;
  373. for i in range(0,self.rows):
  374. for j in range(0,self.cols):
  375. self.back[i][j] = 0;
  376. self.canvas.itemconfig(self.gridBack[i][j],fill="black",outline="white");
  377. for i in range(0,len(self.arr)):
  378. for j in range(0,len(self.arr[i])):
  379. self.canvas1.itemconfig(self.preBack[i][j],fill="black",outline="white");
  380. self.getCurBrick();
  381. self.drawRect();
  382. self.downThread = threading.Thread(target=self.brickDown,args=());
  383. self.downThread.start();
  384. def clickPause(self):
  385. self.isPause=not self.isPause
  386. print(self.isPause)
  387. if not self.isPause:
  388. self.btnPause["text"]="暂停"
  389. else:
  390. self.btnPause["text"]="恢复"
  391. def clickReStart(self):
  392. ackRestart =askquestion("重新开始","你确定要重新开始吗?")
  393. if ackRestart == 'yes':
  394. self.clickStart()
  395. else:
  396. return
  397. def clickQuit(self):
  398. ackQuit =askquestion("退出","你确定要退出吗?")
  399. if ackQuit == 'yes':
  400. self.window.destroy()
  401. exit()
  402. #判断是否死了
  403. def isDead(self):
  404. for j in range(0,len(self.back[0])):
  405. if self.back[0][j]!=0:
  406. showinfo("提示","你挂了,再来一盘吧!");
  407. self.start = False;
  408. break;
  409. #运行
  410. def __init__(self):
  411. self.window = Tk();
  412. self.window.title(self.title);
  413. self.window.minsize(self.width,self.height);
  414. self.window.maxsize(self.width,self.height);
  415. self.frame1 = Frame(self.window,width=300,height=600,bg="black");
  416. self.frame1.place(x=20,y=30);
  417. self.scoreLabel1 = Label(self.window,text="Score:",font=(30))
  418. self.scoreLabel1.place(x=340,y=60)
  419. self.scoreLabel2 = Label(self.window,text="0",fg='red',font=(30))
  420. self.scoreLabel2.place(x=410,y=60)
  421. self.frame2 = Frame(self.window,width=90,height=90,bg="black");
  422. self.frame2.place(x=340,y=120);
  423. self.canvas = Canvas(self.frame1,width=300,height=600,bg="black");
  424. self.canvas1 = Canvas(self.frame2,width=90,height=90,bg="black");
  425. self.btnStart = Button(self.window,text="开始",command=self.clickStart);
  426. self.btnStart.place(x=340,y=400,width=80,height=25);
  427. self.btnPause = Button(self.window,text="暂停",command=self.clickPause);
  428. self.btnPause.place(x=340,y=450,width=80,height=25);
  429. self.btnReStart = Button(self.window,text="重新开始",command=self.clickReStart);
  430. self.btnReStart.place(x=340,y=500,width=80,height=25);
  431. self.btnQuit = Button(self.window,text="退出",command=self.clickQuit);
  432. self.btnQuit.place(x=340,y=550,width=80,height=25);
  433. self.init();
  434. #获得当前的方块
  435. self.getCurBrick();
  436. #按照数组,绘制格子
  437. self.drawRect();
  438. self.canvas.pack();
  439. self.canvas1.pack();
  440. #监听键盘事件
  441. self.window.bind("<KeyPress>",self.onKeyboardEvent);
  442. #启动方块下落线程
  443. self.downThread = threading.Thread(target=self.brickDown,args=());
  444. self.downThread.start();
  445. self.window.mainloop();
  446. self.start=False;
  447. pass;
  448. if __name__=='__main__':
  449. brickGame = BrickGame();

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/笔触狂放9/article/detail/832567
推荐阅读
相关标签
  

闽ICP备14008679号