游客发表
用Canvas画一个方块,小游戏代监听键盘事件,小游戏代每帧更新坐标——这就是小游戏代最原始的JS小游戏。别小看它,小游戏代贪吃蛇、小游戏代俄罗斯方块、小游戏代打砖块,小游戏代底层逻辑全绕不开这套“画图-清屏-重绘”的小游戏代循环。很多人学JS卡在DOM操作上,小游戏代其实游戏才是小游戏代最好的练手场,因为反馈即时,小游戏代对错一眼便知。小游戏代
先说贪吃蛇。小游戏代核心就三个数组:蛇身坐标、小游戏代食物坐标、小游戏代方向变量。蛇头每帧按方向前进一格,判断是否撞墙或撞到自己。吃到食物就往蛇尾push一个新节点,没吃到就shift掉尾部。渲染用fillRect逐个画格子就行。难点在方向控制——不能允许180度掉头,否则蛇会瞬间咬到自己。我的做法是用一个方向队列,每次按键push新方向,出队时才真正改变。这样连按两次也不会出bug。
let dirQueue = []; document.addEventListener('keydown', e => { const map = { ArrowUp:[0,-1], ArrowDown:[0,1], ArrowLeft:[-1,0], ArrowRight:[1,0]}; if (map[e.key]) dirQueue.push(map[e.key]); }); // 每帧从队列取一个方向,与当前方向做反向判断 俄罗斯方块稍微复杂点。七种方块用二维矩阵表示,旋转就是矩阵转置加翻转。碰撞检测写一个collide(board, piece, offsetX, offsetY)函数,遍历方块的每个格子,看是否越界或与已固定的方块重叠。消行逻辑是遍历每一行,如果全满就splice掉,顶部补一行空数组。有个细节容易忽略:方块落地后不能立刻固定,得给一个短暂的锁定延迟,否则玩家没法做“贴地旋转”这种操作。我一般设300毫秒,手感刚好。
打砖块的关键在碰撞反弹。球撞到砖块要判断是从哪一侧撞的——比较球心与砖块中心的相对位置,水平距离大于垂直距离就是左右撞,反之是上下撞。反弹方向错了,球会卡在砖缝里来回抖动。挡板反弹角度可以跟击中位置挂钩:击中挡板左侧往左偏,右侧往右偏,这样玩家能主动控制球路。这个小设计让可玩性提升一大截。
再提一个冷门的:像素鸟。它的代码量极小,但物理手感很讲究。重力加速度不能太大,否则下落太快来不及反应;跳跃冲量要刚好抵消下落趋势。我试过用velocity += gravity; bird.y += velocity;,重力取0.5,跳跃速度设为-8,玩起来就很跟手。管道生成用setInterval或者基于帧计数都行,但要注意清除计时器,不然游戏结束后管道还在冒出来。
这些游戏的完整代码网上到处都是,但直接复制粘贴学不到东西。我的建议是:先自己写一遍,卡住了再去搜。哪怕写出来的贪吃蛇移动起来像蚯蚓爬,那也是你的代码。调参数的过程比读一百行注释都有用。比如把帧率从60降到30,你会发现游戏手感完全变了——这就是实时渲染的微妙之处。
最后说个实际观察:很多人写小游戏喜欢用requestAnimationFrame,这没错,但别忘了在页面失焦时暂停。否则切到别的标签页再回来,你的蛇可能已经撞墙十次了。加个document.hidden判断,简单又实用。
友情链接