Note that there are some explanatory texts on larger screens.

plurals
  1. PO"after" looping indefinitely: never entering mainloop
    primarykey
    data
    text
    <p>This is my first post. I started coding when considering a career swap two months ago and am working on a Tetris clone. I've implemented most of the core features, but cannot get the game to refresh continually with an after loop. </p> <p>I'm using Tkinter to produce my Gui and am trying out event oriented programming. </p> <p>My understanding is that <code>after(Time, Event)</code> from <code>Tkinter</code> should schedule whatever the <code>Event</code> callback function is to occur after a delay specified by <code>Time</code>. I think that the code is supposed to continue executing subsequent items after this. </p> <p>My frame refresh function (<code>game.updateBoard()</code>) does most of the necessary events for tetris to work, then calls itself using after. I call it once when initializing an instance of the game. </p> <p>Instead of proceeding to <code>mainloop()</code>, the <code>game.updateboard()</code> function calls itself via <code>after</code> indefinitely. </p> <p>I suspect that it is not behaving how I thought <code>after</code> worked which would be to continue to execute the script until the specified delay occurs. I think it is waiting for the callback to terminate to continue. </p> <p>I tried to find a resource on this but could not. </p> <p>If you have suggestions for fixing this question, the attached code, or for coding in general, I am very happy to hear them! This is a learning process and I'll gladly try pretty much anything you suggest.</p> <p>Here is the relevant portion of the code:</p> <pre><code>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('&lt;KeyPress-Up&gt;', self.turn) self.root.bind('&lt;KeyPress-Right&gt;', self.moveR) self.root.bind('&lt;KeyPress-Left&gt;', self.moveL) self.root.bind('&lt;KeyPress-Down&gt;',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() </code></pre>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload