2012-01-10 67 views
0

因此,我正在尝试制作第三人称视图控制演示。此演示将显示执行以下操作的能力:第三人称视图控制演示中的错误

1)围绕“播放器”旋转摄像头。

2)根据您推动操纵杆的方向和相机的方向移动播放器。

3)根据玩家角度和相机角度显示billboarded玩家精灵的正确角度。

现在1和2正在工作,但我无法弄清楚显示正确的敌人角度有什么问题。

这是相关的代码,我走到这一步:

private void updateLogic(int delta) { 

     if (joystick != null) { 
      joystick.poll(); 


      rjoyAngle += ((joystick.getRXAxisValue()/5)); 
      rjoyAngle = ((rjoyAngle + 360) % 360); 

      System.out.println("rangle = " + rjoyAngle); 


      camPos.x = (float) (player.pos.x - (Math.sin(rjoyAngle) * camRadius)); 
      camPos.z = (float) (player.pos.z + (Math.cos(-rjoyAngle) * camRadius)); 

      camYaw = (float) ((Math.toDegrees(((Math.atan2(-(camPos.x - player.pos.x), -(camPos.z - player.pos.z)))))+ 360) % 360); 
      System.out.println("Cam X: " + camPos.x + " Z: " + camPos.z + " yaw: " + camYaw); 


      float pyaw = ((player.yaw + 360) % 360); 
      float eyaw = ((camYaw + 360) % 360); 
      dirYaw = (pyaw + eyaw) % 360; 

      if(joystick.getXAxisValue() >= -0.5f && joystick.getXAxisValue() <= 0.5f && joystick.getYAxisValue() >= -0.5f && joystick.getYAxisValue() <= 0.5f){ 
       //deadzone? 
      } 

      else{ 
       player.yaw = (float) Math.toDegrees(Math.atan2(joystick.getXAxisValue(), joystick.getYAxisValue())); 
       pyaw = ((player.yaw + 360) % 360); 
       eyaw = ((camYaw + 360) % 360); 
       dirYaw = (pyaw + eyaw) % 360; 
       Vector3f move = new Vector3f(); 
       move.x -= 3 * (float)Math.sin(Math.toRadians(dirYaw)); 
       move.z -= 3 * (float)Math.cos(Math.toRadians(dirYaw)); 

       Vector3f.add(player.pos, move, player.pos); 

      } 

      pyaw = ((player.yaw + 360) % 360); 
      eyaw = ((camYaw + 360) % 360); 
      playerViewYaw = (dirYaw + eyaw) % 360; 
     } 

     player.update(); 
    } 

而平局和getSpriteNumber方法:

private void renderGL() { 

     GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT); // Clear The Screen And The Depth Buffer 
     loadIdentity(); // Reset The View 


     floorTex.bind(); 
     GL11.glTexParameterf(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_S, GL11.GL_REPEAT); 
     GL11.glTexParameterf(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_T, GL11.GL_REPEAT); 

     GL11.glBegin(GL11.GL_QUADS); // Start Drawing The Cube 
      GL11.glColor3f(1.0f, 1.0f, 1.0f); // Set The Color To White 
       GL11.glTexCoord2f(0,0);                    GL11.glVertex3f(-fieldSize, -groundDepth, -fieldSize); // Top left Of The Quad (bottom) 
       GL11.glTexCoord2f(fieldSize/floorTex.getTextureWidth(),0);           GL11.glVertex3f(fieldSize, -groundDepth, -fieldSize); // Top right Of The Quad (bottom) 
       GL11.glTexCoord2f(fieldSize/floorTex.getTextureWidth(),fieldSize/floorTex.getTextureHeight());  GL11.glVertex3f(fieldSize, -groundDepth, fieldSize); // Bottom right Of The Quad (bottom) 
       GL11.glTexCoord2f(0,fieldSize/floorTex.getTextureHeight());           GL11.glVertex3f(-fieldSize, -groundDepth, fieldSize); // Bottom left Of The Quad (bottom) 
     GL11.glEnd(); // Done Drawing The Quad 

     int direction = getSpriteNum(playerViewYaw); 

     drawBillBoardSprite(playerTex[0][direction],player.pos, 0, 1,1,1, 5, 10); 
    } 


    public int getSpriteNum(float direction){ 
     direction = (float) Math.abs(Math.floor((direction + 22.5)/45.0)); 

    // direction = direction * 2; 

     if (direction == 8) direction = 0; 

     return (int)direction; 
    } 

这应该是你需要看到的唯一的代码,但我会发布所有这些只是为了安全,我甚至会给你们一个项目的zip。

Dream.java:

import java.nio.FloatBuffer; 

import org.lwjgl.BufferUtils; 
import org.lwjgl.LWJGLException; 
import org.lwjgl.Sys; 
import org.lwjgl.input.Controller; 
import org.lwjgl.input.Controllers; 
import org.lwjgl.input.Keyboard; 
import org.lwjgl.input.Mouse; 
import org.lwjgl.opengl.Display; 
import org.lwjgl.opengl.DisplayMode; 
import org.lwjgl.opengl.GL11; 
import org.lwjgl.util.glu.GLU; 

import org.lwjgl.util.vector.Vector3f; 

import org.newdawn.slick.opengl.Texture; 
import org.newdawn.slick.opengl.TextureLoader; 
import org.newdawn.slick.util.ResourceLoader; 

public class Dream { 

    String windowTitle = "Dream - By William Starkovich"; 
    public boolean closeRequested = false; 

    Player player; 
    Vector3f camPos; 
    float camYaw; 
    float camRadius; 
    float rjoyAngle = 0; 
    Controllers controllers ; 
    Controller joystick; 
    Texture playerTex[][]; 
    Texture floorTex; 
    float dirYaw; 
    float playerViewYaw; 
    long lastFrameTime; // used to calculate delta 
    float fieldSize = 500; 
    float groundDepth = 5; 

    public void run() { 

     createWindow(); 
     getDelta(); // Initialise delta timer 
     init(); 
     initGL(); 


     while (!closeRequested) { 
      pollInput(getDelta()); 
      updateLogic(getDelta()); 
      renderGL(); 

      Display.update(); 
      Display.sync(60); 

     } 

     cleanup(); 
    } 


    public void init(){ 
     player = new Player(0,0,0); 
     camRadius = 25; 
     camYaw = 0; 
     camPos = new Vector3f(0,0,-camRadius); 
     playerTex = new Texture[1][8]; 

     try{ 

      floorTex = TextureLoader.getTexture("PNG", ResourceLoader.getResourceAsStream("data/graphics/floor.png"));     

      for(int i = 0; i < 1; i++){ 
       for(int j = 0; j < 8; j++){ 
        playerTex[i][j] = TextureLoader.getTexture("PNG", ResourceLoader.getResourceAsStream("data/graphics/player/enemy"+i+"-"+j+".png")); 
       } 
      } 

      controllers = new Controllers(); 
      Controllers.create(); 
       if (Controllers.getControllerCount() > 0) { 
        joystick = Controllers.getController(0); 
        joystick.setXAxisDeadZone(0.7f); 
        joystick.setYAxisDeadZone(0.7f); 
        joystick.setRXAxisDeadZone(0.7f); 
        joystick.setRYAxisDeadZone(0.7f); 
        System.out.println("Joystick has "+joystick.getButtonCount() +" buttons. Its name is "+joystick.getName()); 
       } 
       else joystick = null; 
     } 

     catch(Exception e){ 
      e.printStackTrace(); 
     } 
    } 

    private void initGL() { 

     /* OpenGL */ 
     int width = Display.getDisplayMode().getWidth(); 
     int height = Display.getDisplayMode().getHeight(); 

     GL11.glViewport(0, 0, width, height); // Reset The Current Viewport 
     GL11.glMatrixMode(GL11.GL_PROJECTION); // Select The Projection Matrix 
     GL11.glLoadIdentity(); // Reset The Projection Matrix 
     GLU.gluPerspective(45.0f, ((float) width/(float) height), 0.1f, 600.0f); // Calculate The Aspect Ratio Of The Window 
     GL11.glMatrixMode(GL11.GL_MODELVIEW); // Select The Modelview Matrix 
     GL11.glLoadIdentity(); // Reset The Modelview Matrix 

     GL11.glShadeModel(GL11.GL_SMOOTH); // Enables Smooth Shading 
     GL11.glClearColor(0, 0.3f, 0.5f, 1f); // Black Background 
     GL11.glClearDepth(1.0f); // Depth Buffer Setup 
     GL11.glEnable(GL11.GL_DEPTH_TEST); // Enables Depth Testing 
     GL11.glDepthFunc(GL11.GL_LEQUAL); // The Type Of Depth Test To Do 
     GL11.glHint(GL11.GL_PERSPECTIVE_CORRECTION_HINT, GL11.GL_NICEST); // Really Nice Perspective Calculations 
     GL11.glEnable(GL11.GL_TEXTURE_2D); 
     GL11.glEnable(GL11.GL_BLEND); 
     GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA); 
     GL11.glEnable(GL11.GL_ALPHA_TEST); 
     GL11.glAlphaFunc(GL11.GL_GREATER, 0.9f); 
    } 

    private void updateLogic(int delta) { 

     if (joystick != null) { 
      joystick.poll(); 


      rjoyAngle += ((joystick.getRXAxisValue()/5)); 
      rjoyAngle = ((rjoyAngle + 360) % 360); 

      System.out.println("rangle = " + rjoyAngle); 


      camPos.x = (float) (player.pos.x - (Math.sin(rjoyAngle) * camRadius)); 
      camPos.z = (float) (player.pos.z + (Math.cos(-rjoyAngle) * camRadius)); 

      camYaw = (float) ((Math.toDegrees(((Math.atan2(-(camPos.x - player.pos.x), -(camPos.z - player.pos.z)))))+ 360) % 360); 
      System.out.println("Cam X: " + camPos.x + " Z: " + camPos.z + " yaw: " + camYaw); 


      float pyaw = ((player.yaw + 360) % 360); 
      float eyaw = ((camYaw + 360) % 360); 
      dirYaw = (pyaw + eyaw) % 360; 

      if(joystick.getXAxisValue() >= -0.5f && joystick.getXAxisValue() <= 0.5f && joystick.getYAxisValue() >= -0.5f && joystick.getYAxisValue() <= 0.5f){ 
       //deadzone? 
      } 

      else{ 
       player.yaw = (float) Math.toDegrees(Math.atan2(joystick.getXAxisValue(), joystick.getYAxisValue())); 
       pyaw = ((player.yaw + 360) % 360); 
       eyaw = ((camYaw + 360) % 360); 
       dirYaw = (pyaw + eyaw) % 360; 
       Vector3f move = new Vector3f(); 
       move.x -= 3 * (float)Math.sin(Math.toRadians(dirYaw)); 
       move.z -= 3 * (float)Math.cos(Math.toRadians(dirYaw)); 

       Vector3f.add(player.pos, move, player.pos); 

      } 

      pyaw = ((player.yaw + 360) % 360); 
      eyaw = ((camYaw + 360) % 360); 
      playerViewYaw = (dirYaw + eyaw) % 360; 
     } 

     player.update(); 
    } 


    private void loadIdentity(){ 
     /* OpenGL */ 
     int width = Display.getDisplayMode().getWidth(); 
     int height = Display.getDisplayMode().getHeight(); 

     GL11.glLoadIdentity(); // Reset The Modelview Matrix 
     //roatate the yaw around the Y axis 
     GL11.glRotatef(camYaw, 0.0f, -1.0f, 0.0f); 
     GL11.glTranslatef(camPos.x, -3, camPos.z); 
    } 

    private void renderGL() { 

     GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT); // Clear The Screen And The Depth Buffer 
     loadIdentity(); // Reset The View 


     floorTex.bind(); 
     GL11.glTexParameterf(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_S, GL11.GL_REPEAT); 
     GL11.glTexParameterf(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_T, GL11.GL_REPEAT); 

     GL11.glBegin(GL11.GL_QUADS); // Start Drawing The Cube 
      GL11.glColor3f(1.0f, 1.0f, 1.0f); // Set The Color To White 
       GL11.glTexCoord2f(0,0);                    GL11.glVertex3f(-fieldSize, -groundDepth, -fieldSize); // Top left Of The Quad (bottom) 
       GL11.glTexCoord2f(fieldSize/floorTex.getTextureWidth(),0);           GL11.glVertex3f(fieldSize, -groundDepth, -fieldSize); // Top right Of The Quad (bottom) 
       GL11.glTexCoord2f(fieldSize/floorTex.getTextureWidth(),fieldSize/floorTex.getTextureHeight());  GL11.glVertex3f(fieldSize, -groundDepth, fieldSize); // Bottom right Of The Quad (bottom) 
       GL11.glTexCoord2f(0,fieldSize/floorTex.getTextureHeight());           GL11.glVertex3f(-fieldSize, -groundDepth, fieldSize); // Bottom left Of The Quad (bottom) 
     GL11.glEnd(); // Done Drawing The Quad 

     int direction = getSpriteNum(playerViewYaw); 

     drawBillBoardSprite(playerTex[0][direction],player.pos, 0, 1,1,1, 5, 10); 
    } 


    public int getSpriteNum(float direction){ 
     direction = (float) Math.abs(Math.floor((direction + 22.5)/45.0)); 

    // direction = direction * 2; 

     if (direction == 8) direction = 0; 

     return (int)direction; 
    } 

    public void drawBillBoardSprite(Texture texture, Vector3f sprPos, float y, float r, float g, float b, float sprWidth, float sprHeight){ 
     // store the current model matrix 
     GL11.glPushMatrix(); 
      GL11.glColor3f(r,g,b); 
      GL11.glTranslatef(-sprPos.x, y, -sprPos.z); 
      // bind to the appropriate texture for this sprite 
      texture.bind(); 

      FloatBuffer modelview = BufferUtils.createFloatBuffer(16); 

      // get the current modelview matrix 
      GL11.glGetFloat(GL11.GL_MODELVIEW_MATRIX, modelview); 

      // Note that a row in the C convention is a column 
      // in OpenGL convention (see the red book, pg.106 in version 1.2) 
      // right vector is [1,0,0] (1st column) 
      // lookAt vector is [0,0,1] (3d column) 
      // leave the up vector unchanged (2nd column) 
      // notice the increment in i in the first cycle (i+=2) 
      for(int i=0; i<3; i+=2) 
       for(int j=0; j<3; j++) { 
        if (i==j) 
         modelview.put(i*4+j, 1.0f); 
        else 
         modelview.put(i*4+j, 0.0f); 
       } 

      // set the modelview matrix 
      GL11.glLoadMatrix(modelview); 

      // draw a quad textured to match the sprite 
      GL11.glBegin(GL11.GL_QUADS); 
       GL11.glTexCoord2f(0,0);          GL11.glVertex3f((float) - (sprWidth/2),(float) (sprHeight/2), 0); // Top left Of The Quad (Left) 
       GL11.glTexCoord2f(texture.getWidth(), 0);     GL11.glVertex3f((float) + (sprWidth/2),(float) (sprHeight/2), 0); // Top right Of The Quad (Left) 
       GL11.glTexCoord2f(texture.getWidth(), texture.getHeight()); GL11.glVertex3f((float) + (sprWidth/2),(float) -(sprHeight/2), 0); // Bottom right Of The Quad (Left) 
       GL11.glTexCoord2f(0, texture.getHeight());     GL11.glVertex3f((float) - (sprWidth/2),(float) -(sprHeight/2), 0); // Bottom left Of The Quad (Left) 
      GL11.glEnd(); 

     // restore the model view matrix to prevent contamination 
     GL11.glPopMatrix(); 
    } 

    /** 
    * Poll Input 
    */ 
    public void pollInput(float delta) {  

     if (Keyboard.isKeyDown(Keyboard.KEY_F12)){ 
      closeRequested = true; 
     } 

     if (Display.isCloseRequested()) { 
      closeRequested = true; 
     } 
    } 

    /** 
    * Calculate how many milliseconds have passed 
    * since last frame. 
    * 
    * @return milliseconds passed since last frame 
    */ 
    public int getDelta() { 
     long time = (Sys.getTime() * 1000)/Sys.getTimerResolution(); 
     int delta = (int) (time - lastFrameTime); 
     lastFrameTime = time; 

     return delta; 
    } 


    private void createWindow() { 
     try { 
      Display.setDisplayMode(new DisplayMode(640, 480)); 
      Display.setFullscreen(true); 
      Display.setVSyncEnabled(true); 
      Display.setTitle(windowTitle); 
      Display.create(); 

      //hide the mouse 
      Mouse.setGrabbed(true); 
     } catch (LWJGLException e) { 
      Sys.alert("Error", "Initialization failed!\n\n" + e.getMessage()); 
      System.exit(0); 
     } 
    } 

    /** 
    * Destroy and clean up resources 
    */ 
    private void cleanup() { 
     Display.destroy(); 
    } 

    public static void main(String[] args) { 
     Dream dream = new Dream(); 
     dream.run(); 
    } 
} 

Player.java:

import java.util.Vector; 

import org.lwjgl.util.vector.Vector3f; 


public class Player { 
    float mouseSensitivity = 0.05f; 
    float movementSpeed = 0.04f; //move 10 units per second 

    Vector3f pos; 
    float yaw = 0; 
    float pitch = 0; 
    float maxPitch = 90; 

    float width = 1; 
    float height = 1; 

    int inFieldType = 0; 


    public Player(float sx, float sz, float sa){ 
     pos = new Vector3f(sx,0,sz); 
     yaw = sa; 
    } 

    public void update(){ 

    } 
} 

这里是(在Eclipse)演示项目: http://dl.dropbox.com/u/28109593/Dream.zip

+0

我无法弄清楚什么是错误的,也不是非常倾向于通过代码转储来猜测。你期待什么行为?发生了什么呢? – 2012-01-10 01:30:29

+0

我期待着我可以旋转相机来查看所有8个角色的角度,然后从相机所在的位置,我可以向上推动操纵杆,使他走向相机所面对的方向,并将角色转换为背面相机。现在它可以完成所有这些,除了将精灵旋转到背对着相机。 – CyanPrime 2012-01-10 01:36:09

+0

您是否真的编写过代码来尝试让精灵转身朝向相机?如果是这样,那比你发布的任何其他东西都更有意义。另外你的'Player'类中的'update()'方法是空的,你期望它做什么? – Deco 2012-01-10 02:37:26

回答

0

这是你的问题(updateLogic()线147/157和168):

dirYaw = (pyaw + eyaw) % 360; 
... 
playerViewYaw = (dirYaw + eyaw) % 360; 

您正试图计算玩家的查看方向,但是您执行的赔偿是两次。 (另外,我想你会想要减去从玩家偏航的相机偏航以获得相机正在查看玩家的角度)。