游戏元素
舞台是游戏开发中的一个术语,意思是用来显示游戏元素的平台,所有的游戏元素只有添加到舞台,才能够显示到用户的界面。以这个音乐跑酷小游戏为例,我们需要实现的有哪些元素呢?归纳起来,主要元素有:
- 菜单按钮
- 主角
- NPC
- 赛道
- 计时分数
- 音乐动画帧

创建舞台场景
我们先不管这些游戏元素该怎么实现的,目前我们的任务是,先实现一个舞台。Three.js 实现一个舞台非常简单:
1 | const scene = new THREE.Scene(); |
但这仅仅只是一个舞台场景而已,在 3D 世界中,我们还需要一台摄影机(相当于用户的眼睛),摄影机的摆放位置(坐标),决定了屏幕呈现元素的角度:
创建摄影机
创建一台摄影机:
1 | const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 4000); |
PerspectiveCamera是透视摄影机类,继承于THREE.Camera类,用这种模式的摄影机,在 3D 世界中,图像会是近大远小的情况。该类分别接受 4 个参数fov(field of view,视野大小), aspect(视窗宽高比), near(距离摄影机最近的位置,最小值为 0.1),far(距离摄影机最远的位置)。

near 和 far 决定了成像的空间范围,far 一般不宜过大,否则会造成性能渲染问题。
还有其他模式的摄影机:
- CubeCamera
- OrthographicCamera
- StereoCamera
这里不作介绍了,感兴趣可以查看:https://threejs.org/docs/index.html#api/zh/cameras/Camera
创建渲染器
有了舞台场景,摄影机了,但是还缺少一个东西:WebGL 渲染器。创建WebGL渲染器:
1 | const renderer = new THREE.WebGLRenderer({ |
这里设置了 3 个参数,作用分别是:
canvas指定渲染到哪个 canvas,如果没有指定,则会创建一个新的 canvas。这里因为微信小游戏默认创建了主屏 canvas,并暴露到全局环境中,所以设置值为canvas即可。alpha是声明 canvas 是否需要透明度,这个游戏需要有透明度,所以为true。antialias则是表示是否需要执行抗锯齿。
为了兼容 Retina 屏幕,我们需要设置 dpr 值为devicePixelRatio。
最后调用render方法,把舞台和摄影机都加入渲染器:
1 | renderer.render(scene, camera); |
创建主角
舞台,摄影机,WebGL 渲染器都具备了,但是如果没有主角的话,我们看到的将是漆黑一片,所以我们还需要创建一个主角,在这个小游戏中,我们的主角非常简单,就是一个 3D 几何体:
1 | const boxGeometry = new THREE.BoxGeometry(8, 8, 8); |
BoxGeometry是立方几何体模型,分别接受宽(width)、高(height),深(depth)3 个参数。
同时还需要创建材质:boxMaterial,相当于模型的皮:
1 | const boxMaterial = new THREE.MeshBasicMaterial({ |
最后创建立方几何体网格:Mesh,并确定位置:
1 | const box = new THREE.Mesh(boxGeometry, boxMaterial); |
然后把 box 元素添加到舞台scene:
1 | scene.add(box); |
主角虽然创建了,但是我们并没有设置camera的位置,因此摄影机和主角都处在 3D 坐标系的原点(0, 0, 0),所以还需要我们完成最后一步,把camera移动到合适的位置。
移动 camera 到合适的位置(坐标)
移动 camera 之前,我们需要认识什么是 3D 坐标系(图转),3D 坐标系遵循右手坐标系:

3D 世界的中心坐标为(0, 0, 0),即x,y,z值分别都为0。
移动 camera 的位置:
1 | // 移动到x坐标为0,y坐标为30,z坐标为60的位置 |
这时候,我们就可以看到舞台上有个橘黄色的立方体:

可能你已经注意到了,舞台上出现了红、绿、蓝的线条,没错,他们分别代表x,y,z轴,这些线条就是辅助坐标系,对于调试元素的位置坐标非常有用,它是 Three.js 提供的AxesHelper。创建辅助坐标系:
1 | // 10000代表辅助线的长度 |
总结
最后我们需要把一些数值参数提取到constant.ts常量文件,后续方便我们调整游戏的参数,调整之后的代码结构是:
1 | ./src |
代码::https://github.com/inarol/rungame/tree/section1
[本文谢绝转载,谢谢]