Pygame俄罗斯方块问题

问题描述:

我一直在python 3.6中编写Pygame的俄罗斯方块的基本版本。到目前为止,唯一的功能是块下降,使他们下降得更快,左右移动,当一个块撞到地面时,会产生一个新块。Pygame俄罗斯方块问题

但是,存在这个问题。当第一个块撞到地面时,块无限制地在屏幕的顶部产生。我搜索了代码并将其展示给我的朋友,但我们无法找到问题。我放弃了代码并重写了它,问题依然存在。有人在这里看到它吗?

谢谢

P.S. 我很确定代码的前2/3不是问题。

import pygame, random 

screen = pygame.display.set_mode((400,600)) 
pygame.display.set_caption("Tetris") 
done = False 
fast = False 
locked = False 
fallingblocks = [] 
setblocks = [] 
clock = pygame.time.Clock() 
fallcooldown = 0 

class Block: 

    def __init__(self, x, y, color): 
    self.x = x 
    self.y = y 
    self.color = color 
    fallingblocks.append(self) 
    self.rect = pygame.Rect(self.x + 1, self.y, 23, 25) #game only cares if falling block collides on the top or bottom, not side 

    def fall(self): 
    self.y += 25 

    def move(self): 
    if pressed[pygame.K_a] or pressed[pygame.K_LEFT]: self.x -= 25 
    if pressed[pygame.K_d] or pressed[pygame.K_RIGHT]: self.x += 25 

    def drawblock(self): #just to make it look nice 
    pygame.draw.rect(screen, self.color[0], pygame.Rect(self.x,self.y,25,25)) 
    pygame.draw.polygon(screen, self.color[1], ((self.x,self.y),(self.x+3,self.y+3),(self.x+21,self.y+3),(self.x+24,self.y))) 
    pygame.draw.polygon(screen, self.color[2], ((self.x,self.y),(self.x+3,self.y+3),(self.x+3,self.y+21),(self.x,self.y+24))) 
    pygame.draw.polygon(screen, self.color[3], ((self.x,self.y+24),(self.x+3,self.y+21),(self.x+21,self.y+21),(self.x+24,self.y+24))) 
    pygame.draw.polygon(screen, self.color[4], ((self.x+24,self.y+24),(self.x+21,self.y+21),(self.x+21,self.y+3),(self.x+24,self.y))) 

def spawn(): 
    blocknum = random.randint(0,6) 

    if blocknum == 0: 
    #I block 
    colors = [(129,184,231), 
    (179,223,250), 
    (146,202,238), 
    (76,126,189), 
    (96,157,213)] 

    Block(175,0,colors) 
    Block(175,25,colors) 
    Block(175,50,colors) 
    Block(175,75,colors) 
    elif blocknum == 1: 
    #J block 
    colors = [(77,110,177), 
    (149,178,229), 
    (104,145,203), 
    (49,63,136), 
    (63,85,158)] 

    Block(200,0,colors) 
    Block(200,25,colors) 
    Block(200,50,colors) 
    Block(175,50,colors) 
    elif blocknum == 2: 
    #L block 
    colors = [(219,127,44), 
    (243,191,122), 
    (229,158,69), 
    (166,71,43), 
    (193,98,44)] 

    Block(175,0,colors) 
    Block(175,25,colors) 
    Block(175,50,colors) 
    Block(200,50,colors) 
    elif blocknum == 3: 
    #O block 
    colors = [(248,222,49), 
    (246,243,139), 
    (245,235,86), 
    (183,160,54), 
    (213,190,55)] 

    Block(175,0,colors) 
    Block(175,25,colors) 
    Block(200,0,colors) 
    Block(200,25,colors) 
    elif blocknum == 4: 
    #S block 
    colors = [(156,195,76), 
    (204,218,127), 
    (174,208,79), 
    (109,157,75), 
    (140,183,93)] 

    Block(175,0,colors) 
    Block(175,25,colors) 
    Block(200,0,colors) 
    Block(150,25,colors) 
    elif blocknum == 5: 
    #Z block 
    colors = [(204,42,40), 
    (226,138,132), 
    (213,90,69), 
    (151,34,42), 
    (181,37,43)] 

    Block(175,0,colors) 
    Block(225,25,colors) 
    Block(200,0,colors) 
    Block(200,25,colors) 
    else: 
    #T block 
    colors = [(147,68,149), 
    (187,145,194), 
    (156,101,167), 
    (108,45,123), 
    (128,47,135)] 

    Block(175,0,colors) 
    Block(175,25,colors) 
    Block(200,0,colors) 
    Block(150,0,colors) 

spawn() 

#Pretty sure that everything above here is not the issue 

while not done: #main loop 

    screen.fill((0,0,32)) 
    pressed = pygame.key.get_pressed() 

    for fallingblock in fallingblocks: 
    fallingblock.drawblock() 
    fallingblock.move() 

    for setblock in setblocks: 
    setblock.drawblock() 

    if fallcooldown >= 50: #makes all pieces fall at once 
    for fallingblock in fallingblocks: 
     fallingblock.fall() 
    fallcooldown = 0 
    pygame.display.flip() 

    if pressed[pygame.K_SPACE]: #if you want the piece to go the ground instantly 
    fast = True 

    if fast: fallcooldown = 50 #falling movements 
    elif pressed[pygame.K_DOWN]: fallcooldown += 8 #goes faster 
    else: fallcooldown += 1 #default speed 

    for fallingblock in fallingblocks: 
    for setblock in setblocks: 
     if fallingblock.rect.colliderect(setblock.rect): #if fallingblock collides with setblock 
     locked = True 
    if fallingblock.y >= 575 and not locked: #if block hits the bottom 
     locked = True 

    if locked: #if block is in final state 
    setblocks += fallingblocks 
    fallingblocks = [] 
    spawn() 
    locked = False 

    clock.tick(50) 
    pygame.display.flip() 

    for event in pygame.event.get(): 
     if event.type == pygame.QUIT: 
      done = True 

问题是在Blockfall方法引起的。您只更改y属性,但不要移动块的rect,因此它实际上始终停留在屏幕的顶部。因此,请删除x, y属性并仅使用self.rect.xself.rect.y,或者选择设置self.rect.y = self.y

要调试我第一印刷print(locked, len(fallingblocks), len(setblocks))上述if locked:线以确认locked总是True第一块着地后的代码。然后我试图用setblocks注释掉碰撞检测,并停止连续产卵。下一步是打印setblocks和下降块的rects,它揭示了rects的y-pos总是0或25,并且永远不会改变。我看了一下fall方法中的移动代码,发现rect没有移动。

还有更多的问题,但我认为你应该先尝试继续调试,如果仍有问题,可以提出新的问题。