2017-05-07 17 views
1

파이썬 3.6에서 테트리스를 매우 기초적인 버전으로 작성했습니다. 지금까지는 블럭이 떨어지면서 블럭이 빠르게 떨어지면서 좌우로 움직였습니다. 블럭이 땅에 떨어지면 새로운 블럭이 생깁니다.파이 게임 테트리스 문제

그러나 문제가 있습니다. 첫 번째 블록이 땅에 떨어지면 블록이 무기한 화면 상단에 나타납니다. 나는 코드를 샅샅이 뒤지며 또한 내 친구에게 보여 주었고 문제를 찾을 수 없었습니다. 코드를 폐기하고 다시 작성하면 문제가 지속됩니다. 여기 누구든지 그것을 볼 수 있습니까?

감사합니다.

P. 코드의 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으로 충돌 감지를 주석 처리하고 연속 스폰이 중단되었습니다. 다음 단계는 setblocks 및 fallingblocks의 rect를 인쇄하는 것이 었으며 rect의 y-pos는 항상 0 또는 25이며 변경되지 않았 음이 밝혀졌습니다. fall 메서드에서 이동 코드를 살펴보면 rect가 이동하지 않는다는 것을 알 수 있습니다.

더 많은 문제가 있지만 먼저 디버깅을 계속하고 문제가 계속되면 새로운 질문을 시도해야한다고 생각합니다.