Błąd odwołania do vectora [C++, openGL, QT]

0

Mam za zadanie napisać grę sieciową, wybrałem Pinga:

*mam już kod w c++

*wiem jak zainicjować "sieciowość"

Wymyśliłem sobie, że umieszczę to w QT i przenosząc kod natrafiłem na kilka błędów. Zrozumiałem z różnych poradników, że OpenGL w QT implementuję się w następujący sposób: tworzę widget -> zmieniam jego klasę na dziedziczącą po QGLWidget w moim przypadku PanelOpengl. -> tam umieszczam void initializeGL(), void resizeGL(int w, int h) ,void paintGL(). Tak zrobiłem i przykładowe programy mi chodziły. Jednak nie wiem czy dobrze zaimplementowałem moją grę?

PLIK NAGŁÓWKOWY

class PanelOpengl : public QGLWidget
{
    Q_OBJECT
public:
    explicit PanelOpengl(QWidget *parent = 0);
    ~PanelOpengl();
 
    void drawText(int x, int y, char *string); // rysuje napis "string" w pozycji x, y
    void drawText2(int x, int y, char *string);
    void loop();
    void key(unsigned char key, int x, int y);
    static void mouse(int klawisz, int stan, int x_d, int y_d); //zmiana pozycji zoltej i czerwonej paletki przy kliknieciu
    void mouse1(int x_d, int y_d);//poruszanie paletka nr 1 przy pomocy myszki
    void mouse2(int x_d, int y_d); //poruszanie paletka nr 2 przy pomocy myszki
 
protected:
 
    void initializeGL();
    void resizeGL(int w, int h);
    void paintGL();
 
public slots:
 
private:
 
    std::vector <Okrag*> pPilka;
    std::vector <Prostokat*> pPaletka;
    std::vector <Prostokat*> pSciana;
    std::vector <Prostokat*> pScianaP;
    Prostokat p[10];
    int punkty1;
    int punkty2;
    int licznik;
 
    int etap;
 
};

WYBRANE METODY PLIK .CPP

PanelOpengl::PanelOpengl(QWidget *parent) : QGLWidget(parent)
{
   setFormat(QGL::DoubleBuffer | QGL::DepthBuffer);
 
   punkty1 = 0;
   punkty2 = 0;
   licznik = 1;
       //piłka
      // pPilka.push_back(new Okrag(0, 0, 0.6, 0, 0, 1));
       pPilka.push_back(new Okrag(0,0,1,1,0,0));
       //paletka
       pPaletka.push_back(new Prostokat(-18, 0, 1, 10, 1, 0, 0));//MOŻE BEZ WSKAŹNIKÓW TUTAJ
       pPaletka.push_back(new Prostokat(18, 0, 1, 10, 1, 1, 0));
 
       //ściany
       pSciana.push_back(new Prostokat(0, 40, 102, 3, 0, 0, 1));
       pSciana.push_back(new Prostokat(0, -40, 102, 3, 0, 0, 1));
 
       //ściany punktujące
       pScianaP.push_back(new Prostokat(52, 0, 3, 84, 0, 1, 0));
       pScianaP.push_back(new Prostokat(-52, 0, 3, 84, 0, 1, 0));
 
}
 
 
void PanelOpengl::loop()
{
 
    //sprawdzanie kolizji ze ścianami
    for (int i = 0; i < 4; i++)
    {
        if (pPilka[0]->Kolizja(*pSciana[i]));
    }
 
    //sprawdzanie kolizji ze ścianami znajdujacymi sie za graczami
    for (int i = 0; i < licznik; i++)
    {
        if (pPilka[0]->Kolizja(*pSciana[2]))
        {
 
            punkty1++;
            pPaletka[0]->Pozycja(-18, 0);
            pPaletka[1]->Pozycja(18, 0);
            pPilka[0]->Pozycja(13, 0);
            pPilka[0]->UstawPredkosc(0, 0);
            pPilka[0]->UstawFizyke(0, 0);
            etap = 1;
 
        }
    }
 
 
    if (pPilka[0]->Kolizja(*pSciana[1]))
    {
        punkty2++;
        pPaletka[0]->Pozycja(-18, 0);
        pPaletka[1]->Pozycja(18, 0);
        pPilka[0]->Pozycja(-13, 0);
        pPilka[0]->UstawPredkosc(0, 0);
        pPilka[0]->UstawFizyke(0, 0);
        etap = 2;
    }
 
    if ((punkty1 > 2 || punkty2 > 2) && punkty1 > punkty2) //warunek ukonczenia gry przez 1. zawodnika
        etap = 3;
 
    if ((punkty1 > 2 || punkty2 > 2) && punkty1 < punkty2)//warunek ukonczenia gry przez 2. zawodnika
        etap = 4;
 
    for (int l = 0; l < licznik; l++)
    {
        //sprawdzanie kolizji z pierwsza paletką
        if (pPilka[0]->Kolizja(*pPaletka[0]));
 
        //wyliczenie nowej pozycji piłki
        pPilka[0]->Aktualizuj(GetTickCount());
 
        pPilka[0]->Reset();
    }
 
 
    for (int l = 0; l < licznik; l++)
    {
        //sprawdzanie kolizji z druga paletką
        if (pPilka[0]->Kolizja(*pPaletka[1]));
 
        //wyliczenie nowej pozycji piłki
        pPilka[0]->Aktualizuj(GetTickCount());
 
        pPilka[0]->Reset();
    }
 
    Sleep(1);
}
 
void PanelOpengl::initializeGL()
{
    glShadeModel(GL_SMOOTH);
    glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
    glClearDepth(1.0f);
    glEnable(GL_DEPTH_TEST);
    glDepthFunc(GL_LEQUAL);
    glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
}
 
void PanelOpengl::paintGL()
{
   glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glLoadIdentity();
 
    for(auto it=pPilka.begin(); it!=pPilka.end(); ++it)
    {
    (*it)->Rysuj();
    }
 
    for(auto it=pPaletka.begin(); it!=pPaletka.end(); ++it)
    {
    (*it)->Rysuj();
    }
 
    for(auto it=pSciana.begin(); it!=pSciana.end(); ++it)
    {
    (*it)->Rysuj();
    }
 
    for(auto it=pScianaP.begin(); it!=pScianaP.end(); ++it)
    {
    (*it)->Rysuj();
    }
 
 
    //glColor3f(0.3, 0.6, 0.5);
    glColor3f(0.1, 0.5, 0.1);
    char wynik[100];//tablica wynikow
    sprintf_s(wynik, "Yellow: %d ", punkty1);
    drawText(13, 17, wynik);
 
    char pole[100];
    sprintf_s(pole, "Red: %d ", punkty2);
    drawText(13, 15, pole);
 
 
    if (etap == 2) //pilka dotyka prawej sciany
    {
        char wynik[100];
        char wynik2[100];
        char wynik3[100];
        glColor3f(1, 0, 0);
        sprintf_s(wynik, "Gracz 1 zdobyl punkt!!!", punkty1);
        drawText2(0, 10, wynik);
        sprintf_s(wynik, "Serwuje GRACZ 1 (czerwony)", punkty1);
        drawText2(0, 8, wynik2);
        sprintf_s(wynik, "(aby zaserwowac wcisnij g)", punkty1);
        drawText2(0, 6, wynik3);
    }
 
    if (etap == 1) //pilka dotyka lewej sciany
    {
        char wynik[100];
        char wynik2[100];
        char wynik3[100];
        glColor3f(1, 1, 0);
        sprintf_s(wynik, "Gracz 1 zdobyl punkt!!!", punkty1);
        drawText2(0, 10, wynik);
        sprintf_s(wynik, "Serwuje GRACZ 2 (zolty)", punkty1);
        drawText2(0, 8, wynik2);
        sprintf_s(wynik, "(aby zaserwowac wcisnij h)", punkty1);
        drawText2(0, 6, wynik3);
    }
 
 
    if (etap == 3) //gracz z zoltym kolorem zdobyl x pkt (koniec gry)
    {
        char wynik1[100];
        char wynik2[100];
        glColor3f(1, 1, 0);
        sprintf_s(wynik1, "KONIEC GRY! WYGRAL ZAWODNIK");
        drawText(-9, 0, wynik1);
        sprintf_s(wynik2, "Z KOLOREM ZOLTYM!!!");
        drawText(-6, -2, wynik2);
    }
    if (etap == 4) //gracz z czerwonym kolorem zdobyl x pkt (koniec gry)
    {
        char wynik3[100];
        char wynik4[100];
        glColor3f(1, 0, 0);
        sprintf_s(wynik3, "KONIEC GRY! WYGRAL ZAWODNIK");
        drawText(-9, 0, wynik3);
        sprintf_s(wynik4, "Z KOLOREM CZERWONYM!!!");
        drawText(-6, -2, wynik4);
    }
     
    glutPostRedisplay();
    glutSwapBuffers();
}
 
void PanelOpengl::resizeGL(int width, int height)
{
    glViewport(0, 0, width, height);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluPerspective(45.0f,(GLfloat)width/(GLfloat)height,0.1f,100.0f);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
 
    //FUNKCJE DODANE
 
    glutKeyboardFunc(&PanelOpengl::key);
    glutMouseFunc(&PanelOpengl::mouse); //poruszanie zoltej i czerownej paletki przy pomocy myszki(klikniecie)
    glutIdleFunc(&PanelOpengl::loop);
 
    //glutPassiveMotionFunc(mouse1); //poruszanie pasywne czerwonej paletki przy pomocy myszki
    //glutPassiveMotionFunc(mouse2); //poruszanie pasywne zoltej paletki przy pomocy myszki
 
 
    glutMainLoop();
 
}

Pojawiające się błędy dotyczą odwoływania się do poszczególnych elementów w vetorze przez [] (czy tam ogólnie odwoływania się). Gdzie np. instrukcja: pPilka[0]->Kolizja(*pSciana[i]) powinna mi dać dostęp do metody klasy Fizyka od kotórej dziedziczą Okrąg i Prostokat, a tak się nie dzieje, nie "widzi" że to jest element klasy Okrąg i Prostokat. Tak jak widać deklarację vektorów są w klasie, w konstruktorze dodaje kolejne elementy i nie mogę się w innych metodach do nich odwołać. Gdzie w takim razie lepiej dodaj elementy do vektora?

Błędy:

błąd: C2597: illegal reference to non-static member 'PanelOpengl::pPaletka'

błąd: C3867: 'PanelOpengl::pPaletka': function call missing argument list; use '&PanelOpengl::pPaletka' to create a pointer to member

błąd: C2109: subscript requires array or pointer type

błąd: C2227: left of '->Pozycja' must point to class/struct/union/generic type

błąd: C2597: illegal reference to non-static member 'PanelOpengl::pPaletka'

1

Hola hola, zagalopowałeś się;

  1. Pokaż hierarchię tych twoich twoich figur, z którymi masz problem.
  2. Pokaż odwołanie, które sprawia problem.

Na co nam ta cała reszta kodu, skoro i tak jest niekompletna?

  • Naprawdę nie musisz się ograniczać do 2 plików na projekt.
0

W sumie tak nie wrzuciłem tej hierarchii ponieważ ona działała mi poza QT, a wrzucłem praktycznie większą część kody z .cpp ponieważ liczę, że specjaliści od QT czy tam OpenGL w QT podpowiedzą mi czy dobrze zdefiniowałem metody i czy np. w dobrym miejscu umieściłem.

glutKeyboardFunc(&PanelOpengl::key);
    glutMouseFunc(&PanelOpengl::mouse); //poruszanie zoltej i czerownej paletki przy pomocy myszki(klikniecie)
    glutIdleFunc(&PanelOpengl::loop);

Nie rozumiem co masz na myśli odnoście ograniczenia się do 2 plików. ponieważ sam pojekt ma ich ponad 10. Sugerujesz, że w jakiś sposób mam jeszcze rozbić tą klasy od OpenGL którą zaprezentowałem ?
No dobrze to wrzucam kody klas figur:

class Prostokat : public Fizyka
{
    float m_a, m_b;//długość i wysokość boku
    int m_kolor;
public:
    /*konstruktory*/
    Prostokat(void);
    Prostokat(float X, float Y, float A, float B, float r, float g, float b);
    ~Prostokat(void);

    /*operacje graficzne*/
    void Rysuj();
    void Przesun(float dx, float dy);
    void Pozycja(float x, float y);
    void Obrot(float z);
    void ZmienKolor(int kolor);
    float Pole();
    void ZmienRozmiar(float A, float B);

    float kolor[3];//przechowuje informacje o kolorze
};
class Okrag : public Fizyka
{
    float m_r;//promień okręgu
    int m_kolor;
public:
    float iks, igrek;
    /*konstruktory*/
    Okrag(void);
    Okrag(float X, float Y, float R, float r, float g, float b);
    ~Okrag(void);

    /*operacje graficzne*/
    void Rysuj();
    void Przesun(float dx, float dy);
    void ZmienKolor(int kolor);
    float Pole();
    void ZmienRozmiar(float A);
    void Pozycja(float x, float y);

    float kolor[3];//przechowuje informacje o kolorze
};
typedef struct sGranica
{
    float xa; //minimalna wartosc x
    float ya; //minimalna wartosc y
    float xb; //maskymalna wartosc x
    float yb; //maskymalna wartosc y
} sGranica;/*granice okreslaja lewy gorny naroznik (xa,ya) i prawy dolny (xb,yb) */


class Fizyka
{
protected:
    int m_czas; //czas ostatniej aktualizacji
    sGranica m_granica; //granice obiektu
    float m_x, m_y; //polozenie srodka masy
    float m_v;//predkosc
    float m_alfa_v;//kierunek wektora predkosci w [stopniach]
    float m_g; //grawitacja
    float m_alfa_g;//kierunek wektora grawitacji

public:
    Fizyka();
    ~Fizyka();
    void Aktualizuj(int czas_aktualny);//zmienia polozenie obiektu na podstawie aktualnego czasu
    void UstawPredkosc(float _v, float _m_alfa_v); //ustawia poczatkowa predkosc
    void UstawFizyke(float _g, float _m_alfa_g); //ustawia poczatkowe przyspieszenie
    void UstawGeometrie(float _x, float _y, float _xa, float _ya, float _xb, float _yb);
    virtual int Kolizja(const Fizyka& X); //wykrywanie kolizji z innym obiektem (funkcja przekazuje 1 gdy jest kolizja 0 gdy brak)
    void Reset(); //resetuje czas

private:
    void Odbicie(float alfa_n); //odbicie od sciany charakteryzowanej za pomoca normalnej alfa_n
    int WProstokacie(float _x, float _y, const Fizyka& X);//wykrywa czy dany punkt (_x,_y) znajduje sie wewnatrz pewnego prostokąta
    float Odleglosc(float _x, float _y, float _xa, float _ya, float _xb, float _yb);//wyznacza odleglosc od pewnej prostej przechodzacej przez 2 punkty
    virtual float ZnajdzNormalna(const Fizyka& X);//znajduje normalna boku ktory jest najblizej srodka obiektu (wynikiem funkcji jest orientacja normalnej);
};

PS Dziękuje za szybką reakcję na mój post.

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