0

我正在研究我的“游戏引擎”,在完成玩家课程后,我意识到相机移动不起作用......我做了一堆 try/catch if/else 语句,我把它缩小到要么是Mouse.getDX 无法正常运行的问题,或者 glRotate 无法正常运行...

这是我的游戏课:

package com.matisse.engine;

import static org.lwjgl.opengl.GL11.GL_POINTS;
import static org.lwjgl.opengl.GL11.glBegin;
import static org.lwjgl.opengl.GL11.glCallList;
import static org.lwjgl.opengl.GL11.glColor3f;
import static org.lwjgl.opengl.GL11.glEnd;
import static org.lwjgl.opengl.GL11.glVertex3f;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;

import org.lwjgl.LWJGLException;
import org.lwjgl.input.Keyboard;

import assets.TestBlock;

import com.matisse.world.Chunk;
import com.matisse.world.Level;
import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.io.xml.DomDriver;

public class Game {

public boolean[] keys;
public XStream xstream;
public Level world;
public File file;
public Camera camera;


public Game() throws LWJGLException {

     run();

 }

public void run() {

     try {

        Keyboard.create();

        keys = new boolean[256];

        xstream = new XStream(new DomDriver());

         Level first_world = new Level(0, 0);

        Chunk first_chunk = new Chunk();

        TestBlock floor = new TestBlock(-10, -2, -10, 10, -1, 10);

        first_chunk.voxels.add(floor);

         first_world.chunks.add(first_chunk);

        first_world.genLists();

        String xml = xstream.toXML(first_world);

        saveFile("world", xml);

        world = (Level) xstream.fromXML(readFile("res/maps/world.xml"));

        camera = new Camera(this, world.startx, world.startz);


    } catch (LWJGLException e) {

        e.printStackTrace();

    }

}

 public void update() {

    if (Keyboard.isKeyDown(Keyboard.KEY_ESCAPE)) {

        Engine.state = State.MENU;

    }

    mapKeys();
    camera.update();

    camera.translateCamera();


 }

 public void draw3D() {

    for (Chunk i : world.chunks) {

        i.render();
        glCallList(i.displayListHandle);

    }

}

public void draw2D() {

    glBegin(GL_POINTS);
    glColor3f(1, 0, 0);
    glVertex3f(0, 0, 10);
    glEnd();

}

public void mapKeys() {

    for (int i = 0; i < keys.length; i++) {

        keys[i] = Keyboard.isKeyDown(i);

    }

}

public void saveFile(String mapname, String xml) {

    FileOutputStream fop = null;
    String content = xml;

    try {

        file = new File("res/maps/" + mapname + ".xml");
        fop = new FileOutputStream(file);

        // if file doesnt exists, then create it
        if (!file.exists()) {
            file.createNewFile();
         }

        // get the content in bytes
        byte[] contentInBytes = content.getBytes();

        fop.write(contentInBytes);
        fop.flush();
        fop.close();

        System.out.println("Done");

    } catch (IOException e) {

        e.printStackTrace();

     } finally {

        try {

             if (fop != null) {
                 fop.close();
            }

        } catch (IOException e) {

            e.printStackTrace();

        }

    }

}

public String readFile(String filename) {
    StringBuffer result = new StringBuffer();

    // The name of the file to open

    // This will reference one line at a time
    String line = null;

    try {
        // FileReader reads text files in the default encoding.
        FileReader fileReader = new FileReader(filename);

        // Always wrap FileReader in BufferedReader.
        BufferedReader bufferedReader = new BufferedReader(fileReader);

        while ((line = bufferedReader.readLine()) != null) {
            result.append(line);
        }

        // Always close files.
        bufferedReader.close();
    } catch (FileNotFoundException ex) {
        System.out.println("Unable to open file '" + filename + "'");
    } catch (IOException ex) {
        System.out.println("Error reading file '" + filename + "'");
        // Or we could just do this:
        // ex.printStackTrace();

     }

    String product = result.toString();
    return product;

}

}

这是我的相机类:(注意:这是我尝试使用的第一个“引擎”之一,几乎没有外部参考,所以其余代码有点土气)

package com.matisse.engine;

import static org.lwjgl.opengl.GL11.glRotatef;
import static org.lwjgl.opengl.GL11.glTranslatef;

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

public class Camera {

static float speed = 0.35f;

Vector3f vector = new Vector3f(7, 1, 7);
Vector3f rotation = new Vector3f(0, 1, 0);
Vector3f previous = new Vector3f();
boolean moveForward = false, moveBackward = false, strafeLeft = false,
        strafeRight = false;

Game world;

public Camera(Game app, float startx, float starty) {
    world = app;
     vector.x = startx;
    vector.y = starty;
}

public void translateCamera() {

    glRotatef(rotation.x, 1, 0, 0);
    glRotatef(rotation.y, 0, 1, 0);
    glRotatef(rotation.z, 0, 0, 1);
    glTranslatef(-vector.x, -vector.y - 1.4f, -vector.z);

}

public void update() {

    if (Engine.state == State.GAME) {

        Mouse.setGrabbed(true);

    } else {

        Mouse.setGrabbed(false);

     }

     updatePreviousVector();
    updateMotion();
    input();

 }

public void input() {

    if (world.keys[Keyboard.KEY_W]) {
        moveForward = true;
    } else {
        moveForward = false;
    }

    if (world.keys[Keyboard.KEY_S]) {
         moveBackward = true;
     } else {
         moveBackward = false;
    }

     if (world.keys[Keyboard.KEY_A]) {
         strafeLeft = true;
    } else {
        strafeLeft = false;
     }

     if (world.keys[Keyboard.KEY_D]) {
        strafeRight = true;
    } else {
        strafeRight = false;
    }

     try {

        float mouseDX = Mouse.getDX() * 0.8f * 0.16f;
        float mouseDY = Mouse.getDY() * 0.8f * 0.16f;

         System.out.println(Mouse.getDX());

        if (rotation.y + mouseDX >= 360) {

             rotation.y = rotation.y + mouseDX - 360;

         } else if (rotation.y + mouseDX < 0) {

             rotation.y = 360 - rotation.y + mouseDX;

        } else {

            rotation.y += mouseDX;
             System.out.println(mouseDX);

         } 

         if (rotation.x - mouseDY >= -89 && rotation.x - mouseDY <= 89) {

            rotation.x += -mouseDY;

         } else if (rotation.x - mouseDY < -89) {

             rotation.x = -89;

        } else if (rotation.x - mouseDY > 89) {

            rotation.x = 89;

        }

     } catch (Exception e) {

         e.printStackTrace();

    }

}

 public void updatePreviousVector() {
    previous.x = vector.x;
    previous.y = vector.y;
    previous.z = vector.z;
}

public void updateMotion() {

    if (moveForward) {
        vector.x += Math.sin(rotation.y * Math.PI / 180) * speed;
        vector.z += -Math.cos(rotation.y * Math.PI / 180) * speed;
     }
    if (moveBackward) {
        vector.x -= Math.sin(rotation.y * Math.PI / 180) * speed;
        vector.z -= -Math.cos(rotation.y * Math.PI / 180) * speed;
     }
    if (strafeLeft) {
        vector.x += Math.sin((rotation.y - 90) * Math.PI / 180) * speed;
         vector.z += -Math.cos((rotation.y - 90) * Math.PI / 180) * speed;
     }
    if (strafeRight) {
        vector.x += Math.sin((rotation.y + 90) * Math.PI / 180) * speed;
        vector.z += -Math.cos((rotation.y + 90) * Math.PI / 180) * speed;
    }

 }

}

拜托,它最终可能会成为 Wolfenstien 的克隆,但我想尝试实现鼠标的使用。

4

1 回答 1

0

由于我在您的代码中没有看到您加载单位矩阵的位置,因此我只能假设您的相机的转换在您每次调用时都会累积translateCamera (...),这是您问题的根源。

您必须意识到 OpenGL 归结为一个非常简单的状态机。在不使用 GLSL 和任意程序矩阵制服的情况下,您必须依靠矩阵堆栈来操作您的转换。每次您这样做glRotatef (...)glTranslatef (...)它都会将“当前”矩阵乘以旋转或平移矩阵。当前矩阵是使用该模式的矩阵堆栈Matrix Mode的顶部和顶部定义的。

除非您将新矩阵加载到当前矩阵中,或者更改矩阵堆栈的顶部,否则每次调用旋转、平移、缩放等函数时,您实际上都是相对于矩阵的先前状态进行旋转、平移和缩放.

我查看了您相机的代码,但我认为这不是您想要的行为。看起来您想要绝对旋转和平移,而不是相对。调用glLoadIdentity (...)将纠正此问题。

于 2013-08-29T08:22:24.720 回答