Python Pygame实现俄罗斯方块


Posted in Python onFebruary 19, 2021

本文实例为大家分享了Python Pygame实现俄罗斯方块的具体代码,供大家参考,具体内容如下

源码:

# coding : utf-8

#: pip install pygame
import random
import sys
import pygame

#: 颜色定义
COLOR_WHITE = (255, 255, 255)
COLOR_BLACK = (0, 0, 0)

class Block:
 """小块"""
 width = 24
 height = 24

 @staticmethod
 def draw(s, left, top, color, bg_color):
  pygame.draw.rect(s, bg_color, pygame.Rect(left, top, Block.width, Block.height))
  pygame.draw.rect(s, color, pygame.Rect(left, top, Block.width - 1, Block.height - 1))


class Building:
 """积木"""

 def __init__(self):
  """
  方块的7种基本形状
  每次初始化随机选择一个形状
  @:return True / False
  """
  self.form = random.choice(
   [
    [
     [0, 0, 0, 0, 0],
     [0, 0, 1, 0, 0],
     [0, 1, 1, 1, 0],
     [0, 0, 0, 0, 0],
     [0, 0, 0, 0, 0]
    ],
    [
     [0, 0, 0, 0, 0],
     [0, 0, 0, 0, 0],
     [1, 1, 1, 1, 0],
     [0, 0, 0, 0, 0],
     [0, 0, 0, 0, 0]
    ],
    [
     [0, 0, 0, 0, 0],
     [0, 1, 1, 0, 0],
     [0, 0, 1, 1, 0],
     [0, 0, 0, 0, 0],
     [0, 0, 0, 0, 0]
    ],
    [
     [0, 0, 0, 0, 0],
     [0, 0, 1, 1, 0],
     [0, 1, 1, 0, 0],
     [0, 0, 0, 0, 0],
     [0, 0, 0, 0, 0]
    ],
    [
     [0, 0, 0, 0, 0],
     [0, 1, 1, 0, 0],
     [0, 0, 1, 0, 0],
     [0, 0, 1, 0, 0],
     [0, 0, 0, 0, 0]
    ],
    [
     [0, 0, 0, 0, 0],
     [0, 0, 1, 1, 0],
     [0, 0, 1, 0, 0],
     [0, 0, 1, 0, 0],
     [0, 0, 0, 0, 0]
    ],
    [
     [0, 0, 0, 0, 0],
     [0, 1, 1, 0, 0],
     [0, 1, 1, 0, 0],
     [0, 0, 0, 0, 0],
     [0, 0, 0, 0, 0]
    ]
   ])

 def __getitem__(self, pos):
  return self.form[pos]

 def __setitem__(self, key, value):
  self.form[key] = value


class Layout:
 """棋盘"""

 def __init__(self):
  self.block_x_count = 16;
  self.block_y_count = 22;
  self.layout = [[0 if 1 < i < self.block_x_count - 2 and j < self.block_y_count - 2 else 1
      for i in range(self.block_x_count)] for j in range(self.block_y_count)]

 @property
 def size(self):
  """返回棋盘屏幕大小(width,height)"""
  return (self.block_x_count * Block.width, self.block_y_count * Block.height)

 def create_new_building(self):
  """
  创建新的积木,初始化位置为第5,0格, 速度为4
  :return: 返回是否无空间创建了
  """
  self.building = Building()
  self.building_left, self.building_top = 5, 0 #
  self.drop_speed = 3
  print(self.test_building_touch_wall())
  return self.test_building_touch_wall()
 
 @property
 def speed(self):
  return self.drop_speed

 def test_building_touch_wall(self, x_offset=0, y_offset=0):
  """
  积木是否已经触底/墙壁
  具体操作:
  判断积木最后一排的1,是否在当前棋牌对应的位置是也是1
  @:param x_offset: x的偏移量 移动时可以传入1/-1来判断
  @:param y_offset: y的偏移量 正常下落时可以传入1来判断
  """
  for i in range(4, -1, -1):
   for j in range(5):
    if self.building[i][j]:
     if self.layout[i + self.building_top + y_offset][j + self.building_left + x_offset]:
      return True
  return False

 def move_left_right(self, x):
  """
  左右移动
  @:param x: 移动量 x_offset
  """
  #: 移动时不能撞墙
  if not self.test_building_touch_wall(x_offset=x):
   self.building_left += x

 def down_build(self):
  """ 盒子的自动下移 """
  self.building_top += 1

 def direct_down(self):
  """ 手动快速降落 """
  self.drop_speed = 50

 def convert_building(self):
  """
  * 扭转盒子的总方位 (右转)
  具体操作:
  把第一竖排的倒序给第一横排的
  把第二竖排的倒序给第二横排的
  后面同理.
  """
  new_box = [[0 for i in range(5)] for j in range(5)]
  for i in range(5):
   for j in range(4, -1, -1):
    new_box[i][j] = self.building[4 - j][i]
  self.building = new_box

 def clear_full_lines(self):
  """消除满行的所有行"""
  new_layout = [[0 if 1 < i < self.block_x_count - 2 and j < self.block_y_count - 2 else 1
      for i in range(self.block_x_count)] for j in range(self.block_y_count)]

  row_len = self.block_x_count - 4
  new_row = self.block_y_count - 2 - 1
  for cur_row in range(self.block_y_count - 2 - 1, 0, -1):
   if sum(self.layout[cur_row][2:self.block_x_count - 2]) < row_len:
    new_layout[new_row] = self.layout[cur_row]
    new_row -= 1
  self.layout = new_layout

 def put_building_to_layout(self):
  """将积木放到棋盘里"""
  for i in range(4, -1, -1):
   for j in range(5):
    if self.building[i][j]:
     self.layout[i + self.building_top][j + self.building_left] = 1
  #: 这里会调用消除函数
  self.clear_full_lines()

 def draw_building(self, s):
  """
  显示积木
  @:param s : pygame = screen 
  """
  cur_left, cur_top = self.building_left * Block.width, self.building_top * Block.height
  for i in range(5):
   for j in range(5):
    # 只画积木实体,不管盒子本身
    if self.building[j][i]:
     Block.draw(s, cur_left + i * Block.width, cur_top + j * Block.height, COLOR_BLACK, COLOR_WHITE)

 def draw(self, s):
  """
  显示棋盘
  @:param s : pygame = screen 
  """
  for i in range(self.block_x_count):
   for j in range(self.block_y_count):
    if self.layout[j][i] == 0:
     Block.draw(s, i * Block.width, j * Block.height, COLOR_WHITE, COLOR_BLACK)
    else:
     Block.draw(s, i * Block.width, j * Block.height, COLOR_BLACK, COLOR_WHITE)


# -------------------------------------------------------------------
# Main
# -------------------------------------------------------------------
def main():
 #: 初始化
 while True:
  layout = Layout()
  layout.create_new_building()
  pygame.init()
  pygame.display.set_caption('俄罗斯方块')
  screen = pygame.display.set_mode((layout.size), 0, 32)
  is_over = False
  #: 单局游戏循环开始 [结束后直接重新开始]
  while not is_over:
   #: 处理游戏消息
   for e in pygame.event.get():
    if e.type == pygame.QUIT:
     sys.exit()
    #: 处理按键
    if e.type == pygame.KEYDOWN:
     if e.key == pygame.K_UP:
      layout.convert_building()
     if e.key == pygame.K_DOWN:
      layout.direct_down()
     if e.key == pygame.K_LEFT:
      layout.move_left_right(-1)
     if e.key == pygame.K_RIGHT:
      layout.move_left_right(1)
   #: 是否碰触底部地面了,是 -> 融合背景 否 -> 继续下落
   if layout.test_building_touch_wall(y_offset=1):
    layout.put_building_to_layout()
    is_over = layout.create_new_building()
   else:
    layout.down_build()
   #: 绘制
   layout.draw(screen)
   layout.draw_building(screen)
   pygame.display.update()
   #: 速度
   pygame.time.Clock().tick(layout.speed)


if __name__ == '__main__':
 main()

效果:

Python Pygame实现俄罗斯方块

更多俄罗斯方块精彩文章请点击专题:俄罗斯方块游戏集合 进行学习。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
Django框架中的对象列表视图使用示例
Jul 21 Python
浅谈python中的数字类型与处理工具
Aug 02 Python
Python在groupby分组后提取指定位置记录方法
Apr 20 Python
Python中交换两个元素的实现方法
Jun 29 Python
python多线程高级锁condition简单用法示例
Nov 07 Python
pytorch中nn.Conv1d的用法详解
Dec 31 Python
Ubuntu16.04安装python3.6.5步骤详解
Jan 10 Python
浅谈Tensorflow 动态双向RNN的输出问题
Jan 20 Python
Python多线程通信queue队列用法实例分析
Mar 24 Python
pycharm开发一个简单界面和通用mvc模板(操作方法图解)
May 27 Python
python 爬虫之selenium可视化爬虫的实现
Dec 04 Python
pytorch通过训练结果的复现设置随机种子
Jun 01 Python
python实现图片转字符画
Feb 19 #Python
python读取图片颜色值并生成excel像素画的方法实例
Feb 19 #Python
python 基于DDT实现数据驱动测试
Feb 18 #Python
详解解决jupyter不能使用pytorch的问题
Feb 18 #Python
python 使用openpyxl读取excel数据
Feb 18 #Python
Python用SSH连接到网络设备
Feb 18 #Python
python 实现IP子网计算
Feb 18 #Python
You might like
通俗易懂的php防注入代码
2010/04/07 PHP
PHP autoload与spl_autoload自动加载机制的深入理解
2013/06/05 PHP
php过滤敏感词的示例
2014/03/31 PHP
javascript Demo模态窗口
2009/12/06 Javascript
给jQuery方法添加回调函数一款插件的应用
2013/01/21 Javascript
JS实现的省份级联实例代码
2013/06/24 Javascript
node.js中的fs.truncate方法使用说明
2014/12/15 Javascript
PHP中CURL的几个经典应用实例
2015/01/23 Javascript
javascript实现树形菜单的方法
2015/07/17 Javascript
JavaScript实现向右伸出的多级网页菜单效果
2015/08/25 Javascript
node.js express安装及示例网站搭建方法(分享)
2016/08/22 Javascript
微信小程序加载更多 点击查看更多
2016/11/29 Javascript
jQuery实现文档树效果
2017/02/20 Javascript
JavaScript中最常用的10种代码简写技巧总结
2017/06/28 Javascript
nodejs简单访问及操作mysql数据库的方法示例
2018/03/15 NodeJs
vue 实现的树形菜的实例代码
2018/03/19 Javascript
JS异步执行结果获取的3种解决方式
2019/02/19 Javascript
vue使用Font Awesome的方法步骤
2019/02/26 Javascript
解决layer 关闭当前弹窗 关闭遮罩层 input值获取不到的问题
2019/09/25 Javascript
[03:17]2016完美“圣”典风云人物:冷冷专访
2016/12/08 DOTA
python使用正则表达式检测密码强度源码分享
2014/06/11 Python
浅谈python中对于json写入txt文件的编码问题
2018/06/07 Python
python 字符串只保留汉字的方法
2018/11/16 Python
python字符串下标与切片及使用方法
2020/02/13 Python
python+Selenium自动化测试——输入,点击操作
2020/03/06 Python
学会迭代器设计模式,帮你大幅提升python性能
2021/01/03 Python
详解使用HTML5的classList属性操作CSS类
2017/10/13 HTML / CSS
加拿大健康、婴儿和美容产品在线购物:Well.ca
2016/11/30 全球购物
学习决心书范文
2014/03/11 职场文书
2014年大学生党课心得体会范文
2014/03/29 职场文书
大学生学雷锋活动总结
2014/06/26 职场文书
解除施工合同协议书
2014/10/17 职场文书
2015国庆节放假通知范文
2015/07/30 职场文书
公司人事管理制度
2015/08/05 职场文书
浅谈mysql执行过程以及顺序
2021/05/12 MySQL
详解MongoDB排序时内存大小限制与创建索引的注意事项
2022/05/06 MongoDB