Opóźniona reakcja po przytrzymaniu klawisza (GLUT)

0

Witam,
korzystałem z tego poradnika: Kurs programowania GLUT
Tworzę grę FPS w GLUT'cie i majstruję teraz nad sterowaniem. Niestety gdy używam funkcji:

glutKeyboardFunc(&keyPressed); 

program ma opóźnioną reakcję. Tzn. gdy przytrzymuję klawisz, akcja wykonuje się dopiero po sekundzie :/
Czy jest jakiś sposób żeby akcja zaczynała się natychmiast po przytrzymaniu klawisza? Do kogo się zwrócić z takim pytaniem?
Pozdrawiam,
St4rKiller070

0

Czy jest jakiś sposób żeby akcja zaczynała się natychmiast po przytrzymaniu klawisza?

Akcja zawsze rozpoczyna się natychmiast (mam na myśli wywołanie callbacka tj. ~ kilkadziesiąt ms), jeśli nie to znaczy, że coś jest nie tak w twoim kodzie. Pokaż kod to spróbuje ci pomóc.

Do kogo się zwrócić z takim pytaniem?

Na przykład do mnie ;)

0
yurai napisał(a)

Czy jest jakiś sposób żeby akcja zaczynała się natychmiast po przytrzymaniu klawisza?

Akcja zawsze rozpoczyna się natychmiast (mam na myśli wywołanie callbacka tj. ~ kilkadziesiąt ms), jeśli nie to znaczy, że coś jest nie tak w twoim kodzie. Pokaż kod to spróbuje ci pomóc.

Do kogo się zwrócić z takim pytaniem?

Na przykład do mnie ;)

Więc proszę oto kod :) Porównywałem go z innymi projektami znalezionymi w internecie, one działały dobrze. Tymczasem mój ma jakieś opóźnienie :/ Tzn. na pojedyncze kliknięcie program reaguje natychmiast. Jeśli jednak przytrzymam, jest sekundowe opóźnienie.
main.cpp

 #include <GL/glut.h>    // Header File For The GLUT Library
#include <iostream>
#include "zmienne.cpp"
#include "okno.cpp"

zmienne zm;
okno o;
int zmienne::window;
unsigned int zmienne::window_width = 640;
unsigned int zmienne::window_height = 480;
unsigned int zmienne::mouse_x = 0;
unsigned int zmienne::mouse_y = 0;
float zmienne::playerX = 0;
float zmienne::playerY = 0;
float zmienne::playerZ = 0;
float zmienne::lookUpDown = 0;
float zmienne::lookLeftRight = 0;
//void okno::InitGL(int Width, int Height);

void keyPressed(unsigned char key, int x, int y)
{
    if(key == 'w'){
        zm.playerZ += 0.1;
    }
    if(key == 's'){
        zm.playerZ -= 0.1;
    }
    if(key == 'a'){
        zm.playerX += 0.1;
    }
    if(key == 'd'){
        zm.playerX -= 0.1;
    }
    if(key == '`'){
        exit(0);
    }
    std::cout << key;
}

void ButtonPressed(int x, int y){

}

/* Ta funkcja pilnuje, Âżeby po zmianie rozmiaru okna, aplikacja do tego rozmiaru siĂŞ dostosowywaÂła */
void ReSizeGLScene(int Width, int Height)
{
    if (Height==0)                                // Zabezpiecznie przed dzieleniem przez zero (gdy okno jest zbyt maÂłe)
        Height=1;
    glViewport(0, 0, Width, Height);                // Restartowanie obrazu, perpektywy itp.
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluPerspective(45.0f,(GLfloat)Width/(GLfloat)Height,0.1f,100.0f); //nowa perspektywa
    glMatrixMode(GL_MODELVIEW);
}

/* The main drawing function. */
void DrawGLScene()
{
    //glutWarpPointer(zm.window_width / 2, zm.window_height / 2);
    glutSetWindow(zm.window);        //Ustala aktywne okno

    glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);        // Czyści okno i bufor głebokości
    glLoadIdentity();                                // Restartuje widok

    glRotatef(zm.lookUpDown,1.0f,0.0f,0.0f); //Obrot w osi X
    glRotatef(zm.lookLeftRight,0.0f,1.0f,0.0f); //Obrot w osi Y

    glTranslatef(0.0+zm.playerX, 0.0 + zm.playerY, -5.0 + zm.playerZ); //przesuwa obraz :)

    glColor3f(0.0f, 1.0f, 1.0f);
    glBegin(GL_QUADS); //Rysuj czworokaty
        glColor3f(0.0f,1.0f,0.0f);         // Zielony
        glVertex3f( 1.0f, 1.0f,-1.0f);         // Prawy górny punkt (Góra)
        glVertex3f(-1.0f, 1.0f,-1.0f);         // Lewy górny punkt (Góra)
        glVertex3f(-1.0f, 1.0f, 1.0f);         // Lewy dolny punkt (Góra)
        glVertex3f( 1.0f, 1.0f, 1.0f);         // Prawy dolny (Góra)

        glColor3f(1.0f,0.5f,0.0f);         // Pomarańczowy
        glVertex3f( 1.0f,-1.0f, 1.0f);         // Prawy górny (Dół)
        glVertex3f(-1.0f,-1.0f, 1.0f);         // Lewy górny (Dół)
        glVertex3f(-1.0f,-1.0f,-1.0f);         // Lewy dolny (Dół)
        glVertex3f( 1.0f,-1.0f,-1.0f);         // Prawy dolny (Dół)

        glColor3f(1.0f,0.0f,0.0f);         // Czerwony
        glVertex3f( 1.0f, 1.0f, 1.0f);         // Prawy górny (Przód)
        glVertex3f(-1.0f, 1.0f, 1.0f);         // Lewy górny (Przód)
        glVertex3f(-1.0f,-1.0f, 1.0f);         // Lewy dolny (Przód)
        glVertex3f( 1.0f,-1.0f, 1.0f);         // Prawy dolny (Przód)

         glColor3f(1.0f,1.0f,0.0f);         // Żółty
        glVertex3f( 1.0f,-1.0f,-1.0f);         // Lewy dolny (Tył)
        glVertex3f(-1.0f,-1.0f,-1.0f);         // Prawy dolny (Tył)
        glVertex3f(-1.0f, 1.0f,-1.0f);         // Prawy górny (Tył)
        glVertex3f( 1.0f, 1.0f,-1.0f);         // Lewy górny (Tył)

        glColor3f(0.0f,0.0f,1.0f);         // Niebieski
        glVertex3f(-1.0f, 1.0f, 1.0f);         // Prawy górny (Lewa)
        glVertex3f(-1.0f, 1.0f,-1.0f);         // Lewy górny (Lewa)
        glVertex3f(-1.0f,-1.0f,-1.0f);         // Lewy dolny (Lewa)
        glVertex3f(-1.0f,-1.0f, 1.0f);         // Prawy dolny (Lewa)

        glColor3f(1.0f,0.0f,1.0f);         // Fioletowy
        glVertex3f( 1.0f, 1.0f,-1.0f);         // Prawy górny (Prawa)
        glVertex3f( 1.0f, 1.0f, 1.0f);         // Lewy górny (Prawa)
        glVertex3f( 1.0f,-1.0f, 1.0f);         // Lewy dolny (Prawa)
        glVertex3f( 1.0f,-1.0f,-1.0f);         // Prawy dolny (Prawa)
    glEnd();

     unsigned char pixel[3];
    glReadPixels(zm.mouse_x, zm.mouse_y, 1, 1, GL_RGB, GL_UNSIGNED_BYTE, pixel);
    //std::cout << "R: " << (int)pixel[0] << std::endl;
    //std::cout << "G: " << (int)pixel[1] << std::endl;
    //std::cout << "B: " << (int)pixel[2] << std::endl;
    //std::cout << std::endl;

    glFlush();
    glutSwapBuffers();
}


void motion(int x, int y)
{
    zm.mouse_x = x;
    zm.mouse_y = zm.window_height - y;
    glutPostRedisplay();
}

int main(int argc, char **argv)
{
  /* Initialize GLUT state - glut will take any command line arguments that pertain to it or
     X Windows - look at its documentation at http://reality.sgi.com/mjk/spec3/spec3.html */
  glutInit(&argc, argv);
  glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_ALPHA | GLUT_DEPTH);
  glutInitWindowSize(zm.window_width, zm.window_height);
  glutInitWindowPosition(0, 0);
  zm.window = glutCreateWindow("GLUT TUTORIAL #2");

  glutDisplayFunc(&DrawGLScene);
  glutReshapeFunc(&ReSizeGLScene);


  //Ustalenie funkcji
  //glutKeyboardFunc(&keyPressed);        // która zostanie wywołana po wciśnięciu klawisza
  //glutMotionFunc(&ruchMychyP);                // po ruchu myszki z przyciskiem

  //glutMouseFunc(&mButtonPressed);        // po wciśnięciu przycisku
  glutKeyboardFunc(keyPressed);
  o.InitGL(640, 480);
  glutIdleFunc(&DrawGLScene);
  //glutPassiveMotionFunc(motion);
  glutMainLoop();
  glutDestroyWindow(zm.window);

  return 1;
}

okno.cpp

 #include <GL/glut.h>    // Header File For The GLUT Library
class okno{
    public:
        /* Funckcja która ustawia wszystkie parametry, potrzebne do funkcjonowania aplikacji */
        void InitGL(int Width, int Height)                // Wykonuje siê zaraz po utworzeniu okna
        {
            glClearColor(0.0f, 0.0f, 0.0f, 0.0f);                // Czysci ekrain, ustawia kolor na czarny
            glClearDepth(1.0);                                // Czysci obiekty, ktore sa oddalone wiecej niz 1.0f
            glDepthFunc(GL_LESS);                                // warunek jest spe³niony (tzn. piksel jest rysowany na ekranie i zapisywany w buforze Z), kiedy obecna (sprawdzana) wartoœæ z jest mniejsza od poprzednio zapamiêtanej.
            glEnable(GL_DEPTH_TEST);                        // Funkcja dba o to, ¿eby obiekty ktore sa dalej byly wyswietlane dalej
            glShadeModel(GL_FLAT);                        // Cieniowanie p³askie

            glMatrixMode(GL_PROJECTION);
            glLoadIdentity();                                // Restartuje macierze.

            gluPerspective(45.0f,(GLfloat)Width/(GLfloat)Height,0.1f,100.0f);        // Perspektywa

            glMatrixMode(GL_MODELVIEW);
        }

};

zmienne.cpp

 class zmienne{
    public:
        static int window; /* Numer aktywnego okna */

        //Zmienne przechowuj¹ce
        static float r,g,b;        //kolor "t³a"

        static unsigned int window_width;
        static unsigned int window_height;
        static unsigned int mouse_x;
        static unsigned int mouse_y;
        static float playerX;
        static float playerZ;
        static float playerY;
        static float lookUpDown;
        static float lookLeftRight;

        /*void run_zmienne(){
            window_width = 640;
            window_height = 480;
            mouse_x = 0;
            mouse_y = 0;
            r = 0;
            g = 0;
            b = 0;
        } */
};

Być może ma to związek z tym, że po raz pierwszy rozbijałem projekt na klasy. Nigdy czegoś takiego nie robilem, więc jest duże prawdopodobieństwo że jest źle :)
Z góry dziękuję za odpowiedzi!!!

0

w twoim problemie ci niestety nie pomogę jednak jeśli mogę coś doradzić to nie mieszaj nazewnictwa angielskiego z polskim, źle się na to patrzy.

1

próbowałeś dodać glutPostRedisplay(); do keyPressed()?

1

Jeśli chodzi o program to powiem tak: uruchomiłem go i szczerze mówiąc nie wiem za bardzo co ci w nim przeszkadza. Możliwe że czepiasz się tego, że przytrzymując klawisz następuje ruch, później mamy dłuższą przerwe (~ 1s), a następnie trzymając dalej ruch już jest płynny. glutPostRedisplay nie załatwia sprawy, ale mimo to powinieneś go dodać do keyPressed.
Jeśli chcesz żeby ruch był płynny to obsłuż wciskanie i zwalnianie klawisza (zwalanianie za pomocą glutKeyboardUpFunc) trzymając jendnocześnie dodatkowe zmienne boolowskie (takie coś często się przydaje jeśli np. będzie wciskanych wiele klawiszy naraz).

Co do kodu to oprócz poprawy nazewnictwa powinieneś podzielić projekt na pliki .h i .cpp. No i koniecznie poczytaj o programowaniu obiektowym.

0

Twój program działa jak w wordzie. jak raz klikniesz a, to jest a, a jak przy trzymasz, to dopiero po sekundzie robią się płynnie następne aaaaaaaa.
musisz to zrobić wykorzystując takie coś

bool key_[260];

void keyPressed(unsigned char key, int x, int y)
{
key_[key] = true;
}

void keyUnPressed(unsigned char key, int x, int y)
{
key_[key] = false;
}

void keyboard()
{
if(key['w']){
zm.playerZ += 0.1;
}
if(key['s']){
zm.playerZ -= 0.1;
}
if(key['a']){
zm.playerX += 0.1;
}
if(key['d']){
zm.playerX -= 0.1;
}
if(key['`']){
exit(0);
}
std::cout << key;

glutTimerFunc(1, keyboard, 0);
}

////////////////////(w funkcji "main" dopisać)
glutKeyboardFunc(keyPressed)
glutKeyboardUpFunc(keyUnPressed)
glutTimerFunc(0, keyboard, 0);

i powinno hasać

0

błąd jest w tym co napisałem

funckja keyboard powinna wyglądać tak(wszystkie key powinny być key_):

void keyboard()
{
if(key_['w']){
zm.playerZ += 0.1;
}
if(key_['s']){
zm.playerZ -= 0.1;
}
if(key_['a']){
zm.playerX += 0.1;
}
if(key_['d']){
zm.playerX -= 0.1;
}
if(key_['`']){
exit(0);
}
std::cout < key;

glutTimerFunc(1, keyboard, 0);
}

Jakbyś miał jakieś pytania do mojej całkiem niejasnej odpowiedzi to pytaj

1 użytkowników online, w tym zalogowanych: 0, gości: 1