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

    科技2022-07-16  112

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

    CANNON.SphereCANNON.BodyTHREE.SphereGeometryTHREE.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);

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

    Processed: 0.009, SQL: 8