代码解析
导入模块和定义单词列表
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()
本站资源均来自互联网,仅供研究学习,禁止违法使用和商用,产生法律纠纷本站概不负责!如果侵犯了您的权益请与我们联系!
转载请注明出处: 免费源码网-免费的源码资源网站 » Python打字练习
发表评论 取消回复