热门标签 | HotTags
当前位置:  开发笔记 > 运维 > 正文

pygame库实现俄罗斯方块小游戏

这篇文章主要为大家详细介绍了pygame库实现俄罗斯方块小游戏,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

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

import random,time,pygame,sys
from pygame.locals import *#导pygame内定义的一些常量
FPS=25#每秒传输帧数(刷新率),此处一秒内在屏幕上连续投射出24张静止画面
WINDOWWIDTH=640#窗口宽
WINDOWHEIGHT=480#窗口高
BOXSIZE=20#游戏框大小
BOARDWIDTH=10#游戏框宽度
BOARDHEIGHT=20#游戏框高度
BLANK='.'#定义方块形状模板时,填补空白处的字符

MOVESIDEWAYSFREQ=0.15#玩家一直按下左或右方向键,方块仍是每0.15s才会移动一次
MOVEDOWNFREQ=0.1#玩家一直按下下方向键,方块仍是每0.1s移动一次

XMARGIN=(WINDOWWIDTH-BOARDWIDTH*BOXSIZE)/2#游戏界面的宽度
TOPMARGIN=WINDOWHEIGHT-(BOARDHEIGHT*BOXSIZE)-5#游戏界面的高度

#定义RGB颜色变量
WHITE=(255,255,255)#设置字体颜色
BLACK=(0,0,0)#整个窗口背景为黑色
GRAY=(185,185,185)#字体阴影灰色
#以下的颜色分别被COLORS和LIGHTCOLORS所引用
RED=(155,0,0)
LIGHTRED=(175, 20, 20)#浅红
GREEN=(0,155,0)
LIGHTGREEN=(20,175,20)#浅绿
BLUE=(0,0,155)
LIGHTBLUE=(20,20,175)#浅蓝
YELLOW=(155,155,0)
LIGHTYELLOW=(175,175,20)#浅黄

BORDERCOLOR=BLUE#游戏边框颜色为蓝色
BGCOLOR=BLACK#背景颜色为黑色
TEXTCOLOR=WHITE#字体为白色,被showTextScreen()引用,用来设置暂停时的"Pause"文本字体颜色
TEXTSHADOWCOLOR=GRAY#字体阴影为灰色,被showTextScreen()引用,用来设置暂停时的"Pause"文本阴影字体颜色
COLORS=(BLUE,GREEN,RED,YELLOW)#组成方块的小方块颜色
LIGHTCOLORS=(LIGHTBLUE,LIGHTGREEN,LIGHTRED,LIGHTYELLOW)#围绕在小方块周边颜色,强调轮廓

assert len(COLORS)==len(LIGHTCOLORS)#每个颜色对应其浅色

TEMPLATEWIDTH=5#模板宽
TEMPLATEHEIGHT=5#模板高

#定义方块形状模板(顺时针旋转变换),在列表中嵌入了含有字符串的列表来构成这个模板,模板包含了这个方块可能变换的所有形状
S_SHAPE_TEMPLATE=[['.....',
     '.....',
     '..00.',
     '.00..',
     '.....'],
     ['.....',
     '..0..',
     '..00.',
     '...0.',
     '.....']]
Z_SHAPE_TEMPLATE=[['.....',
     '.....',
     '.00..',
     '..00.',
     '.....'],
     ['.....',
     '..0..',
     '.00..',
     '.0...',
     '.....']]
I_SHAPE_TEMPLATE=[['..0..',
     '..0..',
     '..0..',
     '..0..',
     '.....'],
     ['.....',
     '.....',
     '0000.',
     '.....',
     '.....']]
O_SHAPE_TEMPLATE=[['.....',
     '.....',
     '.00..',
     '.00..',
     '.....']]
J_SHAPE_TEMPLATE=[['.....',
     '.0...',
     '.000.',
     '.....',
     '.....'],
     ['.....',
     '..00.',
     '..0..',
     '..0..',
     '.....'],
     ['.....',
     '.....',
     '.000.',
     '...0.',
     '.....'],
     ['.....',
     '..0..',
     '..0..',
     '.00..',
     '.....']]
L_SHAPE_TEMPLATE=[['.....',
     '...0.',
     '.000.',
     '.....',
     '.....'],
     ['.....',
     '..0..',
     '..0..',
     '..00.',
     '.....'],
     ['.....',
     '.....',
     '.000.',
     '.0...',
     '.....'],
     ['.....',
     '.00..',
     '..0..',
     '..0..',
     '.....']]
T_SHAPE_TEMPLATE=[['.....',
     '..0..',
     '.000.',
     '.....',
     '.....'],
     ['.....',
     '..0..',
     '..00.',
     '..0..',
     '.....'],
     ['.....',
     '.....',
     '.000.',
     '..0..',
     '.....'],
     ['.....',
     '..0..',
     '.00..',
     '..0..',
     '.....']]
#定义字典变量PIECES来存储所有的不同形状模板(重点是所有),即字典变量PIECES包含了每个类型的方块和所有的变换形状
PIECES={'S':S_SHAPE_TEMPLATE,
  'Z':Z_SHAPE_TEMPLATE,
  'I':I_SHAPE_TEMPLATE,
  'O':O_SHAPE_TEMPLATE,
  'J':J_SHAPE_TEMPLATE,
  'L':L_SHAPE_TEMPLATE,
  'T':T_SHAPE_TEMPLATE}
#主函数用于创建一些全局变量并在游戏开始之前显示一个初始画面
def main():
 global FPSCLOCK,DISPLAYSURF,BASICFONT,BIGFONT
 pygame.init()#初始化pygame相关模块,为使用硬件做准备
 FPSCLOCK=pygame.time.Clock()#创建一个新对象,可以使用时钟跟踪的时间量。该时钟还提供多种功能以帮助控制游戏的帧率。返回一个Clock对象
 DISPLAYSURF=pygame.display.set_mode((WINDOWWIDTH,WINDOWHEIGHT))#显示窗口(返回一个Surface对象)
 BASICFOnT=pygame.font.Font('freesansbold.ttf',18)#用来设置暂停时"Press a key to play."字体颜色,被showTextScreen()引用
 BIGFOnT=pygame.font.Font('freesansbold.ttf',100)#用来设置暂停时"Pause"文本及其阴影文本字体大小,被showTextScreen()引用     
 pygame.display.set_caption('俄罗斯方块')
 while True:
  #随机播放背景音乐,mid音乐格式由MIDI继承而来。MID文件并不是一段录制好的音乐,而是记录
  #声音的信息,然后告诉声卡如何再现音乐的一组指令,所以音乐播放的好坏因不同机器的声卡而不同
  if random.randint(0,1)==0:#加入异常语句,没有mid音乐也可直接运行
   try:
    pygame.mixer.music.load('QQ火拼泡泡龙复原BGM---无损[游戏中].mid')
   except:
    pass
  else:
   try:
    pygame.mixer.music.load('蛇蛇争霸.mid')
   except:
    pass
  try:
   pygame.mixer.music.play(-1,0.0)#参数依次为无限循环播放,从音乐开头播放
  except:
   pass
  runGame()
  try:
   pygame.mixer.music.stop()
  except:
   pass
  showTextScreen('Game Over')

def runGame():
 """启动运行游戏函数"""
 board=getBlankBoard()#返回一个新的空白板数据结构
 lastMoveDownTime=time.time()
 lastMoveSidewaysTime=time.time()
 lastFallTime=time.time()
 #按下方向键会将以下三个变量设置为None,上移变量用于翻转方块,故没有上移变量
 movingDown=False
 movingLeft=False
 movingRight=False
 score=0
 level,fallFreq=calculateLevelAndFallFreq(score)
 fallingPiece=getNewPiece()#当前掉落的方块
 nextPiece=getNewPiece()#游戏玩家可以在屏幕的NEXT区域看见的下一个方块

 while True:#开始游戏循环
  if fallingPiece==None:
   fallingPiece=nextPiece#没有下降的一块在运动,所以开始一个新的一块在顶部,把nextPiece变量中的下一个方块赋值给fallingPiece变量
   nextPiece=getNewPiece()
   lastFallTime=time.time()#重置lastFallTime变量,赋值为当前时间,这样就可以通过变量fallFreq控制方块下落频率
   if not isValidPosition(board, fallingPiece):#不能在游戏框中放下新的方块,游戏结束,Valid:有效的,Position:位置
    return#返回runGame函数调用处
  checkForQuit()#不断检查是否要退出
  for event in pygame.event.get():#事件处理循环
   if event.type==KEYUP:
    if event.key==K_p:#暂停游戏
     DISPLAYSURF.fill(BGCOLOR)#将DISPLAYSURF(窗口Surface对象)重新填充为黑色
     showTextScreen('Paused')#DISPLAYSURF(窗口Surface对象)显示暂停字样
     lastMoveDownTime = time.time() 
     lastMoveSidewaysTime = time.time() 
     lastFallTime = time.time()
    elif event.key==K_LEFT or event.key==K_a:
     movingLeft=False
    elif event.key==K_RIGHT or event.key==K_d:
     movingRight=False
    elif event.key==K_DOWN or event.key==K_s:
     movingDown=False
   elif event.type==KEYDOWN:#将方块侧向移动
    if event.key==K_LEFT or event.key==K_a and isValidPosition(board,fallingPiece,adjX=-1):
     fallingPiece['x']-=1
     movingLeft=True
     movingRight=False
     lastMoveSidewaysTime=time.time()
    elif event.key==K_RIGHT or event.key==K_d and isValidPosition(board,fallingPiece,adjX=1):
     fallingPiece['x']+=1
     movingRight=True
     movingLeft=False
     lastMoveSidewaysTime=time.time()
    elif event.key==K_UP or event.key==K_w:#按向上键,旋转方块(如果有空间的话)
     fallingPiece['rotation']=(fallingPiece['rotation']+1)%len(PIECES[fallingPiece['shape']])
     if not isValidPosition(board,fallingPiece):
      fallingPiece['rotation']=(fallingPiece['rotation']-1)%len(PIECES[fallingPiece['shape']])
    elif event.key==K_q:#按q键,按相反方向旋转
     fallingPiece['rotation']=(fallingPiece['rotation']-1)%len(PIECES[fallingPiece['shape']])
     if not isValidPosition(board,fallingPiece):
      fallingPiece['rotation'] = (fallingPiece['rotation'] + 1) % len(PIECES[fallingPiece['shape']])
    elif event.key==K_DOWN or event.key==K_s:#按下向下键,使得方块下落得更快,fallingPiece['y']+=1使方块下落一个格子,
               #前提是这是一个有效下落,把movingDown设置为True,把lastMoveDownTime变量
               #设置为当前时间.当向下方向键一直pp按下时,以后将会检查这个变量保证方块以一个较快速率下降
     movingDown=True
     if isValidPosition(board,fallingPiece,adjY=1):
      fallingPiece['y']+=1
     lastMoveDownTime=time.time()
    elif event.key==K_SPACE:#如果按下的是空格,则将方块一步到底部。程序首先需要找出它着落需要下降多少个格子,有关moving的3个变量都要
          #设置为False,用以保证程序后面部分代码知道游戏玩家已经按下所有方向键。
     movingDown=False
     movingLeft=False
     movingRight=False
     for i in range(1,BOARDHEIGHT):
      if not isValidPosition(board,fallingPiece,adjY=i):
       break
     fallingPiece['y']+=i-1
  if (movingLeft or movingRight) and (time.time()-lastMoveSidewaysTime) > MOVESIDEWAYSFREQ:#如果用户按住按键超过0.15s,那么该表达式返回True,便可使得方块左或右移一个格子
                        #因为如果用户重复按下方向键让方块移动多个格子是很烦人的。好的做法便是用户按下
                        #方向键让方块保持移动,直到松开键为止
   if movingLeft and isValidPosition(board,fallingPiece,adjX=-1):
    fallingPiece['x']-=1
   elif movingRight and isValidPosition(board,fallingPiece,adjX=1):
    fallingPiece['x']+=1
   lastMoveSidewaysTime=time.time()
  if movingDown and time.time()-lastMoveDownTime>MOVEDOWNFREQ and isValidPosition(board,fallingPiece,adjY=1):
   fallingPiece['y']+=1
   lastMoveDownTime=time.time()

  if time.time()-lastFallTime>fallFreq:#让方块自动落下如果它到了下落的时候
   #判断方块是否落地
   if not isValidPosition(board,fallingPiece,adjY=1):#方块已落地
    addToBoard(board,fallingPiece)#将落地的方块添加到游戏框中
    score+=removeCompleteLines(board)#判断游戏框中的每一行是否填满,删除填满的一行,返回填满数
    level,fallFreq=calculateLevelAndFallFreq(score)#计算游戏等级以及下落频率
    fallingPiece=None#将当前下落的方块设置为空对象,然后在函数开头重新赋值nextPiece
   else:#方块没有落地,只是把方块移下来
    fallingPiece['y']+=1
    lastFallTime=time.time()
  #把所有东西画在屏幕上
  DISPLAYSURF.fill(BGCOLOR)#设置窗口背景颜色
  drawBoard(board)#将空白数据模板绘画到窗口
  drawStatus(score,level)#将状态栏绘画到窗口
  drawNextPiece(nextPiece)#将下一个方块显示栏画到窗口
  if fallingPiece != None:
   drawPiece(fallingPiece)
  pygame.display.update()
  FPSCLOCK.tick(FPS) 
    
      
    
    
def getBlankBoard():
 """创建并返回一个新的空白板数据结构,board列表为如下形式:
 [['.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.']
 ,['.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.']
 ,['.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.']
 ,['.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.']
 ,['.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.']
 ,['.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.']
 ,['.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.']
 ,['.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.']
 ,['.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.']
 ,['.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.']]
 
 与BOARDWIDTH=10#游戏框宽度,BOARDHEIGHT=20#游戏框高度对应
 """
 board=[]
 for i in range(BOARDWIDTH):
  board.append([BLANK]*BOARDHEIGHT)
 return board
def calculateLevelAndFallFreq(score):
 """根据分数,返回玩家所处的关卡,以及掉落的棋子掉落到一个空格前的时间间隔。"""
 level=int(score/10)+1#等级
 fallFreq=0.27-(level*0.02)#下落频率(frequence)
 return level,fallFreq
def getNewPiece():
 """以随机旋转和颜色返回随机的新块"""
 shape=random.choice(list(PIECES.keys()))#shape为S,Z,I....
 newPiece={'shape':shape,
    'rotation':random.randint(0,len(PIECES[shape])-1),#PIECES[shape]为S_SHAPE_TEMPLATE,Z_SHAPE_TEMPLATE,I_SHAPE_TEMPLATE.此处指一类方块的可旋转次数
    'x':int(BOARDWIDTH/2)-int(TEMPLATEWIDTH/2),
    'y':-2,
    'color':random.randint(0,len(COLORS)-1)}
 return newPiece
def checkForQuit():
 """检查退出事件"""
 for event in pygame.event.get(QUIT):#获取所有退出事件
  terminate()#如果存在任何退出事件,则调用终止函数
 for event in pygame.event.get(KEYUP):#获取所有的放开键事件
  if event.key==K_ESCAPE:#如果KEYUP事件是针对Esc键的
   terminate()#终止
  pygame.event.post(event)#将其他KEYUP(非Esc键放开)事件对象放回事件队列
  
def terminate():
 """退出函数"""
 pygame.quit()
 sys.exit()
def showTextScreen(text):
 """在窗口Surface对象的中央显示大文本,直到按下一个键。用于绘制文本投影,注意:pygame没有提供直接在现有
 表面绘制文本的方法:相反,您必须使用Font.render()来创建文本的图像(表面),然后将此图像blit到另一个表面。

 """
 #做出阴影效果
 titleSurf,titleRect=makeTextObjs(text,BIGFONT,TEXTSHADOWCOLOR)#BIGFONT为main函数中定义,TEXTSHADOWCOLOR为模块中定义,此处文本颜色TEXTSHADOWCOLOR(灰色),下面是TEXTCOLOR(白色)
 titleRect.center=(int(WINDOWWIDTH/2),int(WINDOWHEIGHT / 2))#设置矩形容器的位置,此处需要注意titleRect指的是每个文本Surface对象与其对应的全覆盖矩形容器,此容器在这里不可见
 DISPLAYSURF.blit(titleSurf,titleRect)#在窗口Surface对象画文本Surface对象和与其对应的矩形Surface对象,做出blit这个动作的人是一个Surface类的实例
 #实体文本整体向左上移动3个单位,与上面的阴影效果唯一不同的就是传入的颜色参数
 titleSurf,titleRect=makeTextObjs(text,BIGFONT,TEXTCOLOR)
 titleRect.center=(int(WINDOWWIDTH/2)-3,int(WINDOWHEIGHT/2)-3)
 DISPLAYSURF.blit(titleSurf,titleRect)
 #绘制"Paused"文本下附加的"Press a key to play."文本
 pressKeySurf,pressKeyRect=makeTextObjs('Press a key to play.',BASICFONT,TEXTCOLOR)
 pressKeyRect.center=(int(WINDOWWIDTH/2),int(WINDOWHEIGHT/2)+100)
 DISPLAYSURF.blit(pressKeySurf,pressKeyRect)
 while checkForKeyPress()==None:
  pygame.display.update()
  FPSCLOCK.tick()#这种方法应该被调用一次。它将计算多少毫秒被调用。如果可选的帧率参数的函数以将延迟保持在低于给
      #定游戏运行时每秒滴答。这有助于限制运行游戏的速度。通过调用clock.tick每帧一次地(40),该程序不会运行超过40帧/秒。
def makeTextObjs(text,font,color):
 """这将创建一个新Surface对象,并在其上呈现指定的文本。"""
 surf=font.render(text,True,color)#参数依次为:要写的文本,布尔值(是否开启抗锯齿功能,True字体较为平滑,),字体颜色,背景色
 return surf,surf.get_rect()#返回一个覆盖整个表面的新矩形(Rect对象,一个矩形的灵活容器)
def isValidPosition(board,piece,adjX=0,adjY=0):
 """如果块在板内且没有碰撞,则返回True,该函数我暂时不理解"""
 for x in range(TEMPLATEWIDTH):
  for y in range(TEMPLATEHEIGHT):
   isAboveBoard=y+piece['y']+adjY<0
   if isAboveBoard or PIECES[piece['shape']][piece['rotation']][y][x]==BLANK:
    continue
   if not isOnBoard(x+piece['x']+adjX,y+piece['y']+adjY):
    return False
   if board[x+piece['x']+adjX][y+piece['y']+adjY]!=BLANK:
    return False
 return True
def isOnBoard(x,y):
 return x>=0 and x=0:
  if isCompleteLine(board,y):#如果填充了这一行,则移开这条线,把所有方块往下一拉
   for pullDownY in range(y,0,-1):
    for x in range(BOARDWIDTH):
     board[x][pullDownY]=board[x][pullDownY-1]
   for x in range(BOARDWIDTH):#将最上面一行设置为空白
    board[x][0]=BLANK
   numLinesRemoved+=1
  else:
   y-=1#继续查看下一行
 return numLinesRemoved
   
   
def isCompleteLine(board,y):
 """如果行中填充了没有空格的框,则返回True"""
 for x in range(BOARDWIDTH):
  if board[x][y]==BLANK:
   return False
 return True
def calculateLevelAndFallFreq(score):
 """基于分数,返回玩家所在的关卡。"""
 level=int(score/10)+1
 fallFreq=0.27-(level*0.02)#根据level变量计算方块每下落一个空间所需要的秒数
 return level,fallFreq

def drawBoard(board): 
 """将空白数据模板画到窗口Surface对象上"""
 pygame.draw.rect(DISPLAYSURF, BORDERCOLOR, (XMARGIN - 3, TOPMARGIN - 7, (BOARDWIDTH * BOXSIZE) + 8, (BOARDHEIGHT * BOXSIZE) + 8), 5) 
 
 # fill the background of the board #填充空白数据模板背景颜色
 pygame.draw.rect(DISPLAYSURF, BGCOLOR, (XMARGIN, TOPMARGIN, BOXSIZE * BOARDWIDTH, BOXSIZE * BOARDHEIGHT)) 
 # draw the individual boxes on the board #在空白数据模板上画出各个盒子
 for x in range(BOARDWIDTH): 
 for y in range(BOARDHEIGHT): 
 drawBox(x, y, board[x][y]) 


def drawStatus(score,level):
 """在Surface窗口对象上画在游戏框旁边的状态栏"""
 #绘制分数文本
 scoreSurf=BASICFONT.render("Score:%s"%score,True,TEXTCOLOR)#TEXTCOLOR为白色
 scoreRect=scoreSurf.get_rect()
 scoreRect.topleft = (WINDOWWIDTH - 150, 20)
 DISPLAYSURF.blit(scoreSurf, scoreRect) 
 #绘制等级文本
 levelSurf = BASICFONT.render('Level: %s' % level, True, TEXTCOLOR)
 levelRect = levelSurf.get_rect()
 levelRect.topleft = (WINDOWWIDTH - 150, 50)
 DISPLAYSURF.blit(levelSurf, levelRect)
def drawNextPiece(piece):
 #绘制"下一个"文本
 nextSurf=BASICFONT.render("Next:",True,TEXTCOLOR)
 nextRect=nextSurf.get_rect()
 nextRect.topleft=(WINDOWWIDTH-120,80)
 DISPLAYSURF.blit(nextSurf, nextRect)
 #绘制下一个"方块",pixel中文为像素
 drawPiece(piece,pixelx=WINDOWWIDTH-120, pixely=100)
def drawPiece(piece,pixelx=None, pixely=None):
 shapeToDraw=PIECES[piece['shape']][piece['rotation']]
 if pixelx==None and pixely==None:
  pixelx,pixely=convertToPixelCoords(piece['x'], piece['y'])#如果没有指定pixelx & pixely,则使用存储在片段数据结构中的位置
 #画出组成这个方块的每一个小方块
 for x in range(TEMPLATEWIDTH):
  for y in range(TEMPLATEHEIGHT):
   if shapeToDraw[y][x] != BLANK:
    drawBox(None,None,piece['color'],pixelx + (x * BOXSIZE), pixely + (y * BOXSIZE))
 
def convertToPixelCoords(boxx,boxy):
 """将board上给定的xy坐标转换为屏幕上位置的xy坐标,convert:转换,pixel:像素,coords:坐标"""
 return (XMARGIN+(boxx*BOXSIZE)),(TOPMARGIN+(boxy * BOXSIZE))

def drawBox(boxx,boxy,color,pixelx=None,pixely=None):
 """在黑板上的xy坐标处画一个盒子(每个四重奏有四个盒子)。或者,如果指定了pixelx & pixely,则绘制到存储在pixelx & pixely中的像素坐标(这用于“下一个”块)"""
 if color==BLANK:
  return
 if pixelx==None and pixely==None:
  pixelx, pixely = convertToPixelCoords(boxx, boxy)
 pygame.draw.rect(DISPLAYSURF, COLORS[color], (pixelx + 1, pixely + 1, BOXSIZE - 1, BOXSIZE - 1)) 
 pygame.draw.rect(DISPLAYSURF, LIGHTCOLORS[color], (pixelx + 1, pixely + 1, BOXSIZE - 4, BOXSIZE - 4))

def checkForKeyPress():
 """遍历事件队列,寻找KEYUP事件,获取KEYDOWN事件,将它们从事件队列中删除"""
 checkForQuit()
 for event in pygame.event.get([KEYDOWN, KEYUP]):
  if event.type!=KEYDOWN:
   continue
  return event.key
 return None
if __name__=='__main__':
 main()

运行结果:

更多关于俄罗斯方块的文章,请点击查看专题:《俄罗斯方块》

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


推荐阅读
  • 本文详细介绍如何在华为鲲鹏平台上构建和使用适配ARM架构的Redis Docker镜像,解决常见错误并提供优化建议。 ... [详细]
  • Flutter 核心技术与混合开发模式深入解析
    本文深入探讨了 Flutter 的核心技术,特别是其混合开发模式,包括统一管理模式和三端分离模式,以及混合栈原理。通过对比不同模式的优缺点,帮助开发者选择最适合项目的混合开发策略。 ... [详细]
  • 如何在DedeCMS专题页节点文档中调用自定义模型字段?
    在完成DedeCMS专题页节点文章列表样式的修改后,如果需要在列表中显示自定义模型的字段,由于DedeCMS默认不支持这一功能,因此需要进行一些二次开发。本文将详细介绍如何通过修改模板文件和核心文件来实现这一需求。 ... [详细]
  • 本文详细介绍了CSS中元素的显示模式,包括块元素、行内元素和行内块元素的特性和应用场景。 ... [详细]
  • 本文介绍了如何将Spring属性占位符与Jersey的@Path和@ApplicationPath注解结合使用,以便在资源路径中动态解析属性值。 ... [详细]
  • ABP框架是ASP.NET Boilerplate的简称,它不仅是一个开源且文档丰富的应用程序框架,还提供了一套基于领域驱动设计(DDD)的最佳实践架构模型。本文将详细介绍ABP框架的特点、项目结构及其在Web API优先架构中的应用。 ... [详细]
  • 作为一名新手开发者,我正在尝试使用 ASP.NET 和 Vue.js 构建一个单页面应用,涉及多个复杂组件(如按钮、图表等)。希望有经验的开发者能够提供指导。 ... [详细]
  • 深入理解Java多线程与并发机制
    本文探讨了Java多线程和并发机制的核心概念,包括多线程类的分类、执行器框架、并发容器及控制工具。通过详细解析这些组件,帮助开发者更好地理解和应用多线程技术。 ... [详细]
  • Spring 中策略模式的应用:Resource 接口详解
    本文探讨了在 Spring 框架中如何利用 Resource 接口实现资源访问策略。Resource 接口作为资源访问策略的抽象,通过多种实现类支持不同类型的资源访问。 ... [详细]
  • Java EE 平台集成了多种服务、API 和协议,旨在支持基于 Web 的多层应用程序开发。本文将详细介绍 Java EE 中的 13 种关键技术规范,帮助开发者更好地理解和应用这些技术。 ... [详细]
  • vue引入echarts地图的四种方式
    一、vue中引入echart1、安装echarts:npminstallecharts--save2、在main.js文件中引入echarts实例:  Vue.prototype.$echartsecharts3、在需要用到echart图形的vue文件中引入:   importechartsfrom&amp;quot;echarts&amp;quot;;4、如果用到map(地图),还 ... [详细]
  • 面试题总结_2019年全网最热门的123个Java并发面试题总结
    面试题总结_2019年全网最热门的123个Java并发面试题总结 ... [详细]
  • 使用Tkinter构建51Ape无损音乐爬虫UI
    本文介绍了如何使用Python的内置模块Tkinter来构建一个简单的用户界面,用于爬取51Ape网站上的无损音乐百度云链接。虽然Tkinter入门相对简单,但在实际开发过程中由于文档不足可能会带来一些不便。 ... [详细]
  • 本文介绍了 Python 中的基本数据类型,包括不可变数据类型(数字、字符串、元组)和可变数据类型(列表、字典、集合),并详细解释了每种数据类型的使用方法和常见操作。 ... [详细]
  • 深入解析Pod中的容器关系
    容器之间的紧密协作如何实现?本文探讨了Kubernetes中Pod的概念及其在处理容器间超亲密关系中的作用。 ... [详细]
author-avatar
倒转流年1990
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有