首页 > 解决方案 > 使用键盘输入在平面上移动 Three.js 主体

问题描述

我一直在尝试创建一个 Color Bump 3D 模型,但它似乎超出了我的想象,但我仍然会尝试。我有一个飞机和一个球,问题是我不能用键盘事件移动球。每当我按下按键时,控制台都会向我发出错误提示

未捕获的类型错误:无法在 Game.onDocumentKeyDown 读取未定义的属性(读取“位置”)

这是代码:

import * as CANNON from '../../libs/cannon-es.js';
import { CannonHelper } from '../../libs/CannonHelper.js';
import { OrbitControls } from '../../libs/three128/OrbitControls.js';
import { Table } from './Table.js';
import { Ball } from './ball.js';

const xSpeed = 0.1;
const ySpeed = 0.1;
class Game{
  constructor(){
    this.initThree();
    this.initWorld();
    this.initScene();
    
    // document.addEventListener('keydown', this.onDocumentKeyDown.bind(this), false);
    // document.addEventListener('keyup', this.keyUp.bind(this));
    
    // document.addEventListener('touchstart', this.mouseDown.bind(this));
    // document.addEventListener('touchend', this.mouseUp.bind(this));
    
    // document.addEventListener('mousedown', this.mouseDown.bind(this));
    // document.addEventListener('mouseup', this.mouseUp.bind(this));
   }

   initThree(){
    const container = document.createElement( 'div' );
    document.body.appendChild( container );
    
    this.camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 20 );
    this.camera.position.set( -6, 2, 0 );
    this.camera.lookAt(0, 0, 6);

    this.cameraContoller = new THREE.Object3D();
    this.cameraContoller.add(this.camera);
    this.cameraTarget = new THREE.Vector3(0, 0, 6);
    
    this.scene = new THREE.Scene();
    this.scene.background = new THREE.Color( 0xaaaaaa );
    this.scene.add(this.cameraContoller);

    const ambient = new THREE.HemisphereLight(0xffffff, 0xbbbbff, 0.3);
    this.scene.add(ambient);
    
    const light = new THREE.DirectionalLight();
    light.position.set( 0.2, 1, 0);
    light.castShadow = true;
    light.shadow.mapSize.width = 1024;
    light.shadow.mapSize.height = 1024;
    const size = 10;
    light.shadow.camera.top = size;
    light.shadow.camera.right = size;
    light.shadow.camera.bottom = -size;
    light.shadow.camera.left = -size;
    light.shadow.camera.near = 0.2;
    light.shadow.camera.far = 10;
    this.scene.add(light);
  
    this.renderer = new THREE.WebGLRenderer({ antialias: true } );
    this.renderer.shadowMap.enabled = true;
    this.renderer.setPixelRatio( window.devicePixelRatio );
    this.renderer.setSize( window.innerWidth, window.innerHeight );
    container.appendChild( this.renderer.domElement );
    
    const controls = new OrbitControls( this.camera, this.renderer.domElement );
    
    this.renderer.setAnimationLoop(this.render.bind(this));

    window.addEventListener('resize', this.resize.bind(this) );
  }

   initWorld() {
    const world = new CANNON.World();
    world.gravity.set(0, -10, 0);

    this.helper = new CannonHelper( this.scene, world);

    this.world = world;
  }

  random(min, max){
    const range = max - min;
    return Math.random() * range + min; 
  }
      // Spheres
  initScene(){
    this.Table = new Table(this);
      const sphereShape = new CANNON.Sphere(0.1)
      const sphereBody = new CANNON.Body({
        mass: 1,
      })
      sphereBody.position.x = -3.5;
      sphereBody.position.y = 1;
      sphereBody.position.z = 0;

      sphereBody.addShape(sphereShape)
      this.world.addBody(sphereBody)
      this.helper.addVisual(sphereBody, 0xFF0000);
      document.addEventListener('keydown', this.onDocumentKeyDown.bind(this), false);
    
    // this.createBalls();
    
  }

  onDocumentKeyDown(event) {


    const keyCode = event.which;
    if (keyCode == 87) {
        console.log(this.sphereBody.position);
        // playerBall.position.y += ySpeed;
    } else if (keyCode == 83) {
        playerBall.position.y -= ySpeed;
    } else if (keyCode == 65) {
        playerBall.position.x -= xSpeed;
    } else if (keyCode == 68) {
        playerBall.position.x += xSpeed;
    } else if (keyCode == 32) {
        playerBall.position.set(0, 0, 0);
    }
};
  updateCamera = () => {
    this.cameraContoller.position.copy(this.playerBall.position);
    this.cameraContoller.position.y = 0;
    this.cameraTarget.copy(this.plane.position);
    this.cameraTarget.z += 6;
    this.camera.lookAt(this.cameraTarget);
  }


  createBalls () {
      // this.playerBall = new Ball(this, -Table.LENGTH/2.5 ,0)
    }


    resize(){
      this.camera.aspect = window.innerWidth / window.innerHeight;
      this.camera.updateProjectionMatrix();
      this.renderer.setSize( window.innerWidth, window.innerHeight );  
    }

    render( ) {   
      this.world.step(0.0167);
      this.helper.update();
      this.renderer.render( this.scene, this.camera );
    }
}

export { Game }; 
<html lang="en">
    <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
        <!--favicon -->
        <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
        <link rel="apple-touch-icon" sizes="180x180" href="../../css/favicon/apple-touch-icon.png">
        <link rel="icon" type="image/png" sizes="32x32" href="../../css/favicon/favicon-32x32.png">
        <link rel="icon" type="image/png" sizes="16x16" href="../../css/favicon/favicon-16x16.png">
        <link rel="manifest" href="../../css/favicon/site.webmanifest">
        <link rel="mask-icon" href="../../css/favicon/safari-pinned-tab.svg" color="#5bbad5">
        <meta name="msapplication-TileColor" content="#da532c">
        <meta name="theme-color" content="#ffffff">

        <title>ColorBump</title>
        <style>
            body{
                margin: 0;
                padding: 0;
            }
        </style>
    </head>
    <body>
        <script type="module">
            import { Game } from './game.js';

            document.addEventListener("DOMContentLoaded", function(){
                const game = new Game();
                window.game = game;
            });
        </script>
    </body>
</html>

标签: javascriptthree.jscannon.js

解决方案


推荐阅读