veelenar Temat założony przez niniejszego użytkownika |
[OpenGL] Obrót ścian kostki Rubika - problem z mieszaniem się kolorów » 2015-12-16 21:43:37 Hej, mam taki mały problem z opisaniem obrotów kostki Rubika, mianowicie mam funkcję(kod poniżej), która działa dla obrotu wokół jednej osi, lecz gdy w grę wejdzie więcej niż jedna oś - zaczyna się magia. To znaczy co drugi ruch źle wstawiane są kolory, np. zamiast niebieskiego robi się czarny, który jest wewnątrz kostki. Prosiłbym o sugestie co może być nie tak i co można zmienić, aby obroty działały poprawnie. Dzięki za każdą podpowiedź :) void ObrocMacierzSciany( osObrotu os, kierunekObrotu kierunek, int numerSciany ) { elementKostki macierz[ 3 ][ 3 ]; elementKostki obracanaMacierz[ 3 ][ 3 ]; switch( os ) { case x: for( int x = 0; x < 3; x++ ) for( int y = 0; y < 3; y++ ) { macierz[ x ][ y ] = kostka[ numerSciany ][ x ][ y ]; } break; case y: for( int x = 0; x < 3; x++ ) for( int y = 0; y < 3; y++ ) { macierz[ x ][ y ] = kostka[ x ][ numerSciany ][ y ]; } break; case z: for( int x = 0; x < 3; x++ ) for( int y = 0; y < 3; y++ ) { macierz[ x ][ y ] = kostka[ x ][ y ][ numerSciany ]; } break; } if( kierunek == lewo ) for( int i = 2; i >= 0; i-- ) { for( int j = 0; j < 3; j++ ) { obracanaMacierz[ j ][ 2 - i ] = macierz[ i ][ j ]; } } if( kierunek == prawo ) for( int j = 2; j >= 0; j-- ) { for( int i = 0; i < 3; i++ ) { obracanaMacierz[ 2 - j ][ i ] = macierz[ i ][ j ]; } } for( int i = 0; i < 3; i++ ) for( int j = 0; j < 3; j++ ) { switch( os ) { case x: if( kierunek == lewo ) { obracanaMacierz[ i ][ j ].obrotx -= 1; } else if( kierunek == prawo ) { obracanaMacierz[ i ][ j ].obrotx += 1; } if( obracanaMacierz[ i ][ j ].obrotx < 0 ) obracanaMacierz[ i ][ j ].obrotx = 3; if( obracanaMacierz[ i ][ j ].obrotx > 3 ) obracanaMacierz[ i ][ j ].obrotx = 0; kostka[ numerSciany ][ i ][ j ] = obracanaMacierz[ i ][ j ]; break; case y: if( kierunek == lewo ) { obracanaMacierz[ i ][ j ].obroty -= 1; } else if( kierunek == prawo ) { obracanaMacierz[ i ][ j ].obroty += 1; } if( obracanaMacierz[ i ][ j ].obroty < 0 ) obracanaMacierz[ i ][ j ].obroty = 3; if( obracanaMacierz[ i ][ j ].obroty > 3 ) obracanaMacierz[ i ][ j ].obroty = 0; kostka[ i ][ numerSciany ][ j ] = obracanaMacierz[ i ][ j ]; break; case z: if( kierunek == lewo ) { obracanaMacierz[ i ][ j ].obrotz -= 1; } else if( kierunek == prawo ) { obracanaMacierz[ i ][ j ].obrotz += 1; } if( obracanaMacierz[ i ][ j ].obrotz < 0 ) obracanaMacierz[ i ][ j ].obrotz = 3; if( obracanaMacierz[ i ][ j ].obrotz > 3 ) obracanaMacierz[ i ][ j ].obrotz = 0; kostka[ i ][ j ][ numerSciany ] = obracanaMacierz[ i ][ j ]; break; } } } |
|
DejaVu |
» 2015-12-21 16:47:20 Przypuszczam, że Twoim problemem jest fakt, że nie wykonujesz aktualizacji stanu kostki po wykonaniu obrotu. Zauważ, że skoro pierwsza iteracja działa, to po pierwszej iteracji powinieneś zapisać stan kostki obróconej i zresetować macierz obrotów. W kolejnej iteracji (czyli w kolejnym obrocie) wykonujesz ponownie tą samą operację względem 'aktualnego' stanu, a nie względem 'początkowego stanu kostki'. |
|
veelenar Temat założony przez niniejszego użytkownika |
» 2015-12-28 12:05:59 To może mieć sens, jednakże poprawiłem kolejność obrotów osi w funkcji wyświetlającej, teraz mam sytuację, że pierwsza seria obrotów (90 stopni w każdej płaszczyźnie) idzie zgodnie z założeniem, a następnie x i y się psują, a z idzie poprawnie. Nie wiem, czy faktycznie jest to problem, że po pierwszej serii obrotów powinienem zapisać stan kostki, czy jest to problem z czym innej, ale podejrzewam, że siedzi to w tej funkcji, lub w funkcji wyświetlania. Dzięki za podpowiedź, dam znać, czy rozwiązanie pomogło :) |
|
Gabes |
» 2015-12-28 19:42:43 Czy nie powinieneś korzystać z tablicy trójwymiarowej? Na Warsztat.GD widziałem jakiś czas temu projekt kostki może znajdziesz kontakt, jakąś konkretną pomoc.:) |
|
veelenar Temat założony przez niniejszego użytkownika |
» 2015-12-28 20:48:41 Ogólnie używam tablicy 3-wymiarowej. Te 2 wymiary to macierze pomocnicze, które mają za zadanie obrócić macierz wybranej ściany, a później ta macierz jest dopisywana do tablicy 3-wymiarowej w zależności czy jest to x, y czy z. |
|
veelenar Temat założony przez niniejszego użytkownika |
» 2016-01-06 14:11:39 Analizując indeksowania wpadłem na pomysł, że problemem mogłoby być złe skonstruowanie funkcji wyświetlania. Jeśli Wam to coś powie to wstawiam kod poniżej. Każda sugestia przebudowy jest jak najbardziej mile widziana :) void Display() { if( !frames++ ) start_time = clock(); glClearColor( 0.3, 0.3, 0.3, 1.0 ); glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); glMatrixMode( GL_MODELVIEW ); glEnable( GL_DEPTH_TEST ); timer(); for( int x = 0; x < 3; x++ ) { for( int y = 0; y < 3; y++ ) { for( int z = 0; z < 3; z++ ) { int * kolor = kostka[ x ][ y ][ z ].kolor; glLoadIdentity(); glTranslatef( 0, 0, -( neaar + faar ) / 2 ); glScalef( scale, scale, scale ); glRotatef( rotatex, 1.0, 0, 0 ); glRotatef( rotatey, 0, 1.0, 0 ); if( os == osObrotu::x ) { if( rotateWallDepth == x ) { glRotatef( rotateWall, 1.0, 0, 0 ); } } else if( os == osObrotu::y ) { if( rotateWallDepth == y ) { glRotatef( rotateWall, 0, 1.0, 0 ); } } else if( os == osObrotu::z ) { if( rotateWallDepth == z ) { glRotatef( rotateWall, 0, 0, 1.0 ); } } glTranslatef( x * 0.6f - 0.6f,( y *- 0.6f ) + 0.6,( z *- 0.6f ) + 0.6f ); glRotatef(( GLfloat )( 90.0f *( float )( kostka[ x ][ y ][ z ].obrotz ) ), 0, 0, 1.0f ); glRotatef(( GLfloat )( 90.0f *( float )( kostka[ x ][ y ][ z ].obroty ) ), 0, 1.0f, 0 ); glRotatef(( GLfloat )( 90.0f *( float )( kostka[ x ][ y ][ z ].obrotx ) ), 1.0f, 0, 0 ); RysujSzescian( 0, 0, 0, kolor[ 0 ], kolor[ 1 ], kolor[ 2 ] ); } } } rotateWall += 0.05; if( rotateWall >= 90 ) { rotateWall = 0; if( os == osObrotu::z ) { ObrocMacierzSciany( os, lewo, rotateWallDepth ); } else { ObrocMacierzSciany( os, prawo, rotateWallDepth ); } rotateWallDepth++; if( rotateWallDepth > 2 ) rotateWallDepth = 0; if( os == osObrotu::x ) os = osObrotu::y; else if( os == osObrotu::y ) os = osObrotu::z; else if( os == osObrotu::z ) os = osObrotu::x; } glLoadIdentity(); glTranslatef( 0, 0, - neaar ); glColor3ub( 255, 255, 255 ); DrawString( - 12.5, 9.5, time_string ); glFlush(); glutSwapBuffers(); } Dorzucam również kod funkcji generującej kostkę. void GenerujKostke() { for( int x = 0; x < 3; x++ ) { for( int y = 0; y < 3; y++ ) { for( int z = 0; z < 3; z++ ) { kostka[ x ][ y ][ z ].iloscScian = dwie; kostka[ x ][ y ][ z ].kolor[ 0 ] = 0; kostka[ x ][ y ][ z ].kolor[ 1 ] = 0; kostka[ x ][ y ][ z ].kolor[ 2 ] = 0; kostka[ z ][ y ][ x ].numerElementu = x + y + z; kostka[ x ][ y ][ z ].obrotx = 0; kostka[ x ][ y ][ z ].obroty = 0; kostka[ x ][ y ][ z ].obrotz = 0; } } } kostka[ 1 ][ 1 ][ 0 ].iloscScian = jedna; kostka[ 1 ][ 1 ][ 2 ].iloscScian = jedna; kostka[ 1 ][ 0 ][ 1 ].iloscScian = jedna; kostka[ 1 ][ 2 ][ 1 ].iloscScian = jedna; kostka[ 0 ][ 1 ][ 1 ].iloscScian = jedna; kostka[ 2 ][ 1 ][ 1 ].iloscScian = jedna; for( int i = 0; i < 3; i++ ) { for( int j = 0; j < 3; j++ ) { kostka[ 0 ][ i ][ j ].kolor[ 0 ] = 6; kostka[ 2 ][ i ][ j ].kolor[ 0 ] = 5; kostka[ i ][ 0 ][ j ].kolor[ 1 ] = 3; kostka[ i ][ 2 ][ j ].kolor[ 1 ] = 2; kostka[ i ][ j ][ 0 ].kolor[ 2 ] = 4; kostka[ i ][ j ][ 2 ].kolor[ 2 ] = 1; if(( i == 0 && j == 0 ) ||( i == 0 && j == 2 ) ||( i == 2 && j == 0 ) ||( i == 2 && j == 2 ) ) { kostka[ i ][ j ][ 0 ].iloscScian = trzy; kostka[ i ][ j ][ 2 ].iloscScian = trzy; } } } |
|
DejaVu |
» 2016-01-07 16:34:41 Raczej trudno o ochotników szukających bugów w Twoim programie. Dostałeś wskazówki w czym może być problem i powinieneś spróbować samodzielnie drążyć dalej temat. |
|
« 1 » |