«После» зацикливания бесконечно: никогда не входя в mainloop

Это мой первый пост. Я начал программировать, когда рассматривал возможность карьерного обмена два месяца назад и работаю над клоном тетриса. Я реализовал большинство основных функций, но не могу заставить игру постоянно обновляться с циклом после.

Я использую Tkinter для создания своего графического интерфейса и пробую программирование, ориентированное на события.

Я понимаю, чтоafter(Time, Event) отTkinter следует запланировать всеEvent функция обратного вызова должна выполняться после задержки, указаннойTime, Я думаю, что код должен продолжать выполнять последующие элементы после этого.

Моя функция обновления кадра (game.updateBoard()) выполняет большинство необходимых событий для работы tetris, а затем вызывает себя с помощью after. Я называю это один раз при инициализации экземпляра игры.

Вместо того, чтобы перейти кmainloop(),game.updateboard() функция вызывает себя черезafter на неопределенный срок.

Я подозреваю, что это не так, как я думалafter сработал, который будет продолжать выполнение сценария, пока не произойдет указанная задержка. Я думаю, что ожидание завершения обратного вызова для продолжения.

Я пытался найти ресурс по этому вопросу, но не смог.

Если у вас есть предложения по исправлению этого вопроса, приложенному коду или по кодированию в целом, я очень рад их услышать! Это учебный процесс, и я с удовольствием попробую почти все, что вы предложите.

Вот соответствующая часть кода:

class game():
    def __init__(self): #Set up board and image board
        self.pieces = ["L","J","S","Z","T","O","I"]
        self.board = boardFrame()
        self.root = Tk()
        self.root.title("Tetris")
        self.root.geometry("250x525")

        self.frame = Frame(self.root)

        #set up black and green squares for display
        self.bSquare = "bsquare.gif"
        self.gSquare = "square.gif"
        self.rSquare = "rsquare.gif"
        self.image0 = PhotoImage(file = self.bSquare)
        self.image1 = PhotoImage(file = self.gSquare)
        self.image2 = PhotoImage(file = self.rSquare)

        #get an initial piece to work with
        self.activeBlock = piece(self.pieces[random.randint(0,6)])

        #Tells program to lower block every half second
        self.blockTimer = 0
        self.updateBoard()

        self.root.bind('<KeyPress-Up>', self.turn)
        self.root.bind('<KeyPress-Right>', self.moveR)
        self.root.bind('<KeyPress-Left>', self.moveL)
        self.root.bind('<KeyPress-Down>',self.moveD)
        print("Entering mainloop")
        self.root.mainloop()

    def turn(self, event):
        self.activeBlock.deOccupy(self.board)
        self.activeBlock.turn()
        self.activeBlock.occupy(self.board)
        self.drawGrid(self.board.grid)

    def moveR(self, event):
        self.activeBlock.deOccupy(self.board)
        self.activeBlock.updatePos([1,0], self.board)
        self.activeBlock.occupy(self.board)
        self.drawGrid(self.board.grid)

    def moveL(self, event):
      if self.activeBlock.checkLeft(self.board) == False:
        self.activeBlock.deOccupy(self.board)
        self.activeBlock.updatePos([-1,0], self.board)
        self.activeBlock.occupy(self.board)
        self.drawGrid(self.board.grid)

    def moveD(self, event): #find
        self.activeBlock.deOccupy(self.board)
        self.activeBlock.updatePos([0,-1],self.board)
        if self.activeBlock.checkBottom(self.board) == True:
            self.activeBlock.occupy(self.board)
            self.activeBlock = piece(self.pieces[random.randint(0,6)])
##            self.activeBlock = piece(self.pieces[1])
            print("bottomed")
            self.activeBlock.occupy(self.board)

        self.activeBlock.occupy(self.board)
        self.drawGrid(self.board.grid)

    def drawGrid(self, dGrid):

        #Generate squares to match tetris board
        for widget in self.frame.children.values():
            widget.destroy()

        self.activeBlock.occupy(self.board)

        for x in range(9,-1,-1):
            for y in range(20,-1,-1):
                if self.board.grid[x][y] == 1:
                    self.frame.displayA = Label(self.frame, image=self.image1)
##                    self.frame.displayA.image = self.image1
                    self.frame.displayA.grid(row=21-y, column=x)


                else:
                    self.frame.displayA = Label(self.frame, image = self.image0)
##                    self.frame.displayA.image = self.image0
                    self.frame.displayA.grid(row=21-y, column=x)

        self.frame.displayA = Label(self.frame, image = self.image2)
        self.frame.displayA.grid(row = 21 - self.activeBlock.center[1], column = self.activeBlock.center[0])

        self.frame.grid()

    def updateBoard(self):
        self.blockTimer += 1
        "print updateBoard Loop"

        ## 1)check for keyboard commands
        #1.1 move block by keyboard commands
        #2) see if block has bottomed out, if it has, have it enter itself into the grid and generate a new block.
        if self.activeBlock.checkBottom(self.board) == True:
            self.activeBlock.occupy(self.board)
            self.activeBlock = piece(self.pieces[random.randint(0,6)])
            print("bottomed")
            self.activeBlock.occupy(self.board)

        #2.2 - if block has not bottomed and 50 frames (~.5 seconds) have passed, move the active block down a square after clearing its old space. 
        elif self.blockTimer%12 == 0:
            self.activeBlock.deOccupy(self.board)
            self.activeBlock.updatePos([0,-1], self.board)
            self.activeBlock.occupy(self.board)


    ## 4) check for filled rows
        for y in range(1,21):
            for x in range(10):
                rowFull = True
                if self.board.grid[x][y] == 0:
                    rowFull == False  
            #4.1 if any row is filled, delete it and then move all rows above the deleted row down by one
            if rowFull == True:
                for x2 in range(10):
                    self.board.grid[x2][y] = 0
                    for y2 in range(y+1,21):
                        if self.board.grid[x2][y2] == 1:
                            self.board.grid[x2][y2] = 0
                            self.board.grid[x2][y2-1] = 1

            #4.11 if the row is full and the row above it was full, delete the row again as well as the row above it, and move all rows down by 2
                for x in range(10):
                    rowFull = True
                    if self.board.grid[x][y] == 0:
                        rowFull == False
                        if rowFull == True:
                            for x2 in range(10):
                                try:
                                    self.board.grid[x2][y] = 0
                                    self.board.grid[x2][y+1] = 0
                                except:
                                    pass
                                for y2 in range(y+2,21):
                                    try:
                                        if self.board.grid[x2][y2] == 1:
                                            self.board.grid[x2][y2] = 0
                                            self.board.grid[x2][y2-2] = 1
                                    except:
                                        pass


        #5) if there is a block in the top row, end the game loop
        for x in range(10):
            if self.board.grid[x][20] == 1:
                game = "over"


        #6) update image
        self.activeBlock.occupy(self.board)
        self.drawGrid(self.board.grid)
        self.frame.after(500, self.updateBoard())


Game = game()

Ответы на вопрос(1)

Ваш ответ на вопрос