【问题标题】:How to make the camera move in the direction 3D Libgdx如何使相机沿 3D Libgdx 方向移动
【发布时间】:2020-07-06 07:43:35
【问题描述】:

我是 Libgdx 的新手,我正在 libgdx 中开发 3d 游戏,所以我想创建第一人称系统,我创建了一个类 -playercontroller- 来移动玩家,然后让相机随着玩家一起移动并且它可以工作

但我希望玩家朝相机方向移动,所以当我旋转相机时,玩家会朝新方向行走。

这是我的代码:-

@Override
    public void create() {
        // load enviroment
        environment = new Environment();
        environment.set(new ColorAttribute(ColorAttribute.AmbientLight, 0.4f, 0.4f, 0.4f, 1f));
        environment.add(new DirectionalLight().set(0.8f, 0.8f, 0.8f, -1f, -0.8f, -0.2f));
        // setup camera
        cam = new PerspectiveCamera(67, Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
        cam.position.set(10f, 10f, 10f);
        cam.lookAt(0, 0, 0);
        cam.near = 0.001f;
        cam.far = 3000f;
        cam.update();
        // setup controller for camera
        camController = new CameraInputController(cam);
        Gdx.input.setInputProcessor(camController);
        
        
        // load the models
        assets = new AssetManager();
        assets.load("ground_stairs.g3db", Model.class);
        assets.load("gathering_node.g3db", Model.class);
        loading = true;
        modelBatch = new ModelBatch();

        // setup bulletphysics
        Bullet.init();
        collisionConfig = new btDefaultCollisionConfiguration();
        dispatcher = new btCollisionDispatcher(collisionConfig);
        broadphase = new btDbvtBroadphase();
        constraintSolver = new btSequentialImpulseConstraintSolver();
        dynamicsWorld = new btDiscreteDynamicsWorld(dispatcher, broadphase, constraintSolver, collisionConfig);
        dynamicsWorld.setGravity(new Vector3(0, -10f, 0));
        contactListener = new MyContactListener();
        loadPlayer();
        
    }

    private void loadPlayer() {
     
        // setup player/camera movement
        pc = new PlayerController(instances,cam,dynamicsWorld);
    }

    private void doneLoading() {
        loading = false;
        onDoneLoadingStatic("ground_stairs.g3db", GROUND);
        onDoneLoadingStatic("gathering_node.g3db", GATHERING_NODE);
        gatheringNode = instances.get(instances.size() - 1);
    }

    public btRigidBody onDoneLoadingStatic(String fileName, int id) {
        Model model = assets.get(fileName, Model.class);
        ModelInstance instance = new ModelInstance(model);
        instances.add(instance);

        btBvhTriangleMeshShape shape = new btBvhTriangleMeshShape(instance.model.meshParts);
        btRigidBody body = new btRigidBody(0, null, shape, new Vector3(0, 0, 0));
        body.proceedToTransform(instance.transform);
        // set id to find with collision detection
        body.setUserValue(id);
        dynamicsWorld.addRigidBody(body);
        
        return body;
    }

    @Override
    public void render() {
        if (loading && assets.update()) {
            doneLoading();
        }
        camController.update();

        pc.update();
       
        
        final float delta = Math.min(1f / 30f, Gdx.graphics.getDeltaTime());
        dynamicsWorld.stepSimulation(delta, 5, 1f / 60f);

        
        Gdx.gl20.glClearColor(0, 0.5f, 1, 1);
        Gdx.gl20.glViewport(0, 0, Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
        Gdx.gl20.glClear(GL20.GL_COLOR_BUFFER_BIT | GL20.GL_DEPTH_BUFFER_BIT);
        modelBatch.begin(cam);
        modelBatch.render(instances, environment);
        modelBatch.end();
    }

    @Override
    public void dispose() {
        modelBatch.dispose();
    }

    

    private class MyContactListener extends ContactListener {

        @Override
        public void onContactStarted(int userValue0, int userValue1) {
            if (userValue0 == PLAYER && userValue1 == GATHERING_NODE) {
                ((ColorAttribute) gatheringNode.materials.first().get(ColorAttribute.Diffuse)).color.set(Color.RED);
            }
            if (userValue0 == PLAYER && userValue1 == GROUND) {
                PlayerController.canJump = true;
            }
        }

        @Override
        public void onContactEnded(int userValue0, int userValue1) {
            if (userValue0 == PLAYER && userValue1 == GATHERING_NODE) {
                ((ColorAttribute) gatheringNode.materials.first().get(ColorAttribute.Diffuse)).color.set(Color.BLUE);
            }
        }
    }
    
}

播放器控制器

public PlayerController(List<ModelInstance> instances,PerspectiveCamera cam,btDynamicsWorld dynamicWorld) {
        this.instances = instances;
        this.cam = cam;
        this.dynamicsWorld = dynamicWorld;
        
        player = new ModelInstance(new ModelBuilder()
                                   .createCapsule(0.25f, 3, 10, new Material(ColorAttribute.createAmbient(Color.BLACK)), Usage.Normal | Usage.Position)
                                   );
        player.transform.translate(5, 7, 0);
        instances.add(player);
        // load player rigid body
        btCapsuleShape playerShape = new btCapsuleShape(0.25f, 2.5f);
        float mass = 10;
        Vector3 localInertia = new Vector3();
        playerShape.calculateLocalInertia(mass, localInertia);
        playerBody = new btRigidBody(mass, null, playerShape, localInertia);
        playerBody.proceedToTransform(player.transform);
        playerBody.setCollisionFlags(playerBody.getCollisionFlags() | btCollisionObject.CollisionFlags.CF_CUSTOM_MATERIAL_CALLBACK);
        // set id to find with collision detection
        playerBody.setUserValue(PLAYER);
        dynamicsWorld.addRigidBody(playerBody);
        
        
    }
    
    public void update() {
        // make sure to activate the player body so bullet doesnt put it to sleep
        playerBody.activate();
        // prevent the capsule from falling over
        playerBody.setAngularFactor(new Vector3(0, 0, 0));
        playerBody.getWorldTransform(player.transform);
        
        
        Vector3 velocity = new Vector3(0, playerBody.getLinearVelocity().y, 0);
        velocity.x = xposition;
        velocity.z = yposition;
        
    cam.position.set(player.transform.getTranslation(new Vector3()));
        cam.position.y=5;
        cam.rotate(Vector3.Y,angleX);
        cam.rotate(cam.direction.cpy().crs(Vector3.Y),-angleY);
       
        
        
        playerBody.setLinearVelocity(velocity);
        cam.update();
    }
    
    
}

代码可以正常工作,我可以向前和向后走,但是当我旋转方向时不起作用,那我怎样才能让它工作呢?

【问题讨论】:

    标签: java android libgdx perspectivecamera


    【解决方案1】:
     public float posX, posY, posZ;
     private float move = 0.02f;
    
    public void moveForward(float moveSpeed) {
      // normal speed moveForward(3.9);
      //call moveForward(0); to stop moving
      moveRCam(-moveSpeed, 0);
     }
    
      public void moveBackward(float moveSpeed) {
        moveRCam(moveSpeed, 0);
      }
    
      private void moveRCam(float moveSpeed, float st) {
        float speed = moveSpeed * move;
        float strVel = st * move;
    
        float angleY = (cam.rotation.y / 180 * 3.141592654f);
        posX += speed*(Math.sin(angleY));
        posZ -= speed*(Math.cos(angleY));
        
        angleY += (3.141592654f/2);
        posX -= strVel*(Math.sin(angleY));
        posZ += strVel*(Math.cos(angleY));
           cam.position.x = posX;
           cam.position.y = posY;
           cam.position.z = posZ;
       }
    

    【讨论】:

    • 欢迎来到 stackoverflow,如果这是一个答案,请添加更多详细信息/描述,说明您的代码实际在做什么。等,以避免投票。谢谢
    猜你喜欢
    • 1970-01-01
    • 2018-07-21
    • 2022-01-22
    • 1970-01-01
    • 1970-01-01
    • 2019-05-26
    • 2012-07-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多