上接
六、让游戏动起来
产生了方块后,接着就要让它自由下落。
首先在类class Tetris中添加定义一些基本的参数
class Tetris():
def __init__(self,x0,y0):
...
self.speed = fps #速度,和帧率一致
self.fall_buffer = self.speed #自动下落的缓冲时间,屏幕每刷一次自动减1
self.fall_speed_up = False #是否加速下落
...
def move(self, dx, dy):
#方块左、右、下移动:左:dx=-1,dy=0 右:dx=1,dy=0 下:dx=0,dy=1
if True: #暂时让它可以下移动即可
self.x += dx
self.y += dy
elif dy: #一步步来,下面的没有实现
#不能下落:在顶部位置不能下落,游戏结束,以下位置则停止移动
if self.y <= 0:
self.game_over()
else:
self.stop_move()
def display(self):
...
#每刷一次缓冲计数减1,缓冲计数=0,或按住了向下键则下落一格
self.fall_buffer -= 1
if self.fall_buffer == 0 or self.fall_speed_up:
self.fall_buffer = self.speed
self.move(0,1)
time = pygame.time.Clock() #新增
player = Tetris(0, 0) #初始化游戏
while True:
time.tick(fps) #新增
screen.fill((166,138,88))
player.display()
pygame.display.update()
这样,就可以往下移动了。如图
七、控制它到底部不动,同时产生一个新的方块
还记得上面第六步的代码 move 方法中的stop_move吧,下面完成这部分逻辑
涉及到方法:
can_move:判断这个方块能不能移动,包括出界或碰到其他方块
stop_move:方块停止移动,停落区域赋值1和相应的颜色,产生一个新块
class Tetris():
...
def move(self, dx, dy):
#方块左、右、下移动:左:dx=-1,dy=0 右:dx=1,dy=0 下:dx=0,dy=1
if self.can_move(self.index, dx, dy): #增加条件
self.x += dx
self.y += dy
...
def can_move(self, index, dx, dy):
#方块能否移动,包括出界或碰到其他方块
for (x,y) in blocks[self.key][index]:
col, row = self.x + x + dx , self.y + y + dy
if col >= cols or col < 0 or row >= rows or row < 0: #出界
return False
if self.display_arrs[row][col]: #值等于1时不能移动
return False
return True
def stop_move(self):
#方块停止移动,停落区域赋值1和相应的颜色
for (x,y) in blocks[self.key][self.index]:
self.display_arrs[y+self.y][x+self.x] = 1
self.color_arrs[y+self.y][x+self.x] = self.key
self.creat_new_block()
到这里,可以判断方块能否移动,不能移动的时候就产生新方块。
但是发现新问题:下落后不能显示在屏幕的最下面。为什么呢?我们知道,pygame的原理其实就是在整个内存中模拟页面,让后用update方法显示出来。而程序到目前为止,只操作当前的方块,就是说一个方块掉到最下面了,然后产生新的方块了,前面的方块在内存中就被“抛弃”了。那接下来的任务是将这些都显示出来。
八、优化一下,显示所有的方块
涉及到方法:
display_stop_blocks:显示不能移动的方块,值为1的画原来的色彩的方块,值为0画底色块
class Tetris():
...
def display_stop_blocks(self):
#显示不能移动的方块,值为1的画原来的色彩的方块,值为0画底色块
for y in range(rows):
for x in range(cols):
self.rect.topleft = x * cell_size, y * cell_size
if self.display_arrs[y][x]:
self.draw_block(self.color_arrs[y][x], 1)
else:
self.draw_block(0, 0)
...
现在显示成这样了,基本达到了现阶段要求:
敬请期待: