简体   繁体   中英

JavaScript array optimization to improve performance

Im using WebGL creating spheres that will drop onto a plane. These spheres are stored into an array called ballArray and are created ccontinuously on a timer. If any sphere goes past a certain -y value they get removed from the scene and the array. The trouble im having is as I call render() every frame so if say ball0 has been removed my loop still looks for it but the way the program runs any ball could fall regardless of position in the array. How I do it is this:

    var ballArray =[];
    var i = 0;
    var temp;

    function createBall()
    {
        temp = Math.random() * (4 - 1) + 1; //creates the size of the ball
        ball = new Physijs.SphereMesh(
        new THREE.SphereGeometry(temp,16,16),
        Physijs.createMaterial(new THREE.MeshLambertMaterial(
        {
            color: 0xff0000,
            reflectivity: 0.8
        }),0.4,0.6),1 ); //generates the ball with Physijs (this uses three.js)

        var r = 
        {
            x: Math.random() * (Math.PI - Math.PI / 12) + Math.PI / 12,
            y: Math.random() * (Math.PI - Math.PI / 12) + Math.PI / 12,
            z: Math.random() * (Math.PI - Math.PI / 12) + Math.PI / 12
        };

        //sets all the attributes associated with the ball
        ball.rotation.set(r.x, r.y, r.z);
        ball.position.y = 40;
        ball.castShadow = true;
        ball.receiveShadow = true;
        ball.name = "ball"+i; //sets the name to 'ball' + whatever iteration its on

        //Gather all the ball information
        var json = {Name: "ball"+i, X: ball.position.x, Y: ball.position.y, Z: ball.position.z, Size: temp, Ball: ball};
        console.log(JSON.stringify(json));
        ballArray.push(json); // Push it to the array
        delete temp, json, ball; // clear the variables used

    }

    var timer = setInterval(function() { addBall() }, 1000); // Call add ball using a timer

    function addBall()
    {
        if(i >= 0) // just to be used while testing the balls will fall continuously 
        {
            createBall();
            scene.add(ballArray[i].Ball); //add the ball to the scene
            i++;  // increment i 

        }
        else
        {
            //console.log("Finished");
            clearInterval(timer);
        }
    }

    render();
    scene.simulate();

    function render() 
    {
        for (var i = 0; i < ballArray.length; i++)  //Loop through the array
        {
            object = scene.getObjectByName( "ball"+i, true ); //get the reference to the ball
            if(object) //if there is a ball
            {
                if (object.position.y <= -50) //if the balls position has gone below -50 
                {
                    scene.remove(object); //remove the object from the scene
                    ballArray.splice(i,1); //remove the object from the array
                    console.log(" ball"+i+" removed"); //print out
                }
            }
            else //if there is not a ball in the scene
            {
                console.log("ball gone is ball"+i);
            }
            delete object;
        }
        renderer.render(scene, camera); //render
        requestAnimationFrame(render);
    }

I know that the line object = scene.getObjectByName( "ball"+i, true ); is why it looks for it but is there a more optimized way to use the array for searching the scene so that say when it gets to a later stage it wont have to search through 100's of removed balls before it can update current balls on the screen.

******This question has been edited to include all neccassary info on how i create the balls and use them

Would do something like this:

//empty ball array    
var ballArray = [];

//add any ball you want
ballArray.push("ball1");
ballArray.push("ball2");
ballArray.push("ball3");

//It will keep in note the index to delete AFTER the forEach loop
var indexToDelete = [];

//For each ball that are still in the table
ballArray.forEach(function(entry) {

    object = scene.getObjectByName(entry, true);

    //That IF statement can be removed if you want
    //Maybe you can use now a try catch
    if (object) {
         if (object.position.y <= -50) //if the balls position has gone below -50 
         {
            scene.remove(object); //remove the object from the scene
            console.log(entry + " removed"); //print out
            indexToDelete.push(ballArray.indexOf(entry)) //add the index to delete
         }
    }

    delete object;

});

//Loop to remove the balls
for (var i = 0; i < indexToDelete.length; i++)
{
    ballArray.splice(indexToDelete[i], 1);
}

Edit: code with no table copy

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM