当前位置:   article > 正文

用Pygame写俄罗斯方块_pygame俄罗斯方块代码

pygame俄罗斯方块代码

此文章参考的是吃饭超人的文章

首先我们先打开cmd输入如下令命

pip install pygame

然后打开python或者pycharm

输入如下代码

  1. import os
  2. import pygame
  3. import sys
  4. import random
  5. import pygame.font
  6. import time
  7. pygame.init()
  8. clos = 10 #游戏网格列数,可以调整,>=8
  9. rows = 20 #游戏网格行数,可以调整
  10. cell_size = 40 #一个网格的大小
  11. block_size = cell_size - 1 #一个方块的大小,小于等于cell_size
  12. block_edge = int(block_size /2) #方块的立体感,数字>=1,数字越小立体感越强
  13. fps = 40 #每秒帧数,建议范围20-60,越大难度递进越越缓
  14. win_width = clos * 2 * cell_size + 6 * cell_size
  15. win_hight = (rows + 1) * cell_size
  16. os.environ['SDL_VIDEO_WINDOW_POS'] = "%d,%d" % (400,40)
  17. screen = pygame.display.set_mode((win_width, win_hight))
  18. pygame.display.set_caption("Crystal方块")
  19. #在4*4的小网格内,以左上角坐标为(0,0),7种方块及其各形态4个方块在小网格的相对坐标
  20. #移动时记录小网络(0,0)点在游戏网格的(x,y),就知道4个方块在游戏网格中的位置
  21. blocks = {
  22. 1: [[(0,1),(1,1),(2,1),(3,1)],
  23. [(2,0),(2,1),(2,2),(2,3)]], #I型
  24. 2: [[(1,1),(2,1),(1,2),(2,2)]], #O型
  25. 3: [[(0,1),(1,1),(2,1),(1,2)],
  26. [(1,0),(0,1),(1,1),(1,2)],
  27. [(1,1),(0,2),(1,2),(2,2)],
  28. [(1,0),(1,1),(2,1),(1,2)]], #T型
  29. 4: [[(0,1),(1,1),(2,1),(0,2)],
  30. [(0,0),(1,0),(1,1),(1,2)],
  31. [(2,1),(0,2),(1,2),(2,2)],
  32. [(1,0),(1,1),(1,2),(2,2)]], #L型
  33. 5: [[(0,1),(1,1),(2,1),(2,2)],
  34. [(1,0),(1,1),(0,2),(1,2)],
  35. [(0,1),(0,2),(1,2),(2,2)],
  36. [(1,0),(2,0),(1,1),(1,2)]], #J型
  37. 6: [[(1,1),(2,1),(0,2),(1,2)],
  38. [(0,0),(0,1),(1,1),(1,2)]], #s型
  39. 7: [[(0,1),(1,1),(1,2),(2,2)],
  40. [(2,0),(1,1),(2,1),(1,2)]],} #Z型
  41. #第1个为网格底色,后7个为对应方块的颜色,因为要加和原色相近的明暗边,自定义色RGB值最小得不低于50,最高不超过205,否则出错。
  42. #最后一个颜色(灰)用来画NEXT方块,也可以用NEXT方块的next_key值来指向本色
  43. block_color = [(199,238,206),(200,50,50),(50,200,200),(50,50,200),(200,200,50),(200,50,200),(50,200,50),(125,50,125),(180,180,180)]
  44. class Game_machine():
  45. def __init__(self,x0,y0):
  46. self.x0, self.y0 = x0, y0 #记录player游戏区(0,0)点在屏幕的坐标
  47. self.rect = pygame.Rect(0,0,block_size, block_size) #方块矩形大小
  48. self.display_array = [[0 for i in range(clos)] for j in range(rows)] #游戏区每格初始值设为0,为1时不能通过
  49. self.color_array = [[0 for i in range(clos)] for j in range(rows)] #游戏区每格的颜色block_color的索引值
  50. self.x, self.y = 0, 0 #记录移动方块(0,0)点在游戏网格的(clo,row)位置
  51. self.key = 0 #记录移动方块在blocks的键,是哪种方块
  52. self.index_ = 0 #记录移动方块形态的索引
  53. self.next_key = self.rand_key() #记录NEXT方块在blocks的键
  54. self.speed = fps #速度,和帧率一致
  55. self.fall_buffer = self.speed #自动下落的缓冲时间,屏幕每刷一次自动减1
  56. self.fall_speed_up = False #是否加速下落
  57. self.score = 0
  58. self.lines = 0
  59. self.level = 0
  60. self.creat_new_block()
  61. def creat_new_block(self):
  62. #产生新的移动方块和NEXT方块,以第一形态作为初始形态
  63. self.key = self.next_key
  64. self.next_key = self.rand_key()
  65. self.index = 0
  66. self.x = 4 #初始列设在第4列
  67. self.y = -1 #初始高度设为-1,保证方块在最顶部位置出现,研究每种方块第一形态坐标可以找到答案
  68. def rand_key(self):
  69. keys = [1,1,2,3,3,3,3,4,4,4,4,5,5,5,5,6,6,7,7] #决定每种方块出现概率
  70. return keys[random.randint(0,len(keys)-1)]
  71. def move(self, dx, dy):
  72. #方块左、右、下移动:左:dx=-1,dy=0 右:dx=1,dy=0 下:dx=0,dy=1
  73. if self.can_move(self.index, dx, dy):
  74. self.x += dx
  75. self.y += dy
  76. elif dy:
  77. #不能下落:在顶部位置不能下落,游戏结束,以下位置则停止移动
  78. if self.y <= 0:
  79. self.game_over()
  80. else:
  81. self.stop_move()
  82. def rotate(self):
  83. #方块旋转至下一形态,使用的顺时针旋转,被注释的是逆时针旋转
  84. next_index = (self.index + 1) % len(blocks[self.key])
  85. #next_index = (self.index - 1 + len(blocks[self.key])) % len(blocks[self.key])
  86. if self.can_move(next_index, 0, 0):
  87. self.index = next_index
  88. def can_move(self, index, dx, dy):
  89. #方块能否移动:出界或碰到其他方块
  90. for (x,y) in blocks[self.key][index]:
  91. clo, row = self.x + x + dx , self.y + y + dy
  92. if clo >= clos or clo < 0 or row >= rows or row < 0: #出界
  93. return False
  94. if self.display_array[row][clo]: #值等于1时不能移动
  95. return False
  96. return True
  97. def stop_move(self):
  98. #方块停止移动,停落区域赋值1和相应的颜色
  99. self.score += 4
  100. for (x,y) in blocks[self.key][self.index]:
  101. self.display_array[y+self.y][x+self.x] = 1
  102. self.color_array[y+self.y][x+self.x] = self.key
  103. self.del_full_row()
  104. self.creat_new_block()
  105. def del_full_row(self):
  106. #删除填满的行,记录成绩
  107. lines = 0
  108. for row in range(rows):
  109. if sum(self.display_array[row]) == clos: #填满行判断
  110. lines += 1 #记录一次连续删除的行数,实现多消多奖
  111. self.lines += 1
  112. if self.lines % 5 == 0: #每消5行等级升1,速度加快
  113. self.level = self.lines / 5
  114. self.speed = int(self.speed * 0.9) #越小越快
  115. self.score += (self.level + clos * lines) * 5
  116. del self.display_array[row]
  117. self.display_array.insert(0,[0 for i in range(clos)])
  118. def display(self):
  119. self.display_stop_blocks()
  120. self.display_next_blocks()
  121. self.display_move_blocks()
  122. self.display_score()
  123. #每刷一次缓冲计数减1,缓冲计数=0,或按住了向下键则下落一格
  124. self.fall_buffer -= 1
  125. if self.fall_buffer == 0 or self.fall_speed_up:
  126. self.fall_buffer = self.speed
  127. self.move(0,1)
  128. def display_stop_blocks(self):
  129. #显示不移动的方块,值为1画彩色立体方块,值为0画底色块
  130. for y in range(rows):
  131. for x in range(clos):
  132. self.rect.topleft = x * cell_size, y * cell_size
  133. if self.display_array[y][x]:
  134. self.draw_block(self.color_array[y][x], 1)
  135. else:
  136. self.draw_block(0, 0)
  137. def display_next_blocks(self):
  138. #显示下一个方块
  139. for (x,y) in blocks[self.next_key][0]:
  140. self.rect.topleft = x * cell_size , (y - 1) * cell_size
  141. self.draw_block(8, 1)
  142. def display_move_blocks(self):
  143. #显示移动的方块
  144. for (x,y) in blocks[self.key][self.index]:
  145. self.rect.topleft = (self.x + x) * cell_size, (self.y + y) * cell_size
  146. self.draw_block(self.key, 1)
  147. def display_score(self):
  148. #显示得分记录
  149. text = "得分:%d 行数:%d 等级:%d" %(self.score,self.lines,self.level)
  150. self.img = pygame.font.SysFont("kaiti",25).render(text, True, (0,0,255))
  151. self.img_rect = self.img.get_rect()
  152. self.img_rect.topleft = (self.x0, rows* cell_size)
  153. screen.blit(self.img, self.img_rect)
  154. def game_over(self):
  155. #只是简单的数据重新初始化后立即重新开始
  156. self.__init__(self.x0, self.y0)
  157. def draw_block(self, color_index, draw_edge):
  158. #在指定位置画方块
  159. (r,g,b) = block_color[color_index]
  160. self.rect.centerx = self.rect.left + self.x0 + int(cell_size / 2)
  161. self.rect.centery = self.rect.top + self.y0 + int(cell_size / 2)
  162. if draw_edge:
  163. #画方块明暗过度边,增加立体感,x0~x4是方块四角和中心的坐标。
  164. x0 = self.rect.center
  165. x1 = self.rect.topleft
  166. x2 = self.rect.topright
  167. x3 = self.rect.bottomright
  168. x4 = self.rect.bottomleft
  169. pygame.draw.polygon(screen, (r+50, g+50, b+50), (x0,x1,x2), 0)
  170. pygame.draw.polygon(screen, (r+20, g+20, b+20), (x0,x2,x3), 0)
  171. pygame.draw.polygon(screen, (r-50, g-50, b-50), (x0,x3,x4), 0)
  172. pygame.draw.polygon(screen, (r-20, g-20, b-20), (x0,x4,x1), 0)
  173. pygame.draw.rect(screen, (r,g,b), self.rect.inflate(-block_edge, -block_edge), 0)
  174. else:
  175. pygame.draw.rect(screen, (r,g,b), self.rect, 0)
  176. time = pygame.time.Clock()
  177. player1 = Game_machine(0, 0)
  178. player2 = Game_machine((clos + 6) * cell_size, 0)
  179. while True:
  180. time.tick(fps)
  181. screen.fill((166,124,64))
  182. player1.display()
  183. player2.display()
  184. pygame.display.update()
  185. #移动旋转控制
  186. for event in pygame.event.get():
  187. if event.type == pygame.KEYDOWN:
  188. if event.key == pygame.K_g: #player1 :g键右移动一格
  189. player1.move(1,0)
  190. elif event.key == pygame.K_d: #player1 :d键左移动一格
  191. player1.move(-1,0)
  192. elif event.key == pygame.K_r: #player1 :r键旋转一次
  193. player1.rotate()
  194. elif event.key == pygame.K_f: #player1 :f键加速下移
  195. player1.fall_speed_up = True
  196. if event.key == pygame.K_RIGHT: #player2 :→键右移动一格
  197. player2.move(1,0)
  198. elif event.key == pygame.K_LEFT: #player2 :←键左移动一格
  199. player2.move(-1,0)
  200. elif event.key == pygame.K_UP: #player2 :↑键旋转一次
  201. player2.rotate()
  202. elif event.key == pygame.K_DOWN: #player2 :↓键加速下移
  203. player2.fall_speed_up = True
  204. elif event.key == pygame.K_q:
  205. sys.exit()
  206. elif event.type == pygame.KEYUP:
  207. if event.key == pygame.K_f:
  208. player1.fall_speed_up = False
  209. if event.key == pygame.K_DOWN:
  210. player2.fall_speed_up = False
  211. elif event.type == pygame.QUIT:
  212. sys.exit()

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

闽ICP备14008679号