3D堆叠游戏——第三步 切割等功能
主题列表: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贡献主题:http...
主题列表: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对象 leadBsp
和lastLeadBsp
再进行裁切和模型材质赋值
``` 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值
堆叠几次之后的效果
那么接下来需要做一下无效区域的下落动画(非物理运动)
自由落体单独写吧,挺复杂的,游戏开发接近尾声,剩下记分器,镜头移动等其他功能
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)