Я нахожусь на длинном пути разработки моей собственной маленькой игры MMORPG с использованием LWJGL. До сих пор я импортировал кролика в свою игру, а sorta просто позировал его выше травы. Как это:
Я хочу, чтобы мои объекты в игре могли взаимодействовать. Например, нажатие на них вызовет небольшое меню опций или сделает это, когда вы столкнетесь с ними, что-то произойдет. Для этого мне нужно обнаружение столкновения. Я работал с ним раньше в 2D-играх, что намного проще.
Вот мой класс Bunny.java:
public class Bunny {
public static Model m = null;
public static int displayList;
public static void init() {
displayList = glGenLists(1);
glNewList(displayList, GL_COMPILE);
{
try {
m = OBJLoader.loadModel(new File("res/models/bunny.obj"));
} catch (FileNotFoundException e) {
e.printStackTrace();
Display.destroy();
System.exit(1);
} catch (IOException e) {
e.printStackTrace();
Display.destroy();
System.exit(1);
}
glBegin(GL_TRIANGLES);
for (Face face : m.faces) {
Vector3f n1 = m.normals.get((int) face.normal.x - 1);
glNormal3f(n1.x, n1.y, n1.z);
Vector3f v1 = m.vertices.get((int) face.vertex.x - 1);
glVertex3f(v1.x, v1.y, v1.z);
Vector3f n2 = m.normals.get((int) face.normal.y - 1);
glNormal3f(n2.x, n2.y, n2.z);
Vector3f v2 = m.vertices.get((int) face.vertex.y - 1);
glVertex3f(v2.x, v2.y, v2.z);
Vector3f n3 = m.normals.get((int) face.normal.z - 1);
glNormal3f(n3.x, n3.y, n3.z);
Vector3f v3 = m.vertices.get((int) face.vertex.z - 1);
glVertex3f(v3.x, v3.y, v3.z);
}
glEnd();
}
glEndList();
}
public static void draw(float x, float y, float z) {
glPushMatrix();
glTranslatef(x, y, z);
glCallList(displayList);
glPopMatrix();
}
}
И мой Основной класс:
public class Main {
public static float PlayerX = 0;
public static float PlayerY = 0;
public static float PlayerZ = 0;
public static float walkSpeed = 0.016f;
public static float PlayerRot = 0;
private static float[] lightPosition = {-2.19f, 1.36f, 11.45f, 1f};
public float pCenterX = 0;
public float pCenterY = 0;
public float pCenterZ = 0;
public static Model m = null;
public static void main(String[] args) {
initDisplay();
Bunny.init();
gameLoop();
cleanUp();
}
public static void gameLoop() {
Texture tex = loadTexture("tex", "png");
Texture wood = loadTexture("wood", "png");
loadLight();
Camera camera = new Camera(70, (float) Display.getWidth() / (float) Display.getHeight(), 0.3f, 1000);
while (!Display.isCloseRequested()) {
if(Keyboard.isKeyDown(Keyboard.KEY_W)) camera.move(walkSpeed, 1);
if(Keyboard.isKeyDown(Keyboard.KEY_S)) camera.move(-walkSpeed, 1);
if(Keyboard.isKeyDown(Keyboard.KEY_A)) camera.rotateY(-0.1f);
if(Keyboard.isKeyDown(Keyboard.KEY_D)) camera.rotateY(0.1f);
if(Keyboard.isKeyDown(Keyboard.KEY_SPACE)) camera.moveY(0.05f, 1);
if(Keyboard.isKeyDown(Keyboard.KEY_Z)) camera.moveY(0.05f, 0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
glTranslatef(0, 2.5f, 0);
glLoadIdentity();
//camera.setX(-PlayerX); camera.setY(-PlayerY - 3); camera.setZ(-PlayerZ - 10);
glLight(GL_LIGHT0, GL_POSITION, asFloatBuffer(new float[] {-2.19f, 1.36f, 11.45f, 1f}));
camera.useView();
//Draw.rect(PlayerX, PlayerY, PlayerZ, 0.5f, 0.5f, 0.5f, tex);
Draw.rect(1, 0, 1, 100, 0.5f, 100, wood);
Bunny.draw(10, 2.5f, 10);
Bunny.draw(50, 2.5f, 50);
Display.update();
}
}
public static void cleanUp() {
Display.destroy();
}
public static void initDisplay() {
try {
Display.setDisplayMode(new DisplayMode(800, 600));
Display.create();
} catch (LWJGLException e) {
e.printStackTrace();
}
}
public static Texture loadTexture(String key, String fileType) {
try {
return TextureLoader.getTexture(fileType, new FileInputStream(new File("res/img/" + key + "." + fileType)));
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
private static FloatBuffer asFloatBuffer(float[] values) {
FloatBuffer buffer = BufferUtils.createFloatBuffer(values.length);
buffer.put(values);
buffer.flip();
return buffer;
}
public static void loadLight() {
glShadeModel(GL_SMOOTH);
glEnable(GL_DEPTH_TEST);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glLightModel(GL_LIGHT_MODEL_AMBIENT, asFloatBuffer(new float[] {0.05f, 0.05f, 0.05f, 1f}));
glLight(GL_LIGHT0, GL_DIFFUSE, asFloatBuffer(new float[] {1.5f, 1.5f, 1.5f, 1f}));
//glEnable(GL_CULL_FACE);
//glCullFace(GL_BACK);
glEnable(GL_COLOR_MATERIAL);
glColorMaterial(GL_FRONT, GL_DIFFUSE);
}
}
Как я могу получить точки кролика и использовать их в алгоритме для обнаружения, когда мы столкнулись?
Вы уже показали код для вершин в первом фрагменте. Итак, у вас есть они.
Что касается второй части вопроса: то, что вы ищете, - это обнаружение и сбор столкновений. Покрытие их в ответ слишком много, поэтому вам придется искать их.
Один из способов сделать это - график сцены.
Это дает древовидную структуру. Теперь вы просто проверяете, произошло ли столкновение, проверив ограничивающие поля узла против партнера по конфликтам. Если он попадает вам, проверьте его подносы и объекты для столкновения. Если у вас есть удар для объекта, вы делаете еще одну проверку, основанную на фактических данных модели.
Для обычных объектов вы используете свои ограничивающие поля и данные для проверки. Для выбора вы используете луч, стрелянный из координат мира щелчка мыши.
Это как раз для этого, но в этой теме есть много оттенков. Например, OpenGL предлагает свою собственную поддержку выбора.