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 相关文章推荐
打开电脑上的QQ的python代码
Feb 10 Python
Python比较两个图片相似度的方法
Mar 13 Python
Python时间戳使用和相互转换详解
Dec 11 Python
python编写Logistic逻辑回归
Dec 30 Python
python的pandas工具包,保存.csv文件时不要表头的实例
Jun 14 Python
Selenium定时刷新网页的实现代码
Oct 31 Python
详解django中url路由配置及渲染方式
Feb 25 Python
Python使用os.listdir()和os.walk()获取文件路径与文件下所有目录的方法
Apr 01 Python
详解Numpy数组转置的三种方法T、transpose、swapaxes
May 27 Python
浅谈django 重载str 方法
May 19 Python
python tkinter Entry控件的焦点移动操作
May 22 Python
Python3 类型标注支持操作
Jun 02 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中删除变量时unset()和null的区别分析
2011/01/27 PHP
PHP中使用array函数新建一个数组
2015/11/19 PHP
PHP面向对象五大原则之单一职责原则(SRP)详解
2018/04/04 PHP
javascript function、指针及内置对象
2009/02/19 Javascript
document.body.scrollTop 值总为0的解决方法 比较常见的标准问题
2009/11/30 Javascript
javascript 四则运算精度修正函数代码
2010/05/31 Javascript
将json当数据库一样操作的javascript lib
2013/10/28 Javascript
js 通用订单代码
2013/12/23 Javascript
通过url查找a元素应用案例
2014/04/29 Javascript
ANGULARJS中用NG-BIND指令实现单向绑定的例子
2014/12/08 Javascript
jQuery知识点整理
2015/01/30 Javascript
javascript实现动态显示颜色块的报表效果
2017/04/10 Javascript
angular2中router路由跳转navigate的使用与刷新页面问题详解
2017/05/07 Javascript
详谈表单格式化插件jquery.serializeJSON
2017/06/23 jQuery
vue-resource拦截器设置头信息的实例
2017/10/27 Javascript
nodejs实现大文件(在线视频)的读取
2020/10/16 NodeJs
聊聊JS动画库 Velocity.js的使用
2018/03/13 Javascript
javascript标准库(js的标准内置对象)总结
2018/05/26 Javascript
详解vue中async-await的使用误区
2018/12/05 Javascript
vue基础之使用get、post、jsonp实现交互功能示例
2019/03/12 Javascript
vue vant Area组件使用详解
2019/12/09 Javascript
uni-app使用微信小程序云函数的步骤示例
2020/05/22 Javascript
通过angular CDK实现页面元素拖放的步骤详解
2020/07/01 Javascript
Vue使用Proxy代理后仍无法生效的解决
2020/11/13 Javascript
java直接调用python脚本的例子
2014/02/16 Python
python实现socket客户端和服务端简单示例
2014/02/24 Python
pycharm 使用心得(七)一些实用功能介绍
2014/06/06 Python
速记Python布尔值
2017/11/09 Python
Python实现抢购IPhone手机
2018/02/07 Python
PyQt5每天必学之事件与信号
2018/04/20 Python
Jupyter notebook在mac:linux上的配置和远程访问的方法
2019/01/14 Python
jupyter notebook tensorflow打印device信息实例
2020/04/20 Python
对python中list的五种查找方法说明
2020/07/13 Python
Python如何使用input函数获取输入
2020/08/06 Python
python利用paramiko实现交换机巡检的示例
2020/09/22 Python
幼儿教师师德师风自我剖析材料
2014/09/29 职场文书