主题列表:juejin, github, smartblue, cyanosis, channing-cyan, fancy, hydrogen, condensed-night-purple, greenwillow, v-green, vue-pro, healer-readable, mk-cute, jzman, geek-black, awesome-green

贡献主题:https://github.com/xitu/juejin-markdown-themes

theme: juejin

highlight:

上一篇文章

上一篇游戏功能做到主角的动画以及控制

在进行下一次主角出现之前需要做很多工作。第一步先对主角进行切割

分出在有效范围内和有效范围外的模型

将有效范围内放置到场景内,有效范围外的模型做自由落体

切割主要用threebsp

require("../utils/threebsp.js");

源码中将threebsp绑定到windows上,所以可以直接用const ThreeBSP = (window as any).ThreeBSP引用

function ThreeBSP(treeIsh, matrix) { this.matrix = matrix; this.intersect = __bind(this.intersect, this); this.union = __bind(this.union, this); this.subtract = __bind(this.subtract, this); this.toGeometry = __bind(this.toGeometry, this); this.toMesh = __bind(this.toMesh, this); this.toTree = __bind(this.toTree, this); if (this.matrix == null) { this.matrix = new THREE.Matrix4(); } this.tree = this.toTree(treeIsh); }

这是源码中对几个方法的封装

intersect 处理结果为相交

union 处理结果为联合

subtract 处理结果为减法,前面的模型减去后面的模型得出的结果

感兴趣的童鞋可以阅读一下源码,主要对顶点信息进行的计算

进行bsp计算之前需要将底板的高度提升和主角的高度一样,不然永远没有相交区域

大概这个意思(灵魂画手表示哭泣)

进行的相交计算

计算的结果大致这样

所以需要进行两次计算 一次相交计算 得到有效区域 一次减法计算 得到无效区域

先处理有效区域

const ThreeBSP = (window as any).ThreeBSP //生成ThreeBSP对象 var leadBsp = new ThreeBSP(lead); var lastLeadBsp = new ThreeBSP(lastLead);

这样就得到两个bsp对象 leadBsplastLeadBsp

再进行裁切和模型材质赋值

``` typescript function handleBsp(firstBSP: any, secondBSP: any, type: string) { // 进行相减计算 前面的减去与后面进行交叉计算 var mesh if(type === 'intersect') { mesh = firstBSP.intersect(secondBSP); } if (type === 'subtract') { mesh = firstBSP.subtract(secondBSP); }

// 将裁剪的模块转为object var intersectResult = mesh.toMesh();

//更新模型的面和顶点的数据 intersectResult.geometry.computeFaceNormals(); intersectResult.geometry.computeVertexNormals();

// 判断是否存在顶点信息 if (intersectResult.geometry.vertices.length > 0) { //重新赋值一个纹理 var material = new THREE.MeshNormalMaterial(); intersectResult.material = material; return intersectResult } } ```

将计算好的结果 返回给initGame方法,再进行处理

``` const intersectResult = handleBsp(leadBsp, lastLeadBsp, 'intersect') meshList.push(intersectResult)

``` 得到的结果

透明区域是抬高位置的底板

接下来处理多余的部分(无效区域)

方法是相同的 传不同的参数即可

然后通过有效区域,将下一次的主角定位有效区域的尺寸

接下来就是将此次的有效区域克隆clone一份,作为下一次的主角

typescript this.leadCube = meshArr[0].clone()

之前计算的位置关系再赋值给克隆的主角,

奇数在右侧出现的,修改z值位置,偶数在左侧出现的,修改x值

y值跟第一次创建主角时候使用同一种计算方式

let nextPosition = this.leadCube.position.clone() // 奇数在右侧出现的,修改z值位置,偶数在左侧出现的,修改x值 if (flag) { nextPosition.setX(sx) } else { nextPosition.setZ(sz) } nextPosition.setY(y) this.leadCube.position.copy(nextPosition)

下面需要计算终点位置

同样 如果是奇数 从右侧来,不改变z值 如果是偶数 从左侧来 不改变x值

堆叠几次之后的效果

那么接下来需要做一下无效区域的下落动画(非物理运动)

自由落体单独写吧,挺复杂的,游戏开发接近尾声,剩下记分器,镜头移动等其他功能

3D堆叠游戏——第一步 基础 初始化游戏

3D堆叠游戏——第二步 控制 控制主角移动以及停止

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐