引言:为什么"一拍一坠"是青少组上机的高频题
第十八届蓝桥杯全国青少年智能科技创新实践活动(原蓝桥杯青少组,第十八届起升级更名)程序设计组别的省级活动正在 2026 年 10---12 月进行中,其中 Scratch 创意编程组按年龄分初级 U10(7---10 岁)与中级 U14(11---14 岁),统一 90 分钟上机、线下现场个人独立完成,裁判依据完成度与运行效果客观评分。
翻一翻历年青少组上机真题的风格,会发现一大类题目长这样:一个角色受"重力"持续下坠,玩家通过按键给它一个向上的速度,让它穿过一道道缺口。这类题看似只是"一个小游戏",实则把图形化编程的核心考点几乎全覆盖:变量(速度与加速度分离)、循环(每帧主循环)、条件(碰撞与计分判定)、克隆体(管道批量生成)、自制积木(逻辑封装)、广播(开始 / 得分 / 撞击 / 结束解耦)。
本文以「校园飞鸟穿越赛」为题,按比赛评分习惯做一份完整拆解:先读题,再列考点,然后逐模块给出积木级实现,最后附 Python 同构对照与进阶方向。文中所有参数都给了具体数值,照着搭即可运行。

一、题目与项目目标
题面(按典型题型原创):制作一个"校园飞鸟穿越赛"小游戏。小鸟位于舞台左侧,受重力作用下坠;玩家每次按下空格,小鸟拍翅获得一次向上的速度。管道从舞台右侧成对出现、向左移动,每对管道留有一个缺口。小鸟穿过一对管道得 1 分;撞到管道或落到地面则游戏结束。随着得分增加,管道移动变快、缺口变窄。游戏结束后显示本局得分与历史最佳成绩,按任意键可重新开始。
功能清单:
- 开始界面:显示标题与"按空格开始"提示,小鸟悬停待命;
- 游戏进行:重力下坠 + 空格拍翅 + 管道成对生成 + 穿过计分;
- 难度递增:每得 5 分提速 0.3、缺口收窄 8(设下限保护);
- 结束判定:撞管道或落地,弹出成绩面板,历史最佳写入成绩榜;
- 重新开始:一键重置全部状态,管道克隆体清空。
二、核心考点
| 考点 | 在本项目中的落点 |
|---|---|
| 变量 | vy(竖直速度)与 gravity(每帧速度增量)分离;score / speed / gap / state 全局状态 |
| 循环 | 小鸟"重复执行"主循环每帧刷新;管道克隆体循环左移与自检 |
| 条件 | 落地判定、管道碰撞(坐标法)、缺口穿越计分、难度递增分支 |
| 克隆体 | 管道母体成批生成"上管道 / 下管道"克隆体,私有变量记缺口中心与计分标记 |
| 自制积木 | 初始化一局、记录成绩、画成绩榜、生成一对管道 |
| 广播 | 开始游戏 / 拍翅 / 生成管道 / 得分 / 撞击 / 落地 / 游戏结束 / 重置 |
| 列表 | history 历史成绩列表,冒泡思路求历史最佳 best |
三、解法拆解
3.1 角色与数据设计
角色清单:小鸟(主角,两个造型做扇翅动画)、管道母体(隐藏,仅作克隆模板)、开始按钮(只广播不干活)、背景(蓝天 + 地面)。
全局变量(适合所有角色):
gravity = 0.55:每帧加到 vy 上的增量,即"加速度";flap = -7.5:拍翅时直接把 vy 设为该值(舞台 y 轴向上为正,故取负);speed = 3:管道每帧左移像素数;gap = 130:缺口高度(像素);score、best:本局得分与历史最佳;state = 0:0 等待开始 / 1 进行中 / 2 已结束。
小鸟私有变量 (仅当前角色):y_speed(即 vy)。建议用"仅适用当前角色"的变量,避免和全局 score 混淆。
列表 :history,每局结束把 score 追加进去,求 best 时遍历取最大。
管道克隆体私有变量 :my_center(本对管道的缺口中心 y)、my_scored(是否已计分,防止穿过一对管道重复加分)、my_is_top(是上管道还是下管道,碰撞与计分只由下管道统一判定,避免双倍触发)。
3.2 物理核心:速度与加速度分离
这是全部代码的"发动机"。Scratch 的"重复执行"约每秒 30 帧,把每帧当作一个时间步:
- 每帧先加速:
vy = vy + gravity; - 再按速度位移:
y = y + vy; - 按下空格时把
vy直接改写为flap(一拍上去),随后重力再把它慢慢拉回来。
三个积木要点:
- 先加速后位移的顺序不能反。反了等价于晚一帧受重力,手感发"飘";
- 拍翅是"重置速度"而不是"累加速度" 。若写成
vy = vy + flap,长按连拍会飞出天际; - y 轴向上为正,所以重力是"正数往下",拍翅是"负数往上",符号不要搞反。
待命与结束状态(state 为 0 或 2)时不做物理积分,小鸟只做轻微上下浮动(y = -30 + 8 × sin(计时器×5)),表示"待机动画"。
3.3 管道流水线:克隆体 + 私有变量
母体管道隐藏,自己不画任何东西,只负责"按下时钟生孩子":
- 主控(舞台或小鸟)在 state = 1 时,每 1.1 秒广播一次「生成管道」;
- 母体收到广播:把本次缺口中心存进全局变量
next_center = 在 -60 到 60 之间取随机数,然后连续"生成克隆体"两次------分别代表上管道与下管道。两个克隆体在启动时都读同一个next_center,保证缺口对齐。
每个管道克隆体启动时:
- 显示,移到 x = 240(舞台右缘外);
- 记住
my_center = next_center; - 上管道:
y = my_center + gap/2 + 90(柱高 180,中心落在缺口上沿之上半个柱高);下管道:y = my_center - gap/2 - 90。两根柱子一上一下,中间自然留出高度为 gap 的缺口; - 下管道把
my_scored置 0。
克隆体主循环:
- 仅当 state = 1 时
x = x - speed; x < -260时删除此克隆体(飞出左缘,回收内存);- 计分(仅下管道执行):如果
my_scored = 0且我的x < 小鸟的x,则 score 加 1、my_scored置 1、广播「得分」; - 难度递增放在计分分支里:如果 score 是 5 的倍数,
speed = speed + 0.3、gap = gap - 8,并给 gap 设下限(如不小于 90),否则中后期缺口消失必死。
3.4 碰撞判定:坐标法,不靠颜色侦测
青少组评分里一个常见失分点是"用颜色侦测判碰撞"------小鸟造型一切换、背景一花,判定就误报。稳妥做法是坐标数值判定,由下管道克隆体统一执行:
- 横向重叠:
|小鸟的x - 我的x| < 18 + 26(小鸟碰撞半宽 18 + 管道半宽 26,按角色实际尺寸量); - 纵向出界:
小鸟的y > my_center + gap/2(撞上管道)或小鸟的y < my_center - gap/2(撞下管道)。
两个条件同时满足即判定撞击,广播「撞击」并走结束流程。地面判定放小鸟主循环:y < -150 广播「落地」。
小技巧:判定用"中心点 + 半宽半高"的矩形近似即可,不必精确到造型轮廓;比赛看重的是"稳定不误判",不是像素级精确。
3.5 状态机与广播解耦
state 三态是全项目的"总闸门",按钮只发广播、不算逻辑,逻辑全在管理员角色里:
- 开始按钮:被点击时只广播「开始游戏」;
- 小鸟(管理员):收到「开始游戏」→ 调用自制积木"初始化一局"→ state = 1;收到「撞击」/「落地」→ state = 2、广播「游戏结束」;
- 播报员角色(可由小鸟兼任):只听广播说话------收到「得分」说"干得漂亮!",收到「撞击」说"撞到管道啦",收到「游戏结束」说"本局得分 X,历史最佳 Y";
- 重置:state = 2 时按空格,广播「重置」→ 删除所有管道克隆体、初始化一局、state 回 1。
这样做的好处评委一眼能看出来了:按钮、逻辑、表现三者分离,哪一层出错改哪一层,不会牵一发动全身。
3.6 自制积木清单
| 自制积木 | 职责 |
|---|---|
| 初始化一局 | score = 0、speed = 3、gap = 130、vy = 0、小鸟回到 (-120, -30)、state 置位 |
| 生成一对管道 | 随机 next_center,连续生成两个克隆体(上下各一) |
| 记录成绩 | score 追加进 history,遍历取最大值赋给 best |
| 画成绩榜 | 把 history 与 best 拼成多行文本显示(连接积木) |
| 结束一局 | state = 2、记录成绩、画成绩榜、广播「游戏结束」 |
其中"记录成绩"是列表考点的标准动作:用"将 score 加入 history"追加,再用重复执行遍历每一项与当前 best 比较,大则替换------这就是冒泡排序求最大值的简化版,青少组与考级都常考。
四、运行效果
游戏开始后,小鸟在舞台左侧悬停待命;按下空格,小鸟一拍翅向上冲,随即在重力下缓慢下坠。右侧每约 1.1 秒涌出一对上下管道,缺口位置随机;小鸟穿过缺口时下方管道触发计分,播报员喝彩。随着得分到 5、10、15,管道左移明显加快、缺口逐步收窄,压迫感一点点上来。一旦撞管或落地,画面定格,弹出"本局得分 / 历史最佳"面板,按空格即刻再战一局。

五、进阶挑战
1. Python 逐帧对照。把主循环翻译成代码,物理与 Scratch 逐字同构,适合备考时验证参数手感:
python
GRAVITY = 0.55 # 每帧速度增量(对应 Scratch 的 gravity)
FLAP = -7.5 # 拍翅时直接重置的速度(向上为负)
SPEED = 3.0 # 管道左移速度(像素/帧)
class Pipe:
def __init__(self, center_y, gap):
self.x = 240.0
self.center_y = center_y
self.gap = gap
self.scored = False
def hit(bird_x, bird_y, p, bird_half=18, pipe_half=26):
if abs(bird_x - p.x) >= bird_half + pipe_half:
return False
return bird_y > p.center_y + p.gap / 2 or bird_y < p.center_y - p.gap / 2
def step(bird_y, vy, pipes, tap):
if tap: # 拍翅:重置速度,而不是累加
vy = FLAP
vy += GRAVITY # 先加速
bird_y += vy # 后位移,顺序与 Scratch 一致
for p in pipes:
p.x -= SPEED
return bird_y, vy
2. 极限窄口模式:gap 下限压到 70,得分倍率 ×2,拼的是稳定性而非运气。
3. 昼夜与天气:用计时器控制背景造型在"白天 / 黄昏 / 夜晚"间切换,夜晚给小鸟加一个手电筒光圈(用绘图编辑器做一个半透明黑色遮罩造型即可)。
4. 成绩榜升级:history 存满 10 条后弹出最早一条(列表删除第 1 项),真正实现"只留最近十次";再按 best 从大到小排序展示。
5. 自动模式(AI 陪玩) :给小鸟写一条极简策略------目标高度取最近一对管道的缺口中心 my_center,每帧若 我的y > my_center + 8 且 vy > 0 就自动拍翅。观察它能不能稳定拿分,是理解"感知---决策---执行"三段式的最好入口。
6. 双人轮换:history 旁边再加一名玩家成绩,一局结束轮换,三局两胜------顺带练列表的成对存储。
六、小结与互动
回看这个项目,"一拍一坠"背后是一条完整的图形化思维链:
- 物理层:速度与加速度分离,先加速后位移;
- 生成层:母体 + 克隆体流水线,私有变量管好"每个孩子的私事";
- 判定层:坐标法碰撞与缺口计分,稳定优先于花哨;
- 调度层:state 状态机做总闸门,广播让按钮、逻辑、表现各司其职;
- 数据层:history 列表沉淀成绩,遍历求最佳。
这也正是蓝桥杯青少组程序设计组别的评分视角:不只看"跑起来",更看结构是否清晰、状态是否可控、数据是否有沉淀。备考的同学可以把本文参数当作基线,先复现通关,再逐项加进阶,一份作品就能覆盖大部分考点。
你在做这类"重力 + 穿越"项目时踩过哪些坑?是拍翅手感调不好,还是克隆体删不干净?欢迎在评论区交流,我会挑典型问题在后续文章里继续拆解。
📚 免费少儿编程资料(夸克网盘领取)
以下资料来自夸克网盘分享,点击链接可直接保存;若需在 App 内打开,也可复制下方明文链接:
- 全国青少年信息素养大赛复赛集训题目Python&C++.docx
https://pan.quark.cn/s/93995d3cb150 - 2024信息素养-智能算法应用挑战赛-复赛初中组题目7月7日.pdf
https://pan.quark.cn/s/da97b5dbf75d - Python背记手册.pdf
https://pan.quark.cn/s/7568ae9ca92b - Python课程
https://pan.quark.cn/s/a94bf02d00c6 - 2024信息素养大赛图形化复赛集训题答案3-9
https://pan.quark.cn/s/6ccab7ec3cbc - 2025年03月份电子学会考级真题
https://pan.quark.cn/s/4403c4228912 - 2025全国青少年信息素养大赛赛项说明
https://pan.quark.cn/s/d9d0df4a9f29 - 青少儿信息素养大赛编程资料
https://pan.quark.cn/s/4ab6bd83be8a
资料持续更新,关注获取最新分享。