如何在Three.js游戏中解决滞后问题

时间:2019-05-12 21:58:20

标签: javascript three.js

当我在Three.js中的游戏开始时,没有任何滞后。但是,随着时间的流逝,运行此功能的计算机在五分钟的时间内开始变慢。我不知道为什么会这样。

我已经尝试查看我的代码并检查我的数组。我开始更改一些值以查看是否是问题所在,但是我尝试过的任何方法都没有起作用!

// cloud spawning

for(i = 0; i < 100; i++){

makeCloud()

}

// skeleton spawning

for (i = 0; i < 30; i++){

    makeSkeleton()

}


// render

function render() {

      // animation  

       requestAnimationFrame(render);

    renderer.render(scene, camera);

    // skybox position update

    skybox.position.set(player.position.x + 125, player.position.y + 125, player.position.z + 125)


    // camera positioning
    camera.position.set(player.position.x, player.position.y - 1, player.position.z)

    camera.position.z += 5 * Math.cos(playerDegree * Math.PI / 180);

        camera.position.x -= 5 * Math.sin(playerDegree * Math.PI / 180);
        camera.position.y += 3


    // function calling
    move()

    turn()

    jumpOn()

    gravity()

    cameraDistance()

    addBarrier(rock)

    addBarrier(bush)

    correctPlayer()

    energyGain()


}
render()

// distance function

function distance(x1, y1,z1,x2,y2,z2){

   let one = square(x1-x2)

   let two = square(y1-y2)

   let three = square(z1 - z2)

 let d= Math.sqrt(one+two+ three);

 return d;

 }
// squaring function

 function square(input){

   let output = input * input

   return output;

 }


// camera to rock distance function

 function cameraDistance(){

if (distance(camera.position.x, camera.position.y,  camera.position.z,

     rock.position.x,    rock.position.y,   rock.position.z) < 5){
rockMaterial.transparent = true

}else{

    rockMaterial.transparent = false

}}


// collision

   function collision(obj1, obj2){

    if(obj1.position.x + obj1.scale.x > obj2.position.x &&

            obj1.position.x < obj2.position.x + obj2.scale.x &&

            obj1.position.y + obj1.scale.y > obj2.position.y &&

            obj1.position.y < obj2.position.y + obj2.scale.y &&

            obj1.position.z + obj1.scale.z > obj2.position.z &&
            obj1.position.z < obj2.position.z + obj2.scale.z                     ){
        return true;

    }else{
        return false;
    }

}


// barrier function

   function addBarrier(obj){

if (collision(player, obj)){


    //xpos pos barrier


    if (player.position.x > obj.position.x && 
    !player.position.y + player.scale.y > obj.position.y){

        player.position.x += playerSpeed

        console.log("xpos pos push")

    }else

    // xpos neg barrier

    if (player.position.x + player.scale.x < obj.position.x && 
    !player.position.y + player.scale.y > obj.position.y){

player.position.x -= playerSpeed

        console.log("xpos neg push")
    }else

    //zpos pos barrier

    if (player.position.z > obj.position.z && 
    !player.position.y + player.scale.y > obj.position.y){

        player.position.z += playerSpeed

        console.log("zpos pos push")
    }else

    // zpos neg barrier

    if (player.position.z + player.scale.z < obj.position.z && 
    !player.position.y + player.scale.y > obj.position.y){
        player.position.z -= playerSpeed
        console.log("zpos neg push")
    }else

    // ypos barrier

    if (player.position.y + player.scale.y >= obj.position.y &&  player.position.y <= obj.position.y + player.scale.y  && 
        player.position.x >= obj.position.x && player.position.x <= obj.position.x + obj.scale.x &&             
        player.position.z >= obj.position.z && player.position.z <= obj.position.z + obj.scale.z){


        //groundedObject = true
        //grounded = true
        console.log("top stay")

    }
    }
}


// cloud function

function makeCloud(){

    let bool;

 bool = (Math.random()*1000) + (Math.random()*-1000)

let cloudGeom1 = new THREE.CubeGeometry(Math.random() * 30, Math.random() * 5, Math.random() * 30)

let cloudGeom2 = new THREE.CubeGeometry(Math.random() * 30, Math.random() * 5, Math.random() * 30)

let cloudGeom3 = new THREE.CubeGeometry(Math.random() * 30, Math.random() * 5, Math.random() * 30)

let cloudMat = new THREE.MeshLambertMaterial({color: 0xffffff, transparent: true})

let cloudMesh1 = new THREE.Mesh(cloudGeom1, cloudMat)

let cloudMesh2 = new THREE.Mesh(cloudGeom2, cloudMat)

let cloudMesh3 = new THREE.Mesh(cloudGeom3, cloudMat)


let cloudMesh = new THREE.Group()

cloudMesh.add(cloudMesh1)

cloudMesh.add(cloudMesh2)

cloudMesh.add(cloudMesh3)


cloudMesh1.position.set(Math.random() * -10, Math.random() * 10 + 30, Math.random() * -100)

cloudMesh2.position.set(Math.random() * -10, Math.random() * 10 + 30, Math.random() * -100)

cloudMesh3.position.set(Math.random() * -10, Math.random() * 10 + 30, Math.random() * -100)

cloudMesh.position.set(Math.random() * bool, Math.random() * 10, Math.random() * bool)


scene.add(cloudMesh)

cloudArray.push(cloudMesh)

}


// correct player to random terrain height function


function correctPlayer(){

    for(i = 0; i < groundArray.length; i++){

if(collision(player, groundArray[i])|| player.position.y - player.scale.y <= groundArray[i].position.y){

    grounded = true


}else{
    grounded = false

}}}


// make a skeleton

function makeSkeleton(){

var skeletonArray = [] 



  // skeleton geometries
   let skeletonGeometry = new THREE.CubeGeometry(1,2,1)

   let skeletonRightEyeG = new THREE.CubeGeometry(0.1,0.2,0.2) 

   let skeletonLeftEyeG = new THREE.CubeGeometry(0.1,0.2,0.2)

   let skeletonMouthAG = new THREE.CubeGeometry(0.1,0.1,0.4)

  let skeletonMouthBG = new THREE.CubeGeometry(0.1,0.2,0.1) 

//skeleton meshes

  let skeletonRightEye = new THREE.Mesh(skeletonRightEyeG, new THREE.MeshPhongMaterial({color: 0x0f0f0f})) 

  let skeletonLeftEye = new THREE.Mesh(skeletonLeftEyeG, new THREE.MeshPhongMaterial({color: 0x0f0f0f})) 

  let skeletonBody = new THREE.Mesh(skeletonGeometry, new THREE.MeshLambertMaterial({color: 0xffffff})) 

// skeleton materials ( not in use )

  let blackMaterial = new THREE.MeshPhongMaterial({color: 0x0f0f0f})

  let skeletonMaterial = new THREE.MeshLambertMaterial({color: 0xffffff}) 

// more skeleton meshes

     let skeletonMouthA = new THREE.Mesh(skeletonMouthAG, new THREE.MeshPhongMaterial({color: 0x0f0f0f}))

     let skeletonMouthB = new THREE.Mesh(skeletonMouthBG, new THREE.MeshPhongMaterial({color: 0x0f0f0f}))

     let skeletonMouthC = new THREE.Mesh(skeletonMouthBG, new THREE.MeshPhongMaterial({color: 0x0f0f0f}))

     let skeletonMouthD = new THREE.Mesh(skeletonMouthBG, new THREE.MeshPhongMaterial({color: 0x0f0f0f}))



      // skeleton group

      let skeleton = new THREE.Group() 

      skeleton.add(skeletonBody),

       skeleton.add(skeletonRightEye) 

       skeleton.add(skeletonLeftEye) 

       skeleton.add(skeletonMouthA) 

       skeleton.add(skeletonMouthB) 

       skeleton.add(skeletonMouthC)

       skeleton.add(skeletonMouthD) 


      // skeleton potitioning

      skeletonBody.position.x = 10 

      skeletonBody.position.y = 2 

      skeletonLeftEye.position.set(9.5, 2.5, 0.3)

       skeletonRightEye.position.set(9.5, 2.5, -0.3)

       skeletonMouthA.position.set(9.5, 2.0, 0),

    skeletonMouthB.position.set(9.5, 2.0, -0.133)
,
    skeletonMouthC.position.set(9.5, 2.0, 0),

    skeletonMouthD.position.set(9.5, 2.0, 0.133)

skeleton.position.set(Math.random() * 150,  skeletonBody.scale.y, Math.random() * -150)


        skeleton.rotation.y = (Math.PI / 2) * -2;

        scene.add(skeleton)

        skeletonArray.push(skeleton)


}

更改数组的值并使地图更小后,我的预期结果是滞后问题将停止。

我的实际结果只是滞后。

1 个答案:

答案 0 :(得分:1)

正如其他人所说,请尝试使您的代码可读性和简洁性。最好组织成小块。它使其他人更容易阅读,从而为您提供帮助。另外,缩进并使用分号;,尽管不是必需的,但它们也可以提高可读性。


顺便说一句,让我尝试解释您问题背后的原因是什么。

因此,您的代码不完整。它有一些遗漏的部分,使调试更加困难。但是我相信这是一个内存泄漏问题,您似乎在场景中添加了太多对象而没有删除它们。

在每帧被调用的主要更新函数render()中,您将无限期添加障碍。这会导致出现滞后,因为您只是用越来越多的信息填充了场景和内存,而没有清除所有这些对象。

您需要跟踪场景中的对象,将它们从场景中移除,并在不再需要它们时调用.dispose()。这应该有助于避免滞后。

但是,如果没有更多有关此问题的信息,就不可能确定。尝试编辑缺少信息的原始帖子,使其更具可读性,我很乐意编辑此答案