Hallo, ich habe ein Spiel in First Person Perspektive, die man ändern kann, indem man die Maus bewegt. Dazu ist sie unsichtbar und wird immer wieder in die Mitte des Displays gesetzt. Und ich prüfe, wie die Maus vor dem Zurücksetzten zum Mittelpunkt steht und setze so die Kamera. Die zwei Punkte der Kamera sind die Kameraposition und die Fokusposition. Der Vektor dieser Punkte ist die Blickrichtung, der Fokuspunkt bewegt sich auf Kreisbahnen um die Kameraposition. Das Problem ist, dass das ganze wackelig und sehr merkwürdig ist. Es lässt sich schwer in Worte fassen, deshalb ein KSKB:
import static org.lwjgl.opengl.GL11.GL_BLEND;
import static org.lwjgl.opengl.GL11.GL_COLOR_BUFFER_BIT;
import static org.lwjgl.opengl.GL11.GL_DEPTH_BUFFER_BIT;
import static org.lwjgl.opengl.GL11.GL_DEPTH_TEST;
import static org.lwjgl.opengl.GL11.GL_MODELVIEW;
import static org.lwjgl.opengl.GL11.GL_ONE;
import static org.lwjgl.opengl.GL11.GL_PROJECTION;
import static org.lwjgl.opengl.GL11.GL_SRC_ALPHA;
import static org.lwjgl.opengl.GL11.GL_TRIANGLES;
import static org.lwjgl.opengl.GL11.*;
import java.awt.Canvas;
import java.awt.Dimension;
import java.awt.Point;
import java.awt.event.HierarchyBoundsListener;
import java.awt.event.HierarchyEvent;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.IntBuffer;
import javax.swing.JFrame;
import org.lwjgl.LWJGLException;
import org.lwjgl.input.Cursor;
import org.lwjgl.input.Keyboard;
import org.lwjgl.input.Mouse;
import org.lwjgl.opengl.Display;
import org.lwjgl.util.glu.GLU;
public class Main implements HierarchyBoundsListener{
public static void main(String[] args){
new Main();
}
private JFrame f;
private Cursor normalCursor;
private Cursor invisibleCursor;
private int w, h;
private float camX = 0;
private float camY = 3;
private float camZ = 0;
private float camFocusX = 5;
private float camFocusY = 3;
private float camFocusZ = 0;
private float upX = 0;
private float upY = 1;
private float upZ = 0;
private boolean gestartet;
private double camAlphaYZ;
private float camAlphaXZ;
private boolean exited;
public Main(){
f = new JFrame("Krieger und Burgen");
f.getContentPane().addHierarchyBoundsListener(this);
f.setPreferredSize(new Dimension(700, 550));
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setLocation(900, 50);
f.pack();
Canvas canvas = new Canvas();
f.add(canvas);
try {
Display.setParent(canvas);
f.setVisible(true);
Display.create();
normalCursor = Mouse.getNativeCursor();
int[] ints = {
0, 0, 0, 0
};
invisibleCursor = new Cursor(1, 1, 0, 0, 1, putIntCoords(ints), putIntCoords(ints));
Mouse.setNativeCursor(invisibleCursor);
} catch (LWJGLException e) {
e.printStackTrace();
}
gestartet = true;
w = Display.getWidth();
h = Display.getHeight();
new Thread(new Runnable(){
@Override
public void run() {
while(!Display.isCloseRequested()){
while(Keyboard.next()){
if(Keyboard.isKeyDown(Keyboard.KEY_ESCAPE)){
exited = true;
try {
Mouse.setNativeCursor(normalCursor);
} catch (LWJGLException e) {
e.printStackTrace();
}
}
}
if(!exited){
if(Mouse.getX() < w/2){
camAlphaXZ -= 0.005;
camFocusX = getCirclePosition((float)camAlphaXZ, 5.0f, new Point((int)camX, (int)camZ)).x;
camFocusZ = getCirclePosition((float)camAlphaXZ, 5.0f, new Point((int)camX, (int)camZ)).y;
Mouse.setCursorPosition(w/2, h/2);
}
if(Mouse.getX() > w/2){
camAlphaXZ += 0.005;
camFocusX = getCirclePosition((float)camAlphaXZ, 5.0f, new Point((int)camX, (int)camZ)).x;
camFocusZ = getCirclePosition((float)camAlphaXZ, 5.0f, new Point((int)camX, (int)camZ)).y;
Mouse.setCursorPosition(w/2, h/2);
}
if(Mouse.getY() > h/2){
camAlphaYZ += 0.005;
camFocusZ = getCirclePosition((float)camAlphaYZ, 5.0f, new Point((int)camY, (int)camZ)).x;
camFocusY = getCirclePosition((float)camAlphaYZ, 5.0f, new Point((int)camY, (int)camZ)).y;
Mouse.setCursorPosition(w/2, h/2);
}
if(Mouse.getY() < h/2){
camAlphaYZ -= 0.005;
camFocusZ = getCirclePosition((float)camAlphaYZ, 5.0f, new Point((int)camY, (int)camZ)).x;
camFocusY = getCirclePosition((float)camAlphaYZ, 5.0f, new Point((int)camY, (int)camZ)).y;
Mouse.setCursorPosition(w/2, h/2);
}
}
}
}
}).start();
Mouse.setCursorPosition(w/2, h/2);
while(!Display.isCloseRequested()){
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glViewport(0, 0, w, h);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_SRC_ALPHA);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
GLU.gluPerspective(45.0f, (float) w / (float) h, 0.1f, 1000);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
GLU.gluLookAt(camX, camY, camZ, camFocusX, camFocusY, camFocusZ, upX, upY, upZ);
glDisable(GL_BLEND);
glViewport( 0, 0, w, h);
glColor4f(0, 1, 0, 1);
glBegin(GL_TRIANGLES);
glVertex3f(25, 0,-25);
glVertex3f(-25, 0, -25);
glVertex3f(-25, 0, 25);
glVertex3f(-25, 0, 25);
glVertex3f(25, 0, 25);
glVertex3f(25, 0, -25);
glEnd();
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE);
glDisable(GL_DEPTH_TEST);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
GLU.gluOrtho2D(0, w, h, 0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glColor4f(1, 1, 1, 1);
glBegin(GL_TRIANGLES);
glVertex3f((w-20)/2+20, (h-20)/2, 0);
glVertex3f((w-20)/2, (h-20)/2, 0);
glVertex3f((w-20)/2, (h-20)/2+20, 0);
glVertex3f((w-20)/2, (h-20)/2+20, 0);
glVertex3f((w-20)/2+20, (h-20)/2+20, 0);
glVertex3f((w-20)/2+20, (h-20)/2, 0);
glEnd();
glEnable(GL_DEPTH_TEST);
Display.update();
}
}
public static IntBuffer putIntCoords(int[] ints){
ByteBuffer vbb = ByteBuffer.allocateDirect(ints.length * 4);
vbb.order(ByteOrder.nativeOrder());
IntBuffer vertexBuffer = vbb.asIntBuffer();
vertexBuffer.put(ints);
vertexBuffer.position(0);
return vertexBuffer;
}
@Override
public void ancestorMoved(HierarchyEvent arg0) {
}
@Override
public void ancestorResized(HierarchyEvent arg0) {
if(gestartet){
h = Display.getHeight();
w = Display.getWidth();
}
}
public Point getCirclePosition(float angle, float r, Point mittelPos){
double x = Math.cos(angle)*r+mittelPos.x;
double y = Math.sin(angle)*r+mittelPos.y;
return new Point((int)x, (int)y);
}
}
Warum ist das so unkomfortabel zu steuern und was kann man besser machen ?