|
最近在教舅舅家上初二的儿子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 pygameimport randomimport mathimport sysimport osfrom pygame.locals import *folder_name = os.path.dirname(__file__)bg_music = os.path.join(folder_name, '丛林.ogg')# 初始化Pygamepygame.init()pygame.mixer.init()pygame.mixer.music.load(bg_music)pygame.mixer.music.play(-1)# 游戏窗口设置WIDTH, HEIGHT = 1000, 700screen = 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 = Nonefont_medium = Nonefont_small = Nonefont_tiny = Nonefont_word = Nonefont_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() |
重要声明:以上内容仅代表作者七千亿房产老板观点,不代表本站测量协会立场。如有涉及侵权请尽快告知,我们将会在第一时间处理。作者原创内容未经允许不得转载!
站长联系邮箱:1339305021@qq.com
站长联系微信:dddnnbbb
|