• 售前

  • 售后

热门帖子
入门百科

Python Pygame实现俄罗斯方块

[复制链接]
笑看人生458 显示全部楼层 发表于 2021-10-25 19:12:09 |阅读模式 打印 上一主题 下一主题
本文实例为各人分享了Python Pygame实现俄罗斯方块的具体代码,供各人参考,具体内容如下
源码:
  1. # coding : utf-8
  2. #: pip install pygame
  3. import random
  4. import sys
  5. import pygame
  6. #: 颜色定义
  7. COLOR_WHITE = (255, 255, 255)
  8. COLOR_BLACK = (0, 0, 0)
  9. class Block:
  10. """小块"""
  11. width = 24
  12. height = 24
  13. @staticmethod
  14. def draw(s, left, top, color, bg_color):
  15.   pygame.draw.rect(s, bg_color, pygame.Rect(left, top, Block.width, Block.height))
  16.   pygame.draw.rect(s, color, pygame.Rect(left, top, Block.width - 1, Block.height - 1))
  17. class Building:
  18. """积木"""
  19. def __init__(self):
  20.   """
  21.   方块的7种基本形状
  22.   每次初始化随机选择一个形状
  23.   @:return True / False
  24.   """
  25.   self.form = random.choice(
  26.    [
  27.     [
  28.      [0, 0, 0, 0, 0],
  29.      [0, 0, 1, 0, 0],
  30.      [0, 1, 1, 1, 0],
  31.      [0, 0, 0, 0, 0],
  32.      [0, 0, 0, 0, 0]
  33.     ],
  34.     [
  35.      [0, 0, 0, 0, 0],
  36.      [0, 0, 0, 0, 0],
  37.      [1, 1, 1, 1, 0],
  38.      [0, 0, 0, 0, 0],
  39.      [0, 0, 0, 0, 0]
  40.     ],
  41.     [
  42.      [0, 0, 0, 0, 0],
  43.      [0, 1, 1, 0, 0],
  44.      [0, 0, 1, 1, 0],
  45.      [0, 0, 0, 0, 0],
  46.      [0, 0, 0, 0, 0]
  47.     ],
  48.     [
  49.      [0, 0, 0, 0, 0],
  50.      [0, 0, 1, 1, 0],
  51.      [0, 1, 1, 0, 0],
  52.      [0, 0, 0, 0, 0],
  53.      [0, 0, 0, 0, 0]
  54.     ],
  55.     [
  56.      [0, 0, 0, 0, 0],
  57.      [0, 1, 1, 0, 0],
  58.      [0, 0, 1, 0, 0],
  59.      [0, 0, 1, 0, 0],
  60.      [0, 0, 0, 0, 0]
  61.     ],
  62.     [
  63.      [0, 0, 0, 0, 0],
  64.      [0, 0, 1, 1, 0],
  65.      [0, 0, 1, 0, 0],
  66.      [0, 0, 1, 0, 0],
  67.      [0, 0, 0, 0, 0]
  68.     ],
  69.     [
  70.      [0, 0, 0, 0, 0],
  71.      [0, 1, 1, 0, 0],
  72.      [0, 1, 1, 0, 0],
  73.      [0, 0, 0, 0, 0],
  74.      [0, 0, 0, 0, 0]
  75.     ]
  76.    ])
  77. def __getitem__(self, pos):
  78.   return self.form[pos]
  79. def __setitem__(self, key, value):
  80.   self.form[key] = value
  81. class Layout:
  82. """棋盘"""
  83. def __init__(self):
  84.   self.block_x_count = 16;
  85.   self.block_y_count = 22;
  86.   self.layout = [[0 if 1 < i < self.block_x_count - 2 and j < self.block_y_count - 2 else 1
  87.       for i in range(self.block_x_count)] for j in range(self.block_y_count)]
  88. @property
  89. def size(self):
  90.   """返回棋盘屏幕大小(width,height)"""
  91.   return (self.block_x_count * Block.width, self.block_y_count * Block.height)
  92. def create_new_building(self):
  93.   """
  94.   创建新的积木,初始化位置为第5,0格, 速度为4
  95.   :return: 返回是否无空间创建了
  96.   """
  97.   self.building = Building()
  98.   self.building_left, self.building_top = 5, 0 #
  99.   self.drop_speed = 3
  100.   print(self.test_building_touch_wall())
  101.   return self.test_building_touch_wall()
  102. @property
  103. def speed(self):
  104.   return self.drop_speed
  105. def test_building_touch_wall(self, x_offset=0, y_offset=0):
  106.   """
  107.   积木是否已经触底/墙壁
  108.   具体操作:
  109.   判断积木最后一排的1,是否在当前棋牌对应的位置是也是1
  110.   @:param x_offset: x的偏移量 移动时可以传入1/-1来判断
  111.   @:param y_offset: y的偏移量 正常下落时可以传入1来判断
  112.   """
  113.   for i in range(4, -1, -1):
  114.    for j in range(5):
  115.     if self.building[i][j]:
  116.      if self.layout[i + self.building_top + y_offset][j + self.building_left + x_offset]:
  117.       return True
  118.   return False
  119. def move_left_right(self, x):
  120.   """
  121.   左右移动
  122.   @:param x: 移动量 x_offset
  123.   """
  124.   #: 移动时不能撞墙
  125.   if not self.test_building_touch_wall(x_offset=x):
  126.    self.building_left += x
  127. def down_build(self):
  128.   """ 盒子的自动下移 """
  129.   self.building_top += 1
  130. def direct_down(self):
  131.   """ 手动快速降落 """
  132.   self.drop_speed = 50
  133. def convert_building(self):
  134.   """
  135.   * 扭转盒子的总方位 (右转)
  136.   具体操作:
  137.   把第一竖排的倒序给第一横排的
  138.   把第二竖排的倒序给第二横排的
  139.   后面同理.
  140.   """
  141.   new_box = [[0 for i in range(5)] for j in range(5)]
  142.   for i in range(5):
  143.    for j in range(4, -1, -1):
  144.     new_box[i][j] = self.building[4 - j][i]
  145.   self.building = new_box
  146. def clear_full_lines(self):
  147.   """消除满行的所有行"""
  148.   new_layout = [[0 if 1 < i < self.block_x_count - 2 and j < self.block_y_count - 2 else 1
  149.       for i in range(self.block_x_count)] for j in range(self.block_y_count)]
  150.   row_len = self.block_x_count - 4
  151.   new_row = self.block_y_count - 2 - 1
  152.   for cur_row in range(self.block_y_count - 2 - 1, 0, -1):
  153.    if sum(self.layout[cur_row][2:self.block_x_count - 2]) < row_len:
  154.     new_layout[new_row] = self.layout[cur_row]
  155.     new_row -= 1
  156.   self.layout = new_layout
  157. def put_building_to_layout(self):
  158.   """将积木放到棋盘里"""
  159.   for i in range(4, -1, -1):
  160.    for j in range(5):
  161.     if self.building[i][j]:
  162.      self.layout[i + self.building_top][j + self.building_left] = 1
  163.   #: 这里会调用消除函数
  164.   self.clear_full_lines()
  165. def draw_building(self, s):
  166.   """
  167.   显示积木
  168.   @:param s : pygame = screen
  169.   """
  170.   cur_left, cur_top = self.building_left * Block.width, self.building_top * Block.height
  171.   for i in range(5):
  172.    for j in range(5):
  173.     # 只画积木实体,不管盒子本身
  174.     if self.building[j][i]:
  175.      Block.draw(s, cur_left + i * Block.width, cur_top + j * Block.height, COLOR_BLACK, COLOR_WHITE)
  176. def draw(self, s):
  177.   """
  178.   显示棋盘
  179.   @:param s : pygame = screen
  180.   """
  181.   for i in range(self.block_x_count):
  182.    for j in range(self.block_y_count):
  183.     if self.layout[j][i] == 0:
  184.      Block.draw(s, i * Block.width, j * Block.height, COLOR_WHITE, COLOR_BLACK)
  185.     else:
  186.      Block.draw(s, i * Block.width, j * Block.height, COLOR_BLACK, COLOR_WHITE)
  187. # -------------------------------------------------------------------
  188. # Main
  189. # -------------------------------------------------------------------
  190. def main():
  191. #: 初始化
  192. while True:
  193.   layout = Layout()
  194.   layout.create_new_building()
  195.   pygame.init()
  196.   pygame.display.set_caption('俄罗斯方块')
  197.   screen = pygame.display.set_mode((layout.size), 0, 32)
  198.   is_over = False
  199.   #: 单局游戏循环开始 [结束后直接重新开始]
  200.   while not is_over:
  201.    #: 处理游戏消息
  202.    for e in pygame.event.get():
  203.     if e.type == pygame.QUIT:
  204.      sys.exit()
  205.     #: 处理按键
  206.     if e.type == pygame.KEYDOWN:
  207.      if e.key == pygame.K_UP:
  208.       layout.convert_building()
  209.      if e.key == pygame.K_DOWN:
  210.       layout.direct_down()
  211.      if e.key == pygame.K_LEFT:
  212.       layout.move_left_right(-1)
  213.      if e.key == pygame.K_RIGHT:
  214.       layout.move_left_right(1)
  215.    #: 是否碰触底部地面了,是 -> 融合背景 否 -> 继续下落
  216.    if layout.test_building_touch_wall(y_offset=1):
  217.     layout.put_building_to_layout()
  218.     is_over = layout.create_new_building()
  219.    else:
  220.     layout.down_build()
  221.    #: 绘制
  222.    layout.draw(screen)
  223.    layout.draw_building(screen)
  224.    pygame.display.update()
  225.    #: 速度
  226.    pygame.time.Clock().tick(layout.speed)
  227. if __name__ == '__main__':
  228. main()
复制代码
结果:

更多俄罗斯方块出色文章请点击专题:俄罗斯方块游戏聚集 举行学习。
以上就是本文的全部内容,盼望对各人的学习有所帮助,也盼望各人多多支持脚本之家。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x

帖子地址: 

回复

使用道具 举报

分享
推广
火星云矿 | 预约S19Pro,享500抵1000!
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

草根技术分享(草根吧)是全球知名中文IT技术交流平台,创建于2021年,包含原创博客、精品问答、职业培训、技术社区、资源下载等产品服务,提供原创、优质、完整内容的专业IT技术开发社区。
  • 官方手机版

  • 微信公众号

  • 商务合作