Объект под мышкой? - PullRequest
       1

Объект под мышкой?

0 голосов
/ 08 сентября 2010

Мой маленький игровой движок в основном имеет 3D-массив Cubes [x] [y] [z] (на самом деле это большой одномерный массив, но я немного перегружен).Я знаю, на каком кубе в XYZ стоит игрок.Игрок сможет стрелять кубом, чтобы уничтожить его, поэтому мне нужно выяснить, как найти куб, под которым находится мышь.Я нашел некоторую документацию OpenGL по комплектации, но этот метод был медленным.Поскольку мои кубы организованы, и я знаю, на каком кубе находится игрок, а также угол камеры по осям X и Y (камера не вращается по Z), и что мышь всегда находится на screenwidth / 2, screenheight / 2, я уверенTheres более быстрый способ, чем техника выбора gl.

Вот как настроена камера:

void CCubeGame::SetCameraMatrix()
{

    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();

    glRotatef(Camera.rotx,1,0,0);
    glRotatef(Camera.roty,0,1,0);
    glRotatef(Camera.rotz,0,0,1);

    glTranslatef(-Camera.x , -Camera.y,-Camera.z );
}

void CCubeGame::MouseMove(int x, int y)
{
    if(!isTrapped)
        return;

    int diffx = x-lastMouse.x; 
    int diffy = y-lastMouse.y; 

    lastMouse.x = x; 
    lastMouse.y = y;
    Camera.rotx += (float) diffy * 0.2; 
    Camera.roty += (float) diffx * 0.2; 
    if(Camera.rotx > 90)
    {
        Camera.rotx = 90;
    }

    if(Camera.rotx < -90)
    {
        Camera.rotx = -90;
    }

    if(isTrapped)
    if (fabs(ScreenDimensions.x/2 - x) > 1 || fabs(ScreenDimensions.y/2 - y) > 1) {
        resetPointer();
    }

}

Vertex3f CCubeGame::MoveCamera( int direction, float amount )
{
    float xrotrad, yrotrad;
    Vertex3f result(0,0,0);

    switch(direction)
    {
    case CAM_FORWARD:
        yrotrad = (Camera.roty / 180 * 3.141592654f);
        xrotrad = (Camera.rotx / 180 * 3.141592654f);

        result.x = float(sin(yrotrad)) * amount;
        result.z = -(float(cos(yrotrad)) * amount);
        result.y = 0;
        //Camera.y -= float(sin(xrotrad)) * amount;
        break;
    case CAM_BACKWARD:
        yrotrad = (Camera.roty / 180 * 3.141592654f);
        xrotrad = (Camera.rotx / 180 * 3.141592654f);
        result.x = -(float(sin(yrotrad)) * amount);
        result.z = float(cos(yrotrad)) * amount;
        result.y = 0;

        //Camera.y += float(sin(xrotrad)) * amount;
        break;
    case CAM_RIGHT:
        yrotrad = (Camera.roty / 180 * 3.141592654f);
        result.x = float(cos(yrotrad)) * amount;
        result.z += float(sin(yrotrad)) * amount;
        result.y = 0;
        break;
    case CAM_LEFT:
        yrotrad = (Camera.roty / 180 * 3.141592654f);
        result.x = -(float(cos(yrotrad)) * amount);
        result.z = -(float(sin(yrotrad)) * amount);
        result.y = 0;
        break;
    default:
        break;
    }

    Camera.x += result.x;
    Camera.y += result.y;
    Camera.z += result.z;

    return result;

}

Спасибо

1 Ответ

0 голосов
/ 08 сентября 2010

Если вы не можете вращаться по Z, то вы можете стрелять кубом только на той же высоте Z, на которой находится пистолет.Это делает вещи намного проще, потому что вы можете сортировать свои кубы по Z и выбрасывать те, которые слишком высоки или слишком низки (это займет log(N) время в количестве кубов, если они могут быть на дробных высотах; если онивсе одинаковой высоты и все на одной высоте, вы просто индексируете эту часть массива).

Теперь вам нужно нарисовать линию из пушки через сетку и выяснить, к какому ее кубу относитсябьет первымСпособ сделать это с помощью вектора вдоль линии пушки:

v = (cos(angle), sin(angle))

и найти каждую границу, где эта линия пересекает целое число в X или Y. Если мы находимся в

(x0,y0)

для начала и движение в направлении v, тогда мы нажмем (при условии, что cos (угол)> 0)

ceil(x0), ceil(x0+1), ...

иногда

(ceil(x0)-x0)/cos(angle), (ceil(x1)-x1)/cos(angle), ...

и аналогичноy0 и sin(angle).Теперь вы просто идете по списку раз - который приведет вас в новый квадрат - и когда вы впервые столкнетесь с кубом, вы нажмете на него.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...