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 相关文章推荐
Python批量按比例缩小图片脚本分享
May 21 Python
Python中遍历字典过程中更改元素导致异常的解决方法
May 12 Python
使用50行Python代码从零开始实现一个AI平衡小游戏
Nov 21 Python
Python2和Python3中urllib库中urlencode的使用注意事项
Nov 26 Python
python装饰器常见使用方法分析
Jun 26 Python
python 魔法函数实例及解析
Sep 25 Python
基于Python实现大文件分割和命名脚本过程解析
Sep 29 Python
基于python2.7实现图形密码生成器的实例代码
Nov 05 Python
Python-openCV读RGB通道图实例
Jan 17 Python
解决python ThreadPoolExecutor 线程池中的异常捕获问题
Apr 08 Python
matplotlib交互式数据光标实现(mplcursors)
Jan 13 Python
Python进程池与进程锁之语法学习
Apr 11 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
ThinkPHP行为扩展Behavior应用实例详解
2014/07/22 PHP
调试WordPress中定时任务的相关PHP脚本示例
2015/12/10 PHP
php的PDO事务处理机制实例分析
2017/02/16 PHP
PHP+jQuery实现双击修改table表格功能示例
2019/02/21 PHP
laravel通用化的CURD的实现
2019/12/13 PHP
jQuery 页面载入进度条实现代码
2009/02/08 Javascript
JavaScript高级程序设计 学习笔记 js高级技巧
2011/09/20 Javascript
jQuery $.get 的妙用 访问本地文本文件
2012/07/12 Javascript
nodejs文件操作模块FS(File System)常用函数简明总结
2014/06/05 NodeJs
JS面向对象编程详解
2016/03/06 Javascript
微信小程序 Nginx环境配置详细介绍
2017/02/14 Javascript
vue cli使用绝对路径引用图片问题的解决
2017/12/06 Javascript
nodejs使用http模块发送get与post请求的方法示例
2018/01/08 NodeJs
JS实现将链接生成二维码并转为图片的方法
2018/03/17 Javascript
vue-infinite-loading2.0 中文文档详解
2018/04/08 Javascript
npm 下载指定版本的组件方法
2018/05/17 Javascript
小程序接入腾讯位置服务的详细流程
2020/03/03 Javascript
JavaScript实现沿五角星形线摆动的小圆实例详解
2020/07/28 Javascript
[46:20]CHAOS vs Alliacne 2019国际邀请赛小组赛 BO2 第二场 8.15
2019/08/16 DOTA
Python二叉树定义与遍历方法实例分析
2018/05/25 Python
Pycharm 创建 Django admin 用户名和密码的实例
2018/05/30 Python
selenium+python实现1688网站验证码图片的截取功能
2018/08/14 Python
Django项目中实现使用qq第三方登录功能
2019/08/13 Python
python实现将json多行数据传入到mysql中使用
2019/12/31 Python
深入了解python列表(LIST)
2020/06/08 Python
flask框架中的cookie和session使用
2021/01/31 Python
会计人员岗位职责
2014/03/19 职场文书
祖国在我心中演讲稿300字
2014/05/04 职场文书
伊琍体标语
2014/06/25 职场文书
四风问题班子对照检查材料
2014/09/27 职场文书
公安纪律作风整顿剖析材料
2014/10/10 职场文书
法人身份证明书
2015/06/18 职场文书
2016年小学中秋节活动总结
2016/04/05 职场文书
工作计划范文之财务管理
2019/08/09 职场文书
分享几个JavaScript运算符的使用技巧
2021/04/24 Javascript
Java实现简单小画板
2022/06/10 Java/Android