pygame实现俄罗斯方块游戏(基础篇2)


Posted in Python onOctober 29, 2019

接上章《pygame实现俄罗斯方块游戏(基础篇1)》继续写俄罗斯方块游戏

五、计算方块之间的碰撞

在Panel类里增加函数

def check_overlap(self, diffx, diffy):
 for x,y in self.moving_block.get_rect_arr():
  for rx,ry in self.rect_arr:
  if x+diffx==rx and y+diffy==ry:
   return True
 return False

修改move_block函数的判断,增加check_overlap函数检测

def move_block(self):
 if self.moving_block is None: create_move_block()
 if self.moving_block.can_move(0,1) and not self.check_overlap(0,1): 
  self.moving_block.move(0,1)
 else:
  self.add_block(self.moving_block)
  self.create_move_block()

现在的效果是方块可以堆叠了

pygame实现俄罗斯方块游戏(基础篇2)

六、键盘控制左右移动

导入变量

from pygame.locals import KEYDOWN,K_LEFT,K_RIGHT,K_UP,K_DOWN

Panel类里增加一个控制移动方块的函数

def control_block(self, diffx, diffy):
 if self.moving_block.can_move(diffx,diffy) and not self.check_overlap(diffx, diffy):
  self.moving_block.move(diffx,diffy)

鼠标事件监听处做下键盘的响应

if event.type == KEYDOWN:
  if event.key == K_LEFT: main_panel.control_block(-1,0)
  if event.key == K_RIGHT: main_panel.control_block(1,0)
  if event.key == K_UP: pass # 变形过会实现
  if event.key == K_DOWN: main_panel.control_block(0,1)

由于Block类的can_move函数没有实现左右移动的判断,所以需要再对can_move
增加左右边界的处理

def can_move(self,xdiff,ydiff):
 for x,y in self.rect_arr:
  if y+ydiff>=20: return False
  if x+xdiff<0 or x+xdiff>=10: return False
 return True

现在,左右的移动也正常了,效果图如下

pygame实现俄罗斯方块游戏(基础篇2)

贴下目前的代码

# -*- coding=utf-8 -*-
import random
import pygame
from pygame.locals import KEYDOWN,K_LEFT,K_RIGHT,K_UP,K_DOWN

class Panel(object): # 用于绘制整个游戏窗口的版面
 rect_arr=[] # 已经落底下的方块
 moving_block=None # 正在落下的方块
 def __init__(self,bg, block_size, position):
 self._bg=bg;
 self._x,self._y,self._width,self._height=position
 self._block_size=block_size
 self._bgcolor=[0,0,0]
 
 def add_block(self,block):
 for rect in block.get_rect_arr():
  self.rect_arr.append(rect)

 def create_move_block(self):
 block = create_block()
 block.move(5-2,-2) # 方块挪到中间 
 self.moving_block=block

 def check_overlap(self, diffx, diffy, check_arr=None):
 if check_arr is None: check_arr = self.moving_block.get_rect_arr()
 for x,y in check_arr:
  for rx,ry in self.rect_arr:
  if x+diffx==rx and y+diffy==ry:
   return True
 return False

 def control_block(self, diffx, diffy):
 if self.moving_block.can_move(diffx,diffy) and not self.check_overlap(diffx, diffy):
  self.moving_block.move(diffx,diffy)

 def move_block(self):
 if self.moving_block is None: create_move_block()
 if self.moving_block.can_move(0,1) and not self.check_overlap(0,1): 
  self.moving_block.move(0,1)
 else:
  self.add_block(self.moving_block)
  self.create_move_block()

 def paint(self):
 mid_x=self._x+self._width/2
 pygame.draw.line(self._bg,self._bgcolor,[mid_x,self._y],[mid_x,self._y+self._height],self._width) # 用一个粗线段来填充背景
 
 # 绘制已经落底下的方块
 bz=self._block_size
 for rect in self.rect_arr:
  x,y=rect
  pygame.draw.line(self._bg,[0,0,255],[self._x+x*bz+bz/2,self._y+y*bz],[self._x+x*bz+bz/2,self._y+(y+1)*bz],bz)
  pygame.draw.rect(self._bg,[255,255,255],[self._x+x*bz,self._y+y*bz,bz+1,bz+1],1)
 
 # 绘制正在落下的方块
 if self.move_block:
  for rect in self.moving_block.get_rect_arr():
  x,y=rect
  pygame.draw.line(self._bg,[0,0,255],[self._x+x*bz+bz/2,self._y+y*bz],[self._x+x*bz+bz/2,self._y+(y+1)*bz],bz)
  pygame.draw.rect(self._bg,[255,255,255],[self._x+x*bz,self._y+y*bz,bz+1,bz+1],1)


class Block(object):
 def __init__(self):
 self.rect_arr=[]

 def get_rect_arr(self): # 用于获取方块种的四个矩形列表
 return self.rect_arr

 def move(self,xdiff,ydiff): # 用于移动方块的方法
 self.new_rect_arr=[]
 for x,y in self.rect_arr:
  self.new_rect_arr.append((x+xdiff,y+ydiff))
 self.rect_arr=self.new_rect_arr

 def can_move(self,xdiff,ydiff):
 for x,y in self.rect_arr:
  if y+ydiff>=20: return False
  if x+xdiff<0 or x+xdiff>=10: return False
 return True

class LongBlock(Block):
 def __init__(self, n=None): # 两种形态
 super(LongBlock, self).__init__()
 if n is None: n=random.randint(0,1)
 self.rect_arr=[(1,0),(1,1),(1,2),(1,3)] if n==0 else [(0,2),(1,2),(2,2),(3,2)]

class SquareBlock(Block): # 一种形态
 def __init__(self, n=None):
 super(SquareBlock, self).__init__()
 self.rect_arr=[(1,1),(1,2),(2,1),(2,2)]


class ZBlock(Block): # 两种形态
 def __init__(self, n=None):
 super(ZBlock, self).__init__()
 if n is None: n=random.randint(0,1)
 self.rect_arr=[(2,0),(2,1),(1,1),(1,2)] if n==0 else [(0,1),(1,1),(1,2),(2,2)]

class SBlock(Block): # 两种形态
 def __init__(self, n=None):
 super(SBlock, self).__init__()
 if n is None: n=random.randint(0,1)
 self.rect_arr=[(1,0),(1,1),(2,1),(2,2)] if n==0 else [(0,2),(1,2),(1,1),(2,1)]

class LBlock(Block): # 四种形态
 def __init__(self, n=None):
 super(LBlock, self).__init__()
 if n is None: n=random.randint(0,3)
 if n==0: self.rect_arr=[(1,0),(1,1),(1,2),(2,2)]
 elif n==1: self.rect_arr=[(0,1),(1,1),(2,1),(0,2)]
 elif n==2: self.rect_arr=[(0,0),(1,0),(1,1),(1,2)]
 else: self.rect_arr=[(0,1),(1,1),(2,1),(2,0)]

class JBlock(Block): # 四种形态
 def __init__(self, n=None):
 super(JBlock, self).__init__()
 if n is None: n=random.randint(0,3)
 if n==0: self.rect_arr=[(1,0),(1,1),(1,2),(0,2)]
 elif n==1: self.rect_arr=[(0,1),(1,1),(2,1),(0,0)]
 elif n==2: self.rect_arr=[(2,0),(1,0),(1,1),(1,2)]
 else: self.rect_arr=[(0,1),(1,1),(2,1),(2,2)]

class TBlock(Block): # 四种形态
 def __init__(self, n=None):
 super(TBlock, self).__init__()
 if n is None: n=random.randint(0,3)
 if n==0: self.rect_arr=[(0,1),(1,1),(2,1),(1,2)]
 elif n==1: self.rect_arr=[(1,0),(1,1),(1,2),(0,1)]
 elif n==2: self.rect_arr=[(0,1),(1,1),(2,1),(1,0)]
 else: self.rect_arr=[(1,0),(1,1),(1,2),(2,1)]
 

def create_block():
 n = random.randint(0,19)
 if n==0: return SquareBlock(n=0)
 elif n==1 or n==2: return LongBlock(n=n-1)
 elif n==3 or n==4: return ZBlock(n=n-3)
 elif n==5 or n==6: return SBlock(n=n-5)
 elif n>=7 and n<=10: return LBlock(n=n-7)
 elif n>=11 and n<=14: return JBlock(n=n-11)
 else: return TBlock(n=n-15)

def run():
 pygame.init()
 space=30
 main_block_size=30
 main_panel_width=main_block_size*10
 main_panel_height=main_block_size*20
 screencaption = pygame.display.set_caption('Tetris')
 screen = pygame.display.set_mode((main_panel_width+160+space*3,main_panel_height+space*2)) #设置窗口长宽
 main_panel=Panel(screen,main_block_size,[space,space,main_panel_width,main_panel_height])

 pygame.key.set_repeat(200, 30)
 main_panel.create_move_block()

 diff_ticks = 300 # 移动一次蛇头的事件,单位毫秒
 ticks = pygame.time.get_ticks() + diff_ticks

 while True:
 for event in pygame.event.get():
  if event.type == pygame.QUIT:
   pygame.quit()
   exit()
  if event.type == KEYDOWN:
  if event.key == K_LEFT: main_panel.control_block(-1,0)
  if event.key == K_RIGHT: main_panel.control_block(1,0)
  if event.key == K_UP: pass # 变形过会实现
  if event.key == K_DOWN: main_panel.control_block(0,1)
 
 screen.fill((100,100,100)) # 将界面设置为灰色
 main_panel.paint() # 主面盘绘制

 pygame.display.update() # 必须调用update才能看到绘图显示

 if pygame.time.get_ticks() >= ticks:
  ticks+=diff_ticks
  main_panel.move_block()

run()

七、控制变形

变形的实现,我们对每个方块子类的初始化函数稍作修改,将获取形状做一个独立的get_shape函数,并且给每个子类增加一个变量用于记录当前形态id,用一个变量用于标识每种方块的形态数量,以T型为例,修改后代码如下

class TBlock(Block): # 四种形态
 shape_id=0
 shape_num=4
 def __init__(self, n=None):
 super(TBlock, self).__init__()
 if n is None: n=random.randint(0,3)
 self.shape_id=n
 self.rect_arr=self.get_shape()

 def get_shape(self):
 if self.shape_id==0: return [(0,1),(1,1),(2,1),(1,2)]
 elif self.shape_id==1: return [(1,0),(1,1),(1,2),(0,1)]
 elif self.shape_id==2: return [(0,1),(1,1),(2,1),(1,0)]
 else: return [(1,0),(1,1),(1,2),(2,1)]

这样我们在Block父类里可以加一个change函数,用于变换至下一形态,由于变化时要保持原来的移动位置,我们增加sx,sy两个变量将方块移动过的位置存着,便于在变化时使用

class Block(object):
 sx=0
 sy=0
 def __init__(self):
 self.rect_arr=[]

 def get_rect_arr(self): # 用于获取方块种的四个矩形列表
 return self.rect_arr

 def move(self,xdiff,ydiff): # 用于移动方块的方法
 self.sx+=xdiff
 self.sy+=ydiff
 self.new_rect_arr=[]
 for x,y in self.rect_arr:
  self.new_rect_arr.append((x+xdiff,y+ydiff))
 self.rect_arr=self.new_rect_arr

 def can_move(self,xdiff,ydiff):
 for x,y in self.rect_arr:
  if y+ydiff>=20: return False
  if x+xdiff<0 or x+xdiff>=10: return False
 return True

 def change(self):
 self.shape_id+=1 # 下一形态
 if self.shape_id >= self.shape_num: 
  self.shape_id=0

 arr = self.get_shape()
 new_arr = []
 for x,y in arr:
  if x+self.sx<0 or x+self.sx>=10: # 变形不能超出左右边界
  self.shape_id -= 1
  if self.shape_id < 0: self.shape_id = self.shape_num - 1
  return None 

  new_arr.append([x+self.sx,y+self.sy])

 return new_arr

在Panel类里的再增加一个change函数,直接调用moving_block的change

def change_block(self):
 if self.moving_block:
  new_arr = self.moving_block.change()
  if new_arr and not self.check_overlap(0, 0, check_arr=new_arr): # 变形不能造成方块重叠
  self.moving_block.rect_arr=new_arr

最后将key_up事件的响应加入change_block的调用就好了

if event.key == K_UP: main_panel.change_block()

现在已经实现了,变形和移动了,方块基本可以正常下落了

pygame实现俄罗斯方块游戏(基础篇2)

八、方块的消除

这个计算主要是处理Panel类的rect_arr,如果数组中出现某一行有10个就符合消除条件,为简化计算,我们将这些矩形按y值存到一个数组中,便于计算

def check_clear(self):
 tmp_arr = [[] for i in range(20)]
 # 先将方块按行存入数组
 for x,y in self.rect_arr:
  if y<0: return
  tmp_arr[y].append([x,y])

 clear_num=0
 clear_lines=set([])
 y_clear_diff_arr=[[] for i in range(20)]
 # 从下往上计算可以消除的行,并记录消除行后其他行的向下偏移数量
 for y in range(19,-1,-1):
  if len(tmp_arr[y])==10:
  clear_lines.add(y)
  clear_num += 1
  y_clear_diff_arr[y] = clear_num

 if clear_num>0:
  new_arr=[]
  # 跳过移除行,并将其他行做偏移
  for y in range(19,-1,-1):
  if y in clear_lines: continue
  tmp_row = tmp_arr[y]
  y_clear_diff=y_clear_diff_arr[y]
  for x,y in tmp_row:
   new_arr.append([x,y+y_clear_diff])
  
  self.rect_arr = new_arr

在Panel的move_block处增加check_clear的调用

def move_block(self):
 if self.moving_block is None: create_move_block()
 if self.moving_block.can_move(0,1) and not self.check_overlap(0,1): 
  self.moving_block.move(0,1)
 else:
  self.add_block(self.moving_block)
  self.check_clear()
  self.create_move_block()

现在游戏可以消除方块了

九、增加空格键使快速落下

快速落下可以快速调用Panel的move_block函数,我们在move_block函数增加一个返回值,用于标记使正常下移还是移到底部后新的方块   

def move_block(self):
 if self.moving_block is None: create_move_block()
 if self.moving_block.can_move(0,1) and not self.check_overlap(0,1): 
  self.moving_block.move(0,1)
  return 1
 else:
  self.add_block(self.moving_block)
  self.check_clear()
  self.create_move_block()
  return 2

在键盘响应处增加键盘处理

if event.key == K_SPACE:
  while main_panel.move_block()==1: 
   pass

十、增加游戏结束判断

游戏结束同样可以在Panel类的move_block中处理,如果一个方块到底,并且消除进行后,发现有方块的y值小于0,那么一定是失败了
修改Panel类的move_block函数

def move_block(self):
 if self.moving_block is None: create_move_block()
 if self.moving_block.can_move(0,1) and not self.check_overlap(0,1): 
  self.moving_block.move(0,1)
  return 1
 else:
  self.add_block(self.moving_block)
  self.check_clear()

  for x,y in self.rect_arr:
  if y<0: return 9 # 游戏失败
  self.create_move_block()
  return 2

增加一个变量记录游戏状态

game_state = 1 # 游戏状态1.表示正常 2.表示失败

计时器处修改程序

if game_state == 1 and pygame.time.get_ticks() >= ticks:
  ticks+=diff_ticks
  if main_panel.move_block()==9: game_state = 2

鼠标键盘响应空格键中也增加一下判断

if event.key == K_SPACE:
    flag = main_panel.move_block()
    while flag==1: 
     flag = main_panel.move_block()
    if flag == 9: game_state = 2

最后增加游戏结束文字的绘制

if game_state == 2:
   myfont = pygame.font.Font(None,30)
   white = 255,255,255
   textImage = myfont.render("Game over", True, white)
   screen.blit(textImage, (160,190))

好了,现在会提示游戏结束了

pygame实现俄罗斯方块游戏(基础篇2)

最后附下目前的完整代码

# -*- coding=utf-8 -*-
import random
import pygame
from pygame.locals import KEYDOWN,K_LEFT,K_RIGHT,K_UP,K_DOWN,K_SPACE

class Panel(object): # 用于绘制整个游戏窗口的版面
 rect_arr=[] # 已经落底下的方块
 moving_block=None # 正在落下的方块
 def __init__(self,bg, block_size, position):
 self._bg=bg;
 self._x,self._y,self._width,self._height=position
 self._block_size=block_size
 self._bgcolor=[0,0,0]
 
 def add_block(self,block):
 for rect in block.get_rect_arr():
  self.rect_arr.append(rect)

 def create_move_block(self):
 block = create_block()
 block.move(5-2,-2) # 方块挪到中间 
 self.moving_block=block

 def check_overlap(self, diffx, diffy, check_arr=None):
 if check_arr is None: check_arr = self.moving_block.get_rect_arr()
 for x,y in check_arr:
  for rx,ry in self.rect_arr:
  if x+diffx==rx and y+diffy==ry:
   return True
 return False

 def control_block(self, diffx, diffy):
 if self.moving_block.can_move(diffx,diffy) and not self.check_overlap(diffx, diffy):
  self.moving_block.move(diffx,diffy)

 def change_block(self):
 if self.moving_block:
  new_arr = self.moving_block.change()
  if new_arr and not self.check_overlap(0, 0, check_arr=new_arr): # 变形不能造成方块重叠
  self.moving_block.rect_arr=new_arr

 def move_block(self):
 if self.moving_block is None: create_move_block()
 if self.moving_block.can_move(0,1) and not self.check_overlap(0,1): 
  self.moving_block.move(0,1)
  return 1
 else:
  self.add_block(self.moving_block)
  self.check_clear()

  for x,y in self.rect_arr:
  if y<0: return 9 # 游戏失败
  self.create_move_block()
  return 2

 def check_clear(self):
 tmp_arr = [[] for i in range(20)]
 # 先将方块按行存入数组
 for x,y in self.rect_arr:
  if y<0: return
  tmp_arr[y].append([x,y])

 clear_num=0
 clear_lines=set([])
 y_clear_diff_arr=[[] for i in range(20)]
 # 从下往上计算可以消除的行,并记录消除行后其他行的向下偏移数量
 for y in range(19,-1,-1):
  if len(tmp_arr[y])==10:
  clear_lines.add(y)
  clear_num += 1
  y_clear_diff_arr[y] = clear_num

 if clear_num>0:
  new_arr=[]
  # 跳过移除行,并将其他行做偏移
  for y in range(19,-1,-1):
  if y in clear_lines: continue
  tmp_row = tmp_arr[y]
  y_clear_diff=y_clear_diff_arr[y]
  for x,y in tmp_row:
   new_arr.append([x,y+y_clear_diff])
  
  self.rect_arr = new_arr


 def paint(self):
 mid_x=self._x+self._width/2
 pygame.draw.line(self._bg,self._bgcolor,[mid_x,self._y],[mid_x,self._y+self._height],self._width) # 用一个粗线段来填充背景
 
 # 绘制已经落底下的方块
 bz=self._block_size
 for rect in self.rect_arr:
  x,y=rect
  pygame.draw.line(self._bg,[0,0,255],[self._x+x*bz+bz/2,self._y+y*bz],[self._x+x*bz+bz/2,self._y+(y+1)*bz],bz)
  pygame.draw.rect(self._bg,[255,255,255],[self._x+x*bz,self._y+y*bz,bz+1,bz+1],1)
 
 # 绘制正在落下的方块
 if self.move_block:
  for rect in self.moving_block.get_rect_arr():
  x,y=rect
  pygame.draw.line(self._bg,[0,0,255],[self._x+x*bz+bz/2,self._y+y*bz],[self._x+x*bz+bz/2,self._y+(y+1)*bz],bz)
  pygame.draw.rect(self._bg,[255,255,255],[self._x+x*bz,self._y+y*bz,bz+1,bz+1],1)


class Block(object):
 sx=0
 sy=0
 def __init__(self):
 self.rect_arr=[]

 def get_rect_arr(self): # 用于获取方块种的四个矩形列表
 return self.rect_arr

 def move(self,xdiff,ydiff): # 用于移动方块的方法
 self.sx+=xdiff
 self.sy+=ydiff
 self.new_rect_arr=[]
 for x,y in self.rect_arr:
  self.new_rect_arr.append((x+xdiff,y+ydiff))
 self.rect_arr=self.new_rect_arr

 def can_move(self,xdiff,ydiff):
 for x,y in self.rect_arr:
  if y+ydiff>=20: return False
  if x+xdiff<0 or x+xdiff>=10: return False
 return True

 def change(self):
 self.shape_id+=1 # 下一形态
 if self.shape_id >= self.shape_num: 
  self.shape_id=0

 arr = self.get_shape()
 new_arr = []
 for x,y in arr:
  if x+self.sx<0 or x+self.sx>=10: # 变形不能超出左右边界
  self.shape_id -= 1
  if self.shape_id < 0: self.shape_id = self.shape_num - 1
  return None 

  new_arr.append([x+self.sx,y+self.sy])

 return new_arr

class LongBlock(Block):
 shape_id=0
 shape_num=2
 def __init__(self, n=None): # 两种形态
 super(LongBlock, self).__init__()
 if n is None: n=random.randint(0,1)
 self.shape_id=n
 self.rect_arr=self.get_shape()

 def get_shape(self):
 return [(1,0),(1,1),(1,2),(1,3)] if self.shape_id==0 else [(0,2),(1,2),(2,2),(3,2)]

class SquareBlock(Block): # 一种形态
 shape_id=0
 shape_num=1
 def __init__(self, n=None):
 super(SquareBlock, self).__init__()
 self.rect_arr=self.get_shape()

 def get_shape(self):
 return [(1,1),(1,2),(2,1),(2,2)]

class ZBlock(Block): # 两种形态
 shape_id=0
 shape_num=2
 def __init__(self, n=None):
 super(ZBlock, self).__init__()
 if n is None: n=random.randint(0,1)
 self.shape_id=n
 self.rect_arr=self.get_shape()

 def get_shape(self):
 return [(2,0),(2,1),(1,1),(1,2)] if self.shape_id==0 else [(0,1),(1,1),(1,2),(2,2)]

class SBlock(Block): # 两种形态
 shape_id=0
 shape_num=2
 def __init__(self, n=None):
 super(SBlock, self).__init__()
 if n is None: n=random.randint(0,1)
 self.shape_id=n
 self.rect_arr=self.get_shape()

 def get_shape(self):
 return [(1,0),(1,1),(2,1),(2,2)] if self.shape_id==0 else [(0,2),(1,2),(1,1),(2,1)]

class LBlock(Block): # 四种形态
 shape_id=0
 shape_num=4
 def __init__(self, n=None):
 super(LBlock, self).__init__()
 if n is None: n=random.randint(0,3)
 self.shape_id=n
 self.rect_arr=self.get_shape()

 def get_shape(self):
 if self.shape_id==0: return [(1,0),(1,1),(1,2),(2,2)]
 elif self.shape_id==1: return [(0,1),(1,1),(2,1),(0,2)]
 elif self.shape_id==2: return [(0,0),(1,0),(1,1),(1,2)]
 else: return [(0,1),(1,1),(2,1),(2,0)]

class JBlock(Block): # 四种形态
 shape_id=0
 shape_num=4
 def __init__(self, n=None):
 super(JBlock, self).__init__()
 if n is None: n=random.randint(0,3)
 self.shape_id=n
 self.rect_arr=self.get_shape()

 def get_shape(self):
 if self.shape_id==0: return [(1,0),(1,1),(1,2),(0,2)]
 elif self.shape_id==1: return [(0,1),(1,1),(2,1),(0,0)]
 elif self.shape_id==2: return [(2,0),(1,0),(1,1),(1,2)]
 else: return [(0,1),(1,1),(2,1),(2,2)]

class TBlock(Block): # 四种形态
 shape_id=0
 shape_num=4
 def __init__(self, n=None):
 super(TBlock, self).__init__()
 if n is None: n=random.randint(0,3)
 self.shape_id=n
 self.rect_arr=self.get_shape()

 def get_shape(self):
 if self.shape_id==0: return [(0,1),(1,1),(2,1),(1,2)]
 elif self.shape_id==1: return [(1,0),(1,1),(1,2),(0,1)]
 elif self.shape_id==2: return [(0,1),(1,1),(2,1),(1,0)]
 else: return [(1,0),(1,1),(1,2),(2,1)]
 
def create_block():
 n = random.randint(0,19)
 if n==0: return SquareBlock(n=0)
 elif n==1 or n==2: return LongBlock(n=n-1)
 elif n==3 or n==4: return ZBlock(n=n-3)
 elif n==5 or n==6: return SBlock(n=n-5)
 elif n>=7 and n<=10: return LBlock(n=n-7)
 elif n>=11 and n<=14: return JBlock(n=n-11)
 else: return TBlock(n=n-15)

def run():
 pygame.init()
 space=30
 main_block_size=30
 main_panel_width=main_block_size*10
 main_panel_height=main_block_size*20
 screencaption = pygame.display.set_caption('Tetris')
 screen = pygame.display.set_mode((main_panel_width+160+space*3,main_panel_height+space*2)) #设置窗口长宽
 main_panel=Panel(screen,main_block_size,[space,space,main_panel_width,main_panel_height])

 pygame.key.set_repeat(200, 30)
 main_panel.create_move_block()

 diff_ticks = 300 # 移动一次蛇头的事件,单位毫秒
 ticks = pygame.time.get_ticks() + diff_ticks

 game_state = 1 # 游戏状态1.表示正常 2.表示失败
 while True:
 for event in pygame.event.get():
  if event.type == pygame.QUIT:
   pygame.quit()
   exit()
  if event.type == KEYDOWN:
  if event.key == K_LEFT: main_panel.control_block(-1,0)
  if event.key == K_RIGHT: main_panel.control_block(1,0)
  if event.key == K_UP: main_panel.change_block()
  if event.key == K_DOWN: main_panel.control_block(0,1)
  if event.key == K_SPACE:
  flag = main_panel.move_block()
  while flag==1: 
   flag = main_panel.move_block()
  if flag == 9: game_state = 2
 
 screen.fill((100,100,100)) # 将界面设置为灰色
 main_panel.paint() # 主面盘绘制

 if game_state == 2:
  myfont = pygame.font.Font(None,30)
  white = 255,255,255
  textImage = myfont.render("Game over", True, white)
  screen.blit(textImage, (160,190))

 pygame.display.update() # 必须调用update才能看到绘图显示

 if game_state == 1 and pygame.time.get_ticks() >= ticks:
  ticks+=diff_ticks
  if main_panel.move_block()==9: game_state = 2 # 游戏结束

run()

今天先写到这,下章继续

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

Python 相关文章推荐
Python转码问题的解决方法
Oct 07 Python
python基础之入门必看操作
Jul 26 Python
python3读取excel文件只提取某些行某些列的值方法
Jul 10 Python
Django 视图层(view)的使用
Nov 09 Python
Python解决两个整数相除只得到整数部分的实例
Nov 10 Python
Python字典遍历操作实例小结
Mar 05 Python
详解pandas DataFrame的查询方法(loc,iloc,at,iat,ix的用法和区别)
Aug 02 Python
关于numpy.where()函数 返回值的解释
Dec 06 Python
使用 Python ssh 远程登陆服务器的最佳方案
Mar 06 Python
Spring @Enable模块驱动原理及使用实例
Jun 23 Python
python中str内置函数用法总结
Dec 27 Python
变长双向rnn的正确使用姿势教学
May 31 Python
pygame实现俄罗斯方块游戏(基础篇1)
Oct 29 #Python
pygame实现五子棋游戏
Oct 29 #Python
python多线程案例之多任务copy文件完整实例
Oct 29 #Python
jenkins配置python脚本定时任务过程图解
Oct 29 #Python
pygame实现成语填空游戏
Oct 29 #Python
Python多线程及其基本使用方法实例分析
Oct 29 #Python
基于python的itchat库实现微信聊天机器人(推荐)
Oct 29 #Python
You might like
php Undefined index的问题
2009/06/01 PHP
Memcache 在PHP中的使用技巧
2010/02/08 PHP
php实现微信公众号无限群发
2015/10/11 PHP
PHP7多线程搭建教程
2017/04/21 PHP
浅谈laravel5.5 belongsToMany自身的正确用法
2019/10/17 PHP
jquery validation插件表单验证的一个例子
2010/03/03 Javascript
js Form.elements[i]的使用实例
2011/11/13 Javascript
jQuery对象数据缓存Cache原理及jQuery.data方法区别介绍
2013/04/07 Javascript
jQuery中bind与live的用法及区别小结
2014/01/27 Javascript
JS通过分析userAgent属性来判断浏览器的类型及版本
2014/03/28 Javascript
jQuery EasyUI 菜单与按钮之创建简单的菜单和链接按钮
2015/11/18 Javascript
Jquery为DIV添加click事件的简单实例
2016/06/02 Javascript
jquery 抽奖小程序实现代码
2016/10/12 Javascript
微信小程序项目实践之九宫格实现及item跳转功能
2018/07/19 Javascript
vue+element的表格实现批量删除功能示例代码
2018/08/17 Javascript
vue data恢复初始化数据的实现方法
2019/10/31 Javascript
python+selenium实现京东自动登录及秒杀功能
2017/11/18 Python
python如何修改装饰器中参数
2018/03/20 Python
python3将视频流保存为本地视频文件
2018/06/20 Python
pytorch 实现tensor与numpy数组转换
2019/12/27 Python
Python流程控制常用工具详解
2020/02/24 Python
Python实现自动打开电脑应用的示例代码
2020/04/17 Python
python模拟实现分发扑克牌
2020/04/22 Python
Django权限设置及验证方式
2020/05/13 Python
Python读取JSON数据操作实例解析
2020/05/18 Python
PyQt中使用QtSql连接MySql数据库的方法
2020/07/28 Python
python 实现简易的记事本
2020/11/30 Python
CSS3 Flexbox中flex-shrink属性的用法示例介绍
2013/12/30 HTML / CSS
美国亚马逊旗下时尚女装网店:SHOPBOP(支持中文)
2020/10/17 全球购物
奥林匹克的口号
2014/06/13 职场文书
村党的群众路线教育实践活动工作总结
2014/10/25 职场文书
结婚纪念日感言
2015/08/01 职场文书
关于感恩老师的古诗句
2019/08/20 职场文书
八年级作文之友谊
2019/12/02 职场文书
2022新作动画《福星小子》释出宣传影片 加入内田真礼&宫野真守配音演出
2022/04/08 日漫
volatile保证可见性及重排序方法
2022/08/05 Java/Android