java - 如何使我的第一人称相机流畅?

标签 java opengl

我已经弄清楚如何制作一个简单的第一人称相机,但我想让相机变得更闷,任何方法都可以(即加速)。

我还没有找到任何简单的方法来增加相机的平滑度,希望你们能提供帮助。

相机类别(WIP)

package entities;

import org.lwjgl.input.Keyboard;
import org.lwjgl.input.Mouse;
import org.lwjgl.opengl.Display;
import org.lwjgl.util.vector.Vector3f;

import renderEngine.DisplayManager;
import terrains.Terrain;

public class Camera
{
    private float distanceFromPlayer = 50;
    private float angleAroundPlayer = 0;
    private boolean FPS = false;

    private Vector3f position = new Vector3f(110, 10, -52);
    private float pitch = 20;
    private float yaw;
    private float roll;

    private static final float RUN_SPEED = 20;
    private static final float GRAVITY = -50f;
    private static final float JUMP_POWER = 30;

    private int clickedOnPlayer = 0;

    private float upwardsSpeed = 0;

    private boolean isInAir = false;

    private Player player;

    public Camera(Player player)
    {
        this.player = player;
    }

    public void move(Terrain terrain)

        {

            Mouse.setGrabbed(true);
            this.yaw = (Mouse.getX());
            float MouseY = Mouse.getY();

            if(MouseY > 360)
            {
                pitch = 465 - MouseY;
            }

            if (yaw >= 1079)
            {
                Mouse.setCursorPosition(Display.getWidth() / 2 + 80,
                        Display.getHeight() / 2);
                this.yaw = 720;
            }
            else if (yaw <= 359)
            {
                Mouse.setCursorPosition(Display.getWidth() / 2 + 80,
                        Display.getHeight() / 2);
                this.yaw = 720;
            }

            if(pitch <= -100)
            {
                pitch = -100;
            }

            float theta = yaw - 720;

            float offsetX = (float) (2 * Math.sin(Math.toRadians(theta)));
            float offsetZ = (float) (2 * Math.cos(Math.toRadians(theta)));
            moveCamera();
            upwardsSpeed += GRAVITY * DisplayManager.getFrameTimeSeconds();
            position.y += upwardsSpeed * DisplayManager.getFrameTimeSeconds();
            player.getPosition().y += upwardsSpeed * DisplayManager.getFrameTimeSeconds();
            float terrainHeight = terrain.getHeightOfTerain(player.getPosition().x, player.getPosition().z);
            if (position.y - 10 <= terrainHeight)
            {
                upwardsSpeed = 0;
                isInAir = false;
                position.y = terrainHeight + 10;
                player.getPosition().y = terrainHeight;
            }

            player.getPosition().x = position.x - offsetX;
            player.getPosition().z = position.z + offsetZ;
            player.setRotY(180 - theta);

        }




    private void jump()
    {
        if (!isInAir)
        {
            this.upwardsSpeed = JUMP_POWER;
            isInAir = true;
        }
    }

    public void moveCamera()
    {
        float theta = yaw - 720;
        float offsetX = (float) (2 * Math.sin(Math.toRadians(theta)));
        float offsetZ = (float) (2 * Math.cos(Math.toRadians(theta)));
        if (Keyboard.isKeyDown(Keyboard.KEY_LSHIFT))
        {
            if (Keyboard.isKeyDown(Keyboard.KEY_W))
            {
                position.z -= ((offsetZ * RUN_SPEED * 3) * DisplayManager.getFrameTimeSeconds());
                position.x += ((offsetX * RUN_SPEED * 3) * DisplayManager.getFrameTimeSeconds());
            }
            else if (Keyboard.isKeyDown(Keyboard.KEY_S))
            {
                position.z += ((offsetZ * RUN_SPEED * 3) * DisplayManager.getFrameTimeSeconds());
                position.x -= ((offsetX * RUN_SPEED * 3) * DisplayManager.getFrameTimeSeconds());
            }
            else
            {
                position.x = position.x;
                position.z = position.z;
            }
            if (Keyboard.isKeyDown(Keyboard.KEY_D))
            {
                position.z += ((offsetX * RUN_SPEED * 3) * DisplayManager.getFrameTimeSeconds());
                position.x += ((offsetZ * RUN_SPEED * 3) * DisplayManager.getFrameTimeSeconds());
            }
            else if (Keyboard.isKeyDown(Keyboard.KEY_A))
            {
                position.z -= ((offsetX * RUN_SPEED * 3) * DisplayManager.getFrameTimeSeconds());
                position.x -= ((offsetZ * RUN_SPEED * 3) * DisplayManager.getFrameTimeSeconds());
            }
            else
            {
                position.x = position.x;
                position.z = position.z;
            }
            if (Keyboard.isKeyDown(Keyboard.KEY_SPACE))
            {
                jump();
            }
        }
        else
        {
            if (Keyboard.isKeyDown(Keyboard.KEY_W))
            {

                position.z -= ((offsetZ * RUN_SPEED) * DisplayManager.getFrameTimeSeconds());
                position.x += ((offsetX * RUN_SPEED) * DisplayManager.getFrameTimeSeconds());
            }
            else if (Keyboard.isKeyDown(Keyboard.KEY_S))
            {

                position.z += ((offsetZ * RUN_SPEED) * DisplayManager.getFrameTimeSeconds());
                position.x -= ((offsetX * RUN_SPEED) * DisplayManager.getFrameTimeSeconds());
            }
            else
            {
                position.x = position.x;
                position.z = position.z;
            }

            if (Keyboard.isKeyDown(Keyboard.KEY_D))
            {
                position.z += ((offsetX * RUN_SPEED) * DisplayManager.getFrameTimeSeconds());
                position.x += ((offsetZ * RUN_SPEED) * DisplayManager.getFrameTimeSeconds());
            }
            else if (Keyboard.isKeyDown(Keyboard.KEY_A))
            {
                position.z -= ((offsetX * RUN_SPEED) * DisplayManager.getFrameTimeSeconds());
                position.x -= ((offsetZ * RUN_SPEED) * DisplayManager.getFrameTimeSeconds());
            }
            else
            {
                position.x = position.x;
                position.z = position.z;
            }
            if (Keyboard.isKeyDown(Keyboard.KEY_SPACE))
            {
                jump();
            }
        }
    }

    public void invertPitch(){
        this.pitch = -pitch;
    }




    public boolean getFPS()
    {
        return FPS;
    }

    public Vector3f getPosition()
    {
        return position;
    }

    public void setPosition(Vector3f position)
    {
        this.position = position;
    }

    public float getPitch()
    {
        return pitch;
    }

    public float getYaw()
    {
        return yaw;
    }

    public float getRoll()
    {
        return roll;
    }

    private void calculateCameraPosition(float horizDistance,
            float verticDistance)
    {
        float theta = player.getRotY() + angleAroundPlayer;
        float offsetX = (float) (horizDistance * Math
                .sin(Math.toRadians(theta)));
        float offsetZ = (float) (horizDistance * Math
                .cos(Math.toRadians(theta)));
        position.x = player.getPosition().x - offsetX;
        position.z = player.getPosition().z - offsetZ;
        position.y = player.getPosition().y + verticDistance;
    }

    private float calculateHorizontalDistance()
    {
        return (float) (distanceFromPlayer * Math.cos(Math.toRadians(pitch)));
    }

    private float calculateVerticalDistance()
    {
        return (float) (distanceFromPlayer * Math.sin(Math.toRadians(pitch)));
    }

    private void calculateZoom()
    {
        float zoomLevel = Mouse.getDWheel() * 0.1f;
        distanceFromPlayer -= zoomLevel;
    }

    private void calculatePitch()
    {
        if (Mouse.isButtonDown(0))
        {
            float pitchChange = Mouse.getDY() * 0.1f;
            pitch -= pitchChange;
        }
    }

    private void calculateAngleAroundPlayer()
    {
        if (Mouse.isButtonDown(0))
        {
            float angleChange = Mouse.getDX() * 0.3f;
            angleAroundPlayer -= angleChange;
        }
    }
}

最佳答案

这真的很简单。 首先,将 move() 方法更改为如下所示:

 public void move() {
    calculatePitch();
    calculateAngleAroundPlayer();
    this.yaw = 180 - (player.getRotY() + angleAroundPlayer);
    yaw %= 360;
}

然后,其次,将 distanceFromPlayer 更改为 0

private float distanceFromPlayer = 0;

希望这会有所帮助!(可能)

关于java - 如何使我的第一人称相机流畅?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34843398/

相关文章:

java - Flex Java BlazeDS 仪表板——使用 Spring/JDBC 还是 Hibernate?

c++ - 尽可能快地渲染立方体? (OpenGL)

python - python 中的 SVG 与 cairo、opengl 和 rsvg 的交互

multithreading - LWJGL3共享上下文抛出 “GLFW_VERSION_UNAVAILABLE”

java - JOGL 没有渲染任何东西

java - 如何在 Java 中将字节数组转换为十六进制格式

java - 为什么我的 UUID 使用了太多时间?

java - 如何使用standalone.xml在JBoss 7.0中分离应用程序日志

java - 创建一个url字符串以在java中获取一个图标

opengl - 如何计算网格表面上一致的切向量?