Geg-Babylonjs是基于Geg.js开发的3D项目,项目采用Babylonjs引擎。
以微信小游戏平台说明
# 克隆项目
git clone https://github.com/GengineJS/geg-babylonjs.git
# 进入项目目录
cd geg-babylonjs
├── src # 源代码
│ ├── gegbabylon # babylonjs组件
│ ├── libs # 用到的源码库
│ ├── app.js # 功能入口
│ └── template.xml # template层级文件
│
├── game.js # 微信小游戏入口
├── game.json # 小游戏相关配置
└── project.config.json # 工程相关配置
Geg-Babylonjs中的所有组件都可以通过v-bind方式给各个组件中对应的对象赋值, 以Babylonjs中的Box对象为例,它具备的属性如下(列举部分):
@serializeAsVector3("position") private _position = Vector3.Zero(); /** * Gets or set the node position (default is (0.0, 0.0, 0.0)) */ public get position(): Vector3 { return this._position; } public set position(newPosition: Vector3) { this._position = newPosition; this._isDirty = true; } @serializeAsVector3("rotation") private _rotation = Vector3.Zero(); /** * Gets or sets the rotation property : a Vector3 defining the rotation value in radians around each local axis X, Y, Z (default is (0.0, 0.0, 0.0)). * If rotation quaternion is set, this Vector3 will be ignored and copy from the quaternion */ public get rotation(): Vector3 { return this._rotation; } public set rotation(newRotation: Vector3) { this._rotation = newRotation; this._rotationQuaternion = null; this._isDirty = true; } @serializeAsVector3("scaling") protected _scaling = Vector3.One(); /** * Gets or sets the scaling property : a Vector3 defining the node scaling along each local axis X, Y, Z (default is (0.0, 0.0, 0.0)). */ public get scaling(): Vector3 { return this._scaling; } public set scaling(newScaling: Vector3) { this._scaling = newScaling; this._isDirty = true; }
自定义的组件就可以通过以下方式为对应的属性赋值
// mesh组件的默认对象就是立方体 <mesh :position="{x:0,y:0,z:0}" :scaling="{x:2,y:2,z:2}"></mesh>
除了engine组件外,其余组件都直接或间接继承至(mixins)base组件,base组件中需要说明的内容如下:
特殊生命周期
Awake: Awake函数在 new Babylon.Engine(canvas) 后调用,它传递了初始化后的engine对象
Start: Start函数在当前场景初始化后调用,它传递了初始化后的scene对象,它与Awake不同,Awake调用时,scene对象还不存在
Update: Update函数在engine render函数内调用,每渲染一次调用一次当前组件的Update函数并传递delta参数
可以通过以下方式定义特殊生命周期
export default { name: 'customLifeCycle', data() { return { test: 'custom' } }, Awake(engine) { console.log(this.test) }, Start(scene) { }, Update(delta) { } }
逻辑组件:
为了与Vue/Geg中的组件定义区分开,我们把base组件内部中的components属性定义为逻辑组件的集合,逻辑组件是为当前Babylonjs对象 编写额外逻辑代码而设计,它类似于Unity3D中的组件概念
props: { components: { type: Array, default() { return [] } } }, methods: { // 为当前geg组件添加逻辑组件 AddComponent(component) { this.components.push(component) }, // 根据逻辑组件名称获取逻辑组件 GetComponentFromName(name) { return this.components.filter(comp => {return comp.name === name}) }, // 根据逻辑组件ID获取逻辑组件 GetComponentFromID(id) { return this.components.filter(comp => {return comp.id === id}) }, // 移除逻辑组件 RemoveComponent(component) { let compIndex = this.components.indexOf(component) if(compIndex > -1) { this.components.splice(compIndex, 1) } } }
该组件定义了如何添加Babylonjs实体对象的方法,并对实体对象的变化或相应属性的变化进行监听,它通过config对象进行管理:
config对象
所有继承(mixins)DisplayObject的子组件都具备config属性,所以如果要对Babylonjs中的实体对象进行操作,即可通过config调用相应实体对象对应的属性即可完成修改实体对象的功能,如:
<Light ref="currLight"></Light> export default { Start() { this.$refs.currLight.config.position = {x:10, y:20, z:10} // 或 new Babylon.Vector3(10, 20, 10) } }
除了config对象需要说明外,curObj也同样重要
curObj对象
curObj代表着当前组件所要操作的Babylonjs实体对象,如:
// 平行光的定义 this.curObj = new Babylon.DirectionalLight()
那么为什么建议操作config而不是curObj呢? 因为出于性能考虑并没有去监听curObj中的属性变化,所以如果直接修改curObj,config中的值不一定能够同步更新
其余组件的操作,或者组件中是否有特殊的props属性值需要传递,建议看源代码中的定义