2013-08-29 2 views
0

Я работаю над своим «игровым движком», и после завершения игрового класса я понял, что движение камеры не работает ... Я сделал кучу попыток/улов if/else и Я сузил либо быть проблемой с Mouse.getDX не функционирует должным образом, или glRotate не работают должным образом ...My Rotation не работает

Вот моя игра класс:

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, но я хотел бы попытаться реализовать использование мыши.

+1

О, черт побери! Я сделал это так быстро ... Пожалуйста, проигнорируйте комментарии и несущественные классы/методы :) –

+1

Возможно, вы могли бы уменьшить проблему до a) конкретного вопроса и b) пример _concise_. – Andy

+1

Я бы спросил, как я могу исправить камеру. Но это все еще слишком велико, не так ли? Ха-ха ... –

ответ

0

Поскольку я не вижу места в вашем коде, где вы загружаете идентификационную матрицу, я могу только предположить, что преобразования вашей камеры накапливаются каждый раз, когда вы вызываете translateCamera (...) и что это источник вашей проблемы.

Вы должны понимать, что OpenGL сводится к очень сложной машине состояний. Без использования GLSL и произвольной униформы для каждой программы, вы должны полагаться на стек матрицы, чтобы манипулировать вашими преобразованиями. Каждый раз, когда вы делаете glRotatef (...) или glTranslatef (...), он умножает «текущую» матрицу на матрицу вращения или перевода. Текущая матрица определяется с использованием Matrix Mode и top стека матриц для этого режима.

Если вы не загрузите новую матрицу в вашу током матрицы, или изменить верхней стеки матрицы, то каждый раз, когда вы звоните вращать, переводить, масштаб и т.д. функцию вы на самом деле вращаетесь, перевод и масштабирование относительно предшествующего состояния матрицы.

Я просмотрел код вашей камеры, и я не думаю, что это поведение, которое вы хотите. Похоже, вы хотите абсолютного вращения и перевода, а не относительного. Вызов glLoadIdentity (...) исправит это.