2017-05-07 3 views
1

J'ai écrit une version très rudimentaire de Tetris pour Pygame en python 3.6. Les seules caractéristiques à ce jour sont les blocs qui tombent, les faisant tomber plus vite, se déplaçant à gauche et à droite, et lorsqu'un bloc frappe le sol, un nouveau apparaît.Pygame Tetris Issue

Cependant, il y a le problème. Lorsque le premier bloc touche le sol, les blocs apparaissent indéfiniment en haut de l'écran. J'ai balayé le code et l'ai montré à mon ami, et nous n'avons pas pu trouver le problème. J'ai abandonné le code et l'ai réécrit, et le problème a persisté. Est-ce que quelqu'un ici le voit?

Merci

P.S. Je suis à peu près sûr que le top 2/3 du code n'est pas le problème.

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 

Répondre

1

Le problème est dû à la méthode fall du Block. Vous ne modifiez que l'attribut y mais ne déplacez jamais le rect du bloc, il reste donc en permanence en haut de l'écran. Supprimez donc les attributs x, y et utilisez simplement self.rect.x et self.rect.y, ou définissez self.rect.y = self.y.

Pour déboguer le code j'ai imprimé print(locked, len(fallingblocks), len(setblocks)) dessus de la ligne if locked: confirmer que locked a toujours été True après le premier bloc a touché le sol. Ensuite, j'ai essayé de commenter la détection de collision avec le setblocks et le frai continu arrêté. L'étape suivante consistait à imprimer les rects des setblocks et des blocs qui tombaient et cela révélait que le y-pos des rects était toujours 0 ou 25 et ne changeait jamais. J'ai regardé le code de mouvement dans la méthode fall et j'ai remarqué que le rect ne se déplaçait pas.

Il y a plus de problèmes, mais je pense que vous devriez essayer de continuer avec le débogage en premier et poser de nouvelles questions si vous avez encore des problèmes.