代码解析
 
导入模块和定义单词列表
 
import tkinter as tk
import random
sample_words = [
    "apple", "banana", "cherry", "date", "fig", "grape", 
    "kiwi", "lemon", "mango", "orange", "papaya", "quince", 
    "ugli", "vanilla", "yam"
]
 
- 导入'
tkinter'库用于创建 GUI - 导入'
random'库用于随机选择单词  - 定义'
sample_words'列表包含游戏中可能出现的单词 
 
TypingGame 类的初始化
 
class TypingGame:
    def __init__(self, root):
        self.root = root
        self.root.title("打字练习")  # 修改窗口标题
        self.canvas = tk.Canvas(self.root, width=800, height=600, bg="white")
        self.canvas.pack()
        self.user_input = tk.StringVar()
        self.words = []
        self.labels = []
        self.word_y_positions = []
        self.speed = 2  # 掉落速度
        self.game_over = False  # 游戏状态
        self.create_widgets()
        self.new_round()
 
- 初始化游戏类,设置窗口标题和画布 
 - 创建'
user_input'变量用于存储用户输入 - 初始化'
words'、'labels'和'word_y_positions'列表 - 设置'
speed'变量控制单词下落速度 - 初始化'
game_over'状态 - 调用'
create_widgets'方法创建控件,并开始新一轮游戏 
 
创建控件
 
    def create_widgets(self):
        self.entry = tk.Entry(self.root, textvariable=self.user_input, width=50)
        self.entry.pack(pady=10)
        self.entry.bind("<KeyRelease>", self.check_input)
        self.result_label = tk.Label(self.root, text="", wraplength=400)
        self.result_label.pack(pady=10)
        self.new_round_button = tk.Button(self.root, text="New Round", command=self.new_round)
        self.new_round_button.pack(pady=10)
        # 将输入法锁定为英语
        self.root.bind('<FocusIn>', self.set_english_input)
 
- 创建输入框、结果标签和新一轮按钮,并将它们放置在窗口中
 - 绑定'
KeyRelease'事件到'check_input'方法,监听用户输入 - 绑定'
FocusIn'事件到'set_english_input'方法,以确保输入法锁定为英语 
 
设置输入法为英语
 
    def set_english_input(self, event):
        self.root.tk.call('tk', 'scaling', 1.0)  # 假定的命令以确保输入法锁定为英语
 
 
新一轮游戏
 
    def new_round(self):
        num_words = random.randint(1, 5)  # 随机选择1到5个单词
        self.words = random.sample(sample_words, num_words)  # 选择不重复的单词
        self.user_input.set("")
        self.result_label.config(text="")
        self.word_y_positions = [0 for _ in self.words]
        self.game_over = False
        for label in self.labels:
            self.canvas.delete(label)
        self.labels = []
        used_positions = []
        for word in self.words:
            while True:
                x_position = random.randint(50, 750 - len(word) * 15)  # 确保单词不会超出边界
                y_position = 0
                if not any(abs(x_position - pos[0]) < len(word) * 15 and abs(y_position - pos[1]) < 30 for pos in used_positions):
                    used_positions.append((x_position, y_position))
                    break
            label = self.canvas.create_text(x_position, y_position, text=word, font=("Helvetica", 24), fill="black")
            self.labels.append(label)
        self.entry.config(state='normal')
        self.entry.focus()
        self.drop_words()
 
- 随机选择1到5个不重复的单词
 - 清空输入框和结果标签,重置单词位置和游戏状态
 - 删除旧的标签并创建新的标签,确保单词不会重叠
 - 调用'
drop_words'方法开始单词下落 
 
单词下落
 
    def drop_words(self):
        if not self.game_over:
            for i, label in enumerate(self.labels):
                self.word_y_positions[i] += self.speed
                self.canvas.coords(label, self.canvas.coords(label)[0], self.word_y_positions[i])
                if self.word_y_positions[i] >= 600:
                    self.result_label.config(text=f"Game Over! The word was: {self.words[i]}")
                    self.game_over = True
                    self.entry.config(state='disabled')
                    return
            self.root.after(50, self.drop_words)
 
- 如果游戏未结束,所有单词按速度下落
 - 如果单词下落超过画布高度,显示游戏结束信息并禁用输入框
 - 使用'
root.after'方法定时调用'drop_words'方法实现动画效果 
 
检查用户输入
 
    def check_input(self, event):
        if self.game_over:
            return
        input_text = self.user_input.get()
        for index, word in enumerate(self.words):
            if word.startswith(input_text):
                correct_text = ""
                for i, char in enumerate(input_text):
                    if i < len(word) and char == word[i]:
                        correct_text += char
                    else:
                        break
                remaining_text = word[len(correct_text):]
                self.canvas.itemconfig(self.labels[index], text=f"{correct_text}{remaining_text}")
                self.canvas.itemconfig(self.labels[index], fill="green" if correct_text else "black")
            else:
                self.canvas.itemconfig(self.labels[index], fill="black")
            if input_text == word:
                self.canvas.delete(self.labels[index])
                self.words.pop(index)
                self.labels.pop(index)
                self.word_y_positions.pop(index)
                self.user_input.set("")  # 清空输入框
                if not self.words:
                    self.result_label.config(text="Correct! Starting new round...")
                    self.new_round()
                return
 
- 如果游戏结束,直接返回
 - 获取用户输入并遍历所有单词,检查输入是否与单词开头匹配
 - 将匹配部分的单词变为绿色
 - 如果用户输入完整单词,删除该单词并清空输入框
 - 如果所有单词都被正确输入,开始新一轮游戏
 
 
主程序
 
if __name__ == "__main__":
    root = tk.Tk()
    game = TypingGame(root)
    root.mainloop()
 
- 创建主窗口并实例化'
TypingGame'类 - 进入'
tkinter'主循环,开始游戏 
 
全部代码
 
import tkinter as tk
import random
# 一些示例单词供用户练习
sample_words = [
    "apple", "banana", "cherry", "date", "fig", "grape", 
    "kiwi", "lemon", "mango", "orange", "papaya", "quince", 
    "ugli", "vanilla", "yam"
]
class TypingGame:
    def __init__(self, root):
        self.root = root
        self.root.title("打字练习")  # 修改窗口标题
        self.canvas = tk.Canvas(self.root, width=800, height=600, bg="white")
        self.canvas.pack()
        self.user_input = tk.StringVar()
        self.words = []
        self.labels = []
        self.word_y_positions = []
        self.speed = 2  # 掉落速度
        self.game_over = False  # 游戏状态
        self.create_widgets()
        self.new_round()
    def create_widgets(self):
        self.entry = tk.Entry(self.root, textvariable=self.user_input, width=50)
        self.entry.pack(pady=10)
        self.entry.bind("<KeyRelease>", self.check_input)
        self.result_label = tk.Label(self.root, text="", wraplength=400)
        self.result_label.pack(pady=10)
        self.new_round_button = tk.Button(self.root, text="New Round", command=self.new_round)
        self.new_round_button.pack(pady=10)
        # 将输入法锁定为英语
        self.root.bind('<FocusIn>', self.set_english_input)
    def set_english_input(self, event):
        self.root.tk.call('tk', 'scaling', 1.0)  # 假定的命令以确保输入法锁定为英语,如果需要可以进一步研究具体命令
    def new_round(self):
        num_words = random.randint(1, 5)  # 随机选择1到5个单词
        self.words = random.sample(sample_words, num_words)  # 选择不重复的单词
        self.user_input.set("")
        self.result_label.config(text="")
        self.word_y_positions = [0 for _ in self.words]
        self.game_over = False
        for label in self.labels:
            self.canvas.delete(label)
        self.labels = []
        used_positions = []
        for word in self.words:
            while True:
                x_position = random.randint(50, 750 - len(word) * 15)  # 确保单词不会超出边界
                y_position = 0
                if not any(abs(x_position - pos[0]) < len(word) * 15 and abs(y_position - pos[1]) < 30 for pos in used_positions):
                    used_positions.append((x_position, y_position))
                    break
            label = self.canvas.create_text(x_position, y_position, text=word, font=("Helvetica", 24), fill="black")
            self.labels.append(label)
        self.entry.config(state='normal')
        self.entry.focus()
        self.drop_words()
    def drop_words(self):
        if not self.game_over:
            for i, label in enumerate(self.labels):
                self.word_y_positions[i] += self.speed
                self.canvas.coords(label, self.canvas.coords(label)[0], self.word_y_positions[i])
                if self.word_y_positions[i] >= 600:
                    self.result_label.config(text=f"Game Over! The word was: {self.words[i]}")
                    self.game_over = True
                    self.entry.config(state='disabled')
                    return
            self.root.after(50, self.drop_words)
    def check_input(self, event):
        if self.game_over:
            return
        input_text = self.user_input.get()
        for index, word in enumerate(self.words):
            if word.startswith(input_text):
                correct_text = ""
                for i, char in enumerate(input_text):
                    if i < len(word) and char == word[i]:
                        correct_text += char
                    else:
                        break
                remaining_text = word[len(correct_text):]
                self.canvas.itemconfig(self.labels[index], text=f"{correct_text}{remaining_text}")
                self.canvas.itemconfig(self.labels[index], fill="green" if correct_text else "black")
            else:
                self.canvas.itemconfig(self.labels[index], fill="black")
            if input_text == word:
                self.canvas.delete(self.labels[index])
                self.words.pop(index)
                self.labels.pop(index)
                self.word_y_positions.pop(index)
                self.user_input.set("")  # 清空输入框
                if not self.words:
                    self.result_label.config(text="Correct! Starting new round...")
                    self.new_round()
                return
if __name__ == "__main__":
    root = tk.Tk()
    game = TypingGame(root)
    root.mainloop()