I'm very new to python and programming in general. For a school assignment, I made this Memory Game and would love to receive feedback from you guys.
import tkinter as tk # imports tkinter as tk
from tkinter import font as tkfont # imports font as tkfont
import random # imports random
import string # imports string
import sys # imports sys
import time # imports time
import pygame # imports pygame (enables me to use its functions)
pygame.mixer.pre_init(44100, 16, 2, 4096) # Enables me to use music in pygame
pygame.init() # Enables me to use music in pygame
button_click = pygame.mixer.Sound('151022__bubaproducer__laser-shot-silenced.wav')
# Loads '151022__bubaproducer__laser-shot-silenced.wav' file
button_click2 = pygame.mixer.Sound('Mario Coin.wav') # Makes button_click2 play 'Mario Coin.wav' file
pygame.mixer.music.load('merge_from_ofoct.mp3') # Loads my music file
pygame.mixer.music.play(-1) # -1 plays the song infinitely
pygame.mixer.music.set_volume(0.8) # Sets the volume of the music
def logout_logout(): # Defines logout_logout
entUsername.delete(0, tk.END) # Deletes past entry's in the Username entry box
entPassword.delete(0, tk.END) # Deletes past entry's in the Password entry box
entUsername.focus_set() # Makes it so the Username entry box is targeted
def play_music1(): # Defines play_music1
pygame.mixer.music.load('merge_from_ofoct.mp3') # Loads 'merge_from_ofoct.mp3' file
pygame.mixer.music.play(-1) # Makes the song play infinitely
pygame.mixer.music.set_volume(0.8) # Sets the volume (volume can be adjusted from 0-1)
def play_music2(): # Defines play_music2
pygame.mixer.music.load('251461__joshuaempyre__arcade-music-loop.wav')
# Loads '251461__joshuaempyre__arcade-music-loop.wav3' file
pygame.mixer.music.play(-1) # Makes the song play infinitely
pygame.mixer.music.set_volume(0.8) # Sets the volume (volume can be adjusted from 0-1)
def play_music3(): # Defines play_music3
pygame.mixer.music.load('Off Limits.wav') # Loads 'Off Limits.wav') file
pygame.mixer.music.play(-1) # Makes the song play infinitely
pygame.mixer.music.set_volume(0.8) # Sets the volume (volume can be adjusted from 0-1)
def play_music4(): # Defines play_music4
pygame.mixer.music.load('Pim Poy.wav') # Loads 'Pim Poy.wav') file
pygame.mixer.music.play(-1) # Makes the song play infinitely
pygame.mixer.music.set_volume(0.8) # Sets the volume (volume can be adjusted from 0-1)
def play_music5(): # Defines play_music5
pygame.mixer.music.load('Puzzle-Game.mp3') # Loads 'Puzzle-Game.mp3') file
pygame.mixer.music.play(-1) # Makes the song play infinitely
pygame.mixer.music.set_volume(0.8) # Sets the volume (volume can be adjusted from 0-1)
def return_to_main_menu2(): # Defines return_to_main_menu2
pygame.mixer.Sound.play(button_click2).set_volume(0.8) # Plays button_click2/sets the volume of the song
def return_to_main_menu(): # Defines return_to_main_menu
pygame.mixer.Sound.play(button_click).set_volume(0.6) # Plays button_click/sets the volume of the sound
def random_char(y): # Defines random_char
return ''.join(random.choice(string.ascii_letters) for x in range(y))
x = (random_char(6)) # Spawns 6 random characters
word = x # Makes word=x
Class #1
class SampleApp(tk.Tk): # Class - Basically my Main hub
def __init__(self, *args, **kwargs): # Arguments is controller and kwargs are keyword arguments
tk.Tk.__init__(self, *args, **kwargs) # Arguments is controller and kwargs are keyword arguments
self.geometry("1920x1080") # Size of the window when the programs run
self.title("Memory Mania") # Puts "Memory Mania" in the top left of the window
self.title_font = tkfont.Font(family='verdana', size=45, weight="bold", slant="italic")
# Whenever i use use "font=controller.title_font", this font will be used
container = tk.Frame(self) # Defines it
container.pack(side="top", fill="both", expand=True) # Packs it
container.grid_rowconfigure(0, weight=1) # Changes the size
container.grid_columnconfigure(0, weight=1) # Changes the size
self.frames = {} # Below this is all my classes, if the class isn't listed here it wont show
for F in (Login, MainMenu, Tutorial, Tutorial2, Difficulty, Settings, Music, EasyDifficulty, MediumDifficulty,
HardDifficulty, InsaneDifficulty, EnterCharacterScreen, CorrectScreen, IncorrectScreen, Level2,
WinGameScreen):
page_name = F.__name__ # Makes page_name = F._name_
frame = F(parent=container, controller=self) # frame = F(parent=container, controller=self)
self.frames[page_name] = frame # self.frame(page_name) = frame
frame.grid(row=0, column=0, sticky="nsew") # the frames grid size
self.show_frame("Login") # Shows the Login screen as the first screen
def show_frame(self, page_name): # Shows a frame for the given page name
frame = self.frames[page_name] # Makes frame = self.frames(page_name)
frame.tkraise() # Raises the frame
Class #2
class Login(tk.Frame): # Class - My Login screen
def __init__(self, parent, controller): # Defines the window
tk.Frame.__init__(self, parent, bg="#2699C3") # Sets the background as that colour
self.controller = controller # Makes self.controller = controller
background_image = tk.PhotoImage(file="9a4a50632b464e426a71c800f80ad778.png")
background_label = tk.Label(self, image=background_image)
background_label.place(x=0, y=0, relwidth=1, relheight=1)
background_label.image = background_image
def login_button(): # Defines login_button
controller.show_frame("MainMenu"), return_to_main_menu2()
your_username = entUsername.get()
username_label.configure(text=your_username)
# Shows MainMenu and uses return_to_main_menu2 function
def login_button2(event): # Defines login_button2 and marks it as an event
controller.show_frame("MainMenu"), return_to_main_menu2()
your_username = entUsername.get()
username_label.configure(text=your_username)
# Shows MainMenu and uses return_to_main_menu2 function
lbl1 = tk.Label(self, text=" ", fg="white", bg="black") # Bg="#2699C3" is another form of blue
# These labels are used to create blank spaces to centre my program
lbl1.pack() # Packs the label wherever there's space
lbl2 = tk.Label(self, text=" ", fg="white", bg="black") # Changes colour of label
lbl2.pack() # Packs the label wherever there's space
lbl3 = tk.Label(self, text=" ", fg="white", bg="black") # Changes colour of label
lbl3.pack() # Packs the label wherever there's space
lbl4 = tk.Label(self, text=" ", fg="white", bg="black") # Changes colour of label
lbl4.pack() # Packs the label wherever there's space
lbl5 = tk.Label(self, text=" ", fg="white", bg="black") # Changes colour of label
lbl5.pack() # Packs the label wherever there's space
lbl6 = tk.Label(self, text=" ", fg="white", bg="black") # Changes colour of label
lbl6.pack() # Packs the label wherever there's space
lbl7 = tk.Label(self, text=" ", fg="white", bg="black") # Changes colour of label
lbl7.pack() # Packs the label wherever there's space
lbl8 = tk.Label(self, text=" ", fg="white", bg="black") # Changes colour of label
lbl8.pack() # Packs the label wherever there's space
lblUsername = tk.Label(self, text="Username:", fg="white", bg="black") # Makes the Label display Username
lblUsername.place(anchor="center") # Centers the label
global entUsername # Changes entUsername to a global variable (global variables can be used in all classes)
entUsername = tk.Entry(self, justify="center") # Centers the entry box
lblUsername.pack() # Packs it wherever there's space
lblUsername.config(font=("Courier", 32)) # Changes the font/size
entUsername.pack() # Packs it wherever there's space
entUsername.config(font=("Courier", 32)) # Changes the font/size
lblPassword = tk.Label(self, text="Password:", fg="white", bg="black") # Makes the Label display Password
lblPassword.place(anchor="center") # Centers the label
global entPassword # Changes entPassword to a global variable
entPassword = tk.Entry(self, justify="center") # Centers the entry box
lblPassword.pack() # Packs it wherever there's space
lblPassword.config(font=("Courier", 32)) # Changes the font/size
entPassword.pack() # Packs it wherever there's space
entPassword.config(font=("Courier", 32)) # Changes the font/size
entUsername.focus_set()
entPassword.bind("<Return>", login_button2)
btn = tk.Button(self, text="Login", fg="black", bg="lawn green", width=6, height=1, # Changes colour
command=login_button) # Uses login_button function
btn.pack(pady=10) # How many pixels to pad widget, vertically
Class #3
class MainMenu(tk.Frame): # Class - My Main Menu screen
def __init__(self, parent, controller): # Defines the window
tk.Frame.__init__(self, parent, bg="#2699C3") # Sets the background as that colour
self.controller = controller # Makes self.controller = controller
label = tk.Label(self, text="Memory Mania", font=controller.title_font, bg="#2699C3")
# Puts Memory Mania as a large Label
label.pack(side="top", fill="x", pady=10) # Packs the label at the top of the program
global username_label # Makes username_label a global variable
label1 = tk.Label(self, text="Logged in as:", bg="#2699C3") # Changes colour
label1.pack() # Packs the label wherever there's space
username_label = tk.Label(self, text=" ", bg="#2699C3") # Users username is posted here
username_label.pack() # Packs the label wherever there's space
def get_answer2(event):
if entry_characters.get() == word: # Tells program that if the entry of characters = the correct/incorrect
controller.show_frame("CorrectScreen") # Show correct screen (if answer is correct)
else:
controller.show_frame("IncorrectScreen") # Show incorrect screen (if answer is wrong)
def start_game():
pygame.mixer.Sound.play(button_click).set_volume(0.6)
controller.show_frame("Difficulty")
entry_characters.bind("<Return>", get_answer2) # Makes you able to click enter
button1 = tk.Button(self, text="Play", bg="#76EE00", fg="black", height=4, width=20, # Changes colour/size
command=start_game)
# Makes this button take me to the Difficulty screen and uses the 'return_to_main_menu' function
button2 = tk.Button(self, text="Tutorial", bg="yellow", fg="black", height=4, width=20, # Changes colour/size
command=lambda: [controller.show_frame("Tutorial"), return_to_main_menu()])
# Makes this button take me to the Tutorial screen and uses the 'return_to_main_menu function'
button3 = tk.Button(self, text="Settings", bg="#00EEEE", fg="black", height=4, width=20, # Changes colour/size
command=lambda: [controller.show_frame("Settings"), return_to_main_menu()])
# Makes this button take me to the Settings screen and uses the 'return_to_main_menu function'
button4 = tk.Button(self, text="Logout", bg="orange", fg="black", height=4, width=20, # Changes colour/size
command=lambda: [controller.show_frame("Login"), logout_logout()])
# Makes this button take me to the Login screen and uses the 'logout_logout' function
button5 = tk.Button(self, text="Quit", bg="red", fg="black", height=4, width=20, cursor="pirate",
# Changes colour/size/cursor
command=sys.exit)
# Makes this button Quit the program
button1.pack(fill=tk.X, padx=10, pady=10) # How many pixels to pad widget, vertically/horizontally
button1.config(font=("System", 10)) # Changes font/size
button2.pack(fill=tk.X, padx=10, pady=10) # How many pixels to pad widget, vertically/horizontally
button2.config(font=("System", 10)) # Changes font/size
button3.pack(fill=tk.X, padx=10, pady=10) # How many pixels to pad widget, vertically/horizontally
button3.config(font=("System", 10)) # Changes font/size
button4.pack(fill=tk.X, padx=10, pady=10) # How many pixels to pad widget, vertically/horizontally
button4.config(font=("System", 10)) # Changes font/size
button5.pack(fill=tk.X, padx=10, pady=10) # How many pixels to pad widget, vertically/horizontally
button5.config(font=("System", 10)) # Changes font/size
Class #4
class Tutorial(tk.Frame): # Class - My Tutorial screen
def __init__(self, parent, controller): # Defines the window
tk.Frame.__init__(self, parent, bg="#2699C3") # Sets the background as that colour
self.controller = controller # Makes self.controller = controller
# These labels are used to create blank spaces to centre my program
lbl1 = tk.Label(self, text=" ", fg="white", bg="#2699C3") # Changes colour of label
lbl1.pack() # Packs it wherever there's space
lbl2 = tk.Label(self, text=" ", fg="white", bg="#2699C3") # Changes colour of label
lbl2.pack() # Packs it wherever there's space
lbl3 = tk.Label(self, text=" ", fg="white", bg="#2699C3") # Changes colour of label
lbl3.pack() # Packs it wherever there's space
label = tk.Label(self, text="Tutorial (1)", font=controller.title_font, bg="#2699C3") # Changes font/colour
label1 = tk.Label(self, text="Once you click the Play button you will be brought to the Difficulty screen",
bg="#2699C3") # Changes text/colour
label2 = tk.Label(self, text="Once you're in the Difficulty screen, you can select 1 of 4 Difficulties",
bg="#2699C3") # Changes text/colour
label3 = tk.Label(self, text="Easy, Medium, Hard, Insane, all which have 5 levels",
bg="#2699C3") # Changes text/colour
label.pack(side="top", fill="x", pady=10)
# How many pixels to pad widget, vertically/horizontally and at the top
label1.pack(side="top", fill="x", pady=10)
# How many pixels to pad widget, vertically/horizontally
label2.pack(side="top", fill="x", pady=10)
# How many pixels to pad widget, vertically/horizontally
label3.pack(side="top", fill="x", pady=10)
# How many pixels to pad widget, vertically/horizontally
label1.config(font=("System", 14)) # Changes font/size
label2.config(font=("System", 14)) # Changes font/size
label3.config(font=("System", 14)) # Changes font/size
button1 = tk.Button(self, text="Next Page", bg="yellow", fg="black", height=4, width=20,
# Changes colour/size of button
command=lambda: [controller.show_frame("Tutorial2"), return_to_main_menu()])
# Makes this button take me to Tutorial2 screen and uses the 'return_to_main_menu' function
button2 = tk.Button(self, text="Return to Main Menu", bg="yellow", fg="black", height=4, width=20,
# Changes colour/size of button
command=lambda: [controller.show_frame("MainMenu"), return_to_main_menu()])
# Makes this button take me to the Main Menu and uses the 'return_to_main_menu' function
label4 = tk.Label(self, text="Note: Lowercase and Capital letters matter!", bg="#2699C3") # Changes colour
label4.config(font=("System", 10)) # Changes font/size
label4.pack(side="bottom", fill="x", pady=10) # How many pixels to pad widget, vertically/horizontal
button1.pack(fill=tk.X, padx=10, pady=10) # How many pixels to pad widget, vertically/horizontally
button1.config(font=("System", 10)) # Changes font/size
button2.pack(fill=tk.X, padx=10, pady=10) # How many pixels to pad widget, vertically/horizontally
button2.config(font=("System", 10)) # Changes font/size
Class #6
class Difficulty(tk.Frame): # Class - My Difficulty screen
def __init__(self, parent, controller): # Defines the window
tk.Frame.__init__(self, parent, bg="#2699C3") # Sets the background as that colour
self.controller = controller # Makes self.controller = controller
label = tk.Label(self, text="Difficulty", font=controller.title_font, bg="#2699C3") # Changes font/colour
label.pack(side="top", fill="x", pady=10) # How many pixels to pad widget, vertically/horizontally
def wait_fifteen_seconds(): # Defines "wait_fifteen_seconds"
label_check.configure(text="Level 1") # Configures the label to the level specified
global seconds_to_wait # Changes "seconds_to_wait" to a global variable
# Changes "seconds_to_wait" to a global variable meaning you can use it in all classes
seconds_to_wait = 15 # Makes the screen change in 15 seconds
entry_characters.delete(0, tk.END) # Gets rid of the past entry's
x = (random_char(6)) # Generates 6 random characters
global word # Changes "word" to a global variable
word = x # Makes word=x
label2_easy.configure(text=word) # Configures the label to show the "word" variable
controller.show_frame("EasyDifficulty"), return_to_main_menu() # Displays the "EasyDifficulty screen"
entry_characters.pack_forget() # Makes you unable to enter the characters before the screen appears
app.update() # Updates the program
time.sleep(seconds_to_wait) # Makes the program wait for however many seconds depending on difficulty
controller.show_frame("EnterCharacterScreen") # Displays the "EnterCharacterScreen"
entry_characters.pack(fill=tk.X, padx=10, pady=10) # How many pixels to pad widget, vertically/horizontally
button_submit.pack(fill=tk.X, padx=80, pady=80, side=tk.BOTTOM)
# How many pixels to pad widget, vertically/horizontally
entry_characters.focus_set() # Automatically clicks the entry box
def wait_ten_seconds(): # Defines "wait_ten_seconds"
label_check.configure(text="Level 1 ") # Configures the label to the level specified
global seconds_to_wait # Changes "seconds_to_wait" to a global variable
# Changes "seconds_to_wait" to a global variable meaning you can use it in all classes
seconds_to_wait = 10 # Makes the screen change in 10 seconds
entry_characters.delete(0, tk.END) # Gets rid of the past entry's
x = (random_char(6)) # Generates 6 random characters
global word # Changes "word" to a global variable meaning you can use it in all classes
word = x # Makes word=x
label2_medium.configure(text=word) # Configures the label to show the "word" variable
controller.show_frame("MediumDifficulty"), return_to_main_menu() # Displays the "MediumDifficulty screen"
entry_characters.pack_forget() # Makes you unable to enter the characters before the screen appears
app.update() # Updates the program
time.sleep(seconds_to_wait) # Makes the program wait for however many seconds depending on difficulty
controller.show_frame("EnterCharacterScreen") # Displays the "EnterCharacterScreen"
entry_characters.pack(fill=tk.X, padx=10, pady=10) # How many pixels to pad widget, vertically/horizontally
button_submit.pack(fill=tk.X, padx=80, pady=80, side=tk.BOTTOM)
# How many pixels to pad widget, vertically/horizontally
entry_characters.focus_set() # Automatically clicks the entry box
def wait_five_seconds(): # Defines "wait_five_seconds"
label_check.configure(text="Level 1 ") # Configures the label to the level specified
global seconds_to_wait # Changes "seconds_to_wait" to a global variable
# Changes "seconds_to_wait" to a global variable meaning you can use it in all classes
seconds_to_wait = 5 # Makes the screen change in 5 seconds
entry_characters.delete(0, tk.END) # Gets rid of the past entry's
x = (random_char(6)) # Generates 6 random characters
global word # Changes "word" to a global variable meaning you can use it in all classes
word = x # Makes word=x
label2_hard.configure(text=word) # Configures the label to show the "word" variable
controller.show_frame("HardDifficulty"), return_to_main_menu() # Displays the "HardDifficulty screen"
entry_characters.pack_forget() # Makes you unable to enter the characters before the screen appears
app.update() # Updates the program
time.sleep(seconds_to_wait) # Makes the program wait for however many seconds depending on difficulty
controller.show_frame("EnterCharacterScreen") # Displays the "EnterCharacterScreen"
entry_characters.pack(fill=tk.X, padx=10, pady=10) # How many pixels to pad widget, vertically/horizontally
button_submit.pack(fill=tk.X, padx=80, pady=80, side=tk.BOTTOM)
# How many pixels to pad widget, vertically/horizontally
entry_characters.focus_set() # Automatically clicks the entry box
def wait_two_seconds(): # Defines "wait_two_seconds"
label_check.configure(text="Level 1") # Configures the label to the level specified
global seconds_to_wait # Changes "seconds_to_wait" to a global variable
# Changes "seconds_to_wait" to a global variable meaning you can use it in all classes
seconds_to_wait = 2 # Makes the screen change in 2 seconds
entry_characters.delete(0, tk.END) # Gets rid of the past entry's
x = (random_char(6)) # Generates 6 random characters
global word # Changes "word" to a global variable meaning you can use it in all classes
word = x # Makes word=x
label2_insane.configure(text=word) # Configures the label to show the "word" variable
controller.show_frame("InsaneDifficulty"), return_to_main_menu() # Displays the "InsaneDifficulty screen"
entry_characters.pack_forget() # Makes you unable to enter the characters before the screen appears
app.update() # Updates the program
time.sleep(seconds_to_wait) # Makes the program wait for however many seconds depending on difficulty
controller.show_frame("EnterCharacterScreen") # Displays the "EnterCharacterScreen"
entry_characters.pack(fill=tk.X, padx=10, pady=10) # How many pixels to pad widget, vertically/horizontally
button_submit.pack(fill=tk.X, padx=80, pady=80, side=tk.BOTTOM)
# How many pixels to pad widget, vertically/horizontally
entry_characters.focus_set() # Automatically clicks the entry box
button = tk.Button(self, text="Easy", bg="yellow", fg="black", height=4, width=20,
command=wait_fifteen_seconds)
# Makes button wait fifteen seconds/changes text/colour/size
button1 = tk.Button(self, text="Medium", bg="#E99B15", fg="black", height=4, width=20, command=wait_ten_seconds)
# Makes button wait ten seconds/changes text/colour/size
button2 = tk.Button(self, text="Hard", bg="#C04141", fg="black", height=4, width=20, command=wait_five_seconds)
# Makes button wait five seconds/changes text/colour/size
button3 = tk.Button(self, text="Insane", bg="#FC0000", fg="black", height=4, width=20, command=wait_two_seconds)
# Makes button wait two seconds/changes text/colour/size
button4 = tk.Button(self, text="Back", bg="green", fg="black", height=4, width=20,
command=lambda: [controller.show_frame("MainMenu"), return_to_main_menu()])
# Makes this button take me to the MainMenu and uses the 'return_to_main_menu' function
button.pack(fill=tk.X, padx=10, pady=10) # How many pixels to pad widget, vertically/horizontally
button.config(font=("System", 10)) # Changes font/size
button1.pack(fill=tk.X, padx=10, pady=10) # How many pixels to pad widget, vertically/horizontally
button1.config(font=("System", 10)) # Changes font/size
button2.pack(fill=tk.X, padx=10, pady=10) # How many pixels to pad widget, vertically/horizontally
button2.config(font=("System", 10)) # Changes font/size
button3.pack(fill=tk.X, padx=10, pady=10) # How many pixels to pad widget, vertically/horizontally
button3.config(font=("System", 10)) # Changes font/size
button4.pack(fill=tk.X, padx=10, pady=10) # How many pixels to pad widget, vertically/horizontally
button4.config(font=("System", 10)) # Changes font/size
Class #7
class Settings(tk.Frame): # Class - My Settings screen
def __init__(self, parent, controller): # Defines the window
tk.Frame.__init__(self, parent, bg="#2699C3") # Sets the background as that colour
self.controller = controller # Makes self.controller = controller
lbl1 = tk.Label(self, text=" ", fg="white", bg="#2699C3")
lbl1.pack() # Packs the label wherever there's space
lbl2 = tk.Label(self, text=" ", fg="white", bg="#2699C3") # Changes colour of label
lbl2.pack() # Packs the label wherever there's space
lbl3 = tk.Label(self, text=" ", fg="white", bg="#2699C3") # Changes colour of label
lbl3.pack() # Packs the label wherever there's space
label = tk.Label(self, text="Settings", font=controller.title_font, bg="#2699C3") # Changes font/colour
label.pack(side="top", fill="x", pady=10) # How many pixels to pad widget, vertically/horizontally
button1 = tk.Button(self, text="Pause Music", bg="red", fg="white", height=4, width=20, # Changes colour/size
command=pygame.mixer.music.pause)
# Pauses the current song
button2 = tk.Button(self, text="Resume Music", bg="green", fg="white", height=4, width=20, # Colour/size
command=pygame.mixer.music.unpause)
# Resumes the current song
button3 = tk.Button(self, text="Music", bg="yellow", fg="black",
height=4, width=20, # Colour/size
command=lambda: [controller.show_frame("Music"), return_to_main_menu()])
# Makes this button take me to the Music screen and play the 'return_to_main_menu' function
button = tk.Button(self, text="Back", bg="#00EEEE", fg="black", height=4, width=20, # Changes colour/size
command=lambda: [controller.show_frame("MainMenu"), return_to_main_menu()])
# Makes this button take me to the Main Menu and play the 'return_to_main_menu function
label1 = tk.Label(self, text="Note: Music takes a few seconds to start up!", bg="#2699C3") # Changes colour
label1.config(font=("System", 10)) # Changes font/size
label1.pack(side="bottom", fill="x", pady=10) # How many pixels to pad widget, vertically/horizontally
button1.pack(fill=tk.X, padx=10, pady=10) # How many pixels to pad widget, vertically/horizontally
button1.config(font=("System", 10)) # Changes font/size
button2.pack(fill=tk.X, padx=10, pady=10) # How many pixels to pad widget, vertically/horizontally
button2.config(font=("System", 10)) # Changes font/size
button3.pack(fill=tk.X, padx=10, pady=10) # How many pixels to pad widget, vertically/horizontally
button3.config(font=("System", 10)) # Changes font/size
button.pack(fill=tk.X, padx=10, pady=10) # How many pixels to pad widget, vertically/horizontally
button.config(font=("System", 10)) # Changes font/size
Class #8
class Music(tk.Frame): # Class - My Music screen
def __init__(self, parent, controller): # Defines the window
tk.Frame.__init__(self, parent, bg="#2699C3") # Sets the background as that colour
self.controller = controller # Makes self.controller = controller
label = tk.Label(self, text="Music", font=controller.title_font, bg="#2699C3") # Changes font/colour
label.pack(side="top", fill="x", pady=10) # How many pixels to pad widget, vertically/horizontally
button1 = tk.Button(self, text="Soundtrack 1", bg="#0000FF", fg="white", height=4, width=20,
# Changes colour/size
command=play_music1)
# plays the function 'play_music1'
button2 = tk.Button(self, text="Soundtrack 2", bg="#EE3B3B", fg="white", height=4, width=20,
# Changes colour/size
command=play_music2)
# plays the function 'play_music2'
button3 = tk.Button(self, text="Soundtrack 3", bg="#7AC5CD", fg="white", height=4, width=20,
# Changes colour/size
command=play_music3)
# plays the function 'play_music3'
button4 = tk.Button(self, text="Soundtrack 4", bg="#00C957", fg="white", height=4, width=20,
# Changes colour/size
command=play_music4)
# plays the function 'play_music4'
button5 = tk.Button(self, text="Soundtrack 5", bg="#FFB90F", fg="white", height=4, width=20,
# Changes colour/size
command=play_music5)
# plays the function 'play_music5'
button = tk.Button(self, text="Return", bg="#00EEEE", fg="black", height=4, width=20, # Changes colour/size
command=lambda: [controller.show_frame("Settings"), return_to_main_menu()])
button1.pack(fill=tk.X, padx=10, pady=10) # How many pixels to pad widget, vertically/horizontally
button1.config(font=("System", 10)) # Changes font/size
button2.pack(fill=tk.X, padx=10, pady=10) # How many pixels to pad widget, vertically/horizontally
button2.config(font=("System", 10)) # Changes font/size
button3.pack(fill=tk.X, padx=10, pady=10) # How many pixels to pad widget, vertically/horizontally
button3.config(font=("System", 10)) # Changes font/size
button4.pack(fill=tk.X, padx=10, pady=10) # How many pixels to pad widget, vertically/horizontally
button4.config(font=("System", 10)) # Changes font/size
button5.pack(fill=tk.X, padx=10, pady=10) # How many pixels to pad widget, vertically/horizontally
button5.config(font=("System", 10)) # Changes font/size
button.pack(fill=tk.X, padx=10, pady=10) # How many pixels to pad widget, vertically/horizontally
button.config(font=("System", 10)) # Changes font/size
Class #9
class EasyDifficulty(tk.Frame): # Class - My EasyDifficulty screen
def __init__(self, parent, controller): # Defines the window
tk.Frame.__init__(self, parent, bg="#2699C3") # Sets the background as that colour
self.controller = controller # Makes self.controller = controller
label_level = tk.Label(self, text="Level 1", bg="#2699C3") # Changes colour
label_level.pack() # Packs the label wherever there's space
label = tk.Label(self, text="Remember these characters", font=controller.title_font, bg="#2699C3")
# Changes font/colour
label.pack(side="top", fill="x", pady=10) # How many pixels to pad widget, vertically/horizontally
global label2_easy # Global variable
label2_easy = tk.Label(self, height=4, width=15, text=word) # Changes size, text = word
label2_easy.config(font=("Courier", 64)) # Changes font/size
label2_easy.pack() # Packs the label wherever there's space
Class #10
class MediumDifficulty(tk.Frame): # Class - My MediumDifficulty screen
def __init__(self, parent, controller): # Defines the window
tk.Frame.__init__(self, parent, bg="#2699C3") # Sets the background as that colour
self.controller = controller # Makes self.controller = controller
label_level = tk.Label(self, text="Level 1", bg="#2699C3") # Changes colour
label_level.pack() # Packs the label wherever there's space
label = tk.Label(self, text="Remember these characters", font=controller.title_font, bg="#2699C3")
# Changes font/colour
label.pack(side="top", fill="x", pady=10) # How many pixels to pad widget, vertically/horizontally
global label2_medium # Global variable
label2_medium = tk.Label(self, height=4, width=15, text=word) # Changes size, text = word
label2_medium.config(font=("Courier", 64)) # Changes font/size
label2_medium.pack() # Packs the label wherever there's space
Class #11
class HardDifficulty(tk.Frame): # Class - My HardDifficulty screen
def __init__(self, parent, controller): # Defines the window
tk.Frame.__init__(self, parent, bg="#2699C3") # Sets the background as that colour
self.controller = controller # Makes self.controller = controller
label_level = tk.Label(self, text="Level 1", bg="#2699C3") # Changes colour
label_level.pack() # Packs the label wherever there's space
label = tk.Label(self, text="Remember these characters", font=controller.title_font, bg="#2699C3")
# Changes font/colour
label.pack(side="top", fill="x", pady=10) # How many pixels to pad widget, vertically/horizontally
global label2_hard # Global variable
label2_hard = tk.Label(self, height=4, width=15, text=word) # Changes size, text = word
label2_hard.config(font=("Courier", 64)) # Changes font/size
label2_hard.pack() # Packs the label wherever there's space
Class #12
class InsaneDifficulty(tk.Frame): # Class - My InsaneDifficulty screen
def __init__(self, parent, controller): # Defines the window
tk.Frame.__init__(self, parent, bg="#2699C3") # Sets the background as that colour
self.controller = controller # Makes self.controller = controller
label_level = tk.Label(self, text="Level 1", bg="#2699C3") # Changes colour
label_level.pack() # Packs the label wherever there's space
label = tk.Label(self, text="Remember these characters", font=controller.title_font, bg="#2699C3")
# Changes font/colour
label.pack(side="top", fill="x", pady=10) # How many pixels to pad widget, vertically/horizontally
global label2_insane # Global variable
label2_insane = tk.Label(self, height=4, width=15, text=word) # Changes size, text = word
label2_insane.config(font=("Courier", 64)) # Changes font/size
label2_insane.pack() # Packs the label wherever there's space
Class #13
class EnterCharacterScreen(tk.Frame): # Class - My EnterCharacterScreen
def __init__(self, parent, controller): # Defines the window
tk.Frame.__init__(self, parent, bg="#2699C3") # Sets the background as that colour
self.controller = controller # Makes self.controller = controller
# These labels are used to create blank spaces to centre my program
lbl1 = tk.Label(self, text=" ", fg="white", bg="#2699C3") # Changes colour of label
lbl1.pack() # Packs label wherever there's space
lbl2 = tk.Label(self, text=" ", fg="white", bg="#2699C3") # Changes colour of label
lbl2.pack() # Packs label wherever there's space
lbl3 = tk.Label(self, text=" ", fg="white", bg="#2699C3") # Changes colour of label
lbl3.pack() # Packs label wherever there's space
lbl4 = tk.Label(self, text=" ", fg="white", bg="#2699C3") # Changes colour of label
lbl4.pack() # Packs label wherever there's space
lbl5 = tk.Label(self, text=" ", fg="white", bg="#2699C3") # Changes colour of label
lbl5.pack() # Packs label wherever there's space
label = tk.Label(self, text="What were your characters?", font=controller.title_font, bg="#2699C3")
# Changes font/colour
label.pack(side="top", fill="x", pady=10) # How many pixels to pad widget, vertically/horizontally
def get_answer(): # Defines get_answer
if entry_characters.get() == word: # Tells program that if the entry of characters = the correct/incorrect
controller.show_frame("CorrectScreen") # Show correct screen (if answer is correct)
else:
controller.show_frame("IncorrectScreen") # Show incorrect screen (if answer is wrong)
def get_answer2(event): # Defines get_answer (event is needed so users can click enter when submitting)
if entry_characters.get() == word: # Tells program that if the entry of characters = the correct/incorrect
controller.show_frame("CorrectScreen") # Show correct screen (if answer is correct)
else:
controller.show_frame("IncorrectScreen") # Show incorrect screen (if answer is wrong)
global entry_characters # Global variable
entry_characters = tk.Entry(self, justify="center") # Centers the entry
entry_characters.pack(fill=tk.X, padx=10, pady=10) # How many pixels to pad widget, vertically/horizontally
entry_characters.config(font=("Courier", 96)) # Changes the font/size
entry_characters.bind("<Return>", get_answer2) # Makes you able to click enter
global button_submit # Global variable
button_submit = tk.Button(self, text="Submit", command=get_answer, height=4, width=20) # Changes size of button
button_submit.pack(fill=tk.X, padx=10, pady=10) # How many pixels to pad widget, vertically/horizontally
button_submit.config(font=("System", 10)) # Changes the font/size
Class #14
class CorrectScreen(tk.Frame): # Class - My CorrectScreen
def __init__(self, parent, controller): # Defines the window
tk.Frame.__init__(self, parent, bg="green") # Sets the background as that colour
self.controller = controller # Makes self.controller = controller
# These labels are used to create blank spaces to centre my program
lbl1 = tk.Label(self, text=" ", fg="white", bg="green") # Changes colour of label
lbl1.pack() # Packs label wherever there's space
lbl2 = tk.Label(self, text=" ", fg="white", bg="green") # Changes colour of label
lbl2.pack() # Packs label wherever there's space
lbl3 = tk.Label(self, text=" ", fg="white", bg="green") # Changes colour of label
lbl3.pack() # Packs label wherever there's space
lbl4 = tk.Label(self, text=" ", fg="white", bg="green") # Changes colour of label
lbl4.pack() # Packs label wherever there's space
label = tk.Label(self, text="CORRECT!!:)", font=controller.title_font, bg="green") # Changes font/colour
label.pack(side="top", fill="x", pady=10) # How many pixels to pad widget, vertically/horizontally
def next_level_two(): # Defines next_level_two
label_check.configure(text="Level 2") # Shows Level 2 at the top
entry_characters.delete(0, tk.END) # Makes it so last entry's are deleted
x = (random_char(6)) # Displays 6 random characters
global word # Global variable
word = x # Word = x
label2_level2.configure(text=word) # Text=word
entry_characters.delete(0, tk.END) # Makes it so last entry's are deleted
controller.show_frame("Level2") # Shows Level 2 screen
app.update() # Updates program
time.sleep(float(seconds_to_wait)) # Time program waits before changing to next screen
controller.show_frame("EnterCharacterScreen") # Shows EnterCharacterScreen
button_next_screen.configure(command=next_level_three) # Shows Level 3 screen
button_lose.configure(command=difficulty_change) # Shows Difficulty screen
button_tutorial_lose.configure(command=tutorial_show) # Shows Tutorial screen
button_main_lose.configure(command=main_menu) # Shows Main Menu
def next_level_three(): # Defines next_level_three
label_check.configure(text="Level 3") # Shows Level 3 at the top
button_next_screen.configure(command=next_level_four) # Shows Level 4 screen
entry_characters.delete(0, tk.END) # Makes it so last entry's are deleted
x = (random_char(6)) # Displays 6 random characters
global word # Global variable
word = x # Word = x
label2_level2.configure(text=word) # Text=word
entry_characters.delete(0, tk.END) # Makes it so last entry's are deleted
controller.show_frame("Level2") # Shows Level 2 screen
app.update() # Updates program
time.sleep(float(seconds_to_wait)) # Time program waits before changing to next screen
controller.show_frame("EnterCharacterScreen") # Shows EnterCharacterScreen
def next_level_four(): # Defines next_level_four
label_check.configure(text="Level 4") # Shows Level 4 at the top
button_next_screen.configure(command=next_level_five) # Shows Level 5 screen
entry_characters.delete(0, tk.END) # Makes it so last entry's are deleted
x = (random_char(6)) # Displays 6 random characters
global word # Global variable
word = x # Word = x
label2_level2.configure(text=word) # Text=word
entry_characters.delete(0, tk.END) # Makes it so last entry's are deleted
controller.show_frame("Level2") # Shows Level 2 screen
app.update() # Updates program
time.sleep(float(seconds_to_wait)) # Time program waits before changing to next screen
controller.show_frame("EnterCharacterScreen") # Shows EnterCharacterScreen
def next_level_five(): # Defines next_level_five
entry_characters.bind("<Return>", win_game) # Makes you able to click enter
label_check.configure(text="Level 5") # Shows Level 5 at the top
entry_characters.delete(0, tk.END) # Makes it so last entry's are deleted
x = (random_char(6)) # Displays 6 random characters
global word # Global variable
word = x # Word = x
label2_level2.configure(text=word) # Text=word
entry_characters.delete(0, tk.END) # Makes it so last entry's are deleted
controller.show_frame("Level2") # Shows Level 2 screen
app.update() # Updates program
time.sleep(float(seconds_to_wait)) # Time program waits before changing to next screen
controller.show_frame("EnterCharacterScreen") # Shows EnterCharacterScreen
def get_answer_last_screen(): # Defines get_answer_last_screen
if entry_characters.get() == word:
# Tells program that if the entry of characters = the correct/incorrect
controller.show_frame("WinGameScreen") # if answer is correct, WinGameScreen is shown
else:
controller.show_frame("IncorrectScreen") # if answer is incorrect, IncorrectScreen is shown
button_submit.configure(command=get_answer_last_screen)
# Upon pressing button will change screen to either WinGameScreen or IncorrectScreen
global button_next_screen # Global variable
button_next_screen = tk.Button(self, text="Progress to Next Level", bg="white", fg="black", height=4, width=20,
# Changes colour/size
command=next_level_two)
# Uses the 'next_level_two' function
def tutorial_show(): # Defines tutorial_show
button_next_screen.configure(command=next_level_two) # Uses the 'next_level_two' function
controller.show_frame("Tutorial") # Shows Tutorial screen
def main_menu(): # Defines main_menu
entUsername.focus_set() # Makes it so the Username entry box is targeted
button_next_screen.configure(command=next_level_two) # Uses the 'next_level_two' function
controller.show_frame("MainMenu") # Shows MainMenu
def win_game(event): # Activated when user is on level 5
controller.show_frame("WinGameScreen") # Shows the WinGameScreen
def difficulty_change(): # Defines difficulty_change
entUsername.focus_set() # Makes it so the Username entry box is targeted
button_next_screen.configure(command=next_level_two) # Uses the 'next_level_two' function
controller.show_frame("Difficulty") # Shows Difficulty screen
button2 = tk.Button(self, text="Try a different difficulty", bg="white", fg="black", height=4, width=20,
# Changes colour/size
command=difficulty_change)
# Shows Difficulty screen and uses the 'difficulty_change' function
button3 = tk.Button(self, text="Return to Main Menu", bg="white", fg="black", height=4, width=20,
# Changes colour/size
command=main_menu)
# Shows Main Menu and uses the 'main_menu' function
button_next_screen.pack(fill=tk.X, padx=10, pady=10) # How many pixels to pad widget, vertically/horizontally
button_next_screen.config(font=("System", 10)) # Changes font/size
button2.pack(fill=tk.X, padx=10, pady=10) # How many pixels to pad widget, vertically/horizontally
button2.config(font=("System", 10)) # Changes font/size
button3.pack(fill=tk.X, padx=10, pady=10) # How many pixels to pad widget, vertically/horizontally
button3.config(font=("System", 10)) # Changes font/size
Class #15
class IncorrectScreen(tk.Frame): # Class - Incorrect Screen
def __init__(self, parent, controller): # Defines the window
tk.Frame.__init__(self, parent, bg="red") # Sets the background as that colour
self.controller = controller # Makes self.controller = controller
# These labels are used to create blank spaces to centre my program
lbl1 = tk.Label(self, text=" ", fg="white", bg="red") # Changes colour of label
lbl1.pack() # Packs label wherever there's space
lbl2 = tk.Label(self, text=" ", fg="white", bg="red") # Changes colour of label
lbl2.pack() # Packs label wherever there's space
lbl3 = tk.Label(self, text=" ", fg="white", bg="red") # Changes colour of label
lbl3.pack() # Packs label wherever there's space
lbl4 = tk.Label(self, text=" ", fg="white", bg="red") # Changes colour of label
lbl4.pack() # Packs label wherever there's space
label = tk.Label(self, text="INCORRECT!!:C", font=controller.title_font, bg="red") # Changes font/colour
label.pack(side="top", fill="x", pady=10) # How many pixels to pad widget, vertically/horizontally
def retry_lose(): # Defines retry_lose
pygame.mixer.Sound.play(button_click).set_volume(0.6) # Sets the volume of 'button_click' function
controller.show_frame("Difficulty") # Shows Difficulty screen
entUsername.focus_set() # Makes it so the Username entry box is targeted
global button_lose # Global variable
button_lose = tk.Button(self, text="Retry on a different difficulty", bg="white", fg="black", height=4,
# Changes size/colour
width=20, command=retry_lose)
# Shows Difficulty screen and uses the 'retry_lose' function
def tutorial_lose(): # Defines retry_lose
pygame.mixer.Sound.play(button_click).set_volume(0.6) # Sets the volume of 'button_click' function
controller.show_frame("Tutorial") # Shows Tutorial screen
entUsername.focus_set() # Makes it so the Username entry box is targeted
global button_tutorial_lose # Global variable
button_tutorial_lose = tk.Button(self, text="Review How to Play", bg="white", fg="black", height=4, width=20,
# Changes size/colour
command=tutorial_lose)
# Uses the Tutorial screen and uses the 'tutorial_lose' function
global button_main_lose # Global variable
def main_lose(): # Defines main_lose
pygame.mixer.Sound.play(button_click).set_volume(0.6) # Sets the volume of 'button_click' function
controller.show_frame("MainMenu") # Shows MainMenu
entUsername.focus_set() # Makes it so the Username entry box is targeted
button_main_lose = tk.Button(self, text="Return to Main Menu", bg="white", fg="black", height=4, width=20,
# Changes size/colour
command=main_lose)
# Shows MainMenu and uses the 'main_lose' function
button_lose.pack(fill=tk.X, padx=10, pady=10) # How many pixels to pad widget, vertically/horizontally
button_lose.config(font=("System", 10)) # Changes font/size
button_tutorial_lose.pack(fill=tk.X, padx=10, pady=10) # How many pixels to pad widget, vertically/horizontally
button_tutorial_lose.config(font=("System", 10)) # Changes font/size
button_main_lose.pack(fill=tk.X, padx=10, pady=10) # How many pixels to pad widget, vertically/horizontally
button_main_lose.config(font=("System", 10)) # Changes font/size
Class #16
class Level2(tk.Frame): # Class - Level2 Screen
def __init__(self, parent, controller): # Defines the window
tk.Frame.__init__(self, parent, bg="#2699C3") # Sets the background as that colour
self.controller = controller # Makes self.controller = controller
label = tk.Label(self, text="Remember these characters", font=controller.title_font, bg="#2699C3")
# Changes font/colour
global label_check # Global variable
label_check = tk.Label(self, text="Level 1", bg="#2699C3") # Changes colour of label
label_check.pack() # Packs the label wherever there's space
label.pack(side="top", fill="x", pady=10) # How many pixels to pad widget, vertically/horizontally
global label2_level2 # Global variable
label2_level2 = tk.Label(self, height=4, width=15, text=word) # Changes size, text=word
label2_level2.config(font=("Courier", 64)) # Changes font/size
label2_level2.pack() # Packs the label wherever there's space
Class #17
class WinGameScreen(tk.Frame): # Class - WinGameScreen
def __init__(self, parent, controller): # Defines the window
tk.Frame.__init__(self, parent, bg="#2699C3") # Sets the background as that colour
self.controller = controller # Makes self.controller = controller
# These labels are used to create blank spaces to centre my program
background_image2 = tk.PhotoImage(file="videogame-well-done-4k-a-videogame-screen-with-the-text-well-done-8-bit-retro-style-4k_hv0skuloke_thumbnail-full05.png")
background_label2 = tk.Label(self, image=background_image2)
background_label2.place(x=0, y=0, relwidth=1, relheight=1)
background_label2.image = background_image2
lbl1 = tk.Label(self, text=" ", fg="white", bg="black") # Changes colour of label
lbl1.pack() # Packs the label wherever there's space
lbl2 = tk.Label(self, text=" ", fg="white", bg="black") # Changes colour of label
lbl2.pack() # Packs the label wherever there's space
lbl3 = tk.Label(self, text=" ", fg="white", bg="black") # Changes colour of label
lbl3.pack() # Packs the label wherever there's space
lbl4 = tk.Label(self, text=" ", fg="white", bg="black") # Changes colour of label
lbl4.pack() # Packs the label wherever there's space
lbl5 = tk.Label(self, text=" ", fg="white", bg="black") # Changes colour of label
lbl5.pack() # Packs the label wherever there's space
lbl6 = tk.Label(self, text=" ", fg="white", bg="black") # Changes colour of label
lbl6.pack() # Packs the label wherever there's space
lbl7 = tk.Label(self, text=" ", fg="white", bg="black") # Changes colour of label
lbl7.pack() # Packs the label wherever there's space
lbl8 = tk.Label(self, text=" ", fg="white", bg="black") # Changes colour of label
lbl8.pack() # Packs the label wherever there's space
lbl9 = tk.Label(self, text=" ", fg="white", bg="black") # Changes colour of label
lbl9.pack() # Packs the label wherever there's space
lbl10 = tk.Label(self, text=" ", fg="white", bg="black") # Changes colour of label
lbl10.pack() # Packs the label wherever there's space
lbl11 = tk.Label(self, text=" ", fg="white", bg="black") # Changes colour of label
lbl11.pack() # Packs the label wherever there's space
lbl12 = tk.Label(self, text=" ", fg="white", bg="black") # Changes colour of label
lbl12.pack() # Packs the label wherever there's space
lbl13 = tk.Label(self, text=" ", fg="white", bg="black") # Changes colour of label
lbl13.pack() # Packs the label wherever there's space
lbl14 = tk.Label(self, text=" ", fg="white", bg="black") # Changes colour of label
lbl14.pack() # Packs the label wherever there's space
def get_answer_last_screen(): # Defines get_answer_last_screen
if entry_characters.get() == word:
# Tells program that if the entry of characters = the correct/incorrect
controller.show_frame("WinGameScreen") # if answer is correct, WinGameScreen is shown
else:
controller.show_frame("IncorrectScreen") # if answer is incorrect, IncorrectScreen is shown
def get_answer(): # Defines get_answer
if entry_characters.get() == word: # Tells program that if the entry of characters = the correct/incorrect
controller.show_frame("CorrectScreen") # Show correct screen (if answer is correct)
else:
controller.show_frame("IncorrectScreen") # Show incorrect screen (if answer is wrong)
def get_answer2(event): # Defines get_answer
if entry_characters.get() == word: # Tells program that if the entry of characters = the correct/incorrect
controller.show_frame("CorrectScreen") # Show correct screen (if answer is correct)
else:
controller.show_frame("IncorrectScreen") # Show incorrect screen (if answer is wrong)
def tutorial_show(): # Defines tutorial_show
button_next_screen.configure(command=next_level_two) # Uses the 'next_level_two' function
controller.show_frame("Tutorial") # Shows Tutorial screen
def main_menu(): # Defines main_menu
button_next_screen.configure(command=next_level_two) # Uses the 'next_level_two' function
controller.show_frame("MainMenu") # Shows MainMenu
def difficulty_change(): # Defines difficulty_change
button_next_screen.configure(command=next_level_two) # Uses the 'next_level_two' function
controller.show_frame("Difficulty") # Shows Difficulty screen
def next_level_two(): # Defines next_level_two
label_check.configure(text="Level 2") # Shows Level 2 at the top
entry_characters.delete(0, tk.END) # Makes it so last entry's are deleted
x = (random_char(6)) # Displays 6 random characters
global word # Global variable
word = x # Word = x
label2_level2.configure(text=word) # Text=word
entry_characters.delete(0, tk.END) # Makes it so last entry's are deleted
controller.show_frame("Level2") # Shows Level 2 screen
app.update() # Updates program
time.sleep(float(seconds_to_wait)) # Time program waits before changing to next screen
controller.show_frame("EnterCharacterScreen") # Shows EnterCharacterScreen
button_next_screen.configure(command=next_level_three) # Shows Level 3 screen
button_lose.configure(command=difficulty_change) # Shows Difficulty screen
button_tutorial_lose.configure(command=tutorial_show) # Shows Tutorial screen
button_main_lose.configure(command=main_menu) # Shows Main Menu
def next_level_three(): # Defines next_level_three
label_check.configure(text="Level 3") # Shows Level 3 at the top
button_next_screen.configure(command=next_level_four) # Shows Level 4 screen
entry_characters.delete(0, tk.END) # Makes it so last entry's are deleted
x = (random_char(6)) # Displays 6 random characters
global word # Global variable
word = x # Word = x
label2_level2.configure(text=word) # Text=word
entry_characters.delete(0, tk.END) # Makes it so last entry's are deleted
controller.show_frame("Level2") # Shows Level 2 screen
app.update() # Updates program
time.sleep(float(seconds_to_wait)) # Time program waits before changing to next screen
controller.show_frame("EnterCharacterScreen") # Shows EnterCharacterScreen
def next_level_four(): # Defines next_level_four
label_check.configure(text="Level 4") # Shows Level 4 at the top
button_next_screen.configure(command=next_level_five) # Shows Level 5 screen
entry_characters.delete(0, tk.END) # Makes it so last entry's are deleted
x = (random_char(6)) # Displays 6 random characters
global word # Global variable
word = x # Word = x
label2_level2.configure(text=word) # Text=word
entry_characters.delete(0, tk.END) # Makes it so last entry's are deleted
controller.show_frame("Level2") # Shows Level 2 screen
app.update() # Updates program
time.sleep(float(seconds_to_wait)) # Time program waits before changing to next screen
controller.show_frame("EnterCharacterScreen") # Shows EnterCharacterScreen
def next_level_five(): # Defines next_level_five
label_check.configure(text="Level 5")
button_next_screen.configure(command=get_answer_last_screen) # Shows Level 5 at the top
entry_characters.delete(0, tk.END) # Makes it so last entry's are deleted
x = (random_char(6)) # Displays 6 random characters
global word # Global variable
word = x # Word = x
label2_level2.configure(text=word) # Text=word
entry_characters.delete(0, tk.END) # Makes it so last entry's are deleted
controller.show_frame("Level2") # Shows Level 2 screen
app.update() # Updates program
time.sleep(float(seconds_to_wait)) # Time program waits before changing to next screen
controller.show_frame("EnterCharacterScreen") # Shows EnterCharacterScreen
def game_finished(): # Defines game_finished
controller.show_frame("MainMenu"), return_to_main_menu()
# Shows MainMenu and uses the 'return_to_main_menu' function
label_check.configure(text="Level 1") # Shows Level 1 at the top of the screen
label2_easy.configure(text=word) # Configures the label so text=word for the corresponding difficulty
label2_medium.configure(text=word) # Configures the label so text=word for the corresponding difficulty
label2_hard.configure(text=word) # Configures the label so text=word for the corresponding difficulty
label2_insane.configure(text=word) # Configures the label so text=word for the corresponding difficulty
button_submit.configure(command=get_answer) # Uses the 'get_answer' function
button_next_screen.configure(command=next_level_two) # Uses the 'next_level_two function
button1 = tk.Button(self, text="Return to Main Menu", bg="yellow", fg="black", height=2, width=20,
# Changes size/colour
command=game_finished)
# Shows MainMenu and uses the 'game_finished' function
button1.pack(pady=10) # How many pixels to pad widget, vertically/horizontally
button1.config(font=("System", 10)) # Changes font/size
if __name__ == "__main__": # If _name="main":
app = SampleApp() # Makes app = SampleApp
app.mainloop() # Loops the program so it can stay open
-
\$\begingroup\$ There also a class called Tutorial2, which is the second page of it, but due to the limit of characters i was unable to add it in! \$\endgroup\$Zachary– Zachary2018年08月09日 11:10:36 +00:00Commented Aug 9, 2018 at 11:10
-
\$\begingroup\$ I also plan to add a leaderboards, a timer when each difficulty is selected, and an error message to appear if the user enters more than 6 characters or less than 6 (all of these im not sure how to do) \$\endgroup\$Zachary– Zachary2018年08月09日 11:11:20 +00:00Commented Aug 9, 2018 at 11:11
-
\$\begingroup\$ Also if you plan to play this game, youll need to download the corresponding music/images but to test it id just advise you to remove them! \$\endgroup\$Zachary– Zachary2018年08月09日 11:12:25 +00:00Commented Aug 9, 2018 at 11:12
-
2\$\begingroup\$ Please fix your indentation, so that the classes actually contain their methods. Also enumerating your classes is not helpful at all. We all can count. \$\endgroup\$Richard Neumann– Richard Neumann2018年08月09日 11:31:11 +00:00Commented Aug 9, 2018 at 11:31
1 Answer 1
Most of your inline comments are useless
I see lots of comments like this:
def login_button(): # Defines login_button
That comment adds no information. It just adds visual "noise". I recommend removing all comments that simply state what the code does. Comments should explain why, and only if it's not obvious
Group your layout code separately from widget creation
In my experience, grouping all of your layout code together makes the code much easier to read, visualize, and maintain. For example, instead of this:
lbl1 = tk.Label(self, text=" ", fg="white", bg="black") # Changes colour of label
lbl1.pack() # Packs the label wherever there's space
lbl2 = tk.Label(self, text=" ", fg="white", bg="black") # Changes colour of label
lbl2.pack() # Packs the label wherever there's space
lbl3 = tk.Label(self, text=" ", fg="white", bg="black") # Changes colour of label
lbl3.pack() # Packs the label wherever there's space
lbl4 = tk.Label(self, text=" ", fg="white", bg="black") # Changes colour of label
lbl4.pack() # Packs the label wherever there's space
Do it like this:
lbl1 = tk.Label(self, text=" ", fg="white", bg="black")
lbl2 = tk.Label(self, text=" ", fg="white", bg="black")
lbl3 = tk.Label(self, text=" ", fg="white", bg="black")
lbl4 = tk.Label(self, text=" ", fg="white", bg="black")
lbl1.pack()
lbl2.pack()
lbl3.pack()
lbl4.pack()
Don't repeat identical code
There's one section that creates 14 identical labels, and you have two blocks of 14 identical lines of code. In this case it would be much more efficient to use a loop:
labels = []
for i in range(14):
label = (tk.Label(self, text=" ", fg="white", bg="black")
label.pack()
labels.append(label)
This makes your intention much more clear. Whereas before I had to read every line (well, every other line) to try to determine if the labels are identical or not, with the loop it's immediately obvious that I'm creating fourteen identical labels.
Use explicit options to pack
I see a lot of code like this:
lbl1.pack()
I find it to be much easier to understand your code if you add explicit options rather than relying on defaults. This isn't true in all cases, but for things like grid
and pack
where the defaults aren't always obvious, I find it good to be explicit. It's also good to explicitly spell out the fill
and expand
options. That way, as a reviewer I can look at the code and know your intention. When you rely on defaults I'm left wondering if you intended to rely on the defaults or if you forgot to fully configure things.
lbl1.pack(side="top", fill="both", expand=False).
Never use sleep
in the main thread of a GUI
You should never use sleep
because it does exactly that: it sleeps the entire application. That includes things like screen updates and the ability to respond to events.
Instead, move the code that you want to run after the sleep into a function, and call that function with after
.
For example, instead of something like this:
time.sleep(seconds_to_wait) # Makes the program wait for however many seconds depending on difficulty
controller.show_frame("EnterCharacterScreen") # Displays the "EnterCharacterScreen"
entry_characters.pack(fill=tk.X, padx=10, pady=10) # How many pixels to pad widget, vertically/horizontally
button_submit.pack(fill=tk.X, padx=80, pady=80, side=tk.BOTTOM)
# How many pixels to pad widget, vertically/horizontally
entry_characters.focus_set() # Automatically clicks the entry box
... do something similar to this:
def callback():
controller.show_frame("EnterCharacterScreen")
entry_characters.pack(fill=tk.X, padx=10, pady=10)
button_submit.pack(fill=tk.X, padx=80, pady=80, side=tk.BOTTOM)
entry_characters.focus_set() # Automatically clicks the entry box
self.after(seconds_to_wait*1000, callback)
Don't repeat code
Consider this block of code:
def play_music3(): # Defines play_music3
pygame.mixer.music.load('Off Limits.wav') # Loads 'Off Limits.wav') file
pygame.mixer.music.play(-1) # Makes the song play infinitely
pygame.mixer.music.set_volume(0.8) # Sets the volume (volume can be adjusted from 0-1)
def play_music4(): # Defines play_music4
pygame.mixer.music.load('Pim Poy.wav') # Loads 'Pim Poy.wav') file
pygame.mixer.music.play(-1) # Makes the song play infinitely
pygame.mixer.music.set_volume(0.8) # Sets the volume (volume can be adjusted from 0-1)
Those two blocks of code (and the others that follow) are virtually identical except for the .wav file to play and the number added to the function name. Sequential numbers on functions are a huge red flag. You should make this function generic, and have it accept a parameter to tell it which sound to play. The parameter can be an integer, but even better would be a string that represents the logical name of the sound (eg: "soundtrack 1"
, etc).
For example:
soundtracks = {
1: 'Pim Poy.wav',
2: 'Off Limits.wav',
}
def play_soundtrack(music_id):
pygame.mixer.music.load(soundtracks[music_id])
pygame.mixer.music.play(-1)
pygame.mixer.music.set_volume(0.8)
With that, when you need to play a sound it would look like this, which I think is much easier to understand:
play_soundtrack(1)
If the sounds have different settings, you can incorporate all of that into your data structure. For example:
soundtracks = {
1: {"file": "Pim Poy.wav", "volume": 0.8}
...
}