# Code Question Set (1)

**URL:** <https://talk.code3dgames.com/t/code-question-set-1/442>\
**Category:** Uncategorized\
**Created:** [November 29, 2021, 2:23am UTC](https://talk.code3dgames.com/t/code-question-set-1/442 "2021-11-29T02:23:36Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![code](https://talk.code3dgames.com/user_avatar/talk.code3dgames.com/code/32/74_2.png) [@code](https://talk.code3dgames.com/u/code)\
**Post date:** [November 29, 2021, 2:23am UTC](https://talk.code3dgames.com/t/code-question-set-1/442/1 "2021-11-29T02:23:36Z")

</div>

我在《代码》的问题你看问题集？ 那个问题我几乎解决了，但还差一点。我很相似，我明明在代码里写的是“rotation.y”，但还是“eeCam”竟旋转了1个"rotation.x"！  
我把rotation.x和rotation.z也试过了，但就是没有正确答案。请求帮助！！！！！！  
我的代码：  
Explain how your code is misbehaving…

```auto
<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);
  
   var aspectRatio = window.innerWidth / window.innerHeight;
  var eeCam = new THREE.PerspectiveCamera(75, aspectRatio, 0.1, 100);
  eeCam.position.set(-8, 8, 8);
  
  var eeCam = new THREE.PerspectiveCamera(75, aspectRatio, 1, 10000);
  eeCam.position.set(0,-1,2);
  eeCam.position.z = 1;
  eeCam.rotation.z = Math.PI/2;
  eeCam.rotation.y = Math.PI/2;
 //new THREE.OrbitControls(abovecam, 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 texture = new THREE.TextureLoader().load("/textures/grass.png");
  var faces = 99;
  var shape = new THREE.PlaneGeometry(10, 20, faces, faces,texture);
  
  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=-15; k<15; k++) {
        shape.vertices[riverCenter + k].z = -1;
    }
  }

  shape.computeFaceNormals();
  shape.computeVertexNormals();
  var _cover = new THREE.MeshPhongMaterial({color: 'lawngreen', shininess: 0});
  var cover = new Physijs.createMaterial(_cover, 0.8, 0.1);
  cover.map = texture;
    
  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 texture = new THREE.TextureLoader().load("/textures/hardwood.png");
  var shape = new THREE.CubeGeometry(10, 20, 1);
  var _cover = new THREE.MeshPhongMaterial({color: 'blue'});
  var cover = new Physijs.createMaterial(_cover, 0, 0.6);
  //cover.map = texture;
  
  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});
  cover.specular.setRGB(r(),r(),r());
  var tube = new THREE.Mesh(shape, cover);
  tube.position.z = -0.08;
  tube.castShadow = true;
  mesh.add(tube);
  mesh.tube = tube;
  mesh.add(eeCam);
    
  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);      
    }
  }
  

  
  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;
    eeCam.rotation.z = eeCam.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…

---

<div class="post-metadata">

**Author:** ![chris](https://talk.code3dgames.com/user_avatar/talk.code3dgames.com/chris/32/5_2.png) [@chris](https://talk.code3dgames.com/u/chris)\
**Post date:** [December 2, 2021, 2:00am UTC](https://talk.code3dgames.com/t/code-question-set-1/442/2 "2021-12-02T02:00:54Z")

</div>

对 `eeCam` 进行此更改:

```auto
  var eeCam = new THREE.PerspectiveCamera(75, aspectRatio, 1, 10000);
  eeCam.position.y = -10;
  eeCam.rotation.x = Math.PI/2;
  eeCam.rotation.y = Math.PI/2;

```

将 `eecam` 添加到 `tube`:

```auto
  //mesh.add(eeCam);
  tube.add(eeCam);

```

不要旋转 `eecam`。 eecam 将与 `tube` 一起旋转：

```auto
  function rotateRaft(direction){
    Raft.tube.rotation.z = Raft.tube.rotation.z + direction * Math.PI/10;
    //eeCam.rotation.z = eeCam.rotation.z + direction * Math.PI/10;
  }

```

---

<div class="post-metadata">

**Author:** ![code](https://talk.code3dgames.com/user_avatar/talk.code3dgames.com/code/32/74_2.png) [@code](https://talk.code3dgames.com/u/code)\
**Post date:** [December 7, 2021, 2:24am UTC](https://talk.code3dgames.com/t/code-question-set-1/442/3 "2021-12-07T02:24:32Z")

</div>

哦！我成功了！我不需要帮助了！！  
我的代码：

> [@code](#):
>
> 说明你的代码是如何失常…
> 
> ```auto
> <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);
>   
> var aspectRatio = window.innerWidth / window.innerHeight;
> var eeCam = new THREE.PerspectiveCamera(75, aspectRatio, 0.1, 100);
> eeCam.position.set(0,-1,2);
> eeCam.position.x = 0;
> eeCam.rotation.z = Math.PI/2;
> eeCam.rotation.y = Math.PI/4;
> //new THREE.OrbitControls(eeCam, 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 texture = new THREE.TextureLoader().load("/textures/grass.png");
> var faces = 99;
> var shape = new THREE.PlaneGeometry(10, 20, faces, faces,texture);
>   
> 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=-15; k<15; k++) {
> shape.vertices[riverCenter + k].z = -1;
> }
> }
> 
> shape.computeFaceNormals();
> shape.computeVertexNormals();
> var _cover = new THREE.MeshPhongMaterial({color: 'lawngreen', shininess: 0});
> var cover = new Physijs.createMaterial(_cover, 0.8, 0.1);
> cover.map = texture;
>     
> 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 texture = new THREE.TextureLoader().load("/textures/hardwood.png");
> var shape = new THREE.CubeGeometry(10, 20, 1);
> var _cover = new THREE.MeshPhongMaterial({color: 'blue'});
> var cover = new Physijs.createMaterial(_cover, 0, 0.6);
> //cover.map = texture;
>   
> 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, 80, 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});
> cover.specular.setRGB(r(),r(),r());
> var tube = new THREE.Mesh(shape, cover);
> tube.position.z = -0.08;
> tube.castShadow = true;
> mesh.add(tube);
> 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);
> tube.add(eeCam);
> scene.add(mesh);
> mesh.setAngularFactor(new THREE.Vector3(0, 0, 0));
> return mesh;
> }
> 
> function addeeCam(){
> if(scoreboard.getTime() < 1) return;
>     
> }
> 
>   
> 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);      
> }
> }
>   
> 
>   
> 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;
> //eeCam.rotation.set(0,direction,0);
> }
>   
> function pushRaft(){
> var angle = Raft.tube.rotation.z+Math.PI;
> 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>
> 
> ```
