2013-08-29 81 views
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; 
    } 

} 

} 

請,它可能最終是一個沃爾芬斯騰克隆,但我想嘗試實現鼠標使用。

+1

哦,該死!我做得這麼快......請忽略評論和不重要的類/方法:) –

+1

也許你可以把問題減少到a)一個具體問題和b)一個_concise_例子。 – Andy

+1

我會問,我該如何修復相機。但是這還是太寬泛了,不是嗎?哈哈... –

回答

0

由於我在您的代碼中看不到加載單位矩陣的位置,因此我只能假設您每次調用translateCamera (...)時攝像機的轉換累積,並且這是問題的根源。

你必須認識到,OpenGL歸結爲一個非常不成熟的狀態機。如果不使用GLSL和任意程序矩陣制服,則必須依靠矩陣堆棧來操縱轉換。每當您執行glRotatef (...)glTranslatef (...)時,它會將「當前」矩陣乘以旋轉或平移矩陣。當前矩陣使用該模式的矩陣堆棧的Matrix Mode頂部來定義。

除非你加載一個新的矩陣到您當前矩陣,或改變矩陣堆棧的頂部,然後每次調用時旋轉,平移,縮放,等你實際上是旋轉功能,翻譯和縮放相對於之前的狀態的矩陣。

我看過你的相機的代碼,我不認爲這是你想要的行爲。看起來你想要絕對的旋轉和平移,而不是相對的。致電glLoadIdentity (...)將解決此問題。