侯体宗的博客
  • 首页
  • 人生(杂谈)
  • 技术
  • 关于我
  • 更多分类
    • 文件下载
    • 文字修仙
    • 中国象棋ai
    • 群聊
    • 九宫格抽奖
    • 拼图
    • 消消乐
    • 相册

python实现俄罗斯方块

Python  /  管理员 发布于 7年前   259

网上搜到一个Pygame写的俄罗斯方块(tetris),大部分看懂的前提下增加了注释,Fedora19下运行OK的

主程序:

#coding:utf8#! /usr/bin/env python# 注释说明:shape表示一个俄罗斯方块形状 cell表示一个小方块import sysfrom random import choiceimport pygamefrom pygame.locals import *from block import O, I, S, Z, L, J, TCOLS = 16ROWS = 20CELLS = COLS * ROWSCELLPX = 32 # 每个cell的像素宽度POS_FIRST_APPEAR = COLS / 2SCREEN_SIZE = (COLS * CELLPX, ROWS * CELLPX)COLOR_BG = (0, 0, 0)def draw(grid, pos=None): # grid是一个list,要么值为None,要么值为'Block' # 非空值在eval()的作用下,用于配置颜色 if pos: # 6x5  s = pos - 3 - 2 * COLS # upper left position  for p in range(0, COLS):   q = s + p * COLS   for i in range(q, q + 6):    if 0 <= i < CELLS:     # 0 <=i < CELLS:表示i这个cell在board内部。     c = eval(grid[i] + ".color") if grid[i] else COLOR_BG     # 执行着色。shape的cell涂对应的class设定好的颜色,否则涂黑(背景色)     a = i % COLS * CELLPX     b = i / COLS * CELLPX     screen.fill(c, (a, b, CELLPX, CELLPX)) else: # all  screen.fill(COLOR_BG)  for i, occupied in enumerate(grid):   if occupied:    c = eval(grid[i] + ".color") # 获取方块对应的颜色    a = i % COLS * CELLPX # 横向长度    b = i / COLS * CELLPX # 纵向长度    screen.fill(c, (a, b, CELLPX, CELLPX))    # fill:为cell上色, 第二个参数表示rect pygame.display.flip() # 刷新屏幕def phi(grid1, grid2, pos): # 4x4# 两个grid之4*4区域内是否会相撞(冲突) s = pos - 2 - 1 * COLS # upper left position for p in range(0, 4):  q = s + p * COLS  for i in range(q, q + 4):   try:    if grid1[i] and grid2[i]:     return False   except:    pass return Truedef merge(grid1, grid2): # 合并两个grid grid = grid1[:] for i, c in enumerate(grid2):  if c:   grid[i] = c return griddef complete(grid): # 减去满行 n = 0 for i in range(0, CELLS, COLS):  # 步长为一行。  if not None in grid[i:i + COLS]:  #这一句很容易理解错误。  #实际含义是:如果grid[i:i + COLS]都不是None,那么执行下面的语句   grid = [None] * COLS + grid[:i] + grid[i + COLS:]   n += 1 return grid, n#n表示减去的行数,用作统计分数pygame.init()pygame.event.set_blocked(None)pygame.event.set_allowed((KEYDOWN, QUIT))pygame.key.set_repeat(75, 0)pygame.display.set_caption('Tetris')screen = pygame.display.set_mode(SCREEN_SIZE)pygame.display.update()grid = [None] * CELLSspeed = 500screen.fill(COLOR_BG)while True: # spawn a block block = choice([O, I, S, Z, L, J, T])() pos = POS_FIRST_APPEAR if not phi(grid, block.grid(pos), pos): break # you lose pygame.time.set_timer(KEYDOWN, speed) # repeatedly create an event on the event queue # speed是时间间隔。。。speed越小,方块下落的速度越快。。。speed应该换为其他名字 while True: # move the block  draw(merge(grid, block.grid(pos)), pos)  event = pygame.event.wait()  if event.type == QUIT: sys.exit()  try:   aim = {    K_UNKNOWN: pos+COLS,    K_UP: pos,    K_DOWN: pos+COLS,    K_LEFT: pos-1,    K_RIGHT: pos+1,   }[event.key]  except KeyError:   continue  if event.key == K_UP:   # 变形   block.rotate()  elif event.key in (K_LEFT, K_RIGHT) and pos / COLS != aim / COLS:   # pos/COLS表示当前位置所在行   # aim/COLS表示目标位置所在行   # 此判断表示,当shape在左边界时,不允许再向左移动(越界。。),在最右边时向右也禁止   continue  grid_aim = block.grid(aim)  if grid_aim and phi(grid, grid_aim, aim):   pos = aim  else:   if event.key == K_UP:    block.rotate(times=3)   elif not event.key in (K_LEFT, K_RIGHT):    break grid = merge(grid, block.grid(pos)) grid, n = complete(grid) if n:  draw(grid)  speed -= 5 * n  if speed < 75: speed = 75

调用的模块:

#coding:utf-8#! /usr/bin/env pythonCOLS = 16ROWS = 20class Block(): color = (255,255,255) def __init__(self):  self._state = 0 def __str__(self):  return self.__class__.__name__ def _orientations(self):  raise NotImplementedError() def rotate(self, times=1):  for i in range(times):   if len(self._orientations())-1 == self._state:    self._state = 0    #只要_state比_orientations长度-1还要小,就让_state加1   else:    self._state += 1 def blades(self):  # 返回对应形状的一种旋转形状。(返回一个list,list中每个元素是一个(x,y))  return self._orientations()[self._state] def grid(self, pos, cols=COLS, rows=ROWS):  # grid()函数:对于一个形状,从它的cell中的pos位置,按照orientations的位置提示,把所有cell涂色  # pos表示的是shape中的一个cell,也就是(0,0)  if cols*rows <= pos:   return None  # 这种情况应该不可能出现吧。如果出现<=的情况  # 那么,pos都跑到界外了。。  grid = [None] * cols * rows  grid[pos] = str(self)  for b in self.blades():   x, y = b   # pos/cols表示pos处于board的第几行   if pos/cols != (pos+x)/cols:    return None   i = pos + x + y * cols   if i < 0:    continue   elif cols*rows <= i:    return None   grid[i] = str(self)   # 给相应的其他位置都“涂色”,比如对于方块,是O型的,那么pos肯定是有值的,pos位于有上角。。  return grid# 以下每个形状class,_orientations()都返回形状的列表。(0,0)一定被包含在其中,为了省略空间所以都没有写出.class O(Block): color = (207,247,0) def _orientations(self):  return (   [(-1,0), (-1,1), (0,1)],   )class I(Block): color = (135,240,60) def _orientations(self):  return (   [(-2,0), (-1,0), (1,0)],   [(0,-1), (0,1), (0,2)],   )class S(Block): color = (171,252,113) def _orientations(self):  return (   [(1,0), (-1,1), (0,1)],   [(0,-1), (1,0), (1,1)],   )class Z(Block): color = (243,61,110) def _orientations(self):  return (   [(-1,0), (0,1), (1,1)],   [(1,-1), (1,0), (0,1)],   )class L(Block): color = (253,205,217) def _orientations(self):  return (   [(-1,1), (-1,0), (1,0)],   [(0,-1), (0,1), (1,1)],   [(-1,0), (1,0), (1,-1)],   [(-1,-1), (0,-1), (0,1)],   )class J(Block): color = (140,180,225) def _orientations(self):  return (   [(-1,0), (1,0), (1,1)],   [(0,1), (0,-1), (1,-1)],   [(-1,-1), (-1,0), (1,0)],   [(-1,1), (0,1), (0,-1)],   )class T(Block): color = (229,251,113) def _orientations(self):  return (   [(-1,0), (0,1), (1,0)],   [(0,-1), (0,1), (1,0)],   [(-1,0), (0,-1), (1,0)],   [(-1,0), (0,-1), (0,1)],   )

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

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


  • 上一条:
    python中的变量如何开辟内存
    下一条:
    解决python报错MemoryError的问题
  • 昵称:

    邮箱:

    0条评论 (评论内容有缓存机制,请悉知!)
    最新最热
    • 分类目录
    • 人生(杂谈)
    • 技术
    • linux
    • Java
    • php
    • 框架(架构)
    • 前端
    • ThinkPHP
    • 数据库
    • 微信(小程序)
    • Laravel
    • Redis
    • Docker
    • Go
    • swoole
    • Windows
    • Python
    • 苹果(mac/ios)
    • 相关文章
    • 在python语言中Flask框架的学习及简单功能示例(0个评论)
    • 在Python语言中实现GUI全屏倒计时代码示例(0个评论)
    • Python + zipfile库实现zip文件解压自动化脚本示例(0个评论)
    • python爬虫BeautifulSoup快速抓取网站图片(1个评论)
    • vscode 配置 python3开发环境的方法(0个评论)
    • 近期文章
    • 在windows10中升级go版本至1.24后LiteIDE的Ctrl+左击无法跳转问题解决方案(0个评论)
    • 智能合约Solidity学习CryptoZombie第四课:僵尸作战系统(0个评论)
    • 智能合约Solidity学习CryptoZombie第三课:组建僵尸军队(高级Solidity理论)(0个评论)
    • 智能合约Solidity学习CryptoZombie第二课:让你的僵尸猎食(0个评论)
    • 智能合约Solidity学习CryptoZombie第一课:生成一只你的僵尸(0个评论)
    • 在go中实现一个常用的先进先出的缓存淘汰算法示例代码(0个评论)
    • 在go+gin中使用"github.com/skip2/go-qrcode"实现url转二维码功能(0个评论)
    • 在go语言中使用api.geonames.org接口实现根据国际邮政编码获取地址信息功能(1个评论)
    • 在go语言中使用github.com/signintech/gopdf实现生成pdf分页文件功能(0个评论)
    • gmail发邮件报错:534 5.7.9 Application-specific password required...解决方案(0个评论)
    • 近期评论
    • 122 在

      学历:一种延缓就业设计,生活需求下的权衡之选中评论 工作几年后,报名考研了,到现在还没认真学习备考,迷茫中。作为一名北漂互联网打工人..
    • 123 在

      Clash for Windows作者删库跑路了,github已404中评论 按理说只要你在国内,所有的流量进出都在监控范围内,不管你怎么隐藏也没用,想搞你分..
    • 原梓番博客 在

      在Laravel框架中使用模型Model分表最简单的方法中评论 好久好久都没看友情链接申请了,今天刚看,已经添加。..
    • 博主 在

      佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 @1111老铁这个不行了,可以看看近期评论的其他文章..
    • 1111 在

      佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 网站不能打开,博主百忙中能否发个APP下载链接,佛跳墙或极光..
    • 2016-10
    • 2016-11
    • 2018-04
    • 2020-03
    • 2020-04
    • 2020-05
    • 2020-06
    • 2022-01
    • 2023-07
    • 2023-10
    Top

    Copyright·© 2019 侯体宗版权所有· 粤ICP备20027696号 PHP交流群

    侯体宗的博客