第一篇是关于‘为什么要制作’的故事,
第二篇是‘怎么制作’的故事。
对于我个人而言,在制作web应用时,我更喜欢处理Django、PostgreSQL、Redis、Docker等后端基础系统。
然而,这个项目几乎完全基于纯JavaScript + HTML5 Canvas进行。
平时我绝对不会深入触及的前端技术在这个游戏中成为了核心。
而令人惊讶的是…
非常有趣。
这是让我更加沉浸的技术因素。
平时我对前端的工作用“不是很喜欢”来形容,可能用“讨厌”更为合适,但对豆柴的爱让我变得喜欢“讨厌的事情”。

1. HTML5 Canvas – “画板 + 动画”的世界
MAME RUN!!的核心是HTML5 Canvas。
这是一个在网页上创建的像‘画板’一样的区域,通过直接绘制像素的方式制作游戏。
通常的web开发是
-
创建按钮(HTML)
-
着色(CSS)
-
增加一些行为(JS)
这样的流程,但是Canvas则完全不同。
Canvas是以30~60fps不断重绘的结构。
每一帧:
-
清除背景
-
重新绘制
-
绘制角色
-
绘制障碍物
-
计算碰撞
-
增加分数
-
预定下一帧
这个过程在每秒重复数十次。
现在的web浏览器真的强大得不亚于游戏引擎。
2. 跳跃与重力: “仅用3行代码创造的魔法”
游戏中的基本“跳跃”其实是通过简单的物理实现的。
dino.vy += gravity * dt; // 应用重力
dino.y += dino.vy * dt; // 改变位置
if (dino.y >= ground) {
dino.y = ground;
dino.vy = 0;
}
仅凭这个简单的逻辑
就能让<强>雷欧娜自然地跳跃、着陆和下落。
在没有游戏引擎的情况下,
“啊……仅凭这种基本物理原理就能产生如此流畅的动作”
让我感动不已。

3. 精灵动画 – 雷欧娜奔跑时赋予了生命
雷欧娜的奔跑动作是如下一张6帧的精灵表。
(※ 建议在博客中插入精灵图片)
在JS中,只需将精灵切割并在每一帧绘制即可:
const frameWidth = sprite.width / 6;
ctx.drawImage(
sprite,
frameIndex * frameWidth, 0, frameWidth, sprite.height,
dino.x, dino.y, dino.width, dino.height
);
只要不断变化帧索引
雷欧娜就会可爱地奔跑。
这个时刻感觉游戏被赋予了‘生命’。
在游戏开发中,动画是非常重要的。
4. 障碍物的随机生成 – “消除单调性的关键”
障碍物有多种类型。
-
橙色锥
-
红色锥
-
黄色锥
-
摩托车(两种颜色)
-
汽车(两种类型)
-
标志(种类共三种)
如果只是简单地重复1~2个,很快就会厌倦,
但通过随机间隔混合多种类型,游戏的节奏感就大大改善了。
const key = OBSTACLE_KEYS[Math.random() * length];
const interval = 0.8 + Math.random() * 1.2;
虽然是很简单的随机,但
玩法感受完全不同。
5. 碰撞判定 – 最困难而又最有趣的部分
碰撞判定通常称为“AABB盒子碰撞”的方式。
if (dino.x < ob.x + ob.width &&
dino.x + dino.width > ob.x &&
dino.y < ob.y + ob.height &&
dino.y + dino.height > ob.y) {
// 碰撞!
}
这里重要的是
-
如果判定得太严格,游戏会让人厌烦
-
如果判定得过于宽松,游戏难度就会下降
因此,我将雷欧娜和障碍物的碰撞盒缩小10~15%,创造了“带来快感的难度”。
这种微调相当有趣。
我有点理解为什么游戏开发者会在难度平衡上投入热情。
6. 距离基础的关卡系统 – 50秒内通关
第一关设计为约50秒内通关。
因此假设雷欧娜的移动速度为每秒16米。
目标距离: 800m
速度: 16 m/s → 约50秒
这不仅仅是通过数字来决定,实际上我玩了30~40次,
“这个长度是否使人愉快,想再来一局?”
不断进行测试。
这是一种虽小却影响游戏体验的重要因素。
7. 服务器联动 – 分数排名与记录保存
作为后端开发者,服务器部分自然是使用Django + DRF构建的。
-
通过POST提交分数
-
在序列化器中进行有效性检查
-
未登录用户使用guest_id记录
-
用户的最高分由UserScore表管理
-
前五名通过HTML片段实时返回给JS进行替换
因此在游戏结束时,排名TOP5会实时更新。
有趣的是,即使在Canvas游戏中,
后端的稳定性和结构化的数据流也确实提供了强大的支持。
这是通过系统化地整理角色的图片和台词数据,并将这些组合发送给浏览器的方式。
8. 移动端适配 – 比预想的要困难得多
在制作web游戏过程中,最意想不到的障碍是移动环境。
-
分辨率适配
-
触控操作
-
画布比例
-
渲染性能
-
背景滚动速度校正
在桌面上表现得非常流畅,但在移动端则出现了小的帧丢失、触控响应性、canvas大小计算等问题。
最终解决了这个问题,不过在这个过程中,我不禁感慨“前端开发者真是值得敬佩……”。
9. 第二篇 – 技术篇完
我喜爱后端,所以主要从事API开发,而以设计为主的游戏用JavaScript制作在web上的工作是第一次。 平时也得做一点前端,所以也无奈地做了些,尤其是如此深入使用HTML5 Canvas的经历几乎没有。
然而通过这个项目,
-
网页比想象中强大
-
那个曾经觉得烦的JavaScript其实是挺有趣的语言
-
游戏开发是“小技术的组合”这点
我学到了这些。
一个出于粉丝之情开始的项目,
但是作为开发者却也获得了相当多的学习与成长。
下篇预告 (第三篇: 故事篇)
在下一篇文章中,
“为什么从涩谷开始?”、“为什么东京巨蛋?”、“各个成员的角色设定是怎么确定的?”
我打算整理与世界观/故事制作相关的幕后故事。
目前没有评论。