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'
PS Wrzuciłem tak dużą liczbę metod ponieważ liczę, że specjaliści o QT podowiedzą mi czy dobrze zaimplementowałem OpenGL w QT? Czy np. w dobry miejscu umieściłem:
glutKeyboardFunc(&PanelOpengl::key);
glutMouseFunc(&PanelOpengl::mouse); //poruszanie zoltej i czerownej paletki przy pomocy myszki(klikniecie)
glutIdleFunc(&PanelOpengl::loop);
Dziękuję za wszelką uwagę i odpowiedzi.