kaneaston
kaneaston

Reputation: 11

Why doesn't my button work while program is running?

After pressing the start button it runs the program but it will not allow me to use the quit button in the bottom right and im not sure why it does this. Could someone please help. I would like it to keep running the program but still allow me to use the button so if i would like to quit mid way through it will let me. Description of the project: "For my project I will be creating a random maze generation software using python. I will create a grid to be presented to the user. The software will start in the top left then create the maze, going in random directions and eventually finishing in the bottom right."

#importing the pygame Module
import pygame
import sys
from random import randint
from time import sleep

#assigning the dimensions of window
width = 450
height = 450

#setting colours to be used (used rgb values)
black = (0,0,0)#for background of maze
white = (255,255,255)#for colour of grid
red = (255,0,0)#colour for actual maze 
blue = (0,0,255)#colour for backtrack
green = (0,255,0)#will be used to show solution
lightgrey = (170,170,170)#used as colours for buttons
darkgrey = (100,100,100)

def moveup(x,y):
  pygame.draw.rect(SCREEN,red,(x+1,y-w+1,19,39),0)
  pygame.display.update() #moves a square up and makes red

def movedown(x,y): 
  pygame.draw.rect(SCREEN,red,(x+1,y+1,19,39),0)
  pygame.display.update() #moves a square down and makes red

def moveleft(x,y):
  pygame.draw.rect(SCREEN,red,(x-w+1,y+1,39,19),0)
  pygame.display.update() #moves a square left and makes red

def moveright(x,y):
  pygame.draw.rect(SCREEN,red,(x+1,y+1,39,19),0)
  pygame.display.update() #moves a square right and makes red

def backtrack(x,y):
  pygame.draw.rect(SCREEN,red,(x+1,y+1,18,18),0)
  pygame.display.update()#this will change colour of cell back to red to indicate it 
  #going back through cells to find unvisited one

def singlecell(x,y):
  pygame.draw.rect(SCREEN,blue,(x+1,y+1,18,18),0)
  pygame.display.update()#this will change colour of cell to indicate it going back 
  #through cells to find unvisited one

def solutionchange(x,y):
  pygame.draw.rect(SCREEN,green,(x+8,y+8,5,5),0)
  pygame.display.update()#This will add a smaller square to the big square to make a 
  #route
  
def drawgrid(x,y,w):
  for i in range(1,21): #this creates cells from left to right then goes down to next 
  #row.
    x = 20
    y = y+20
    for a in range(1,21):
      pygame.draw.line(SCREEN,white,[x,y],[x+w,y])#top line of cell
      pygame.draw.line(SCREEN,white,[x,y+w],[x,y])#left line of cell
      pygame.draw.line(SCREEN,white,[x+w,y+w],[x,y+w])#bottom line of cell
      pygame.draw.line(SCREEN,white,[x+w,y],[x+w,y+w])#right line of cell
      cell_list.append((x,y))
      x = x + 20

def mazemaker(x,y):
  visited.append((x,y))#adds co-ords to list of cells visited
  cellstack.append((x,y))
  while len(cellstack) > 0:
    sleep(0.05) #adds delay between movements so you can see it being made.
    pickmovecell = []
    if (x+w,y) not in visited and (x+w,y) in cell_list:  #multiple if used and not 
    #elif as if they all true they all need to take place or if some true they all 
    #need take place
      pickmovecell.append("right")
    if (x-w,y) not in visited and (x-w,y) in cell_list:
      pickmovecell.append("left")
    if (x,y-w) not in visited and (x,y-w) in cell_list:#checks if x and y co-ords of 
    #next cell is visited or not
      pickmovecell.append("up")#adds to list that it can move up
    if (x,y+w) not in visited and (x,y+w) in cell_list:
      pickmovecell.append("down")
    if len(pickmovecell) > 0: #this point onwards will pick randomly which direction 
      #to go from available diretions.
      choice = randint(0,len(pickmovecell)-1)
      directionmove = pickmovecell[choice]
      if directionmove == "up": 
        solution[x,y-w] = x,y
        moveup(x,y)
        y = y-w 
        visited.append((x,y)) #This part checks what direction has been picked and 
        #changes x and y co-ords based on it and adds new cell to lists.
        cellstack.append((x,y))
      elif directionmove == "down":
        solution[x,y+w] = x,y
        movedown(x,y)
        y = y+w
        visited.append((x,y))
        cellstack.append((x,y))
      elif directionmove == "left":
        solution[x-w,y] = x,y
        moveleft(x,y)
        x = x-w
        visited.append((x,y))
        cellstack.append((x,y))
      elif directionmove == "right":
        solution[x+w,y] = x,y
        moveright(x,y)
        x = x+w
        visited.append((x,y))
        cellstack.append((x,y))
    else:
      x,y = cellstack.pop()#pop removes last thing added to list this allows me to 
      #make the maze go back
      singlecell(x,y)#calls function to show moving back
      sleep(0.04)
      backtrack(x,y)#calls function to make cells red again
  
def solutionroute(x,y): #This will make it solve the maze and call the colour change 
  #function to add a little dot to indicate solution route
  solutionchange(x,y)
  while (x,y) != (20,20):
    x,y = solution[x,y]
    solutionchange(x,y)
    sleep(0.1)

def menu():
  global SCREEN,x,y,w,cell_list,visited,cellstack,solution
  #maze variables
  x = 0 #x axis
  y = 0#y axis
  w = 20#width of cell
  cell_list = []#contains all x and y values of all cells
  visited = []#This will keep track of all visited cells and order visited in
  cellstack = []#order and cells checked/gone through
  solution = {} #This is a dictionary which means it wont have duplicate coordinates 
  #which a list would allow
  pygame.init() #initalising pygame
  SCREEN = pygame.display.set_mode((width,height))#creates the actual window
  SCREEN.fill(black)#fills the background as black
  smallfont = pygame.font.SysFont('Corbel',35)#sets type of font and size of it
  starttext = smallfont.render('Start' , True , white)#sets what text i want on button 
  #to variable
  quittext = smallfont.render("Quit",True,white)
  while True:
    for ev in pygame.event.get():#if x in top right clicked window shuts down
        if ev.type == pygame.QUIT:
            pygame.quit()
            sys.exit()
        if ev.type == pygame.MOUSEBUTTONDOWN:#Checks if mouse button is clicked
            if 170 <= mouse[0] <= 170+140 and 170 <= mouse[1] <= 170+40:#if button is 
        #clicked it runs start functiom
                start()
        if ev.type == pygame.MOUSEBUTTONDOWN:
            if 170 <= mouse[0] <= 170+140 and 220 <= mouse[1] <= 220+40:#if button is 
             #clicked quits program
              pygame.quit()
              sys.exit()
    mouse = pygame.mouse.get_pos()#Stores the x,y cords of mouse to a variable
    if 170 <= mouse[0] <= 170+140 and 170 <= mouse[1] <= 170+40:#if mouse hovers over 
        #button it changes colour
        pygame.draw.rect(SCREEN,lightgrey,[170,170,140,40])
    else:
        pygame.draw.rect(SCREEN,darkgrey,[170,170,140,40]) 
    if 170 <= mouse[0] <= 170+140 and 220 <= mouse[1] <= 220+40:
        pygame.draw.rect(SCREEN,lightgrey,[170,220,140,40])
    else:
        pygame.draw.rect(SCREEN,darkgrey,[170,220,140,40])
    SCREEN.blit(starttext , (170+35,170+7))#Adds text to the button
    SCREEN.blit(quittext , (170+35,220+7))
    pygame.display.update()#Adds the additons to the window
  
def start():#This function calls all the other functions to make the program work
  SCREEN = pygame.display.set_mode((width,height))#Resets the window so button not 
  #there
  SCREEN.fill(black)#fills the background as black
  smallfont = pygame.font.SysFont('Corbel',25)#sets type of font and size of it
  quittext = smallfont.render("Quit",True,white)
  while True:
    for ev in pygame.event.get():
        if ev.type == pygame.MOUSEBUTTONDOWN:
            if 300 <= mouse[0] <= 300+140 and 425 <= mouse[1] <= 425+20:#if button is 
              #clicked goes back to menu
              pygame.quit() 
              sys.exit()
    mouse = pygame.mouse.get_pos()#Stores the x,y cords of mouse to a variable
    if 300 <= mouse[0] <= 300+140 and 425 <= mouse[1] <= 425+20:
        pygame.draw.rect(SCREEN,lightgrey,[300,425,140,20])
    else:
        pygame.draw.rect(SCREEN,darkgrey,[300,425,140,20])  
    SCREEN.blit(quittext , (300+50,425)) 
    pygame.display.update()       
    x,y = 20,20 #sets start x and y co-ords
    drawgrid(40,0,20) #calls draw grid function
    mazemaker(x,y)#makes maze
    solutionroute(400,400)#calls function to show solution route to user
    sleep(30)#Waits 30 seconds
    menu()#Runs main menu again

menu()

Upvotes: 1

Views: 103

Answers (1)

cookertron
cookertron

Reputation: 198

Change the start() function to the code below. It'll display 'quit' once the maze has finished being built. :)

def start():#This function calls all the other functions to make the program work
  SCREEN = pygame.display.set_mode((width,height))#Resets the window so button not 
  #there
  SCREEN.fill(black)#fills the background as black
  smallfont = pygame.font.SysFont('Corbel',25)#sets type of font and size of it
  quittext = smallfont.render("Quit",True,white)
  drawgrid(40,0,20) #calls draw grid function
  x,y = 20,20 #sets start x and y co-ords
  mazemaker(x,y)#makes maze
  solutionroute(400,400)#calls function to show solution route to user
  while True:
    mouse = pygame.mouse.get_pos()
    for ev in pygame.event.get():
        if ev.type == pygame.MOUSEBUTTONDOWN:
            if 300 <= mouse[0] <= 300+140 and 425 <= mouse[1] <= 425+20:#if button is
              pygame.display.get_surface().fill((0, 0, 0))
              #clicked goes back to menu
              return
    #Stores the x,y cords of mouse to a variable
    if 300 <= mouse[0] <= 300+140 and 425 <= mouse[1] <= 425+20:
        pygame.draw.rect(SCREEN,lightgrey,[300,425,140,20])
    else:
        pygame.draw.rect(SCREEN,darkgrey,[300,425,140,20])  
    SCREEN.blit(quittext , (300+50,425)) 
    pygame.display.update()

Upvotes: 1

Related Questions