吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 199|回复: 6
上一主题 下一主题
收起左侧

[原创工具] Python开发的英文打字小游戏

  [复制链接]
跳转到指定楼层
楼主
xhlbudd 发表于 2026-4-17 21:55 回帖奖励
最近在教舅舅家上初二的儿子Python编程,觉得对于男孩来说,用Python开发游戏是一个特别好的方式。因为观察到他之前只用过iPad,用电脑的机会很少,打字很慢,而且不会双手十指分工,所有的字母均使用右手食指盯着键盘输入,看着很让人捉急。因此想着用Python开发一个英文打字小游戏,一是帮助他提高打字速度,二是可以顺便复习英文单词,三是通过这个过程学习Python编程。主要使用的是pygame 2.5.2 (SDL 2.28.3, Python 3.12.6),一共750行代码左右。带背景音乐,正确和错误个数、准确率提示,带计时功能。
下载链接如下(带exe格式的游戏,源代码和音乐素材):
https://pan.baidu.com/s/1bKw7-wZknEO9MhokfvhybA?pwd=52pj

同时把源代码分享如下,请大家多多指教:
[Python] 纯文本查看 复制代码
import pygame
import random
import math
import sys
import os
from pygame.locals import *

folder_name = os.path.dirname(__file__)
bg_music = os.path.join(folder_name, '丛林.ogg')

# 初始化Pygame
pygame.init()

pygame.mixer.init()
pygame.mixer.music.load(bg_music)
pygame.mixer.music.play(-1)

# 游戏窗口设置
WIDTH, HEIGHT = 1000, 700
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("Let's Type")

# 颜色定义
BACKGROUND = (10, 10, 30)  # 深蓝色背景
STAR_COLORS = [
    (255, 255, 200),  # 亮黄色
    (200, 220, 255),  # 淡蓝色
    (255, 220, 180),  # 淡橙色
    (220, 255, 220),  # 淡绿色
]
TEXT_COLOR = (240, 240, 255)  # 亮白色
CORRECT_COLOR = (100, 255, 150)  # 绿色
INCORRECT_COLOR = (255, 100, 100)  # 红色
INPUT_COLOR = (255, 255, 200)  # 黄色
STATS_COLOR = (180, 220, 255)  # 淡蓝色
PROGRESS_COLOR = (100, 200, 255)  # 蓝色
HINT_COLOR = (200, 200, 255)  # 淡紫色
BUTTON_COLORS = {
    "normal": (60, 100, 180),
    "hover": (80, 140, 220),
    "pressed": (40, 80, 160)
}

# 常用300个英文单词(初中水平)及其中文释义
WORD_LIST = [
    ("the", "这个"), ("be", "是"), ("and", "和"), ("of", "...的"), ("a", "一个"),
    ("to", "到"), ("in", "在...里"), ("have", "有"), ("it", "它"), 
    ("that", "那个"), ("for", "为了"), ("you", "你"), ("he", "他"), ("with", "和...一起"),
    ("on", "在...上"), ("do", "做"), ("say", "说"), ("this", "这个"), ("they", "他们"),
    ("at", "在"), ("but", "但是"), ("we", "我们"), ("his", "他的"), ("from", "从"),
    ("not", "不"), ("by", "被"), ("she", "她"), ("or", "或者"), ("as", "如同"),
    ("what", "什么"), ("go", "去"), ("their", "他们的"), ("can", "能"), ("who", "谁"),
    ("get", "得到"), ("if", "如果"), ("would", "将"), ("her", "她的"), ("all", "所有"),
    ("my", "我的"), ("make", "制作"), ("about", "关于"), ("know", "知道"), ("will", "将"),
    ("up", "向上"), ("one", "一个"), ("time", "时间"), ("there", "那里"), ("year", "年"),
    ("so", "所以"), ("think", "想"), ("when", "当...时"), ("which", "哪一个"), ("them", "他们"),
    ("some", "一些"), ("me", "我"), ("people", "人们"), ("take", "拿"), ("out", "出去"),
    ("into", "进入"), ("just", "刚刚"), ("see", "看见"), ("him", "他"), ("your", "你的"),
    ("come", "来"), ("could", "能够"), ("now", "现在"), ("than", "比"), ("like", "喜欢"),
    ("other", "其他"), ("how", "如何"), ("then", "然后"), ("its", "它的"), ("our", "我们的"),
    ("two", "两个"), ("more", "更多"), ("these", "这些"), ("want", "想要"), ("way", "方式"),
    ("look", "看"), ("first", "第一"), ("also", "也"), ("new", "新的"), ("because", "因为"),
    ("day", "天"), ("use", "使用"), ("man", "男人"), ("find", "找到"), ("water", "水"),
    ("been", "曾经"), ("call", "呼叫"), ("oil", "油"), ("now", "现在"), ("find", "发现"),
    ("long", "长的"), ("down", "向下"), ("day", "白天"), ("did", "做了"), ("get", "得到"),
    ("come", "来"), ("made", "制造了"), ("may", "可能"), ("part", "部分"), ("over", "超过"),
    ("new", "新的"), ("sound", "声音"), ("take", "拿"), ("only", "只有"), ("little", "小的"),
    ("work", "工作"), ("know", "知道"), ("place", "地方"), ("year", "年"), ("live", "生活"),
    ("me", "我"), ("back", "后面"), ("give", "给"), ("most", "大多数"), ("very", "非常"),
    ("after", "之后"), ("thing", "事情"), ("our", "我们的"), ("just", "只是"), ("name", "名字"),
    ("good", "好的"), ("sentence", "句子"), ("man", "男人"), ("think", "认为"), ("say", "说"),
    ("great", "伟大的"), ("where", "哪里"), ("help", "帮助"), ("through", "通过"), ("much", "很多"),
    ("before", "之前"), ("line", "线"), ("right", "正确"), ("too", "也"), ("mean", "意思"),
    ("old", "老的"), ("any", "任何"), ("same", "相同的"), ("tell", "告诉"), ("boy", "男孩"),
    ("follow", "跟随"), ("came", "来了"), ("want", "想要"), ("show", "展示"), ("around", "周围"),
    ("form", "形式"), ("three", "三"), ("small", "小的"), ("set", "设置"), ("put", "放"),
    ("end", "结束"), ("does", "做"), ("another", "另一个"), ("well", "好"), ("large", "大的"),
    ("must", "必须"), ("big", "大的"), ("even", "甚至"), ("such", "这样的"), ("turn", "转"),
    ("here", "这里"), ("why", "为什么"), ("ask", "问"), ("went", "去了"), ("men", "男人们"),
    ("read", "读"), ("need", "需要"), ("land", "土地"), ("different", "不同的"), ("home", "家"),
    ("us", "我们"), ("move", "移动"), ("try", "尝试"), ("kind", "种类"), ("hand", "手"),
    ("picture", "图片"), ("again", "再次"), ("change", "改变"), ("off", "离开"), ("play", "玩"),
    ("spell", "拼写"), ("air", "空气"), ("away", "离开"), ("animal", "动物"), ("house", "房子"),
    ("point", "点"), ("page", "页面"), ("letter", "信"), ("mother", "母亲"), ("answer", "答案"),
    ("found", "发现"), ("study", "学习"), ("still", "仍然"), ("learn", "学习"), ("should", "应该"),
    ("world", "世界"), ("high", "高的"), ("every", "每个"), ("near", "近的"),
    ("add", "添加"), ("food", "食物"), ("between", "之间"), ("own", "自己的"), ("below", "下面"),
    ("country", "国家"), ("plant", "植物"), ("last", "最后的"), ("school", "学校"), ("father", "父亲"),
    ("keep", "保持"), ("tree", "树"), ("never", "从不"), ("start", "开始"), ("city", "城市"),
    ("earth", "地球"), ("eye", "眼睛"), ("light", "光"), ("thought", "思想"), ("head", "头"),
    ("under", "下面"), ("story", "故事"), ("saw", "看见"), ("left", "左边"), 
    ("few", "很少"), ("while", "当...时"), ("along", "沿着"), ("might", "可能"), ("close", "关闭"),
    ("something", "某事"), ("seem", "似乎"), ("next", "下一个"), ("hard", "困难的"), ("open", "打开"),
    ("example", "例子"), ("begin", "开始"), ("life", "生活"), ("always", "总是"), ("those", "那些"),
    ("both", "两者"), ("paper", "纸"), ("together", "一起"), ("got", "得到"), ("group", "组"),
    ("often", "经常"), ("run", "跑"), ("important", "重要的"), ("until", "直到"), ("children", "孩子们"),
    ("side", "边"), ("feet", "脚"), ("car", "汽车"), ("mile", "英里"), ("night", "夜晚"),
    ("walk", "走"), ("white", "白色"), ("sea", "海洋"), ("began", "开始"), ("grow", "生长"),
    ("took", "拿了"), ("river", "河流"), ("four", "四"), ("carry", "携带"), ("state", "州"),
    ("once", "一次"), ("book", "书"), ("hear", "听到"), ("stop", "停止"), ("without", "没有"),
    ("second", "第二"), ("later", "后来"), ("miss", "想念"), ("idea", "想法"), ("enough", "足够的"),
    ("eat", "吃"), ("face", "脸"), ("watch", "观看"), ("far", "远的"),
    ("really", "真的"), ("almost", "几乎"), ("let", "让"), ("above", "上面"), ("girl", "女孩"),
    ("sometimes", "有时"), ("mountain", "山"), ("cut", "切"), ("young", "年轻的"), ("talk", "谈话"),
    ("soon", "很快"), ("list", "列表"), ("song", "歌曲"), ("being", "存在"), ("leave", "离开"),
    ("family", "家庭"), ("body", "身体"), ("music", "音乐"), ("color", "颜色"),
    ("stand", "站"), ("sun", "太阳"), ("questions", "问题"), ("fish", "鱼"), ("area", "区域"),
    ("mark", "标记"), ("dog", "狗"), ("horse", "马"), ("birds", "鸟"), ("problem", "问题"),
    ("complete", "完成"), ("room", "房间"), ("knew", "知道"), ("since", "自从"), ("ever", "曾经"),
    ("piece", "片"), ("told", "告诉"), ("usually", "通常"), ("friends", "朋友"),
    ("easy", "容易的"), ("heard", "听到"), ("order", "顺序"), ("red", "红色"), ("door", "门"),
    ("sure", "确定"), ("become", "成为"), ("top", "顶部"), ("ship", "船"), ("across", "穿过"),
    ("today", "今天"), ("during", "在...期间"), ("short", "短的"), ("better", "更好的"), ("best", "最好的"),
    ("however", "然而"), ("low", "低的"), ("hours", "小时"), ("black", "黑色"), ("products", "产品"),
    ("happened", "发生"), ("whole", "整个"), ("measure", "测量"), ("remember", "记住"), ("early", "早的"),
    ("waves", "波浪"), ("reached", "到达"), ("listen", "听"), ("wind", "风"), ("rock", "岩石"),
    ("space", "空间"), ("covered", "覆盖"), ("fast", "快的"), ("several", "几个"), ("hold", "握住"),
    ("himself", "他自己"), ("toward", "朝向"), ("five", "五"), ("step", "步骤"), ("morning", "早晨"),
    ("passed", "经过"), ("vowel", "元音"), ("true", "真的"), ("hundred", "百"), ("against", "反对"),
    ("pattern", "模式"), ("numeral", "数字"), ("table", "桌子"), ("north", "北"), ("slowly", "慢慢地"),
    ("money", "钱"), ("map", "地图"), ("farm", "农场"), ("pulled", "拉"), ("draw", "画"),
    ("voice", "声音"), ("seen", "看见"), ("cold", "冷的"), ("cried", "哭"), ("plan", "计划"),
    ("notice", "注意"), ("south", "南"), ("sing", "唱"), ("war", "战争"), ("ground", "地面"),
    ("fall", "秋天"), ("king", "国王"), ("town", "城镇"), ("unit", "单元"),
    ("figure", "数字"), ("certain", "确定的"), ("field", "田野"), ("travel", "旅行"), ("wood", "木材"),
    ("fire", "火"), ("upon", "在...上"), ("done", "完成"), ("road", "道路"),
    ("half", "一半"), ("ten", "十"), ("fly", "飞"), ("gave", "给"), ("box", "盒子"),
    ("finally", "最后"), ("wait", "等待"), ("correct", "正确的"), ("oh", "哦"), ("quickly", "快速地"),
    ("person", "人"), ("became", "成为"), ("shown", "展示"), ("minutes", "分钟"), ("strong", "强壮的"),
    ("verb", "动词"), ("stars", "星星"), ("front", "前面"), ("feel", "感觉"), ("fact", "事实"),
    ("inches", "英寸"), ("street", "街道"), ("decided", "决定"), ("contain", "包含"), ("course", "课程"),
    ("surface", "表面"), ("produce", "生产"), ("building", "建筑"), ("ocean", "海洋"), ("class", "班级"),
    ("note", "笔记"), ("nothing", "没有东西"), ("rest", "休息"), ("carefully", "小心地"), ("scientists", "科学家"),
    ("inside", "里面"), ("wheels", "轮子"), ("stay", "停留"), ("green", "绿色"), ("known", "知道"),
    ("island", "岛屿"), ("week", "周"), ("less", "更少"), ("machine", "机器"), ("base", "基础"),
    ("ago", "以前"), ("stood", "站"), ("plane", "飞机"), ("system", "系统"), ("behind", "后面"),
    ("ran", "跑"), ("round", "圆的"), ("boat", "船"), ("game", "游戏"), ("force", "力量"),
    ("brought", "带来"), ("understand", "理解"), ("warm", "温暖的"), ("common", "常见的"), ("bring", "带来"),
    ("explain", "解释"), ("dry", "干的"), ("though", "虽然"), ("language", "语言"), ("shape", "形状"),
    ("deep", "深的"), ("thousands", "成千上万"), ("yes", "是的"), ("clear", "清楚的"), ("equation", "方程"),
    ("yet", "尚未"), ("government", "政府"), ("filled", "填满"), ("heat", "热"), ("full", "满的"),
    ("hot", "热的"), ("check", "检查"), ("object", "物体"), ("am", "是"), ("rule", "规则"),
    ("among", "在...中"), ("noun", "名词"), ("power", "力量"), ("cannot", "不能"), ("able", "能够"),
    ("six", "六"), ("size", "大小"), ("dark", "黑暗的"), ("ball", "球"), ("material", "材料"),
    ("special", "特殊的"), ("heavy", "重的"), ("fine", "好的"), ("pair", "一对"), ("circle", "圆圈"),
    ("include", "包括"), ("built", "建造"), ("matter", "物质"), ("square", "正方形"),
    ("syllables", "音节"), ("perhaps", "也许"), ("bill", "账单"), ("felt", "感觉"), ("suddenly", "突然"),
    ("test", "测试"), ("direction", "方向"), ("center", "中心"), ("farmers", "农民"), ("ready", "准备好的"),
    ("anything", "任何东西"), ("divided", "分开"), ("general", "一般的"), ("energy", "能量"), ("subject", "主题"),
    ("moon", "月亮"), ("region", "地区"), ("return", "返回"), ("believe", "相信"),
    ("dance", "跳舞"), ("members", "成员"), ("picked", "捡起"), ("simple", "简单的"), ("cells", "细胞"),
    ("paint", "油漆"), ("mind", "思想"), ("love", "爱"), ("cause", "原因"), ("rain", "雨"),
    ("exercise", "锻炼"), ("eggs", "蛋"), ("train", "火车"), ("blue", "蓝色"), ("wish", "希望"),
    ("drop", "掉落"), ("developed", "发展"), ("window", "窗口"), ("difference", "不同"), ("distance", "距离"),
    ("heart", "心"), ("sit", "坐"), ("sum", "总和"), ("summer", "夏天"), ("wall", "墙"),
    ("forest", "森林"), ("probably", "可能"), ("legs", "腿"), ("sat", "坐"), ("main", "主要的"),
    ("winter", "冬天"), ("wide", "宽的"), ("written", "写的"), ("length", "长度"), ("reason", "原因"),
    ("kept", "保持"), ("interest", "兴趣"), ("arms", "手臂"), ("brother", "兄弟"), ("race", "种族"),
    ("present", "现在"), ("beautiful", "美丽的"), ("store", "商店"), ("job", "工作"), ("edge", "边缘"),
    ("past", "过去"), ("sign", "标志"), ("record", "记录"), ("finished", "完成"), ("discovered", "发现"),
    ("wild", "野生的"), ("happy", "快乐的"), ("beside", "在旁边"), ("gone", "去了"), ("sky", "天空"),
    ("glass", "玻璃"), ("million", "百万"), ("west", "西"), ("lay", "躺"), ("weather", "天气"),
    ("root", "根"), ("instruments", "乐器"), ("meet", "见面"), ("third", "第三"), ("months", "月"),
    ("paragraph", "段落"), ("raised", "举起"), ("represent", "代表"), ("soft", "软的"), ("whether", "是否"),
    ("clothes", "衣服"), ("flowers", "花"), ("shall", "将"), ("teacher", "老师"), ("held", "握住"),
    ("describe", "描述"), ("drive", "驾驶"), ("cross", "穿过"), ("speak", "说话"), ("solve", "解决"),
    ("appear", "出现"), ("metal", "金属"), ("son", "儿子"), ("either", "要么"), ("ice", "冰"),
    ("sleep", "睡觉"), ("village", "村庄"), ("factors", "因素"), ("result", "结果"), ("jumped", "跳"),
    ("snow", "雪"), ("ride", "骑"), ("care", "关心"), ("floor", "地板"), ("hill", "山"),
    ("pushed", "推"), ("baby", "婴儿"), ("buy", "买"), ("century", "世纪"), ("outside", "外面"),
    ("everything", "每件事"), ("tall", "高的"), ("already", "已经"), ("instead", "代替"), ("phrase", "短语"),
    ("soil", "土壤"), ("bed", "床"), ("copy", "复制"), ("free", "自由的"), ("hope", "希望"),
    ("spring", "春天"), ("case", "案例"), ("laughed", "笑"), ("nation", "国家"), ("quite", "相当"),
    ("type", "类型"), ("themselves", "他们自己"), ("temperature", "温度"), ("bright", "明亮的"), ("lead", "领导"),
    ("everyone", "每个人"), ("method", "方法"), ("section", "部分"), ("lake", "湖"), ("consonant", "辅音"),
    ("within", "在...内"), ("dictionary", "字典"), ("hair", "头发"), ("age", "年龄"), ("amount", "数量"),
    ("scale", "规模"), ("pounds", "磅"), ("although", "虽然"), ("per", "每"), ("broken", "破碎的"),
    ("moment", "时刻"), ("tiny", "微小的"), ("possible", "可能的"), ("gold", "金"), ("milk", "牛奶"),
    ("quiet", "安静的"), ("natural", "自然的"), ("lot", "很多"), ("stone", "石头"), ("act", "行动"),
    ("build", "建造"), ("middle", "中间"), ("speed", "速度"), ("count", "数"), ("cat", "猫"),
    ("someone", "某人"), ("sail", "帆"), ("rolled", "滚动"), ("bear", "熊"), ("wonder", "想知道"),
    ("smiled", "微笑"), ("angle", "角度"), ("fraction", "分数"), ("Africa", "非洲"), ("killed", "杀"),
    ("melody", "旋律"), ("bottom", "底部"), ("trip", "旅行"), ("hole", "洞"), ("poor", "贫穷的"),
    ("fight", "战斗"), ("surprise", "惊讶"), ("died", "死"),
    ("beat", "打"), ("exactly", "确切地"), ("remain", "保持"), ("dress", "衣服"), ("iron", "铁"),
    ("fingers", "手指"), ("row", "行"), ("least", "最少的"), ("catch", "抓住"),
    ("climbed", "爬"), ("wrote", "写"), ("shouted", "喊"), ("continued", "继续"), ("itself", "它自己"),
    ("plains", "平原"), ("gas", "气体"), ("burning", "燃烧"), ("design", "设计"),
    ("joined", "加入"), ("foot", "脚"), ("law", "法律"), ("ears", "耳朵"), ("grass", "草"),
    ("grew", "生长"), ("skin", "皮肤"), ("valley", "山谷"), ("cents", "分"),
    ("key", "钥匙"), ("president", "总统"), ("brown", "棕色"), ("trouble", "麻烦"), ("cool", "酷的"),
    ("cloud", "云"), ("lost", "丢失"), ("sent", "发送"), ("symbols", "符号"), ("wear", "穿"),
    ("bad", "坏的"), ("save", "保存"), ("experiment", "实验"), ("engine", "引擎"), ("alone", "独自"),
    ("drawing", "绘画"), ("east", "东"), ("pay", "支付"), ("single", "单一的"), ("touch", "触摸"),
    ("information", "信息"), ("express", "表达"), ("mouth", "嘴"), ("yard", "院子"), ("equal", "等于"),
    ("decimal", "小数"), ("yourself", "你自己"), ("control", "控制"), ("practice", "练习"), ("report", "报告"),
    ("straight", "直的"), ("rise", "上升"), ("statement", "陈述"), ("stick", "棍子"), ("party", "派对"),
    ("seeds", "种子"), ("suppose", "假设"), ("woman", "女人"), ("coast", "海岸"), ("bank", "银行"),
    ("period", "时期"), ("wire", "电线"), ("choose", "选择"), ("clean", "干净的"), ("visit", "访问"),
    ("bit", "一点"), ("whose", "谁的"), ("received", "收到"), ("garden", "花园"), ("please", "请"),
    ("strange", "奇怪的"), ("caught", "抓住"), ("fell", "掉落"), ("team", "团队"), 
    ("captain", "队长"), ("direct", "直接的"), ("ring", "戒指"), ("serve", "服务"), ("child", "孩子"),
    ("desert", "沙漠"), ("increase", "增加"), ("history", "历史"), ("cost", "成本"), ("maybe", "也许"),
    ("business", "商业"), ("separate", "分开"), ("break", "打破"), ("uncle", "叔叔"), ("hunting", "狩猎"),
    ("flow", "流动"), ("lady", "女士"), ("students", "学生们"), ("human", "人类"), ("art", "艺术"),
    ("feeling", "感觉"), ("supply", "供应"), ("corner", "角落"), ("electric", "电的"), ("insects", "昆虫"),
    ("crops", "庄稼"), ("tone", "音调"), ("hit", "打"), ("sand", "沙"), ("doctor", "医生"),
    ("provide", "提供"), ("thus", "因此"), ("cook", "烹饪"), ("bones", "骨头"),
    ("tail", "尾巴"), ("board", "板"), ("modern", "现代的"), ("compound", "化合物"), ("mine", "我的"),
    ("fit", "适合"), ("addition", "添加"), ("belong", "属于"), ("safe", "安全的"),
    ("soldiers", "士兵们"), ("guess", "猜测"), ("silent", "安静的"), ("trade", "贸易"), ("rather", "宁愿"),
    ("compare", "比较"), ("crowd", "人群"), ("poem", "诗歌"), ("enjoy", "享受"), ("elements", "元素"),
    ("indicate", "指示"), ("except", "除了"), ("expect", "期望"), ("flat", "平的"), ("seven", "七"),
    ("interesting", "有趣的"), ("sense", "感觉"), ("string", "弦"), ("blow", "吹"), ("famous", "著名的"),
    ("value", "价值")
]

# 尝试加载中文字体
def load_font(font_path, size):
    try:
        if os.path.exists(font_path):
            return pygame.font.Font(font_path, size)
    except:
        pass
    return None

# 常见的中文字体路径
chinese_font_paths = [
    "C:/Windows/Fonts/simsun.ttc",  # 宋体
    "C:/Windows/Fonts/simhei.ttf",  # 黑体
    "C:/Windows/Fonts/msyh.ttc",    # 微软雅黑
    "C:/Windows/Fonts/msyhbd.ttc",  # 微软雅黑粗体
    "/System/Library/Fonts/PingFang.ttc",  # macOS 苹方字体
    "/usr/share/fonts/truetype/droid/DroidSansFallbackFull.ttf",  # Linux
]

# 加载字体
font_large = None
font_medium = None
font_small = None
font_tiny = None
font_word = None
font_input = None

# 尝试加载中文字体
for font_path in chinese_font_paths:
    if font_large is None:
        font_large = load_font(font_path, 64)
    if font_medium is None:
        font_medium = load_font(font_path, 48)
    if font_small is None:
        font_small = load_font(font_path, 36)
    if font_tiny is None:
        font_tiny = load_font(font_path, 24)
    if font_word is None:
        font_word = load_font(font_path, 72)
    if font_input is None:
        font_input = load_font(font_path, 56)
    
    # 如果都加载成功了就退出循环
    if all([font_large, font_medium, font_small, font_tiny, font_word, font_input]):
        break

# 如果中文字体加载失败,回退到默认字体
if font_large is None:
    print("警告:未找到中文字体,将使用默认字体(中文可能显示为方框)")
    try:
        font_large = pygame.font.Font(None, 64)
        font_medium = pygame.font.Font(None, 48)
        font_small = pygame.font.Font(None, 36)
        font_tiny = pygame.font.Font(None, 24)
        font_word = pygame.font.Font(None, 72)
        font_input = pygame.font.Font(None, 56)
    except:
        font_large = pygame.font.SysFont(None, 64)
        font_medium = pygame.font.SysFont(None, 48)
        font_small = pygame.font.SysFont(None, 36)
        font_tiny = pygame.font.SysFont(None, 24)
        font_word = pygame.font.SysFont(None, 72)
        font_input = pygame.font.SysFont(None, 56)

# 星星类
class Star:
    def __init__(self):
        self.x = random.randint(0, WIDTH)
        self.y = random.randint(0, HEIGHT)
        self.size = random.uniform(1.0, 3.0)
        self.color = random.choice(STAR_COLORS)
        self.speed = random.uniform(0.1, 0.5)
        self.twinkle_speed = random.uniform(0.01, 0.05)
        self.twinkle = random.random() * math.pi * 2
        self.original_brightness = random.uniform(0.6, 1.0)
        self.current_color = self.color
    
    def update(self):
        # 星星闪烁效果
        self.twinkle += self.twinkle_speed
        brightness = self.original_brightness + 0.2 * math.sin(self.twinkle)
        
        # 确保亮度在0-1之间
        brightness = max(0.2, min(1.0, brightness))
        
        # 计算当前颜色
        self.current_color = (
            int(self.color[0] * brightness),
            int(self.color[1] * brightness),
            int(self.color[2] * brightness)
        )
        
        # 确保颜色值在0-255之间
        self.current_color = (
            max(0, min(255, self.current_color[0])),
            max(0, min(255, self.current_color[1])),
            max(0, min(255, self.current_color[2]))
        )
        
        # 星星缓慢移动
        self.y -= self.speed
        if self.y < 0:
            self.y = HEIGHT
            self.x = random.randint(0, WIDTH)
    
    def draw(self, surface):
        pygame.draw.circle(surface, self.current_color, (int(self.x), int(self.y)), int(self.size))

# 流星类
class ShootingStar:
    def __init__(self):
        self.reset()
    
    def reset(self):
        self.x = random.randint(WIDTH // 2, WIDTH)
        self.y = random.randint(0, HEIGHT // 4)
        self.length = random.randint(20, 60)
        self.speed = random.uniform(8, 15)
        self.angle = random.uniform(2.8, 3.5)  # 弧度
        self.active = True
        self.trail = []
        self.max_trail = 10
    
    def update(self):
        if not self.active:
            if random.random() < 0.005:  # 随机生成新流星
                self.reset()
            return
        
        # 更新位置
        self.x -= self.speed * math.cos(self.angle)
        self.y += self.speed * math.sin(self.angle)
        
        # 记录轨迹
        self.trail.append((self.x, self.y))
        if len(self.trail) > self.max_trail:
            self.trail.pop(0)
        
        # 检查是否飞出屏幕
        if self.x < 0 or self.y > HEIGHT:
            self.active = False
    
    def draw(self, surface):
        if not self.active and not self.trail:
            return
        
        # 绘制流星轨迹
        for i, (trail_x, trail_y) in enumerate(self.trail):
            alpha = int(255 * (i / len(self.trail)))
            if alpha > 0:  # 只绘制可见的轨迹
                # 创建一个临时Surface用于绘制半透明圆
                s = pygame.Surface((6, 6), pygame.SRCALPHA)
                color_with_alpha = (255, 255, 255, alpha)
                pygame.draw.circle(s, color_with_alpha, (3, 3), 3)
                surface.blit(s, (trail_x - 3, trail_y - 3))
        
        # 绘制流星头部
        if self.active:
            pygame.draw.circle(surface, (255, 255, 255), (int(self.x), int(self.y)), 2)

# 按钮类
class Button:
    def __init__(self, x, y, width, height, text, action):
        self.rect = pygame.Rect(x, y, width, height)
        self.text = text
        self.action = action
        self.color = BUTTON_COLORS["normal"]
        self.hovered = False
        self.pressed = False
        self.radius = 15
    
    def draw(self, surface):
        # 绘制按钮背景
        color = BUTTON_COLORS["pressed"] if self.pressed else (BUTTON_COLORS["hover"] if self.hovered else BUTTON_COLORS["normal"])
        pygame.draw.rect(surface, color, self.rect, border_radius=self.radius)
        pygame.draw.rect(surface, (255, 255, 255), self.rect, 2, border_radius=self.radius)
        
        # 绘制按钮文字
        text_surf = font_medium.render(self.text, True, TEXT_COLOR)
        text_rect = text_surf.get_rect(center=self.rect.center)
        surface.blit(text_surf, text_rect)
    
    def check_hover(self, pos):
        self.hovered = self.rect.collidepoint(pos)
        return self.hovered
    
    def handle_event(self, event):
        if event.type == MOUSEBUTTONDOWN and event.button == 1:
            if self.hovered:
                self.pressed = True
                return True
        elif event.type == MOUSEBUTTONUP and event.button == 1:
            if self.pressed and self.hovered:
                self.action()
            self.pressed = False
        return False

# 游戏主类
class TypingGame:
    def __init__(self):
        self.reset_game()
        self.stars = [Star() for _ in range(150)]  # 减少星星数量以提高性能
        self.shooting_stars = [ShootingStar() for _ in range(2)]  # 减少流星数量
        self.buttons = []
        self.create_buttons()
        self.game_state = "menu"  # menu, playing, game_over
    
    def reset_game(self):
        self.current_word_idx = 0
        self.user_input = ""
        self.correct_count = 0
        self.incorrect_count = 0
        self.total_time = 0
        self.start_time = pygame.time.get_ticks()
        self.last_word_time = pygame.time.get_ticks()
        self.word_times = []
        self.accuracy = 100.0
        self.current_words = []
        self.shuffle_words()
        self.get_new_word()
    
    def shuffle_words(self):
        # 随机选择30个单词进行练习
        self.current_words = random.sample(WORD_LIST, 30)
    
    def get_new_word(self):
        if self.current_word_idx < len(self.current_words):
            self.current_word, self.current_meaning = self.current_words[self.current_word_idx]
            self.user_input = ""
            self.last_word_time = pygame.time.get_ticks()
        else:
            self.game_over()
    
    def game_over(self):
        self.game_state = "game_over"
        if self.correct_count + self.incorrect_count > 0:
            self.accuracy = (self.correct_count / (self.correct_count + self.incorrect_count)) * 100
    
    def create_buttons(self):
        button_width, button_height = 200, 60
        center_x = WIDTH // 2
        self.buttons = [
            Button(center_x - button_width // 2, HEIGHT // 2, button_width, button_height, "开始游戏", self.start_game),
            Button(center_x - button_width // 2, HEIGHT // 2 + 100, button_width, button_height, "重新开始", self.restart_game),
            Button(center_x - button_width // 2, HEIGHT // 2 + 200, button_width, button_height, "退出游戏", self.quit_game)
        ]
    
    def start_game(self):
        self.reset_game()
        self.game_state = "playing"
    
    def restart_game(self):
        self.start_game()
    
    def quit_game(self):
        pygame.quit()
        sys.exit()
    
    def handle_input(self, event):
        if self.game_state != "playing":
            for button in self.buttons:
                button.handle_event(event)
            return
        
        if event.type == KEYDOWN:
            if event.key == K_RETURN:  # 回车键提交
                self.check_word()
            elif event.key == K_BACKSPACE:  # 退格键
                self.user_input = self.user_input[:-1]
            elif event.key == K_ESCAPE:  # ESC键返回菜单
                self.game_state = "menu"
            else:  # 普通字符输入
                char = event.unicode
                if char.isalpha():  # 只接受字母
                    self.user_input += char.lower()
    
    def check_word(self):
        if not self.user_input:
            return
        
        current_time = pygame.time.get_ticks()
        time_taken = (current_time - self.last_word_time) / 1000.0
        self.word_times.append(time_taken)
        
        if self.user_input == self.current_word:
            self.correct_count += 1
        else:
            self.incorrect_count += 1
        
        self.current_word_idx += 1
        self.get_new_word()
    
    def update(self):
        # 更新星星
        for star in self.stars:
            star.update()
        
        # 更新流星
        for star in self.shooting_stars:
            star.update()
        
        # 更新游戏时间
        if self.game_state == "playing":
            self.total_time = (pygame.time.get_ticks() - self.start_time) / 1000.0
        
        # 计算准确率
        total = self.correct_count + self.incorrect_count
        if total > 0:
            self.accuracy = (self.correct_count / total) * 100
    
    def draw_background(self, surface):
        # 绘制深蓝色背景
        surface.fill(BACKGROUND)
        
        # 绘制星星
        for star in self.stars:
            star.draw(surface)
        
        # 绘制流星
        for shooting_star in self.shooting_stars:
            shooting_star.draw(surface)
        
        # 绘制标题装饰
        title = "Let's Type"
        title_surf = font_large.render(title, True, TEXT_COLOR)
        title_shadow = font_large.render(title, True, (50, 50, 100))
        
        # 绘制阴影效果
        surface.blit(title_shadow, (WIDTH//2 - title_surf.get_width()//2 + 3, 53))
        surface.blit(title_surf, (WIDTH//2 - title_surf.get_width()//2, 50))
        
        # 绘制装饰线
        line_y = 120
        pygame.draw.line(surface, (100, 150, 255), (WIDTH//2 - 180, line_y), (WIDTH//2 + 180, line_y), 2)
        
        # 绘制星星装饰
        for i in range(5):
            x = WIDTH//2 - 100 + i * 50
            pygame.draw.polygon(surface, (255, 255, 200), [
                (x, line_y - 10),
                (x + 5, line_y - 15),
                (x + 10, line_y - 10),
                (x + 5, line_y - 5)
            ])
    
    def draw_menu(self, surface):
        # 绘制游戏说明
        instructions = [
            "游戏说明:",
            "1. 输入显示的英文单词",
            "2. 按Enter键提交",
            "3. 按ESC键返回菜单",
            "4. 练习300个最常用英文单词"
        ]
        
        for i, line in enumerate(instructions):
            text_surf = font_small.render(line, True, TEXT_COLOR)
            surface.blit(text_surf, (WIDTH//2 - text_surf.get_width()//2, 150 + i * 40))
        
        # 绘制按钮
        for button in self.buttons[:1]:  # 只显示开始游戏按钮
            button.draw(surface)
    
    def draw_game(self, surface):
        # 绘制进度显示
        progress_bg = pygame.Rect(50, 150, WIDTH - 100, 20)
        progress_width = (WIDTH - 100) * (self.current_word_idx / max(len(self.current_words), 1))
        progress_fg = pygame.Rect(50, 150, progress_width, 20)
        pygame.draw.rect(surface, (50, 50, 100), progress_bg, border_radius=10)
        pygame.draw.rect(surface, PROGRESS_COLOR, progress_fg, border_radius=10)
        
        progress_text = f"进度: {self.current_word_idx}/{len(self.current_words)}"
        text_surf = font_small.render(progress_text, True, TEXT_COLOR)
        surface.blit(text_surf, (WIDTH//2 - text_surf.get_width()//2, 120))
        
        # 绘制当前单词
        word_surf = font_word.render(self.current_word, True, TEXT_COLOR)
        word_x = WIDTH//2 - word_surf.get_width()//2
        word_y = 200
        surface.blit(word_surf, (word_x, word_y))
        
        # 绘制中文释义
        meaning_surf = font_medium.render(f"中文: {self.current_meaning}", True, HINT_COLOR)
        surface.blit(meaning_surf, (WIDTH//2 - meaning_surf.get_width()//2, 300))
        
        # 绘制输入框
        input_bg = pygame.Rect(WIDTH//2 - 300, 380, 600, 80)
        pygame.draw.rect(surface, (30, 30, 60), input_bg, border_radius=15)
        pygame.draw.rect(surface, INPUT_COLOR, input_bg, 3, border_radius=15)
        
        input_surf = font_input.render(self.user_input, True, INPUT_COLOR)
        cursor_x = WIDTH//2 - input_surf.get_width()//2
        
        # 绘制输入文本
        surface.blit(input_surf, (cursor_x, 400))
        
        # 绘制闪烁的光标
        if pygame.time.get_ticks() % 1000 < 500:
            cursor_pos = cursor_x + input_surf.get_width() + 5
            pygame.draw.line(surface, INPUT_COLOR, (cursor_pos, 400), (cursor_pos, 440), 3)
        
        # 绘制提示
        hint_text = "输入单词后按Enter键提交,按ESC返回菜单"
        hint_surf = font_tiny.render(hint_text, True, HINT_COLOR)
        surface.blit(hint_surf, (WIDTH//2 - hint_surf.get_width()//2, 480))
        
        # 绘制统计数据
        stats_y = 520
        stats = [
            f"正确: {self.correct_count}",
            f"错误: {self.incorrect_count}",
            f"准确率: {self.accuracy:.1f}%",
            f"用时: {self.total_time:.1f}秒"
        ]
        
        for i, stat in enumerate(stats):
            stat_surf = font_tiny.render(stat, True, STATS_COLOR)
            surface.blit(stat_surf, (100 + i * 220, stats_y))
        
        # 如果已经输入了一些字符,在单词上方显示比对
        if self.user_input:
            for i, (user_char, correct_char) in enumerate(zip(self.user_input, self.current_word)):
                if i >= len(self.current_word):
                    break
                
                # 计算每个字符的位置
                char_color = CORRECT_COLOR if user_char == correct_char else INCORRECT_COLOR
                
                # 渲染字符
                char_surf = font_word.render(user_char, True, char_color)
                
                # 计算这个字符在完整单词中的位置
                # 首先获取从单词开始到这个字符的子字符串
                partial_word = self.current_word[:i]
                partial_surf = font_word.render(partial_word, True, TEXT_COLOR)
                
                # 计算这个字符的x坐标
                char_x = word_x + partial_surf.get_width()
                
                # 在单词上方绘制用户输入的这个字符
                # surface.blit(char_surf, (char_x, word_y - 40))

                # 在单词原本的位置绘制用户输入的这个字符
                surface.blit(char_surf, (char_x, word_y))
                
                # 可选:在字符下方绘制下划线
                if user_char != correct_char:
                    underline_y = word_y - 10
                    pygame.draw.line(surface, INCORRECT_COLOR, 
                                    (char_x, underline_y), 
                                    (char_x + char_surf.get_width(), underline_y), 2)
    
    def draw_game_over(self, surface):
        # 绘制游戏结束界面
        game_over_text = "练习完成!"
        text_surf = font_large.render(game_over_text, True, TEXT_COLOR)
        surface.blit(text_surf, (WIDTH//2 - text_surf.get_width()//2, 200))
        
        # 绘制最终统计
        stats = [
            f"正确单词: {self.correct_count}",
            f"错误单词: {self.incorrect_count}",
            f"最终准确率: {self.accuracy:.1f}%",
            f"总用时: {self.total_time:.1f}秒"
        ]
        
        if self.word_times:
            avg_time = sum(self.word_times) / len(self.word_times)
            stats.append(f"平均每个单词: {avg_time:.2f}秒")
            wpm = (self.correct_count / self.total_time * 60) if self.total_time > 0 else 0
            stats.append(f"打字速度: {wpm:.1f} WPM")
        
        for i, stat in enumerate(stats):
            stat_surf = font_medium.render(stat, True, STATS_COLOR)
            surface.blit(stat_surf, (WIDTH//2 - stat_surf.get_width()//2, 280 + i * 50))
        
        # 绘制按钮
        for button in self.buttons[1:]:  # 显示重新开始和退出按钮
            button.draw(surface)
    
    def draw(self, surface):
        # 绘制背景
        self.draw_background(surface)
        
        # 根据游戏状态绘制不同界面
        if self.game_state == "menu":
            self.draw_menu(surface)
        elif self.game_state == "playing":
            self.draw_game(surface)
        elif self.game_state == "game_over":
            self.draw_game_over(surface)
        
        # 绘制版本信息
        version_text = "英文打字练习 - by xhlbudd@52pojie"
        version_surf = font_tiny.render(version_text, True, HINT_COLOR)
        surface.blit(version_surf, (WIDTH//2 - version_surf.get_width()//2, HEIGHT - 30))

# 主游戏循环
def main():
    game = TypingGame()
    clock = pygame.time.Clock()
    running = True
    
    while running:
        mouse_pos = pygame.mouse.get_pos()
        
        # 处理事件
        for event in pygame.event.get():
            if event.type == QUIT:
                running = False
            elif event.type == KEYDOWN and event.key == K_ESCAPE:
                if game.game_state == "playing":
                    game.game_state = "menu"
                else:
                    running = False
            else:
                game.handle_input(event)
        
        # 更新按钮状态
        for button in game.buttons:
            button.check_hover(mouse_pos)
        
        # 更新游戏状态
        game.update()
        
        # 绘制
        game.draw(screen)
        
        # 更新显示
        pygame.display.flip()
        clock.tick(60)
    
    pygame.quit()
    sys.exit()

if __name__ == "__main__":
    main()

软件界面.png (145.68 KB, 下载次数: 0)

软件界面

软件界面

免费评分

参与人数 2吾爱币 +8 热心值 +2 收起 理由
tiger2019 + 1 + 1 谢谢@Thanks!
风之暇想 + 7 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

沙发
 楼主| xhlbudd 发表于 2026-4-19 15:00 |楼主
谢谢斑竹大大的认可,很高兴小工具被置顶了,以后争取再开发一些小游戏和小工具分享给大家
3#
HuiG 发表于 2026-4-19 19:20
4#
 楼主| xhlbudd 发表于 2026-4-19 23:08 |楼主
HuiG 发表于 2026-4-19 19:20
这个必须给个大大赞

谢谢支持,我以后争取再开发一些好的小游戏、小工具分享给大家~~
5#
chifan6666 发表于 2026-4-20 00:10
这个挺有意思的
6#
chenbin03031 发表于 2026-4-20 09:43
     这个必须给个大大赞
7#
yanjiuseng 发表于 2026-4-20 10:43
蛮有意思的,不过能增加点词汇和词汇语音读出来么?
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - 52pojie.cn ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2026-4-20 15:02

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表