383838 Question Set

我的JavaScript控制台说
three.js:1505 THREE.Object3D.add不是THREE.Object3D的一个实例。undefined
这是怎么了?
我的代码:
Explain how your code is misbehaving…

// Paste your code here
<body></body>
<script src="/three.js"></script>
<script src="/physi.js"></script>
<script src="/controls/OrbitControls.js"></script>
<script src="/scoreboard.js"></script>
<script src="/noise.js"></script>
<script src="/sounds.js"></script>
<script>
  // Physics settings
  Physijs.scripts.ammo = '/ammo.js';
  Physijs.scripts.worker = '/physijs_worker.js';

  // The "scene" is where stuff in our game will happen:
  var scene = new Physijs.Scene();
  scene.setGravity(new THREE.Vector3( 0, -10, 0 ));
  var flat = {flatShading: true};
  var light = new THREE.AmbientLight('white', 0.2);
  scene.add(light);
  var sunlight = new THREE.DirectionalLight('white', 0.8);
  sunlight.castShadow = true;
  scene.add(sunlight);
  var d = 10;
  sunlight.shadow.camera.left = -d;
  sunlight.shadow.camera.right = d;
  sunlight.shadow.camera.top = d;
  sunlight.shadow.camera.bottom = -d;
  

  // The "camera" is what sees the stuff:
  var aspectRatio = window.innerWidth / window.innerHeight;
  var camera = new THREE.PerspectiveCamera(75, aspectRatio, 0.1, 100);
  camera.position.set(-8, 8, 8);
  scene.add(camera);
  var abovecam = camera;  

  // The "renderer" draws what the camera sees onto the screen:
  var renderer = new THREE.WebGLRenderer({antialias: true});
  renderer.setClearColor('skyblue');
  renderer.shadowMap.enabled = true;
  renderer.setSize(window.innerWidth, window.innerHeight);
  document.body.appendChild(renderer.domElement);

  // ******** START CODING ON THE NEXT LINE ********
var gameOver;
var ground = addGround();
var water = addWater();
var scoreboard = addScoreboard();
var Raft = addRaft();
reset();

function addGround() {
  var faces = 99;
  var shape = new THREE.PlaneGeometry(10, 20, faces, faces);
  
  var riverPoints = [];
  var numVertices = shape.vertices.length;
  var noiseMaker = new SimplexNoise();
  for (var i=0; i<numVertices; i++) {
    var vertex = shape.vertices[i];
    var noise = 0.25 * noiseMaker.noise(vertex.x, vertex.y);
    vertex.z = noise;
  }

  for (var j=50; j<numVertices; j+=100) {
    var curve = 20 * Math.sin(7*Math.PI * j/numVertices);
    var riverCenter = j + Math.floor(curve);
    riverPoints.push(shape.vertices[riverCenter]);

  for (var k=-20; k<20; k++) {
        shape.vertices[riverCenter + k].z = -1;
    }
  }

  shape.computeFaceNormals();
  shape.computeVertexNormals();
  var _cover = new THREE.MeshPhongMaterial({color: 'green', shininess: 0});
  var cover = new Physijs.createMaterial(_cover, 0.8, 0.1);
  
  var mesh = new Physijs.HeightfieldMesh(shape, cover, 0);
  mesh.rotation.set(-0.475 * Math.PI, 0, 0);
  mesh.receiveShadow = true;
  mesh.castShadow = true;
  mesh.riverPoints = riverPoints;
  
  scene.add(mesh);
  return mesh;
}


function addWater() {
  var shape = new THREE.CubeGeometry(10, 20, 1);
  var _cover = new THREE.MeshPhongMaterial({color: 'blue'});
  var cover = new Physijs.createMaterial(_cover, 0, 0.6);
  
  var mesh = new Physijs.ConvexMesh(shape, cover, 0);
  mesh.rotation.set(-0.475 * Math.PI, 0, 0);
  mesh.position.y = -0.8;
  mesh.receiveShadow = true;
  scene.add(mesh);
}

function addScoreboard() {
  var scoreboard = new Scoreboard();
  scoreboard.score(0);
  scoreboard.timer();
  scoreboard.help(
    "用左右方向键控制木筏方向!"+
    "用空格键或下方向键加速!"+
    "球体是水果,方块是障碍!"+
    "加速前进!越快越好!吃掉水果!躲避障碍!"+
    'Links/Rechpfeiltasten zum drehen. ' +
    'Leertaste zum vorwärtsbewegen. ' +
    'R zum neustart'
    );
    return scoreboard;
}

function addRaft() {
  var shape = new THREE.TorusGeometry(0.1, 0.05, 8, 20);
  var _cover = new THREE.MeshPhongMaterial({visible: false});
  var cover = new Physijs.createMaterial(_cover, cover, 0.25);
  var mesh = new Physijs.ConvexMesh(shape, cover, 0.25);
  mesh.rotation.x = -Math.PI/2;
  
  var furFace = rColor();
    
  cover = new THREE.MeshPhongMaterial({color: furFace});
  var tube = new THREE.Mesh(shape, cover);
  tube.position.z = -0.08;
  tube.castShadow = true;
  mesh.add(tube);
  mesh.add(eecam);
  mesh.tube = tube;
  
  shape = new THREE.SphereGeometry(0.02);
  cover = new THREE.MeshBasicMaterial({color: 'white'});
  var rudder = new THREE.Mesh(shape, cover);
  rudder.position.set(0.15, 0, 0);
  tube.add(rudder);
  
  scene.add(mesh);
  mesh.setAngularFactor(new THREE.Vector3(0, 0, 0));
  return mesh;
}

function reset() {
  resetPoweDowns();
  resetPoweDowns1();
  resetPoweDowns2();
  resetPoweUps();
  
  abovecam.position.set(0,-1,2);
  abovecam.lookAt(new THREE.Vector3(0, 0, 0));
  Raft.add(abovecam);
  
  scoreboard.message('');
  scoreboard.resetTimer();
  scoreboard.score(0);
  
  Raft.__dirtyPosition = true;
  Raft.position.set(0.75, 2, -9.6);
  Raft.setLinearVelocity(new THREE.Vector3(0, 0, 0));
  
  gameOver = false;
  animate();
  scene.onSimulationResume();
  gameStep();
}


  // Animate motion in the game
  function animate() {
    if (gameOver) return;
    requestAnimationFrame(animate);
    renderer.render(scene, camera);
  }
  
  
  var aspectRatio = window.innerWidth / window.innerHeight;
  var qCam = new THREE.PerspectiveCamera(75, aspectRatio, 0.1, 100);
  qCam.position.set(-8, 8, 8);
  scene.add(qCam);
  new THREE.OrbitControls(qCam, renderer.domElement);
  

  // Run physics
  function gameStep() {
    if (gameOver) return;
    checkForgameOver();
    scene.simulate();
    // Update physics 60 times a second so that motion is smooth
    setTimeout(gameStep, 1000/60);
  }
  

    function checkForgameOver(){
  if (Raft.position.z > 9.8){
    if (scoreboard.getTime() < 100){
        gameOver = true;
        scoreboard.stopTimer();
        scoreboard.message("你成功了 !!");
        Sounds.drip.play();
      }
    }
  
    
    if (Raft.position.z > 9.8) {
      if (scoreboard.getTime() > 100){
      gameOver = true;
      scoreboard.stopTimer();
      scoreboard.message("有点慢哟!");
      Sounds.spring.play();
      }
    }
    
     if (scoreboard.getTime() > 180) {
        gameOver = true;
        scoreboard.stopTimer();
        scoreboard.message(" 时间到!太慢了!别灰心,再来一次!!");
        Sounds.knock.play();
    }
    
    if (gameOver){
      var score = Math.floor(101-scoreboard.getTime());
      scoreboard.addPoints(score);
      
      if(scoreboard.getTime() < 80) scoreboard.addPoints(100);
      if(scoreboard.getTime() < 60) scoreboard.addPoints(200);
      if(scoreboard.getTime() < 50) scoreboard.addPoints(500);      
    }
  }
  
   var aspectRatio = window.innerWidth / window.innerHeight;
  var eecam = new THREE.PerspectiveCamera(75, aspectRatio, 0.1, 100);
  eecam.position.set(-8, 8, 8);
  scene.add(eecam);
  var eeecam = camera;  
  
  var eeCam = new THREE.PerspectiveCamera(75, aspectRatio, 1, 10000);
  eeCam.position.set(0, 0, 500);
  eeCam.position.z = 1;
  eeCam.rotation.z = Math.PI/2;
  eeCam.rotation.y = Math.PI/2
  
  function resetPoweDowns1() {
  removeOldPowerDowns1();
  var random50 = 50 + Math.floor(10*Math.random());
  var p50 = ground.riverPoints[random50];
  addPowerDown1(p50);
  
  var random65 = 65 + Math.floor(10*Math.random());
  var p65 = ground.riverPoints[random65];
  addPowerDown1(p65);
}

function addPowerDown1(riverPoint){
  ground.updateMatrixWorld();
  var x = riverPoint.x + 4 * (Math.random() - 0.5);
  var y = riverPoint.y;
  var z = -0.5;
  var p  = new THREE.Vector3(x, y, z);
  ground.localToWorld(p);
  
 var shape =  new THREE.BoxGeometry(0.2, 0.5, 0.2);
  var cover = new THREE.MeshNormalMaterial({color:'black'});
  var mesh = new Physijs.BoxMesh(shape, cover, 0);
  mesh.position.copy(p);
  mesh.powerDown1 = true;
  scene.add(mesh);
  
mesh.addEventListener('collision',function() {
    for (var i=0; i < scene.children.length; i++) {
      var obj = scene.children[i];
      if (obj == mesh) scene.remove(obj);
    }
    scoreboard.addPoints(-18);
    scoreboard.message('哎呀!撞到障碍物了!下次小心哦!!');
    setTimeout(function() {scoreboard.clearMessage();}, 5*1000);    
    Sounds.swish.play();    
  });
  
  return mesh;
}
function resetPoweDowns() {
  removeOldPowerDowns1();
  var random47 = 47 + Math.floor(10*Math.random());
  var p47 = ground.riverPoints[random47];
  addPowerDown1(p47);
  
  var random84 = 84 + Math.floor(10*Math.random());
  var p84 = ground.riverPoints[random84];
  addPowerDown1(p84);
}

function removeOldPowerDowns1() {
  var last = scene.children.length - 1;
  for (var i=last; i>=0; i--) {
    var obj = scene.children[i];
    if (obj.powerDown) scene.remove(obj);
  }
}
function addPowerDown(riverPoint){
  ground.updateMatrixWorld();
  var x = riverPoint.x + 4 * (Math.random() - 0.5);
  var y = riverPoint.y;
  var z = -0.5;
  var p  = new THREE.Vector3(x, y, z);
  ground.localToWorld(p);
  
 var shape =  new THREE.BoxGeometry(0.2, 0.5, 0.2);
  var cover = new THREE.MeshNormalMaterial({color:'black'});
  var mesh = new Physijs.BoxMesh(shape, cover, 0);
  mesh.position.copy(p);
  mesh.powerDown1 = true;
  scene.add(mesh);
  
mesh.addEventListener('collision',function() {
    for (var i=0; i < scene.children.length; i++) {
      var obj = scene.children[i];
      if (obj == mesh) scene.remove(obj);
    }
    scoreboard.addPoints(-18);
    scoreboard.message('哎呀!撞到障碍物了!下次小心哦!!');
    setTimeout(function() {scoreboard.clearMessage();}, 5*1000);
    Sounds.swish.play();
  });
  
  return mesh;
}

function removeOldPowerDowns() {
  var last = scene.children.length - 1;
  for (var i=last; i>=0; i--) {
    var obj = scene.children[i];
    if (obj.powerDown) scene.remove(obj);
  }
}

  function resetPoweDowns2() {
  removeOldPowerDowns2();
  var random36 = 36 + Math.floor(10*Math.random());
  var p36 = ground.riverPoints[random36];
  addPowerDown2(p36);
  
  var random58 = 58+ Math.floor(10*Math.random());
  var p58 = ground.riverPoints[random70];
  addPowerDown2(p58);
}

function addPowerDown2(riverPoint){
  ground.updateMatrixWorld();
  var x = riverPoint.x + 4 * (Math.random() - 0.5);
  var y = riverPoint.y;
  var z = -0.5;
  var p  = new THREE.Vector3(x, y, z);
  ground.localToWorld(p);
  
  var shape =  new THREE.BoxGeometry(0.2, 0.5, 0.2);
  var cover = new THREE.MeshNormalMaterial({color:'black'});
  var mesh = new Physijs.BoxMesh(shape, cover, 0);
  mesh.position.copy(p);
  mesh.powerDown = true;
  scene.add(mesh);
  
mesh.addEventListener('collision',function() {
    for (var i=0; i < scene.children.length; i++) {
      var obj = scene.children[i];
      if (obj == mesh) scene.remove(obj);
    }
    scoreboard.addPoints(-18);
    scoreboard.message('哎呀!撞到障碍物了!下次小心哦!!');
    setTimeout(function() {scoreboard.clearMessage();}, 5*1000); 
    Sounds.swish.play();
  });
  
  return mesh;
}

function removeOldPowerDowns2() {
  var last = scene.children.length - 1;
  for (var i=last; i>=0; i--) {
    var obj = scene.children[i];
    if (obj.powerDown) scene.remove(obj);
  }
}

  function resetPoweDowns2() {
  removeOldPowerDowns2();
  var random20 = 20 + Math.floor(10*Math.random());
  var p20 = ground.riverPoints[random20];
  addPowerDown2(p20);
  
  var random70 = 70 + Math.floor(10*Math.random());
  var p70 = ground.riverPoints[random70];
  addPowerDown2(p70);
}

function addPowerDown2(riverPoint){
  ground.updateMatrixWorld();
  var x = riverPoint.x + 4 * (Math.random() - 0.5);
  var y = riverPoint.y;
  var z = -0.5;
  var p  = new THREE.Vector3(x, y, z);
  ground.localToWorld(p);
  
 var shape =  new THREE.BoxGeometry(0.2, 0.5, 0.2);
  var cover = new THREE.MeshNormalMaterial({color:'black'});
  var mesh = new Physijs.BoxMesh(shape, cover, 0);
  mesh.position.copy(p);
  mesh.powerDown = true;
  scene.add(mesh);
  
mesh.addEventListener('collision',function() {
    for (var i=0; i < scene.children.length; i++) {
      var obj = scene.children[i];
      if (obj == mesh) scene.remove(obj);
    }
    scoreboard.addPoints(-18);
    scoreboard.message('哎呀!撞到障碍物了!下次小心哦!!');
    setTimeout(function() {scoreboard.clearMessage();}, 5*1000);
    Sounds.swish.play(); 
  });
  
  return mesh;
}

function removeOldPowerDowns2() {
  var last = scene.children.length - 1;
  for (var i=last; i>=0; i--) {
    var obj = scene.children[i];
    if (obj.powerDown) scene.remove(obj);
  }
}


function resetPoweUps() {
  removeOldPowerUps();
  var random20 = 20 + Math.floor(10*Math.random());
  var p20 = ground.riverPoints[random20];
  addPowerUp(p20);
  
  var random70 = 70 + Math.floor(10*Math.random());
  var p70 = ground.riverPoints[random70];
  addPowerUp(p70);
}



function addPowerUp(riverPoint){
  ground.updateMatrixWorld();
  var x = riverPoint.x + 4 * (Math.random() - 0.5);
  var y = riverPoint.y;
  var z = -0.5;
  var p  = new THREE.Vector3(x, y, z);
  ground.localToWorld(p);
  
  var shape =  new THREE.SphereGeometry(0.25,25,18);
  var cover = new THREE.MeshNormalMaterial();
  var mesh = new Physijs.SphereMesh(shape, cover, 0);
  mesh.position.copy(p);
  mesh.powerDown = true;
  scene.add(mesh);
  
  mesh.addEventListener('collision',function() {
    for (var i=0; i<scene.children.length; i++) {
      var obj = scene.children[i];
      if (obj == mesh) scene.remove(obj);
    }
    scoreboard.addPoints(200);
    scoreboard.message('好吃!');
    setTimeout(function() {scoreboard.clearMessage();}, 5*1000);
    Sounds.bubble.play();
  });
  
  return mesh;
}

function removeOldPowerUps() {
  var last = scene.children.length - 1;
  for (var i=last; i>=0; i--) {
    var obj = scene.children[i];
    if (obj.powerUp) scene.remove(obj);
  }
}

  document.addEventListener('keydown',sendKeyDown);
  function sendKeyDown(event){
    var code = event.code;
    if (code == 'ArrowLeft') rotateRaft(1);
    if (code == 'ArrowRight') rotateRaft(-1);
    if (code == 'ArrowDown') pushRaft();
    if (code == 'Space') pushRaft();
    if (code == 'KeyR') reset();
    if (code == 'KeyC') switchCamera();
    if (code == 'KeyA') switchCamera1();
  }
  
  function rotateRaft(direction){
    Raft.tube.rotation.z = Raft.tube.rotation.z + direction * Math.PI/10;
  }
  
  function pushRaft(){
    var angle = Raft.tube.rotation.z;
    var force = new THREE.Vector3(Math.cos(angle), 0, -Math.sin(angle));
    
    Raft.applyCentralForce(force);
    Sounds.click.play();
  }
  
   function switchCamera() {
     if (camera == qCam) camera = abovecam;
     else camera = qCam;
  }
  
     function switchCamera1() {
     if (camera == eecam) camera = abovecam;
     else camera = eecam;
  }
  
  

  
  function r(max){
  if (max) return max * Math.random();
  return Math.random();
}

function rColor(){
  return new THREE.Color(r(), r(), r());
}
</script>

Include any more information that you like here...

在 addRaft 函数中,以下行导致了问题:

  mesh.add(eecam);

如果删除该行,错误就会消失