我年前至今至今对微信小游戏尝了尝鲜,从开发到上线全流程做了一款小游戏。特做个记录分享给大家。
长文警告!全文共8527字,阅读此文会耗费不少时间。可收藏备用查看。
小游戏目前只支持JavaScript一种语言,但JS的支持也并不完全,最主要的区别是小游戏BOM 和 DOM API,小游戏提供了canvas,支持2d和webgl,可操作性还是挺高的。需要注意的是小游戏可以同时创建多个canvas画布,但只有一个上屏画布,而其它再次创建的皆是离屏画布。所谓上屏画布就是我们可以看到的画布,离屏画布如果要看到需要绘制到上屏画布。后面会有介绍到。
小游戏的制作引擎可以有几种选择:Cocos、Egret、Laya 和 threejs,跳一跳就是使用threejs作为引擎,本文主要介绍threejs。
01
—
使用threejs开发微信小游戏
1. 创建项目
使用threejs开发小游戏,首先需要下载微信开发者工具,注册一个微信小游戏的账号,然后根据流程创建一个微信小游戏。
使用微信开发者工具默认创建的小游戏项目是类似打飞机的一个小游戏,是使用canvas2d制作的一个有基本的游戏逻辑实现的小游戏,没有小游戏开发经验的可以先读一读这个小游戏的代码可以对小游戏开发有一个简单的了解。
构建项目时可以删除无用的文件,然后引入threejs的文件,需要保留原有项目中的symbol.js和weapp-adapter.js两个文件,这两个文件是对小游戏的适配,根据实际情况可能还需要修改,相关内容可以访问了解https://mp.weixin.qq.com/debug/wxagame/dev/tutorial/base/adapter.html
本文提供了一个简单的示例项目:
链接:https://pan.baidu.com/s/1T5-eDHdkTIjvRM_YZn0alA
提取码:1n38
目录结构为:
其中main.js和main1.js分别是两个示例,main1.js是使用threejs加载一个glb模型并应用模型动画:
main.js是一个旋转的正方体示例:
2. 如何绘制hud元素
什么是hud元素,hud全称平视显示器(head up display)简称HUD。就是在游戏中游戏场景外的元素,比如操作按钮、信息或弹窗等元素。
在使用threejs构建游戏场景中,一般我们场景会使用透视相机PerspectiveCamera渲染场景,透视相机展示的场景会更真实,物体会根据远近不同而显示的大小不同,渲染场景代码类似:
let THREE = require('../three/three')
let ctx = canvas.getContext('webgl')
export default class Main {
constructor() {
var camera, scene, renderer;
this.init();
this.animate();
}
init() {
this.scene = new THREE.Scene();
this.camera = new THREE.PerspectiveCamera(30, window.innerWidth / window.innerHeight, 1, 10000);
this.camera.position.set(1000, 1000, 1000);
this.camera.lookAt(0, 0, 0);
this.renderer = new THREE.WebGLRenderer({ context: ctx, canvas: canvas })
this.renderer.setPixelRatio(window.devicePixelRatio);
}
animate() {
requestAnimationFrame(this.animate.bind(this), canvas);
this.renderer.render(this.scene, this.camera);
}
}
而小游戏只有一个上层canvas,所有元素都需要展示在上层canvas,如果将hud类型的元素直接放在透视相机渲染的场景里,会出现一些问题,比如在游戏的过程中随着场景相机的变化,在场景中的hud元素可能会发生形状和位置的变化。
好在threejs可以有其它解决方法,可以利用正交相机OrthographicCamera渲染另一个场景来达到显示hud元素的目的,所谓正交相机简单来说就是元素无论距离远近大小都不会产生变化,具体可以查看threejs文档详细了解。使用正交相机渲染hud的场景代码:
let THREE = require('../three/three')
let ctx = canvas.getContext('webgl')
export default class Main {
constructor() {
var camera, scene, renderer;
var hudCamera, hudScene;
this.init();
this.animate();
}
init() {
this.scene = new THREE.Scene();
this.camera = new THREE.PerspectiveCamera(30, window.innerWidth / window.innerHeight, 1, 10000);
this.camera.position.set(1000, 1000, 1000);
this.camera.lookAt(0, 0, 0);
this.hudScene = new THREE.Scene();
this.hudCamera = new THREE.OrthographicCamera(-window.innerWidth / 2, window.innerWidth / 2, window.innerHeight / 2, -window.innerHeight / 2, -100, 100);
this.hudCamera.updateProjectionMatrix();
this.hudCamera.lookAt(new THREE.Vector3(0, 0, 0));
this.renderer = new THREE.WebGLRenderer({ context: ctx, canvas: canvas })
this.renderer.setPixelRatio(window.devicePixelRatio);
}
animate() {
requestAnimationFrame(this.animate.bind(this), canvas);
this.renderer.render(this.scene, this.camera);
this.renderer.render(this.hudScene, this.hudCamera);
}
}
这样渲染场景后,所有hud的元素内容都需要放在hudScene场景中。而游戏元素可以放在scene场景中即可。
3. 如何将离屏canvas绘制到上屏
微信小游戏只能显示一个上屏canvas,而通过微信api创建的其它canvas都是离屏canvas,是不会显示在上屏的,需要绘制在上屏才能显示。
而使用threejs创建的场景是基于webgl的,是没有在2d下使用的drawImage方法的。
threejs中我们也是有方法,就是使用纹理和一个二维的几何平面PlaneGeometry形成平面网格,然后放置在场景中,可以实现将离屏canvas绘制到上屏,且这种方法也可以使用图片做纹理。代码:
let THREE = require('./libs/three.js