微信小游戏:漫吃3D球2048
头条抖音同款。
两个球碰撞后,合并成一个大球(摧毁一个,把另一个变大),或者销毁时,一点点逐渐缩小。涉及到几个对象:
- CANNON.Sphere
- CANNON.Body
- THREE.SphereGeometry
- THREE.Mesh
CANNON.Body和THREE.Mesh本身不用变,直径参数在CANNON.Sphere和THREE.SphereGeometry上,需要改变。
改变CANNON.Sphere有2种方法:
(1)重新创建一个
function getBallRadius(value){
//获取球的半径
return c_radius*(1+Math.sqrt(value)/10);
}
function createBallShape(radius){
return new CANNON.Sphere(radius);
}
function getBallShape(radius){
let sphereShape=spheres[radius];
if (!sphereShape){
sphereShape = createBallShape(radius);
spheres[radius]=sphereShape;
}
return sphereShape;
}
ball.shapes=[];
let radius=getBallRadius(ball.wxhValue);
ball.addShape(getBallShape(radius));
(2)直接改变直径
ball.shapes[0].radius=getBallRadius(ball.wxhValue);
//如果没有重新加入shape,只是改变shape的radius,则必须调用updateBoundingRadius()
ball.updateBoundingRadius();
改变THREE.SphereGeometry有3种方法:
(1)重新创建一个,但是放入池子中,下次可以直接用
function createBallGeometry(radius){
let ballGeometry = new THREE.SphereGeometry(radius, 30, 30);
return ballGeometry;
}
function getBallGeometry(radius){
let ballGeometry=geometries[radius];
if (!ballGeometry){
ballGeometry=createBallGeometry(radius);
geometries[radius]=ballGeometry;
}
return ballGeometry;
}
let ballGeometry=getBallGeometry(radius);
ball.wxhMesh.geometry=ballGeometry;
但是,池子中的对象太多了,非常耗内存,特别是做逐渐变小动画时,可能会崩溃。
(2)每次创建,不池化
let ballGeometry=createBallGeometry(radius);
ball.wxhMesh.geometry=ballGeometry;
内存能及时销毁,但是在做逐渐变小动画时,可能GC来不及回收,会出现卡顿现象。
(3)用scale函数
let radius=ball.shapes[0].radius;
if (radius<=1) return false;
if (!ball.wxhRadius0) ball.wxhRadius0=radius;
radius=radius-1;
let r=radius/ball.wxhRadius0;
ball.wxhMesh.scale.set(r,r,r);
这个方法好,不耗内存,也不卡顿。