2017-05-07 82 views
1

我一直在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 

回答

1

問題是在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沒有移動。

還有更多的問題,但我認爲你應該先嚐試繼續調試,如果仍有問題,可以提出新的問題。