Hello everyone , In the first part, we have set up the game , Today we will continue the unfinished work , Use code to realize the function of the game , I don't say much nonsense , Let's get started .
Part 1 —— Build the game interface
The next part —— Implementation of background program
In the previous article, I have already introduced the playing method , It's a simple one here , I believe you can understand it as soon as you read it .
screenshots :
In the previous article, we have drawn a flow chart :
Here we review , It can help us understand what custom functions need to be created . In the previous article, we can say that we have finished “ The picture shows ” Part of , The only thing that needs to be supplemented , How to randomly display idiom pictures , After the player has answered correctly , Switch to the next .
Besides , We also need programs or custom functions that perform the following functions :
Let's explain one by one .
Brother Wen downloaded it from the Internet 444 A picture to guess idioms , Upload in here , Or you can ask me for it by private letter .
These pictures have three characteristics :
The first two features are convenient for us to show in the program , No more code to adjust the size and position of the picture . The third feature is more convenient for us to create an idiom database , We just need to put all the idiom pictures in the folder images Next , Then extract the names of all the files in the folder ( The format is xxxx.png), And then choose before 4 A character is our idiom library . When called , We just have to decide on the idiom first , Add... After the idiom .png This is the corresponding picture .
Extract the names of all files in the folder , Need to use Python Another built-in module of os. seeing the name of a thing one thinks of its function , This module is related to the operating system (operation system) dependent . It's easy to use :
import os
filenames = os.listdir(r'images\words')
Just use os In the module listdir Method , You can extract all the file names under the folder , Return a list .( Because brother Wen put the background picture in images Under the folder , So in order to save time , Another one is created below words The folder is specially used to store idiom pictures .)
When you get this list , We can use the list slicing operation , Extract the first four characters of each string , Form a list of idioms .
word_list = [i[:4] for i in filenames]
Of course , We hope that every time we start playing games , Idioms are displayed randomly , So we need to use what we learned before random.shuffle Method to randomly break up these lists , It's like shuffling , Then draw one card from the top or bottom of the stack at a time , It has become an idiom that we let players guess .
import random
random.shuffle(word_list)
In this way, we have created the idiom Library , Initialization is also done ( Shuffle ).
Considering that the action of extracting idioms is to be operated at each level , Therefore, it is more convenient to customize a function for implementation , This saves you from having to write code repeatedly . Here I ask you to name this function create_random_word()
Let's customize a global variable first word, It is used to save the correct idioms extracted by the computer at each level . As the game goes on , We need to constantly change the value of this variable in the custom function ( The idioms extracted each time are different ), So it's best to use it inside a function global Keyword to declare it as a global variable , Avoid the trouble of transferring reference .
Besides , Because during initialization , We've used shuffle Methods to disorder the order of the idiom library , So we don't need to use random method to extract idioms , But directly from the idiom library ( Deck ) Just take one sheet from the top or bottom of the . Brother Wen uses a list pop() Method , That is, from the end of the list ( The bottom of the deck ) Take one , At the same time, the elements in the idiom list are subtracted by one . The code implementation is as follows :
word=''
def create_random_word():
global word
word = word_list.pop()
Now we can draw the pictures corresponding to the randomly selected idioms to Canvas On the canvas .
In the first part , We define the picture statically , Take a look back. :
img = tk.PhotoImage(file=f"images\words\ everything is going smoothly .png")
cv_word = cv.create_image(150,120,image = img)
Now we have custom functions , You need to move these two sentences of code to the user-defined function . however We need to pay attention to Yes. , Draw on Canvas On the canvas img The picture variable needs to be brought into the loop of the main window (mainloop), If it is moved to a custom function and becomes a local variable , Once the program is running, it leaves the custom function , This variable disappears , There are no pictures . therefore , We need to take img Also declared as a global variable .
Can be directly in global Keyword together with the declaration , And separated by commas .
word=''
def create_random_word():
global word, img
word = word_list.pop()
img = tk.PhotoImage(file=f"images\words\{
word}.png")
cv.create_image(150,120,image = img)
Now we can call this function at the end ,( Be careful , Put it on cv.pack() In front of , Otherwise, idiom pictures can't be drawn )
create_random_word()
cv.pack() # Load canvas in main window
root.mainloop() # The main window is displayed circularly
Check to see the effect :
The picture has , There is also a global variable word, Used to represent the correct idiom corresponding to the picture . But we also need to prepare a Chinese character library for players to choose from . In this way, players will be able to select the correct Chinese characters to form idioms .
We define a local list variable lib To represent this font . At the same time, we must make sure that there are correct idioms in the font word, And there are other 4 A random idiom , As a disturbing answer . So we can use it random.sample Methods calculate at random from the rest of the idiom database 4 An idiom , Then use the string splicing method (“join” and “+”) And correct idioms word Form a 20 A string of Chinese characters . And then put this 20 A string of Chinese characters is converted into a list and loaded into lib. Final use random.shuffle Method to scramble the list , To ensure that the font we finally display is out of order . The code is as follows :
def create_random_word():
lib = list(''.join(random.sample(word_list,4))+word)
random.shuffle(lib)
But here's a little problem , We are from “ Deck ”(word_list) Select another at random 4 A proverb , As the game goes on ,“ Deck ” It will be less and less . When there is less than 4 An idiom , This sampling method is bound to report errors , So we must find a way to ensure that even the last idiom , You can also find other 4 A disturbing idiom lib.
If the idiom thesaurus is compared to a pile of cards , We must have another deck list —— Discard pile , So we can consider using the discard pile . Define a new empty list word_copy, Used to collect idioms after each use word. as long as word Not empty ( At the beginning of the game ), Just add the word “ Discard pile ” list word_copy. And then at random , We can “ Discard pile ” and “ Deck ” Choose from these two lists , The problem can be solved . The revised code is as follows :
word=''
word_copy = []
def create_random_word():
global word, img, word_copy
if word: word_copy.append(word)
word = word_list.pop()
lib = list(''.join(random.sample(word_copy+word_list,4))+word)
So we're ready for 20 individual (5 A proverb ) Disordered Chinese characters , Now just put them “ Write ” Just go to the button .
I still remember that we are ready for the last article 20 A bare button ?
for i in range(4):
for j in range(5):
btn = tk.Button(root, font =(' Square regular script, simplified Chinese ',11),width=2,relief='flat',bg='lightyellow')
btn_window = cv.create_window(300+40*i, 75+35*j, window=btn)
And now we can put lib The Chinese characters in the are written on the button , But at that time, the buttons were arranged for convenience , We call all the buttons btn, Now when we want to write different Chinese characters on each button , You must know the name of each button . So we define a list of buttons , Put all the buttons in the list , In this way, different buttons can be referenced through the list index . therefore , This part of the code is modified as follows :
btn = []
for i in range(4):
for j in range(5):
btn.append(tk.Button(root, font =(' Square regular script, simplified Chinese ',11),width=2,relief='flat',bg='lightyellow'))
btn_window = cv.create_window(300+40*i, 75+35*j, window=btn[i*5+j])
Now we can create_random_word The function is here 20 Chinese characters are written on the buttons , Just modify their... In turn text attribute . So finally create_random_word The code of the function is as follows :
word=''
word_copy=[]
def create_random_word():
global word, img, word_copy
if word: word_copy.append(word) # “ Discard pile ”
word = word_list.pop() # Extract new idioms
lib = list(''.join(random.sample(word_copy+word_list,4))+word)
random.shuffle(lib) # Prepare to disturb the font
for i in range(len(btn)):
btn[i]['text'] = lib[i] # Write Chinese characters on the buttons
img = tk.PhotoImage(file=f"images\words\{
word}.png")
cv.create_image(150,120,image = img) # Draw the picture in the designated position
Run to see the effect :
Now we have two questions before us :
Let's start with the 2 A question , Because this is easier to implement .
In the first chapter , The four square grids are actually ordinary rectangles , We can't write in it .
for i in range(4):
cv.create_rectangle(50*i+50,210,50*i+86,246,fill='ivory')
But we can write on them . Suppose that the string variable composed of Chinese characters selected by the player is txt, Then we just use the canvas in the corresponding position create_text Method creation 4 Just a text .
txt = ' One after another '
for i in range(4):
cv.create_text(50*i+68,228,fill='black', text=txt[i], font =(' Square regular script, simplified Chinese ',18,'bold'))
But because we have to change these four texts at any time , So it's better to put them in the array . The code is modified as follows :
txt = ' One after another '
text=[]
for i in range(4):
text.append(cv.create_text(50*i+68,228,fill='black',text=txt[i], font =(' Square regular script, simplified Chinese ',18,'bold')))
Look at the effect :
Next, we just need to change the variable through the button txt The value of . Of course, at the beginning of the game ,txt The value of should be empty (“”).
Now let's take a look at the first question we just mentioned .tkinter You can add one to all the button components of command Parameters , Used to specify the function to be executed after the button is pressed . But the problem is , This command The specified function cannot pass arguments , Our buttons need to perform different actions when pressed ( Add the word on the button to txt in ).
At this time, we can use the method of object-oriented programming , Think of each button as a living object . Each button has its own method , Is to add your name to txt. besides , These buttons also need to be associated with tkinter Of Button Class has the same properties and methods . So we can create a subclass , Inherit tkinter Of Button class . Because you just need to add your own unique method , So there is no need to define initialization , By default, class members use tkinter Of Button Class initialization . The code is as follows :
class MyButton(tk.Button):
def click(self):
global txt
if len(txt)<4: # Judge whether the player has chosen 4 The Chinese characters
txt+=self['text'] # Add the button's own Chinese characters to txt
for i in range(len(txt)):
cv.itemconfig(text[i],text=txt[i]) # Change the content of the text
self.config(state=tk.DISABLED)
self Represents each call click Method . In this way , We need to judge txt Is there already 4 A character. ( Because only 4 The Chinese characters ), If not , Let's just put the Chinese characters on the button (self[‘text’]) Added to the txt in . meanwhile , According to the changing txt, Use canvas Of itemconfig Method to change the text component text Value . In this way, we can achieve the goal of different players' choices , The effect of real-time change of text content . then , When the player selects a Chinese character ( Press a button ), We want that button to be grayed out , So it can be used directly self.config Method to change the state of the button to DISABLED( You can also directly use the dictionary to call ,self[‘state’]=tk.DISABLED).
Last , We just need to change the previously created button to this new subclass , Put the previous cycles together , The code is modified as follows :
txt = ''
text=[]
btn = []
for i in range(4):
cv.create_rectangle(50*i+50,210,50*i+86,246,fill='ivory')
text.append(cv.create_text(50*i+68,228,fill='black', font =(' Square regular script, simplified Chinese ',18,'bold')))
for j in range(5):
btn.append(MyButton(root, font =(' Square regular script, simplified Chinese ',11),width=2,relief='flat',bg='lightyellow'))
btn_window = cv.create_window(300+40*i, 75+35*j, window=btn[i*5+j])
for i in btn:
i['command']=i.click
The effect is as follows :
In the button subclass we just created click In the method , We need to first judge whether the Chinese characters selected by the player have reached 4 individual . If it reaches 4 individual , We need to judge it . So we are click In the method , Add the following code :
if len(txt)==4:
is_winner()
If txt The length of is 4, It means that there is 4 If Chinese characters are selected , call is_winner() Method , To determine whether the player wins , And subsequent operations . So we started writing is_winner() Method , Or call it a custom function .
This user-defined function actually has many functions to realize , Let's draw a partial flow chart to explain .
thus it can be seen , When the player makes the right choice , There are a lot of things to do :
I'll post the code first :
import tkinter.messagebox as tm
def is_winner():
global word, txt, level, word_list
if txt==word:
for i in btn:
i.config(state=tk.DISABLED)
result=tm.askquestion (" Congratulations "," congratulations , bingo ! Continue with the next question ?")
if result == 'yes':
if len(word_list)==0:
newgame = tm.askquestion (" Congratulations ",f' congratulations ! You have passed all {
level} Turn off , Continue to play from scratch ?')
if newgame == 'yes':
word_list = [i[:4] for i in filenames]
random.shuffle(word_list)
level = 0
else:
root.destroy()
level += 1
cv.itemconfig(level_indicator,text=f' The first {
level} Turn off ')
clean_word()
create_random_word()
else:
tm.showinfo(title=' bye ', message=f' You have passed {
level} Turn off ')
root.destroy()
else:
clean_word()
First , In order to achieve windows The effect of the message box , We need to import tkinter Another sub module of messagebox. Use the following statement to import the module , And abbreviated as tm
import tkinter.messagebox as tm
And then you can use it tkinter Several message boxes come with it . In this small game, we only need to use two kinds , One is to ask the player whether to continue , You need to get the player's choice , The other is that you don't need players to choose , Just tell players some information . The former we use is tm Of askquestion Method , The method is different according to the user's choice , Returns a string , Or “yes”, Or “no”.
The latter is just a notification message box , Wait for the player to click “ confirm ” after , The program automatically executes the following commands , That is to say “ The destruction ” main window , Quit the game .
root.destroy()
It should be noted that , If the player really guessed all the idioms , When you choose to start over , You need to put word_list Reinitialize ( Import idioms from file names 、 Random disruption ). At the same time, clear the level count , Counting from the beginning .
Whether you guessed wrong , Or guess right and start a game , You need to call another custom function clean(), Used to put the selected in the text box 4 Chinese characters are cleared .
It is easier to clear the selected custom function , But there are three things to be done :
The code implementation is as follows :
def clean_word():
global txt
txt = ''
for i in range(4):
cv.itemconfig(text[i],text='')
for i in btn:
i.config(state=tk.NORMAL)
At the same time, we have another two buttons in the lower right corner of the game ,“ Empty ” and “ Tips ”. Now we can put the custom function directly clean_word() Bound to the “ Empty ” The button is on .
btn_clean=ttk.Button(root, text=' Empty ', width=5, command=clean_word)
The last step , It's a computer prompt button . In fact, I think this button is a little redundant , Basically, there will be no unpredictable situation . But considering that the game can be changed , For example, do not guess idioms by selecting Chinese characters , Instead, let the player manually input ( Need to increase the Entry Input box or use Label Components ), The difficulty will be greatly increased , In that case, computer prompts may still be useful . So let's do the function first , Do you want to use it .
In fact, it's very simple , Is to choose a Chinese character at random , And then let Canvas Just show the Chinese character in the text box of . So we can define a local variable hint_word, Then use a random function to generate a 0 To 3 The number of , Represents the position of the Chinese character we want to select in the idiom . And then hint_word Just assign a value to the text box .
And don't forget , It is possible for players to guess a word or two and then use the prompt , Such button states may be DISABLED, So we need to restore the state of all buttons here to NORMAL.
The code is as follows :
def hint():
global word
hint_word = ['']*4
i = random.randint(0,3)
hint_word[i] = word[i]
for i in range(4):
cv.itemconfig(text[i],text=hint_word[i])
for i in btn:
i.config(state=tk.NORMAL)
Last , Don't forget to bind this custom function to “ Tips ” On the button .
btn_submit=ttk.Button(root, text=' Tips ', width=5, command=hint)
Come here , Our little game is finished . You might as well share it with your friends .
Attach complete code :
import tkinter as tk
from tkinter import ttk
import tkinter.messagebox as tm
import os
import random
class MyButton(tk.Button):
def click(self):
global txt
if len(txt)<4:
txt+=self['text']
for i in range(len(txt)):
cv.itemconfig(text[i],text=txt[i])
self.config(state=tk.DISABLED)
if len(txt)==4:
is_winner()
def create_random_word():
global word, img, word_copy
if word: word_copy.append(word)
word = word_list.pop()
lib = list(''.join(random.sample(word_copy+word_list,4))+word)
random.shuffle(lib)
for i in range(len(btn)):
btn[i]['text'] = lib[i]
img = tk.PhotoImage(file=f"images\words\{
word}.png")
cv.create_image(150,120,image = img)
def is_winner():
global word, txt, level, word_list
if txt==word:
for i in btn:
i.config(state=tk.DISABLED)
result=tm.askquestion (" Congratulations "," congratulations , bingo ! Continue with the next question ?")
if result == 'yes':
if len(word_list)==0:
newgame = tm.askquestion (" Congratulations ",f' congratulations ! You have passed all {
level} Turn off , Continue to play from scratch ?')
if newgame == 'yes':
word_list = [i[:4] for i in filenames]
random.shuffle(word_list)
level = 0
else:
root.destroy()
level += 1
cv.itemconfig(level_indicator,text=f' The first {
level} Turn off ')
clean_word()
create_random_word()
else:
tm.showinfo(title=' bye ', message=f' You have passed {
level} Turn off ')
root.destroy()
else:
clean_word()
def clean_word():
global txt
txt = ''
for i in range(4):
cv.itemconfig(text[i],text='')
for i in btn:
i.config(state=tk.NORMAL)
def hint():
global word
hint_word = ['']*4
i = random.randint(0,3)
hint_word[i] = word[i]
for i in range(4):
cv.itemconfig(text[i],text=hint_word[i])
for i in btn:
i.config(state=tk.NORMAL)
# The game starts here
filenames = os.listdir(r'images\words')
word_list = [i[:4] for i in filenames]
random.shuffle(word_list)
# Initialization complete
word=''
word_copy=[]
txt = ''
text=[]
btn = []
level=1
# Start to create GUI window
root = tk.Tk()
root.geometry("500x300")
root.resizable(0,0)
root.title(' Look at the picture and guess the idiom ')
cv=tk.Canvas(root,bg='white',width=500,height=300)
bg = tk.PhotoImage(file=r"images\bg.png")
cv_bg = cv.create_image(250,150,image = bg)
title = tk.PhotoImage(file=r"images\title.png")
cv_tt = cv.create_image(250,30,image = title)
cv.create_rectangle(90,60,210,180,fill='moccasin',outline = '')
for i in range(4):
cv.create_rectangle(50*i+50,210,50*i+86,246,fill='ivory')
text.append(cv.create_text(50*i+68,228,fill='black', font =(' Square regular script, simplified Chinese ',18,'bold')))
for j in range(5):
btn.append(MyButton(root, font =(' Square regular script, simplified Chinese ',11),width=2,relief='flat',bg='lightyellow'))
btn_window = cv.create_window(300+40*i, 75+35*j, window=btn[i*5+j])
for i in btn:
i['command']=i.click
btn_clean=ttk.Button(root, text=' Empty ', width=5, command=clean_word)
btn_submit=ttk.Button(root, text=' Tips ', width=5, command=hint)
cv.create_window(320, 265, window=btn_clean)
cv.create_window(400, 265, window=btn_submit)
level_indicator = cv.create_text(150,270,text=f' The first {
level} Turn off ', fill='black', font=(' Microsoft regular script ',9,'bold'))
create_random_word()
cv.pack()
root.mainloop()
After a week of staying up late , Brother Wen finally explained this little game completely . I don't know if it was detailed enough , Is there anything you don't understand ? You are welcome to send me a private message or leave me a message . meanwhile , Through this little game , We also learned Python Built in graphical components tkinter Some basic operations , I hope that if you feel that you have not explained anything thoroughly , You can also learn by searching similar articles on the Internet , Or ask me directly in a private letter .
Thank you for reading here , See you next time !