2017-05-07 2 views
1

私はpythonのための非常に初歩的なバージョンのPythonをPython 3.6で書いています。これまでの唯一の特徴は、ブロックが落下し、ブロックが速く落ち、左右に移動し、ブロックが地面に当たったときに新しいブロックが生成されることです。Pygame Tetris Issue

ただし、問題があります。最初のブロックが地面に当たると、ブロックが画面の最上部に無期限に出現します。私はコードを精査し、それを私の友人にも示しました。問題を見つけることができませんでした。コードを破棄して書き直しても問題は解決しませんでした。誰もそれを見ますか?

ありがとう

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と設定してください。私は最初の最初のブロックが地面に触れた後lockedは常にTrueであることを確認するためにif locked:線の上print(locked, len(fallingblocks), len(setblocks))を印刷されたコードをデバッグする

。その後、私はsetblocksで衝突検出をコメントアウトしようとし、連続的なスポーンを止めました。次のステップは、setblockとfallingblocksのrectを印刷することで、rectのy-posは常に0または25であり、変更されていないことが明らかになりました。私はfallメソッドの移動コードを見て、rectが動かないことに気づいた。

さらに問題がありますが、最初にデバッグを続行し、まだ問題がある場合は新しい質問をするようにしてください。