首页 > 解决方案 > Pygame俄罗斯方块块在某些条件下不向下移动

问题描述

我在 Pygame 中制作俄罗斯方块,但只有 1 个块(不是 4 个)。这是块类:

# Creating a matrix representing the grid 
environment = numpy.zeros((21, 16), dtype=numpy.int32)

class Block(object) :
    def __init__(self):
        self.x, self.y, self.color, self.row, self.column = 643, -32, 0, 0, 7
        self.img, self.mv_step = myblock, 32
        pygame.time.set_timer(USEREVENT+1, 800)
        self.is_current_block = True
    
    def blit_and_manage(self):
        MyScreen.blit(self.img, (self.x, self.y))
        # this makes the first 2 lines not count, this helps the player at the end of the game ...
        if self.y == 40:
            self.row = 0
        # handling events
        for e in events:
            # moving a block to the left
            if ((e.type == KEYDOWN and e.key == K_LEFT) and self.x != 407) and self.is_current_block and environment[self.row, self.column-1] == 0:
                self.x -= 32
                self.column -= 1
                environment[self.row, self.column+1] = 0
            # moving a block to the right
            elif ((e.type == KEYDOWN and e.key == K_RIGHT) and self.x != 887) and self.is_current_block and environment[self.row, self.column+1] == 0:
                self.x += 32
                self.column += 1
                environment[self.row, self.column-1] = 0
            # moving a block down
            if ((e.type == USEREVENT+1) or ((e.type == KEYDOWN and (e.key == K_DOWN)) and self.is_current_block) and environment[self.row+1, self.column] == 0:
                self.y += self.mv_step
                if self.y > 40:
                    self.row += 1
                    environment[self.row-1, self.column] = 0
        # creating boundaries for the blocks
        if self.y >= 672:
            self.y = 672
            self.is_current_block = False
        # adding the block's color to the matrix in its corresponding position
        if self.y > 3:
            environment[self.row, self.column] = self.color
        # preventing blocks from moving down if there is another block underneath
        if self.row != 20 and environment[self.row+1, self.column] != 0:
            self.is_current_block = False

错误是:当填充水平线时(通过向 K_s 或 K_DOWN 发送垃圾邮件),块将相互站立,直到只剩下两个空间,下一个将产生的块不会向下移动,即使它下面的空间是空,然后游戏将变得无响应,直到我使用 ctrl + c 进行键盘中断。(这只发生在中间线) 数字

这是发生错误时的矩阵:(假设网格不是上面示例代码中的 21 x 16,只是为了不使帖子更长)

[[0 0 0 0 0 0 0 4 0 0 0 0 0 0 0 0]
 [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
 [0 0 0 0 0 0 0 5 0 0 0 0 0 0 0 0]
 [0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0]
 [0 0 0 0 0 0 0 6 0 0 0 0 0 0 0 0]]

标签: pythonnumpypygame

解决方案


我不知道这是否是您的实际问题(如果不是,请留下您想要实现的更详细的描述)但这是我认为您的问题的解决方案:

在向下移动块的条件语句中检查:

if ... and environment[self.row+1, self.column] == 0:

初始化时self.row = 0soself.row+1将为 1environment[self.row+1, ...]并将转到下面的environment(python 具有从零开始的索引)的第二行

self.y += self.mv_step  # self.mv_step = 32
if self.y > 40:
    self.row += 1

这意味着该self.row值将不会增加,直到self.y> 40(在self.y停留在之前0),它位于案例的第三(视觉)行中(在它只有 -32、0 或 32 之前)。因此,当块最终到达第 3(可视)行时,self.row值为 1。因此,块将修改:

environment[self.row, self.column] = self.color

(在这种情况下environment[1, ...]
这意味着environment[1, ...]- 块将检查其原始位置的行 - 被(视觉上的)第三行块修改。

解决方案
如果您仍然希望顶部有 1 行可用空间,只需将用于增加行数的 if 条件更改为:

if self.y > 0:  # instead of > 40
    self.row += 1

如果您不希望顶部没有空间,只需删除此(上述)条件。
编辑:我在向下移动块周围添加了一个try-语句。except IndexError


推荐阅读