打地鼠
基于 C 语言与 EasyX 图形库的打地鼠小游戏,包含菜单、规则、商店、排行榜、音效与背景音乐等模块。
> hello world, i am
一个兴趣使然的全栈开发者
— 点击周围的恒星,探索我的世界 —
一名兴趣使然的全栈开发者,喜欢用代码把脑海里的想法变成能跑起来的东西。技术栈覆盖前端、后端与基础设施,热衷折腾新工具、钻研底层原理,也习惯把踩坑经验整理成文章分享出去。
从 C 语言写游戏,到 JavaScript 写网页,一路都是"兴趣驱动"。相信最好的学习方式是亲手做一个东西,然后在做的时候把不会的全学会。
从 requestAnimationFrame 到视差位移、引力聚集与拖尾残影,拆解一个高性能星空背景的完整实现思路。
这篇文章拆解我用原生 Canvas 做星空背景的完整思路,也是这个主页星空层的由来。
首先是渲染循环:用 requestAnimationFrame 而不是 setInterval,因为它与显示器刷新率同步,能避免掉帧和撕裂。每一帧固定做三件事——更新状态、清空画布、重绘粒子。
粒子建模是核心。每颗星星用一个对象描述,包含位置 x/y、深度 z(0 到 1)、大小和亮度。深度是关键:z 越大,星星离"镜头"越近,看起来越大越亮,视差位移也越明显。
视差位移的原理很简单:记录鼠标位置,让每颗星相对屏幕中心,按 z 的大小反向偏移,公式大致是 offset = (mouseX - centerX) * (0.05 + z * 0.15)。z 越大的星偏移越多,就产生了远近分层、随鼠标移动的立体感。
引力聚集是后来加的效果:在鼠标周围定义一个半径,半径内的星星受到指向鼠标的力,位置向鼠标靠拢。距离越近力越强,但要在接近中心时衰减,避免全部叠成一个点。
拖尾残影是让画面"丝滑"的秘诀。与其每帧用 clearRect 彻底清空,不如用半透明色 fillRect 覆盖一层,让上一帧的星星慢慢淡出,形成拖尾。代价是要控制好透明度:太淡残影过长,太浓就接近直接清屏。
性能上我总结了几条经验:避免在循环里创建新对象,粒子数组提前建好;尽量减少 fillStyle 和 globalAlpha 的切换;用离屏 Canvas 预渲染星点纹理,主循环里只 drawImage,比每颗星都 arc 一次快得多。这套方案在几百颗星上保持 60fps 毫无压力。
用 OscillatorNode 和 GainNode 实时合成启动音、悬停音与点击音,并聊聊浏览器自动播放策略的坑。
Web Audio API 让浏览器具备了实时合成音频的能力,不需要任何音频文件。整个合成流程是一条"节点链":OscillatorNode 产生波形,GainNode 控制音量包络,最后连接到 destination(扬声器)。
先创建 AudioContext,这是所有音频的入口。然后创建一个 OscillatorNode,设定 type(正弦 sine、方波 square、锯齿 sawtooth、三角 triangle)和 frequency(单位 Hz)。频率决定音高:440Hz 是标准 A 音,翻倍就是一个八度。
音量的起止决定音效质感。如果振荡器直接响,声音会突然开始、突然结束,很生硬。用 GainNode 的 gain 做包络:从 0 快速升到峰值(attack),再指数衰减到 0(release),就能得到"叮"一声的短促音效。用 gain.exponentialRampToValueAtTime 做指数曲线会更自然。
悬停音和点击音的区别主要在频率和时长:悬停音频率高、时长短、音量小;点击音频率低一点、时长稍长、音量适中。启动音可以做一段上行音阶,用几个不同频率的振荡器依次触发,营造"开机"的感觉。
最大的坑是浏览器的自动播放策略。为了防止网页自动播放吵人的声音,Chrome 规定 AudioContext 在用户交互之前处于 suspended 状态,此时即使创建了节点也不出声。解决办法是监听一次 pointerdown 或 keydown,在回调里调用 ctx.resume(),之后所有音效就正常了。这也是很多网页第一次点击后才"激活"声音的原因。
从第一个 EasyX 小游戏到这个星空主页,聊聊我踩过的坑、学到的东西,以及给初学者的几点建议。
我的第一个像样的作品,是一个用 C 语言和 EasyX 图形库写的打地鼠游戏。那时候我对"程序"的理解还停留在命令行黑框,直到发现 EasyX 能在窗口里画圆、画方、显示图片、播放音效,才第一次觉得"原来我能做出一个别人可以玩的东西"。
那个打地鼠游戏现在回头看很粗糙,但它教会我的东西比任何教程都多:菜单、规则、商店、排行榜、音效、背景音乐,每一个模块都是一次完整的"需求 → 设计 → 实现 → 调试"循环。尤其是音效和 BGM,让我第一次理解了"事件驱动"——玩家点一下鼠标,程序要响应:播放声音、更新分数、刷新画面。
后来我转向前端,最大的感受是"反馈"变得更快了。改一行 CSS 刷新页面立刻看到效果,这种即时反馈对学习太重要了。我开始用 Canvas 做动画、用 Web Audio 做音效,慢慢把这些零散的知识拼成一个完整的页面——也就是你现在看到的这个主页。
给初学者几点真心话:第一,先做出来,再做好,粗糙的成品比精致的空想强一百倍;第二,遇到 bug 别急着问人,先自己读报错、打断点、缩小范围,调试能力是练出来的;第三,保持"折腾"的心态,很多技能不是学出来的,是玩出来的。
一份详细到每一步的西红柿炒鸡蛋食谱,甜口党必备。
© 2026 Jizen · Built with HTML/CSS/JS