cannon.js如何让球变大或缩小

两个球碰撞后,合并成一个大球(摧毁一个,把另一个变大),或者销毁时,一点点逐渐缩小。涉及到几个对象:

  1. CANNON.Sphere
  2. CANNON.Body
  3. THREE.SphereGeometry
  4. 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);

这个方法好,不耗内存,也不卡顿。

你可能感兴趣的:(微信小游戏,Javascript)